CVS merge

Yet even more code merged.
This commit is contained in:
some weird guy
2023-08-02 02:04:18 -04:00
parent 0d30171496
commit ef1396fe03
37 changed files with 3758 additions and 3643 deletions
+19 -4
View File
@@ -171,11 +171,26 @@ nnid_forbiddens = BASE_DIR + '/forbidden.json'
# Client key to use for iphub.email, because we're using that # Client key to use for iphub.email, because we're using that
# None for no IP checking (recommended since this is so slow) # None for no IP checking (recommended since this is so slow)
iphub_key = "" IPHUB_KEY = ""
# If IP can be checked, then use this to disallow any proxies # If IP can be checked, then use this to disallow any proxies
disallow_proxy = False disallow_proxy = False
# Setting this to True forces every user to log in/
# sign up for the site to view any content.
FORCE_LOGIN = False
# A list of URLs that are always accessible
# whether the above value is set or not.
LOGIN_EXEMPT_URLS = {
r'^login/$',
r'^signup/$',
r'^logout/$',
r'^reset/$',
r'^help/rules$',
r'^help/contact$',
r'^help/login$',
}
# MD # MD
MARKDOWN_DEUX_STYLES = { MARKDOWN_DEUX_STYLES = {
"default": { "default": {
@@ -190,17 +205,17 @@ MARKDOWN_DEUX_STYLES = {
allow_signups = True allow_signups = True
# Whatever the reason may be, you have the option to make your clone invite only. # Whatever the reason may be, you have the option to make your clone invite only.
invite_only = True invite_only = False
# Minimum level required to view IP addresses and user agents. (default: 10) # Minimum level required to view IP addresses and user agents. (default: 10)
# Mods under this level will still be able to manage users, however will not be able to view any sensitive data. # Mods under this level will still be able to manage users, however will not be able to view any sensitive data.
min_lvl_metadata_perms = 100 min_lvl_metadata_perms = 100
# if someone's level is equal or above this, they can edit most community on your clone. # if someone's level is equal or above this, they can edit most community on your clone.
level_needed_to_man_communities = 10 level_needed_to_man_communities = 5
# if someone's level is equal or above this, they can edit any user with a lower level on your clone. # if someone's level is equal or above this, they can edit any user with a lower level on your clone.
level_needed_to_man_users = 10 level_needed_to_man_users = 5
# file size limits in megabytes! only applies when using the community tools. # file size limits in megabytes! only applies when using the community tools.
max_icon_size = .5 max_icon_size = .5
+70 -70
View File
@@ -14,121 +14,121 @@ admin.site.login = login_page
""" """
class UserForm(ModelForm): class UserForm(ModelForm):
class Meta: class Meta:
model = models.User model = models.User
fields = '__all__' fields = '__all__'
widgets = { widgets = {
'password': PasswordInput(), 'password': PasswordInput(),
} }
""" """
@admin.action(description='Hide selected items') @admin.action(description='Hide selected items')
def Hide_Memo(modeladmin, request, queryset): def Hide_Memo(modeladmin, request, queryset):
queryset.update(show = False) queryset.update(show = False)
@admin.action(description='Show selected items') @admin.action(description='Show selected items')
def Show_Memo(modeladmin, request, queryset): def Show_Memo(modeladmin, request, queryset):
queryset.update(show = True) queryset.update(show = True)
@admin.action(description='Hide selected items') @admin.action(description='Hide selected items')
def Hide_content(modeladmin, request, queryset): def Hide_content(modeladmin, request, queryset):
queryset.update(is_rm = True) queryset.update(is_rm = True)
@admin.action(description='Show selected items') @admin.action(description='Show selected items')
def Show_content(modeladmin, request, queryset): def Show_content(modeladmin, request, queryset):
queryset.update(is_rm = False) queryset.update(is_rm = False)
@admin.action(description='Feature selected communities') @admin.action(description='Feature selected communities')
def Feature_community(modeladmin, request, queryset): def Feature_community(modeladmin, request, queryset):
queryset.update(is_feature = True) queryset.update(is_feature = True)
@admin.action(description='Unfeature selected communities') @admin.action(description='Unfeature selected communities')
def Unfeature_community(modeladmin, request, queryset): def Unfeature_community(modeladmin, request, queryset):
queryset.update(is_feature = False) queryset.update(is_feature = False)
@admin.action(description='Force login') @admin.action(description='Force login')
def force_login(modeladmin, request, queryset): def force_login(modeladmin, request, queryset):
queryset.update(require_auth = True) queryset.update(require_auth = True)
@admin.action(description='Unforce login') @admin.action(description='Unforce login')
def unforce_login(modeladmin, request, queryset): def unforce_login(modeladmin, request, queryset):
queryset.update(require_auth = False) queryset.update(require_auth = False)
@admin.action(description='Disable user') @admin.action(description='Disable user')
def Disable_user(modeladmin, request, queryset): def Disable_user(modeladmin, request, queryset):
queryset.update(active = False) queryset.update(active = False)
class UserAdmin(admin.ModelAdmin): class UserAdmin(admin.ModelAdmin):
search_fields = ('id', 'unique_id', 'username', 'nickname', 'email', ) search_fields = ('id', 'unique_id', 'username', 'nickname', 'email', )
list_display = ('id', 'username', 'nickname', 'warned', 'level', 'staff', 'active', ) list_display = ('id', 'username', 'nickname', 'warned', 'level', 'staff', 'active', )
exclude = ('addr', 'signup_addr', 'password', ) exclude = ('addr', 'signup_addr', 'password', )
actions = [Disable_user] actions = [Disable_user]
#exclude = ('staff', ) #exclude = ('staff', )
# Not yet # Not yet
#form = UserForm #form = UserForm
class ProfileAdmin(admin.ModelAdmin): class ProfileAdmin(admin.ModelAdmin):
search_fields = ('id', 'unique_id', 'origin_id', ) search_fields = ('id', 'unique_id', 'origin_id', )
raw_id_fields = ('user', 'favorite', 'adopted', ) raw_id_fields = ('user', 'favorite', )
list_display = ('id', 'user', 'comment', 'let_freedom', ) list_display = ('id', 'user', 'comment', 'let_freedom', )
class ComplaintAdmin(admin.ModelAdmin): class ComplaintAdmin(admin.ModelAdmin):
search_fields = ('id', 'unique_id', 'body', ) search_fields = ('id', 'unique_id', 'body', )
raw_id_fields = ('creator', ) raw_id_fields = ('creator', )
class ConversationAdmin(admin.ModelAdmin): class ConversationAdmin(admin.ModelAdmin):
search_fields = ('id', 'unique_id', ) search_fields = ('id', 'unique_id', )
raw_id_fields = ('source', 'target', ) raw_id_fields = ('source', 'target', )
class PostAdmin(admin.ModelAdmin): class PostAdmin(admin.ModelAdmin):
raw_id_fields = ('creator', 'poll', ) raw_id_fields = ('creator', 'poll', )
search_fields = ('id', 'unique_id', 'body', 'creator__username', ) search_fields = ('id', 'unique_id', 'body', 'creator__username', )
list_display = ('id', 'creator', 'body', 'is_rm', ) list_display = ('id', 'creator', 'body', 'is_rm', )
actions = [Hide_content, Show_content] actions = [Hide_content, Show_content]
def get_queryset(self, request): def get_queryset(self, request):
return models.Post.real.get_queryset() return models.Post.real.get_queryset()
class CommentAdmin(admin.ModelAdmin): class CommentAdmin(admin.ModelAdmin):
raw_id_fields = ('creator', 'original_post', ) raw_id_fields = ('creator', 'original_post', )
search_fields = ('id', 'unique_id', 'body', 'creator__username', ) search_fields = ('id', 'unique_id', 'body', 'creator__username', )
list_display = ('id', 'creator', 'body', 'original_post', 'is_rm', ) list_display = ('id', 'creator', 'body', 'original_post', 'is_rm', )
actions = [Hide_content, Show_content] actions = [Hide_content, Show_content]
def get_queryset(self, request): def get_queryset(self, request):
return models.Comment.real.get_queryset() return models.Comment.real.get_queryset()
class CommunityAdmin(admin.ModelAdmin): class CommunityAdmin(admin.ModelAdmin):
raw_id_fields = ('creator', ) raw_id_fields = ('creator', )
list_display = ('id', 'name', 'description', 'type', 'creator', 'is_rm', 'is_feature', 'require_auth') list_display = ('id', 'name', 'description', 'type', 'creator', 'is_rm', 'is_feature', 'require_auth')
search_fields = ('id', 'unique_id', 'name', 'description', ) search_fields = ('id', 'unique_id', 'name', 'description', )
actions = [Hide_content, Show_content, Feature_community, Unfeature_community, force_login, unforce_login] actions = [Hide_content, Show_content, Feature_community, Unfeature_community, force_login, unforce_login]
def get_queryset(self, request): def get_queryset(self, request):
return models.Community.real.get_queryset() return models.Community.real.get_queryset()
class MessageAdmin(admin.ModelAdmin): class MessageAdmin(admin.ModelAdmin):
raw_id_fields = ('creator', 'conversation', ) raw_id_fields = ('creator', 'conversation', )
search_fields = ('id', 'unique_id', 'body', 'creator__username', ) search_fields = ('id', 'unique_id', 'body', 'creator__username', )
list_display = ('id', 'creator', 'conversation', 'body', ) list_display = ('id', 'creator', 'conversation', 'body', )
actions = [Hide_content, Show_content] actions = [Hide_content, Show_content]
def get_queryset(self, request): def get_queryset(self, request):
return models.Message.real.get_queryset() return models.Message.real.get_queryset()
class NotificationAdmin(admin.ModelAdmin): class NotificationAdmin(admin.ModelAdmin):
raw_id_fields = ('to', 'source', 'context_post', 'context_comment', ) raw_id_fields = ('to', 'source', 'context_post', 'context_comment', )
search_fields = ('unique_id', ) search_fields = ('unique_id', )
list_display = ('id', 'to', 'source', 'context_post', 'context_comment', ) list_display = ('id', 'to', 'source', 'context_post', 'context_comment', )
class AuditAdmin(admin.ModelAdmin): class AuditAdmin(admin.ModelAdmin):
raw_id_fields = ('by', 'user', 'post', 'comment', 'reversed_by', ) raw_id_fields = ('by', 'user', 'post', 'comment', 'reversed_by', )
search_fields = ('by__username', 'user__username', ) search_fields = ('by__username', 'user__username', )
class AdsAdmin(admin.ModelAdmin): class AdsAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'url', 'imageurl') raw_id_fileds = ('id', 'created', 'url', 'imageurl')
class InvitesAdmin(admin.ModelAdmin): class InvitesAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'creator') raw_id_fileds = ('id', 'created', 'creator')
class WelcomemsgAdmin(admin.ModelAdmin): class WelcomemsgAdmin(admin.ModelAdmin):
raw_id_fileds = ('id', 'created', 'message', ) raw_id_fileds = ('id', 'created', 'message', )
list_display = ('Title', 'message', 'show', 'order', 'created', ) list_display = ('Title', 'message', 'show', 'order', 'created', )
actions = [Hide_Memo, Show_Memo] actions = [Hide_Memo, Show_Memo]
class YeahAdmin(admin.ModelAdmin): class YeahAdmin(admin.ModelAdmin):
raw_id_fields = ('by', 'post', 'comment', ) raw_id_fields = ('by', 'post', 'comment', )
list_display = ('by', 'post', 'comment', ) list_display = ('by', 'post', 'comment', )
search_fields = ('by__username', 'post__body', 'comment__body', ) search_fields = ('by__username', 'post__body', 'comment__body', )
class HistoryAdmin(admin.ModelAdmin): class HistoryAdmin(admin.ModelAdmin):
raw_id_fields = ('user',) raw_id_fields = ('user',)
list_display = ('id', 'user') list_display = ('id', 'user')
#class BlockAdmin(admin.ModelAdmin) #class BlockAdmin(admin.ModelAdmin)
+1653 -1651
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -19,7 +19,7 @@ class CommunitySerializer():
'platform': community.platform, 'platform': community.platform,
'allowed_users': json.loads(community.allowed_users) if community.allowed_users else None, 'allowed_users': json.loads(community.allowed_users) if community.allowed_users else None,
'creator': community.creator_id 'creator': community.creator_id
} }
@staticmethod @staticmethod
def many(queryset): def many(queryset):
""" """
@@ -10,9 +10,9 @@
<h2>What can I do with my own community?</h2> <h2>What can I do with my own community?</h2>
<p>You can edit it, and that's basically it.</p> <p>You can edit it, and that's basically it.</p>
<h2>What are C-Tokens, and how do I get them?</h2> <h2>What are C-Tokens, and how do I get them?</h2>
<p>Community tokens are a stupid and overcomplicated method of preventing 200,000 communities from being made by one person. You get one when signing up, and you can use it to make your own community. You'll have to ask a staff member for more C-Tokens if you want to make more communities.&nbsp;</p> <p>Community tokens are a stupid and overcomplicated method of preventing 200,000 communities from being made by one person. You get one when signing up, and you can use it to make your own community. Please do not ask staff for more C-Tokens unless you believe the communities you are going to make are really that good.</p>
<h2>Any future plans?</h2> <h2>Any future plans?</h2>
<p>Fuck, I got no clue. Maybe I should make C-Tokens tradable, or make a community ban system, so you can block people from posting and commenting in your own communities.</p> <p>no</p>
</div> </div>
{% if request.user.c_tokens > 0 %}<a class="big-button" href={% url "main:community-create" %}><span class="symbol-label">Create a community</span></a>{% endif %} {% if request.user.c_tokens > 0 %}<a class="big-button" href={% url "main:community-create" %}><span class="symbol-label">Create a community</span></a>{% endif %}
</div> </div>
@@ -17,7 +17,7 @@
{% post_form request.user community %} {% post_form request.user community %}
{% endif %} {% endif %}
<div class="body-content" id="community-post-list"> <div class="body-content" id="community-post-list">
{% post_list posts next %} {% post_list posts next 0 '' time %}
</div> </div>
</div> </div>
</div> </div>
@@ -0,0 +1,19 @@
{% load closedverse_user %}{% if profile.can_block %}
<div class="dialog none" data-modal-types="post-block">
<div class="dialog-inner">
<div class="window">
<h1 class="window-title">{% if profile.is_blocked %}Unblock{% else %}Block{% endif %} {{ user.nickname }}</h1>
<div class="window-body">
{% user_sidebar_info user profile %}
<form method="post" data-action="{% url "main:user-addblock" user.username %}">
<p class="window-body-content">Really {% if profile.is_blocked %}un{% endif %}block this user?{% if not profile.is_blocked %} You won't be able to see each other's posts or profile.{% endif %}</p>
<div class="form-buttons">
<input type="button" class="olv-modal-close-button gray-button" value="No">
<input type="submit" value="Yes" class="post-button black-button">
</div>
</form>
</div>
</div>
</div>
</div>
{% endif %}
@@ -1,6 +1,7 @@
{% load closedverse_community %}<form id="reply-form" class="for-identified-user" method="post" action="{% url "main:post-comments" post.id %}"> {% load closedverse_community %}
{% if user.is_active %}
<form id="reply-form" class="for-identified-user" method="post" action="{% url "main:post-comments" post.id %}">
{% csrf_token %} {% csrf_token %}
{% if user.is_active %}
{% if not user.limit_remaining is False %} {% if not user.limit_remaining is False %}
<div class="post-count-container"> <div class="post-count-container">
<span>Remaining posts for today</span> <span>Remaining posts for today</span>
@@ -40,8 +41,6 @@
</label> </label>
</div> </div>
</div> </div>
<div class="form-buttons"> <div class="form-buttons">
@@ -51,5 +50,5 @@
{% endif %} {% endif %}
{% if not user.is_active %} {% if not user.is_active %}
<p>Your account has been disabled.</p> <p class="center">Your account has been disabled.</p>
{% endif %} {% endif %}
@@ -1,5 +1,5 @@
{% if not post.is_rm %} {% if not post.is_rm %}
{% load closedverse_tags %}<div id="{{ post.unique_id }}" {% if post.spoils or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}" class="post post-subtype-default trigger{% if post.spoils or not post.creator.is_active %} hidden test-hidden{% endif %}{% if type == 2 %} post-list-outline{% endif %}" tabindex="0"> {% load closedverse_tags %}<div id="{{ post.unique_id }}" {% if post.spoils and not post.is_mine or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% if post.is_reply %}{% url "main:comment-view" post.id %}{% else %}{% url "main:post-view" post.id %}{% endif %}" class="post post-subtype-default trigger{% if post.spoils and not post.is_mine or not post.creator.is_active or post.user_is_blocked %} hidden test-hidden{% endif %}{% if type == 2 %} post-list-outline{% endif %}" tabindex="0">
{% if with_community_container %} {% if with_community_container %}
<p class="community-container"> <p class="community-container">
{% if post.is_reply %} {% if post.is_reply %}
@@ -16,8 +16,8 @@
{% endif %} {% endif %}
<p class="user-name"><a href="{% url "main:user-view" post.creator.username %}"{% if post.creator.color %}style=color:{{ post.creator.color }}{% endif %}>{{ post.creator.nickname }}</a></p> <p class="user-name"><a href="{% url "main:user-view" post.creator.username %}"{% if post.creator.color %}style=color:{{ post.creator.color }}{% endif %}>{{ post.creator.nickname }}</a></p>
{% if not post.creator.is_active %} {% if not post.creator.is_active %}
<p style="color: #f00;">Banned</p> <p style="color: #f00;">Banned</p>
{% endif %} {% endif %}
<p class="timestamp-container"> <p class="timestamp-container">
<span class="spoiler-status{% if post.spoils %} spoiler{% endif %}">Spoilers·</span> <span class="spoiler-status{% if post.spoils %} spoiler{% endif %}">Spoilers·</span>
{% if post.has_edit %} {% if post.has_edit %}
@@ -56,7 +56,11 @@
{% endif %} {% endif %}
<button type="button" class="hidden-content-button">View Anyway</button> <button type="button" class="hidden-content-button">View Anyway</button>
</p></div> </p></div>
{% endif %} {% elif post.user_is_blocked %}
<div class="hidden-content"><p>Content hidden because you've blocked this user.</p>
<button type="button" class="hidden-content-button">View Anyway</button>
</div>
{% endif %}
<div class="post-meta"> <div class="post-meta">
<button type="button" {% if not post.can_yeah %}disabled{% endif %} class="symbol submit yeah-button <button type="button" {% if not post.can_yeah %}disabled{% endif %} class="symbol submit yeah-button
{% if post.has_yeah %}empathy-added{% endif %} {% if post.has_yeah %}empathy-added{% endif %}
@@ -5,7 +5,7 @@
</div> </div>
--> -->
<label class="file-button-container"> <label class="file-button-container">
<span class="input-label">Image <span id="image-dimensions">PNG, JPG, JPEG and GIF are allowed.</span></span> <span class="input-label">Image <span id="image-dimensions">PNG and JPEG are allowed.</span></span>
<span class="button file-upload-button">Upload</span> <span class="button file-upload-button">Upload</span>
<input accept="image/gif, image/png, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" id="upload-file"> <input accept="image/gif, image/png, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" id="upload-file">
<input type="hidden" id="upload-input" name="screen"> <input type="hidden" id="upload-input" name="screen">
@@ -1,6 +1,7 @@
{% load closedverse_community %}<form id="post-form" method="post" action="{% url "main:messages-view" friend.username %}" class="folded"> {% load closedverse_community %}
{% csrf_token %}
{% if user.is_active %} {% if user.is_active %}
<form id="post-form" method="post" action="{% url "main:messages-view" friend.username %}" class="folded">
{% csrf_token %}
{% feeling_selector %} {% feeling_selector %}
<div class="textarea-with-menu active-text"> <div class="textarea-with-menu active-text">
<menu class="textarea-menu"> <menu class="textarea-menu">
@@ -37,5 +38,5 @@
</form> </form>
{% endif %} {% endif %}
{% if not user.is_active %} {% if not user.is_active %}
<p>Your account has been disabled.</p> <p class="center">Your account has been disabled.</p>
{% endif %} {% endif %}
@@ -1,4 +1,4 @@
{% if not comment.is_rm %}{% load closedverse_tags %}<li id="{{ comment.unique_id }}" {% if comment.spoils or not comment.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:comment-view" comment.id %}" class="post {% if comment.owner_post %}my{% else %}other{% endif %}{% if comment.spoils or not comment.creator.is_active %} hidden{% endif %} trigger"> {% if not comment.is_rm %}{% load closedverse_tags %}<li id="{{ comment.unique_id }}" {% if comment.spoils and not comment.is_mine or not comment.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:comment-view" comment.id %}" class="post {% if comment.owner_post %}my{% else %}other{% endif %}{% if comment.spoils and not comment.is_mine or not comment.creator.is_active %} hidden{% endif %} trigger">
{% user_icon_container comment.creator comment.feeling %} {% user_icon_container comment.creator comment.feeling %}
<div class="body"> <div class="body">
<div class="header"> <div class="header">
@@ -9,7 +9,7 @@
<p class="timestamp-container"> <p class="timestamp-container">
<a class="timestamp" {% if comment.spoils and not comment.is_mine %}data-href-hidden{% else %}href{% endif %}="{% url "main:comment-view" comment.id %}">{% time comment.created %}</a> <a class="timestamp" {% if comment.spoils and not comment.is_mine %}data-href-hidden{% else %}href{% endif %}="{% url "main:comment-view" comment.id %}">{% time comment.created %}</a>
{% if comment.drawing %} {% if comment.drawing %}
<span class="spoiler">(drawing)</span> <span class="spoiler">(handwritten)</span>
{% endif %} {% endif %}
{% if comment.has_edit %} {% if comment.has_edit %}
<span class="spoiler">· Edited</span> <span class="spoiler">· Edited</span>
@@ -26,7 +26,7 @@
{% if comment.screenshot %} {% if comment.screenshot %}
<div class="screenshot-container still-image"><img src="{{ comment.screenshot }}"></div> <div class="screenshot-container still-image"><img src="{{ comment.screenshot }}"></div>
{% endif %} {% endif %}
{% if comment.spoils and comment.creator.is_active %} {% if comment.spoils and not comment.is_mine and comment.creator.is_active %}
<div class="hidden-content"><p>This comment contains spoilers.</p> <div class="hidden-content"><p>This comment contains spoilers.</p>
<button type="button" class="hidden-content-button">View Comment</button> <button type="button" class="hidden-content-button">View Comment</button>
</div> </div>
@@ -48,4 +48,4 @@
</div> </div>
</div> </div>
</li> </li>
{% endif %} {% endif %}
@@ -1,7 +1,8 @@
{% load closedverse_community %}<form id="post-form" method="post" action="{% url "main:post-create" community.id %}" class="folded for-identified-user" data-post-subtype="default" name="test-post-default-form"> {% load closedverse_community %}
{% if user.is_active %}
<form id="post-form" method="post" action="{% url "main:post-create" community.id %}" class="folded for-identified-user" data-post-subtype="default" name="test-post-default-form">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="community" value="{{ community.unique_id }}"> <input type="hidden" name="community" value="{{ community.unique_id }}">
{% if user.is_active %}
{% if not user.limit_remaining is False %} {% if not user.limit_remaining is False %}
<div class="post-count-container"> <div class="post-count-container">
<span>Remaining posts for today</span> <span>Remaining posts for today</span>
@@ -65,5 +66,5 @@
{% endif %} {% endif %}
{% if not user.is_active %} {% if not user.is_active %}
<p>Your account has been disabled.</p> <p class="center">Your account has been disabled.</p>
{% endif %} {% endif %}
@@ -1,4 +1,4 @@
{% load closedverse_tags %}{% load closedverse_community %}<div class="list post-list js-post-list" data-next-page-url="{% if next %}?offset={{ next }}{% endif %}"> {% load closedverse_tags %}{% load closedverse_community %}<div class="list post-list js-post-list" data-next-page-url="{% if next %}?offset={{ next }}{% if time %}&offset_time={{ time|urlencode }}{% endif %}{% endif %}">
{% if posts %} {% if posts %}
{% for post in posts %} {% for post in posts %}
{% community_post post type %} {% community_post post type %}
@@ -6,4 +6,4 @@
{% else %} {% else %}
{% if nf %}{% nocontent nf %}{% else %}{% nocontent "The posts couldn't be loaded." %}{% endif %} {% if nf %}{% nocontent nf %}{% else %}{% nocontent "The posts couldn't be loaded." %}{% endif %}
{% endif %} {% endif %}
</div> </div>
@@ -1,4 +1,4 @@
{% load closedverse_tags %}<div id="{{ post.unique_id }}" {% if post.spoils or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:post-view" post.id %}" class="post trigger{% if post.screenshot %} with-image{% endif %}{% if post.spoils or not post.creator.is_active %} hidden test-hidden{% endif %}" tabindex="0"> {% load closedverse_tags %}<div id="{{ post.unique_id }}" {% if post.spoils and not post.is_mine or not post.creator.is_active %}data-href-hidden{% else %}data-href{% endif %}="{% url "main:post-view" post.id %}" class="post trigger{% if post.screenshot %} with-image{% endif %}{% if post.spoils and not post.is_mine or not post.creator.is_active %} hidden test-hidden{% endif %}" tabindex="0">
<p class="community-container"><a {% if post.community.clickable %}href="{% url "main:community-view" post.community_id %}"{% endif %}><img src="{{ post.community.icon }}" class="community-icon">{{ post.community.name }}</a></p> <p class="community-container"><a {% if post.community.clickable %}href="{% url "main:community-view" post.community_id %}"{% endif %}><img src="{{ post.community.icon }}" class="community-icon">{{ post.community.name }}</a></p>
@@ -37,7 +37,7 @@
<p class="post-content-text">{{ post.body|truncatechars:100|linebreaksbr }}</p> <p class="post-content-text">{{ post.body|truncatechars:100|linebreaksbr }}</p>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if post.spoils and post.creator.is_active %} {% if post.spoils and not post.is_mine and post.creator.is_active %}
<div class="hidden-content"><p>This post contains spoilers. <div class="hidden-content"><p>This post contains spoilers.
<button type="button" class="hidden-content-button">View Post</button> <button type="button" class="hidden-content-button">View Post</button>
</p></div> </p></div>
@@ -1,4 +1,4 @@
{% load closedverse_tags %}{% load closedverse_user %}<div class="list post-list js-post-list" data-next-page-url="{% if next %}?offset={{ next }}{% endif %}"> {% load closedverse_tags %}{% load closedverse_user %}<div class="list post-list js-post-list" data-next-page-url="{% if next %}?offset={{ next }}{% if time %}&offset_time={{ time|urlencode }}{% endif %}{% endif %}">
{% if posts %} {% if posts %}
{% for post in posts %} {% for post in posts %}
{% user_post post type %} {% user_post post type %}
@@ -6,4 +6,4 @@
{% else %} {% else %}
{% if nf %}{% nocontent nf %}{% else %}{% nocontent "The posts couldn't be loaded." %}{% endif %} {% if nf %}{% nocontent nf %}{% else %}{% nocontent "The posts couldn't be loaded." %}{% endif %}
{% endif %} {% endif %}
</div> </div>
@@ -30,14 +30,16 @@
</a> </a>
{% endif %} {% endif %}
{% user_sidebar_info user profile %} {% user_sidebar_info user profile %}
{% if request.user.is_authenticated and not user.is_me %} {% if request.user.is_authenticated and not user.is_me and profile.can_friend or profile.can_follow or request.user.can_manage %}
<div class="user-action-content"> <div class="user-action-content">
<div class="toggle-button"> <div class="toggle-button">
{% if profile.can_follow and not user.is_me %}
<button type="button" data-action="{% url "main:user-follow" user.username %}" class="follow-button button symbol{% if user.is_following %} none{% endif %}">Follow</button> <button type="button" data-action="{% url "main:user-follow" user.username %}" class="follow-button button symbol{% if user.is_following %} none{% endif %}">Follow</button>
<button type="button" data-action="{% url "main:user-unfollow" user.username %}" class="unfollow-button button symbol{% if not user.is_following %} none{% endif %}" data-screen-name="{{ user.nickname }}">Follow</button> <button type="button" data-action="{% url "main:user-unfollow" user.username %}" class="unfollow-button button symbol{% if not user.is_following %} none{% endif %}" data-screen-name="{{ user.nickname }}">Follow</button>
{% endif %}
{% if selection == 0 %} {% if selection == 0 %}
{% if user.friend_state == 0 %} {% if user.friend_state == 0 %}
{% if profile.can_friend %} {% if profile.can_friend and not user.is_me %}
<button type="button" data-action="{% url "main:user-fr-create" user.username %}" class="friend-button create button symbol">Send friend request</button> <button type="button" data-action="{% url "main:user-fr-create" user.username %}" class="friend-button create button symbol">Send friend request</button>
{% endif %} {% endif %}
{% elif user.friend_state == 1 %} {% elif user.friend_state == 1 %}
@@ -51,10 +53,11 @@
{% if not has_authority and request.user.can_manage %} {% if not has_authority and request.user.can_manage %}
<button class="button" data-href="{% url "main:user-tools" user.username %}">User Settings</button> <button class="button" data-href="{% url "main:user-tools" user.username %}">User Settings</button>
{% endif %} {% endif %}
{% if not user.is_me and profile.can_block %}
<button type="button" class="button block-button">{% if profile.is_blocked %}Unblock{% else %}Block{% endif %}</button>
{% endif %}
</div> </div>
{% if fr %}{% fr_accept fr %}{% endif %} {% if fr %}{% fr_accept fr %}{% endif %}
{% if user.friend_state == 0 %} {% if user.friend_state == 0 %}
<div class="dialog none" data-modal-types="post-friend-request"> <div class="dialog none" data-modal-types="post-friend-request">
@@ -64,11 +67,7 @@
<div class="window-body"> <div class="window-body">
<p class="description">Friend Request: <img width="36px" height="36px" src="{% avatar user %}">{{ user.nickname }}</p> <p class="description">Friend Request: <img width="36px" height="36px" src="{% avatar user %}">{{ user.nickname }}</p>
<form method="post"> <form method="post">
<textarea name="body" class="textarea" maxlength="2200" data-placeholder="Write a friend request here." placeholder="Write a friend request here."></textarea> <textarea name="body" class="textarea" maxlength="2200" data-placeholder="Write a friend request here." placeholder="Write a friend request here."></textarea>
<div class="form-buttons"> <div class="form-buttons">
<input type="button" class="olv-modal-close-button gray-button" value="Cancel"> <input type="button" class="olv-modal-close-button gray-button" value="Cancel">
<input type="submit" value="Send" class="post-button black-button"> <input type="submit" value="Send" class="post-button black-button">
@@ -80,8 +79,10 @@
</div> </div>
{% endif %} {% endif %}
{% block_modal user profile %}
</div> </div>
{% elif user.is_me and not general %} {% endif %}{% if user.is_me and not general %}
<div id="edit-profile-settings"><a class="button symbol" href="{% url "main:profile-settings" %}">Profile Settings</a></div> <div id="edit-profile-settings"><a class="button symbol" href="{% url "main:profile-settings" %}">Profile Settings</a></div>
{% endif %}{% if user.is_me %} {% endif %}{% if user.is_me %}
<button class="button" onclick="Olv.Closed.lights()">Toggle Dark Mode</button> <button class="button" onclick="Olv.Closed.lights()">Toggle Dark Mode</button>
@@ -5,18 +5,16 @@
<form method="post"> <form method="post">
<img src="{% static "img/menu-logo.svg" %}"> <img src="{% static "img/menu-logo.svg" %}">
<p class="lh">Reset password</p> <p class="lh">Reset password</p>
<p>Hello {{ user.username }}, it's time to change your password.</p> <p>Hello {{ user.username }}, it's time to reset your password.</p>
<form method="post">
<h3 class="label"><label>New password: <input type="password" class="auth-input" name="password" placeholder="Password" required></label></h3> <h3 class="label"><label>New password: <input type="password" class="auth-input" name="password" placeholder="Password" required></label></h3>
<h3 class="label"><label>Confirm new password: <input type="password" class="auth-input" name="password_again" placeholder="Password again" required></label></h3> <h3 class="label"><label>Confirm new password: <input type="password" class="auth-input" name="password_again" placeholder="Password again" required></label></h3>
{% csrf_token %} {% csrf_token %}
<p class="red" style="margin-bottom:6px"></p> <p class="red" style="margin-bottom:6px"></p>
<button type="submit" class="button">Reset</button> <button type="submit" class="button">Reset</button>
</form>
<div class="ll"> <div class="ll">
<p>Once finished you can log into your account with your new password.</p> <p>Once finished you can log into your account with your new password.</p>
</div> </div>
</form>
</form>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
@@ -18,81 +18,10 @@
<h2 class="label">Active clones</h2> <h2 class="label">Active clones</h2>
<div id="guide" class="help-content"> <div id="guide" class="help-content">
<div class="faq"> <div class="faq">
<p>im too lazy to update this</p> <h1>this clone</h1>
<!-- <p>uhh uhh youre using it now and its good enough</p>
<h2>Juice</h2>
{% if not user.is_staff %}
<p>Clone online. - [URL REDACTED]</p>
{% endif %}
{% if user.is_staff and user.is_authenticated %}
<p>Do not share this URL to the public. - [<a href="https://juice.isledelfino.net/">URL</a>]</p>
{% endif %}
<p>Juice is based off Project Ultima. It's been around for a while, considering how long most clones usually last.</p>
<h2>Leaper</h2>
{% if not user.is_staff %}
<p>Clone online. - [URL REDACTED]</p>
{% endif %}
{% if user.is_staff and user.is_authenticated %}
<p>Do not share this URL to the public. - [<a href="https://caustica.isledelfino.net/">URL</a>]</p>
{% endif %}
<p>This clone has a few distinct features that separate it from the others. You have a wide selection of (slightly buggy) themes. You have background music for some pages. And you can edit your post too.</p>
<h2>"Miiverse" Clone</h2>
<p>Clone online. - [<a href="https://miiverse.lol">miiverse.lol</a>]</p>
<p>It's your standard Cedar rehost, it's skinned to fit a "Miiverse" aesthetic. For a while this clone remained a secret until some dude leaked the URL. Since the cat was out of the bag a long time ago, I might as well show it here.</p>
<h2>Bradenverse xddddd</h2>
<p>this clone will last a week, so I don't care.</p>
<p>It comes up, dies and comes back online</p>
<p>i forgor 💀 the url</p>
</div>
</div>
<h2 class="label">Active public clones</h2>
<div id="guide" class="help-content">
<div class="faq">
<h2>Cedar</h2>
<p>You're using this one right now!</p>
<p>This site is not super expensive, and I'm able to reasonably maintain this site. Now this is not happening anytime soon, but eventually Cedar will be shut down. Users will be informed of the upcoming shutdown in advance when that time comes. All user data like profiles, posts, comments, and conversations will all be deleted and not archived by me.</p>
<h2>Exverse</h2>
<p>Clone online, but who fucking cares? - [<a href="https://exverse.ml/">https://exverse.ml/</a>]</p>
<p>Also, I can't sign up to it for whatever reason, don't ask why I want to, but yeah it's a bit broken I guess.</p>
<p>Edit: so I did sign up for that site, it's busted as fuck, the CSS looks HORRIBLE oh god what the fuck</p>
<p>The entire site is ugly as fuck, I don't know what the dude messing with the CSS was smoking.</p>
<h2>Rverse</h2>
<p>Clone online. - [3DS ONLY]</p>
<p>Does this even count?</p>
<p>Well, it's the most active clone out there, the only problem is that it's only accessible through a hacked 3DS system with Rverse installed. For some, this may be a dealbreaker.</p>
</div>
</div>
<h2 class="label">Other clones</h2>
<div id="guide" class="help-content">
<div class="faq">
<p>Goofy ahh clones</p>
<h2 style="background-color: #000000;">Geoverse</h2>
<p>This service has ended. - [<a href="http://geoverse.usecedar.ca/">http://geoverse.usecedar.ca/</a>]</p>
<h3>What the hell happened to it?</h3>
<p>I have a lot of stuff to explain here. Let's just go in chronological order.</p>
<ul>
<li>I hosted this clone for Ghosty Tongue.</li>
<li>A while passes by with zero activity.</li>
<li>I announce its shutdown date on the site itself.</li>
<li>Ghosty decides to give out the SSH password to a few people.</li>
<li>Ghosty claims he had permission from me to do this, but he lied.</li>
<li>Ghosty posts the SSH login on the announcements channel for the Clonepedia Discord server.</li>
<li>So basically the database is now fully accessible, emails, and IPs are free real estate.</li>
<li>The discord goes fucking berserk.</li>
<li>HTML elements are being edited.</li>
<li>I wake up to 1000 pings on people warning me about the compromised server.</li>
<li>I look at the hellhole that's Geoverse.</li>
<li>I shut it down.</li>
<li>I revive it shorty after with a new SSH password.</li>
<li>I turn that shit into fucking Minionsverse.</li>
<li>I shut it down forever this time.</li>
</ul>
<h2>Banama</h2>
<p>Clone online. - [<a href="https://banama.club">https://banama.club</a>]</p>
<p>Now, none of us are getting in, but let's think of this website as a place to accommodate a friend group more than a regular clone. It's nothing all that spectacular.</p>
-->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
@@ -3,7 +3,7 @@
{% user_sidebar request user user.profile 0 True %} {% user_sidebar request user user.profile 0 True %}
<div class="main-column" id="help"> <div class="main-column" id="help">
<div class="post-list-outline"> <div class="post-list-outline">
<h2 class="label">Contact the team behind this</h2> <h2 class="label">Where even do I contact you, anyway?</h2>
<div id="guide" class="help-content"> <div id="guide" class="help-content">
<div class="faq"> <div class="faq">
<p>I'll make this page later, need permission from our admins and shit...</p> <p>I'll make this page later, need permission from our admins and shit...</p>
@@ -1,7 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<title>Hi</title> <title>Hi</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<style>html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto, Helvetica, Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";}</style> <style>html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto, Helvetica, Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";}</style>
</head> </head>
<body style="text-align:center"> <body style="text-align:center">
@@ -12,4 +13,4 @@
<p>If you didn't submit this, please ignore this email, someone probably tried to use your email to reset, and they can't have any access unless they actually have your email address. If you're having trouble, <a href="{{ contact }}">contact us here</a>.</p><br> <p>If you didn't submit this, please ignore this email, someone probably tried to use your email to reset, and they can't have any access unless they actually have your email address. If you're having trouble, <a href="{{ contact }}">contact us here</a>.</p><br>
<p>Thank you for using our service! :)</p> <p>Thank you for using our service! :)</p>
</body> </body>
</html> </html>
@@ -0,0 +1,21 @@
{% extends "closedverse_main/layout.html" %}
{% load static %}{% block main-body %}
<div class="main-column center">
<div class="post-list-outline login-page">
<form method="post">
<img src="{% static "img/menu-logo.png" %}">
<p class="lh">Reset password</p>
<p>Welcome back! It appears you've got the email, and now it's time to reset your password.</p>
<form method="post">
<h3 class="label"><label>New password: <input type="password" class="auth-input" name="password" placeholder="Password" required></label></h3>
<h3 class="label"><label>Confirm new password: <input type="password_again" class="auth-input" name="password" placeholder="Password again" required></label></h3>
{% csrf_token %}
<p class="red" style="margin-bottom:6px"></p>
<button type="submit" class="button">Reset</button>
</form>
</form>
</div>
</div>
{% endblock %}
@@ -15,8 +15,8 @@
<h2>I'm getting "Your password must be reset"?</h2> <h2>I'm getting "Your password must be reset"?</h2>
<p>This means that your password must be reset. Reset it via email, or ask an admin to reset it. In most cases, an admin has emailed you a password reset link.</p> <p>This means that your password must be reset. Reset it via email, or ask an admin to reset it. In most cases, an admin has emailed you a password reset link.</p>
<h2>I'm being hacked! HELP!!!</h2> <h2>i"m bEinG hAcKeD!!!!!!!!!!</h2>
<p>If others are in your account, no worry, when you change your password, everyone gets logged out.<br> <p>If others are in your account, no worry, when you change your password, everyone gets logged out.<br>
Unless your email was changed or you don't have one, in that case, contact an admin and they will help you ASAP. Unless your email was changed or you don't have one, in that case, contact an admin and they will help you ASAP.
<br><br>You should use a random password and keep it in your notes or something. In most cases, public user accounts are made due to one character passwords. Please do not use one character passwords. <br><br>You should use a random password and keep it in your notes or something. In most cases, public user accounts are made due to one character passwords. Please do not use one character passwords.
@@ -26,4 +26,4 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
@@ -3,7 +3,7 @@
{% user_sidebar request user user.profile 0 True %} {% user_sidebar request user user.profile 0 True %}
<div class="main-column" id="help"> <div class="main-column" id="help">
<div class="post-list-outline"> <div class="post-list-outline">
<h2 class="label">Cedar stats</h2> <h2 class="label">Server statistics</h2>
<div id="guide" class="help-content"> <div id="guide" class="help-content">
<div class="faq"> <div class="faq">
<p>These are the current stats of this Cedar instance:</p> <p>These are the current stats of this Cedar instance:</p>
@@ -24,4 +24,4 @@
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
@@ -3,13 +3,12 @@
{% user_sidebar request user user.profile 0 True %} {% user_sidebar request user user.profile 0 True %}
<div class="main-column" id="help"> <div class="main-column" id="help">
<div class="post-list-outline"> <div class="post-list-outline">
<h2 class="label">Why?</h2> <h2 class="label">Why should I join?</h2>
<div id="guide" class="help-content"> <div id="guide" class="help-content">
<p>why should you join?</p>
<div class="faq"> <div class="faq">
<h2>Why should I join ?</h2> <h2>because i said so.</h2>
<ul> <p><small>you don't have to though</small></p>
<li>I don't know...</li>
</ul>
</div> </div>
</div> </div>
</div> </div>
@@ -24,7 +24,7 @@
{% endif %} {% endif %}
{% if not allow_signups %} {% if not allow_signups %}
<div class="ll"> <div class="ll">
<p>Signing up is disabled for now, check by later.</p> <p>Signing up is disabled for now, check back later.</p>
</div> </div>
{% endif %} {% endif %}
</form> </form>
@@ -10,7 +10,7 @@
<div class="tab2"> <div class="tab2">
<a class="tab-icon-my-news selected" href="{% url "main:notifications" %}"> <a class="tab-icon-my-news selected" href="{% url "main:notifications" %}">
<span class="symbol nf"></span> <span class="symbol nf"></span>
<span>Notifications</span> <span>Updates</span>
</a> </a>
<a class="tab-icon-my-news{% if frs %} notify{% endif %}" href="{% url "main:friend-requests" %}"> <a class="tab-icon-my-news{% if frs %} notify{% endif %}" href="{% url "main:friend-requests" %}">
@@ -129,7 +129,6 @@
<p>You must sign in to post a comment.<br><br>Sign in using a Cedar account to make posts and comments, as well as give Yeahs and follow users.</p> <p>You must sign in to post a comment.<br><br>Sign in using a Cedar account to make posts and comments, as well as give Yeahs and follow users.</p>
<a href="{% url "main:signup" %}" class="arrow-button"><span>Create an account</span></a> <a href="{% url "main:signup" %}" class="arrow-button"><span>Create an account</span></a>
<a href="{% url "main:help-faq" %}" class="arrow-button"><span>FAQ/Frequently Asked Questions</span></a> <a href="{% url "main:help-faq" %}" class="arrow-button"><span>FAQ/Frequently Asked Questions</span></a>
<a href="{% url "main:help-contact" %}" class="arrow-button"><span>Contact Us</span></a>
</div> </div>
{% elif not post.can_comment %} {% elif not post.can_comment %}
<div class="cannot-reply"><div> <div class="cannot-reply"><div>
@@ -1,5 +1,5 @@
{% extends "closedverse_main/layout.html" %} {% extends "closedverse_main/layout.html" %}
{% block main-body %}{% load closedverse_user %}{% load closedverse_tags %} {% block main-body %}{% load closedverse_user %}{% load closedverse_tags %}{% load closedverse_community %}
{% user_sidebar request user profile 0 %} {% user_sidebar request user profile 0 %}
<div class="main-column"><div class="post-list-outline"> <div class="main-column"><div class="post-list-outline">
@@ -45,12 +45,13 @@
</div> </div>
<p class="note">Enter your region here. It'll appear on your profile. <p class="note">Enter your region here. It'll appear on your profile.
<br> <br>
<a class="get-ipinfo" href="#">If you want to use your location, you can get it automatically here (it will not be automatically saved).</a>
</p> </p>
</li> </li>
<li class="setting-email"> <li class="setting-email">
<p class="settings-label">E-mail address</p> <p class="settings-label">E-mail address</p>
<div class="center center-input"> <div class="center center-input">
<input type="text" name="email" maxlength="255" placeholder="Email address" value="{{ user.email }}"> <input type="text" name="email" maxlength="255" placeholder="Email address" value="{{ user.email|default_if_none:"" }}">
</div> </div>
<p class="note">Please note that your email can be a fake one, however if you need to reset your password, this must be accessible. You can't share emails.</p> <p class="note">Please note that your email can be a fake one, however if you need to reset your password, this must be accessible. You can't share emails.</p>
{% if user.email %} {% if user.email %}
@@ -90,10 +91,10 @@
<li class="setting-color"> <li class="setting-color">
<p class="settings-label">Nickname color</p> <p class="settings-label">Nickname color</p>
<div class="center center-input"> <div class="center center-input">
<input type="hidden" name="color" maxlength="7" placeholder="Enter a hex color value here" value="{{ user.color }}"> <input type="hidden" name="color" maxlength="7" placeholder="Enter a hex color value here" value="{{ user.color|default_if_none:"" }}">
<button class="button color-thing">Open color picker</button> <button class="button color-thing">Open color picker</button>
</div> </div>
<p class="note">This is the color your nickname will appear as. Leave it blank for the default. It will appear like so.</p> <p class="note">This is the color your nickname will appear as. Set it to white (#ffffff) and it will return to the default. It will appear like so.</p>
{% user_sidebar_info user %} {% user_sidebar_info user %}
</li> </li>
{% if profile.origin_id %} {% if profile.origin_id %}
@@ -186,28 +187,33 @@
<div class="icon-container"> <div class="icon-container">
<img class="icon nnid-icon mii" src="{% miionly user.mh %}"> <img class="icon nnid-icon mii" src="{% miionly user.mh %}">
</div> </div>
<input type="text" name="origin_id" minlength="6" maxlength="16" placeholder="Nintendo Network ID{% if not profile.origin_id %} (None){% endif %}" value="{% if profile.origin_id %}{{ profile.origin_id }}{% endif %}" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}"> <input type="text" name="origin_id" minlength="6" maxlength="16" placeholder="Nintendo Network ID{% if not profile.origin_id %} (None){% endif %}" value="{% if profile.origin_id %}{{ profile.origin_id }}{% endif %}" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
<input type="hidden" name="mh" value="{{ user.mh }}"> <input type="hidden" name="mh" value="{{ user.mh }}">
<p class="error"></p> <p class="error"></p>
<p class="note">Enter your Nintendo Network ID here. It'll appear on your profile if you set it to be visible.</p> <p class="note">Enter your Nintendo Network ID here. It'll appear on your profile if you set it to be visible.</p>
</li> </li>
{% if not user.has_plain_avatar %}
<li class="setting-avatar"> <li class="setting-avatar">
<div class="icon-container"> <div class="icon-container">
<img class="icon nnid-icon mii{% if not user.has_mh %} none{% endif %}" src="{% miionly user.mh %}"> <img class="icon nnid-icon mii{% if not user.has_mh %} none{% endif %}" src="{% miionly user.mh %}">
<img class="icon nnid-icon gravatar{% if user.has_mh %} none{% endif %}" src="{{ user.gravatar }}"> <img class="icon nnid-icon gravatar{% if user.has_mh or user.has_plain_avatar %} none{% endif %}" src="{{ user.gravatar }}">
{% if user.has_freedom %}
<img class="icon nnid-icon custom{% if not user.has_plain_avatar %} none{% endif %}" src="{{ user.do_avatar }}">
{% endif %}
</div> </div>
<p class="settings-label">Do you want the avatar shown beside your content to use the Mii from your Nintendo Network ID or a Gravatar?</p> <p class="settings-label">Do you want the avatar shown beside your content to use the Mii from your Nintendo Network ID or a Gravatar or a custom avatar the way God intended?</p>
<label><input type="radio" name="avatar" value="0"{% if user.has_mh %} checked{% endif %}>Mii</label> <label><input type="radio" name="avatar" value="0"{% if user.has_mh %} checked{% endif %}>Mii</label>
<label><input type="radio" name="avatar" value="1"{% if not user.has_mh %} checked{% endif %}>Gravatar</label> <label><input type="radio" name="avatar" value="1"{% if not user.has_mh %} checked{% endif %}>Gravatar</label>
<p class="note">Selecting the Gravatar option will cause your avatar to be pulled from the <a href="https://gravatar.com">Gravatar account</a> linked to your email address, and feelings won't be shown in your posts unless you choose to use a Mii instead.</p> {% if user.has_freedom %}
<label><input type="radio" name="avatar" value="2"{% if user.has_plain_avatar%} checked{% endif %}>Custom</label>
<span id="upload-thing"{% if not user.has_plain_avatar %} class="none"{% endif %}>{% file_button %}</span>
<style>
.setting-avatar div.file-button-container { display: none; }
</style>
{% else %}
<input type="hidden" name="avatar" value="2">
{% endif %}
<p class="note">Selecting the Gravatar option will cause your avatar to be pulled from the <a href="https://gravatar.com">Gravatar account</a> linked to your email address, and feelings won't be shown in your posts unless you choose to use a Mii instead. Same with the custom avatar option but who really cared anyway?</p>
</li> </li>
{% else %}
<p class="settings-label">It appears that you somehow have a plain URL avatar, change it here (<strong>if you change it to nothing then it will reset to being selectable !!</strong>)</p>
<div class="center center-input">
<input type="text" name="avatar" maxlength="255" placeholder="Avatar url" value="{{ user.avatar }}">
</div>
{% endif %}
{% csrf_token %} {% csrf_token %}
<div class="form-buttons"> <div class="form-buttons">
@@ -13,6 +13,7 @@
<h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}"> <h3 class="label nnid"><label>Nintendo Network ID: <input type="text" class="auth-input" name="origin_id" maxlength="16" minlength="6" placeholder="NNID" data-mii-domain="{{ mii_domain }}" data-action="{{ mii_endpoint }}">
<img class="none"> <img class="none">
</label></h3> </label></h3>
<input type="hidden" name="mh">
<h3 class="label"><label><span class="red">%</span> E-mail address: <input type="email" class="auth-input" name="email" maxlength="254" minlength="6" placeholder="Email"></label></h3> <h3 class="label"><label><span class="red">%</span> E-mail address: <input type="email" class="auth-input" name="email" maxlength="254" minlength="6" placeholder="Email"></label></h3>
<h3 class="label"><label><span class="red">*</span> Password: <input type="password" class="auth-input" name="password" maxlength="32" minlength="6" placeholder="Password"></label></h3> <h3 class="label"><label><span class="red">*</span> Password: <input type="password" class="auth-input" name="password" maxlength="32" minlength="6" placeholder="Password"></label></h3>
<h3 class="label"><label><span class="red">*</span> Confirm password: <input type="password" class="auth-input" name="password_again" maxlength="32" minlength="6" placeholder="Password again"></label></h3> <h3 class="label"><label><span class="red">*</span> Confirm password: <input type="password" class="auth-input" name="password_again" maxlength="32" minlength="6" placeholder="Password again"></label></h3>
@@ -21,15 +22,13 @@
<div class="g-recaptcha" data-sitekey="{{ recaptcha }}" data-theme="dark"></div> <div class="g-recaptcha" data-sitekey="{{ recaptcha }}" data-theme="dark"></div>
<script src='https://www.google.com/recaptcha/api.js'></script> <script src='https://www.google.com/recaptcha/api.js'></script>
{% endif %} {% endif %}
<p class="red" style="margin-bottom:6px"></p> <p class="red" style="margin-bottom:6px"></p>
<button type="submit" class="button" onclick="event.preventDefault();cac();">Create account</button> <button type="submit" class="button" onclick="event.preventDefault();cac();">Create account</button>
<div class="ll"> <div class="ll">
<p>All fields with a red asterisk (<span class="red">*</span>) are required.</p> <p>All fields with a red asterisk (<span class="red">*</span>) are required.</p>
<p>NNIDs are only required for getting a Mii and a nickname from.</p> <p>NNIDs are only required for getting a Mii from.</p>
<p>If you do not provide a nickname but provide an NNID, the nickname will be taken from that ID. The ID's nickname, however, is prioritized over the nickname field.</p> <p>You will be able to change your avatar (or use a custom one) after you sign up.</p>
<p>You will be able to change your avatar after you sign up.</p> <p><span class="red">%</span>: If you don't fill in your email address, you can't reset your password until you have one.</p>
<p><span class="red">%</span>: Emails are not required to sign up, however it is used for Gravatar and account recovery.</p>
<p><span class="red">$</span>: Your username is used to log in. It'll appear similarly to your NNID on Miiverse, below your nickname.</p> <p><span class="red">$</span>: Your username is used to log in. It'll appear similarly to your NNID on Miiverse, below your nickname.</p>
</div> </div>
</form> </form>
@@ -0,0 +1,6 @@
{% extends "closedverse_main/layout.html" %}
{% block main-body %}{% load closedverse_user %}
<div class="no-content"><div class="window-create-new-topic"><p>This user is blocked.</p>
{% if profile.can_block %}<div class="post-buttons-content"><button type="button" class="button block-button">Unblock</button></div>{% endif %}
{% block_modal user profile %}
{% endblock %}
@@ -4,7 +4,7 @@
<div class="main-column"><div class="post-list-outline"> <div class="main-column"><div class="post-list-outline">
<h2 class="label">{{ title }}</h2> <h2 class="label">{{ title }}</h2>
{% u_post_list posts next 3 %} {% u_post_list posts next 3 '' time %}
</div></div> </div></div>
{% endblock %} {% endblock %}
@@ -4,7 +4,7 @@
<div class="main-column"><div class="post-list-outline"> <div class="main-column"><div class="post-list-outline">
<h2 class="label">{{ title }}</h2> <h2 class="label">{{ title }}</h2>
{% u_post_list posts next 0 %} {% u_post_list posts next 0 '' time %}
</div></div> </div></div>
{% endblock %} {% endblock %}
@@ -34,6 +34,12 @@ def user_sidebar_info(user, profile=None):
'user': user, 'user': user,
'profile': profile, 'profile': profile,
} }
@register.inclusion_tag('closedverse_main/elements/block-modal.html')
def block_modal(user, profile):
return {
'user': user,
'profile': profile,
}
@register.inclusion_tag('closedverse_main/elements/fr-accept.html') @register.inclusion_tag('closedverse_main/elements/fr-accept.html')
def fr_accept(fr): def fr_accept(fr):
return { return {
@@ -48,7 +54,7 @@ def user_post(post, type=0):
} }
@register.inclusion_tag('closedverse_main/elements/u-post-list.html') @register.inclusion_tag('closedverse_main/elements/u-post-list.html')
def u_post_list(posts, next_offset=None, type=2, nf_text=''): def u_post_list(posts, next_offset=None, type=2, nf_text='', time=None):
text = { text = {
0: "This user hasn't made any posts yet.", 0: "This user hasn't made any posts yet.",
1: "This user hasn't given a Yeah to any posts yet.", 1: "This user hasn't given a Yeah to any posts yet.",
@@ -59,6 +65,7 @@ def u_post_list(posts, next_offset=None, type=2, nf_text=''):
'posts': posts, 'posts': posts,
'nf': text, 'nf': text,
'next': next_offset, 'next': next_offset,
'time': time,
'type': type, 'type': type,
} }
@register.inclusion_tag('closedverse_main/elements/profile-post.html') @register.inclusion_tag('closedverse_main/elements/profile-post.html')
+94 -100
View File
@@ -15,110 +15,104 @@ uuidr = r'[0-9a-f\-]'
app_name = 'main' app_name = 'main'
urlpatterns = [ urlpatterns = [
# Root # Root
url(r'^^$|^communities$|^index.*$$', views.community_list, name='community-list'), url(r'^^$|^communities$|^index.*$$', views.community_list, name='community-list'),
# Accounts # Accounts
url(r'login/$', views.login_page, name='login'), url(r'login/$', views.login_page, name='login'),
url(r'signup/$', views.signup_page, name='signup'), url(r'signup/$', views.signup_page, name='signup'),
url(r'reset/$', views.forgot_passwd, name='forgot-passwd'), url(r'reset/$', views.forgot_passwd, name='forgot-passwd'),
url(r'logout/$', views.logout_page, name='logout'), url(r'logout/$', views.logout_page, name='logout'),
# User pages # User pages
url(r'users/'+ username +'/follow$', views.user_follow, name='user-follow'), url(r'users/'+ username +'/follow$', views.user_follow, name='user-follow'),
url(r'users/'+ username +'/unfollow$', views.user_unfollow, name='user-unfollow'), url(r'users/'+ username +'/unfollow$', views.user_unfollow, name='user-unfollow'),
url(r'users/'+ username +'$', views.user_view, name='user-view'), url(r'users/'+ username +'$', views.user_view, name='user-view'),
url(r'users/'+ username +'/posts$', views.user_posts, name='user-posts'), url(r'users/'+ username +'/posts$', views.user_posts, name='user-posts'),
url(r'users/'+ username +'/yeahs$', views.user_yeahs, name='user-yeahs'), url(r'users/'+ username +'/yeahs$', views.user_yeahs, name='user-yeahs'),
url(r'users/'+ username +'/comments$', views.user_comments, name='user-comments'), url(r'users/'+ username +'/comments$', views.user_comments, name='user-comments'),
url(r'users/'+ username +'/following$', views.user_following, name='user-following'), url(r'users/'+ username +'/following$', views.user_following, name='user-following'),
url(r'users/'+ username +'/followers$', views.user_followers, name='user-followers'), url(r'users/'+ username +'/followers$', views.user_followers, name='user-followers'),
url(r'users/'+ username +'/friends$', views.user_friends, name='user-friends'), url(r'users/'+ username +'/friends$', views.user_friends, name='user-friends'),
# User page friends # User page friends
url(r'users/'+ username +'/friend_new$', views.user_friendrequest_create, name='user-fr-create'), url(r'users/'+ username +'/friend_new$', views.user_friendrequest_create, name='user-fr-create'),
url(r'users/'+ username +'/friend_accept$', views.user_friendrequest_accept, name='user-fr-accept'), url(r'users/'+ username +'/friend_accept$', views.user_friendrequest_accept, name='user-fr-accept'),
url(r'users/'+ username +'/friend_reject$', views.user_friendrequest_reject, name='user-fr-reject'), url(r'users/'+ username +'/friend_reject$', views.user_friendrequest_reject, name='user-fr-reject'),
url(r'users/'+ username +'/friend_cancel$', views.user_friendrequest_cancel, name='user-fr-cancel'), url(r'users/'+ username +'/friend_cancel$', views.user_friendrequest_cancel, name='user-fr-cancel'),
url(r'users/'+ username +'/friend_delete$', views.user_friendrequest_delete, name='user-fr-delete'), url(r'users/'+ username +'/friend_delete$', views.user_friendrequest_delete, name='user-fr-delete'),
url(r'users/'+ username +'/tools/set$', views.user_tools_set, name='user-tools-set'), url(r'users/'+ username +'/tools/set$', views.user_tools_set, name='user-tools-set'),
url(r'users/'+ username +'/tools$', views.user_tools, name='user-tools'), url(r'users/'+ username +'/tools$', views.user_tools, name='user-tools'),
url(r'users/'+ username +'/tools/meta$', views.user_tools_meta, name='user-tools-meta'), url(r'users/'+ username +'/tools/meta$', views.user_tools_meta, name='user-tools-meta'),
url(r'users/'+ username +'/block$', views.user_addblock, name='user-addblock'),
# Communities
url(r'communities.search$', views.community_search, name='community-search'),
url(r'communities/'+ community +'$', views.community_view, name='community-view'),
url(r'communities/favorites$', views.community_favorites, name='community-favorites'),
url(r'communities/categories/(?P<category>[a-z]+)$', views.community_all, name='community-viewall'),
url(r'communities/(?P<tag>[a-z]+)$', views.special_community_tag, name='special-community-tag'),
url(r'communities/'+ community +'/favorite$', views.community_favorite_create, name='community-favorite-add'),
url(r'communities/'+ community +'/favorite_rm$', views.community_favorite_rm, name='community-favorite-rm'),
url(r'communities/'+ community +'/posts$', views.post_create, name='post-create'),
url(r'communities/'+ community +'/tools$', views.community_tools, name='community-tools'),
url(r'communities/'+ community +'/tools/set$', views.community_tools_set, name='community-tools-set'),
url(r'c/create$', views.community_create, name='community-create'),
url(r'c/create/do$', views.community_create_action, name='community-create-action'),
# Posts and comments
# Some of these NAMES (not patterns) are hardcoded into models.py
url(r'posts/'+ post +'$', views.post_view, name='post-view'),
url(r'posts/'+ post +'/yeah$', views.post_add_yeah, name='post-add-yeah'),
url(r'posts/'+ post +'/yeahu$', views.post_delete_yeah, name='post-delete-yeah'),
url(r'posts/'+ post +'/comments$', views.post_comments, name='post-comments'),
url(r'posts/'+ post +'/comments$', views.post_comments, name='post-comments'),
url(r'posts/'+ post +'/change$', views.post_change, name='post-change'),
url(r'posts/'+ post +'/profile$', views.post_setprofile, name='post-set-profile'),
url(r'posts/'+ post +'/profile_rm', views.post_unsetprofile, name='post-unset-profile'),
url(r'posts/'+ post +'\.rm$', views.post_rm, name='post-rm'),
url(r'comments/'+ comment +'$', views.comment_view, name='comment-view'),
url(r'comments/'+ comment +'/yeah$', views.comment_add_yeah, name='comment-add-yeah'),
url(r'comments/'+ comment +'/yeahu$', views.comment_delete_yeah, name='comment-delete-yeah'),
url(r'comments/'+ comment +'/change$', views.comment_change, name='comment-change'),
url(r'comments/'+ comment +'/rm$', views.comment_rm, name='comment-rm'),
# Post-meta: polls
url(r'poll/(?P<poll>'+ uuidr +'+)/vote$', views.poll_vote, name='poll-vote'),
url(r'poll/(?P<poll>'+ uuidr +'+)/unvote$', views.poll_unvote, name='poll-unvote'),
url(r'users/'+ username +'/block$', views.user_addblock, name='user-addblock'), # Notifications
# Communities url(r'alive$', views.check_notifications, name='check-notifications'),
url(r'communities.search$', views.community_search, name='community-search'), url(r'notifications/?$', views.notifications, name='notifications'),
url(r'communities/'+ community +'$', views.community_view, name='community-view'), url(r'notifications/friend_requests/?$', views.friend_requests, name='friend-requests'),
url(r'communities/favorites$', views.community_favorites, name='community-favorites'), url(r'notifications/(?P<notification>'+ uuidr +'+)\.rm$', views.notification_delete, name='notification-delete'),
url(r'communities/categories/(?P<category>[a-z]+)$', views.community_all, name='community-viewall'),
url(r'communities/(?P<tag>[a-z]+)$', views.special_community_tag, name='special-community-tag'),
url(r'communities/'+ community +'/favorite$', views.community_favorite_create, name='community-favorite-add'),
url(r'communities/'+ community +'/favorite_rm$', views.community_favorite_rm, name='community-favorite-rm'),
url(r'communities/'+ community +'/posts$', views.post_create, name='post-create'),
url(r'communities/'+ community +'/tools$', views.community_tools, name='community-tools'),
url(r'communities/'+ community +'/tools/set$', views.community_tools_set, name='community-tools-set'),
url(r'c/create$', views.community_create, name='community-create'),
url(r'c/create/do$', views.community_create_action, name='community-create-action'),
# Posts and comments
# Some of these NAMES (not patterns) are hardcoded into models.py
url(r'posts/'+ post +'$', views.post_view, name='post-view'),
url(r'posts/'+ post +'/yeah$', views.post_add_yeah, name='post-add-yeah'),
url(r'posts/'+ post +'/yeahu$', views.post_delete_yeah, name='post-delete-yeah'),
url(r'posts/'+ post +'/comments$', views.post_comments, name='post-comments'),
url(r'posts/'+ post +'/comments$', views.post_comments, name='post-comments'),
url(r'posts/'+ post +'/change$', views.post_change, name='post-change'),
url(r'posts/'+ post +'/profile$', views.post_setprofile, name='post-set-profile'),
url(r'posts/'+ post +'/profile_rm', views.post_unsetprofile, name='post-unset-profile'),
url(r'posts/'+ post +'\.rm$', views.post_rm, name='post-rm'),
url(r'comments/'+ comment +'$', views.comment_view, name='comment-view'),
url(r'comments/'+ comment +'/yeah$', views.comment_add_yeah, name='comment-add-yeah'),
url(r'comments/'+ comment +'/yeahu$', views.comment_delete_yeah, name='comment-delete-yeah'),
url(r'comments/'+ comment +'/change$', views.comment_change, name='comment-change'),
url(r'comments/'+ comment +'/rm$', views.comment_rm, name='comment-rm'),
# Post-meta: polls
url(r'poll/(?P<poll>'+ uuidr +'+)/vote$', views.poll_vote, name='poll-vote'),
url(r'poll/(?P<poll>'+ uuidr +'+)/unvote$', views.poll_unvote, name='poll-unvote'),
# Notifications # User meta + messages
url(r'alive$', views.check_notifications, name='check-notifications'), url(r'activity/?$', views.activity_feed, name='activity'),
url(r'notifications/?$', views.notifications, name='notifications'), url(r'users.search$', views.user_search, name='user-search'),
url(r'notifications/friend_requests/?$', views.friend_requests, name='friend-requests'), url(r'pref$', views.prefs, name='prefs'),
url(r'notifications/(?P<notification>'+ uuidr +'+)\.rm$', views.notification_delete, name='notification-delete'), url(r'settings/profile$', views.profile_settings, name='profile-settings'),
url(r'messages/?$', views.messages, name='messages'),
url(r'messages/(?P<message>'+ uuidr +'+)/rm$', views.message_rm, name='message-delete'),
url(r'messages/'+ username +'$', views.messages_view, name='messages-view'),
url(r'messages/'+ username +'/read$', views.messages_read, name='messages-read'),
# User meta + messages # Help/configuration
url(r'activity/?$', views.activity_feed, name='activity'), url(r'lights$', views.set_lighting, name='set-lighting'),
url(r'users.search$', views.user_search, name='user-search'), url(r'complaints$', views.help_complaint, name='complaints'),
url(r'pref$', views.prefs, name='prefs'), url(r'invite$', views.invites, name='invites'),
url(r'settings/profile$', views.profile_settings, name='profile-settings'), url(r'invite/create/$', views.create_invite, name='create_invite'),
url(r'messages/?$', views.messages, name='messages'), url(r'mydata$', views.my_data, name='my-data'),
url(r'messages/(?P<message>'+ uuidr +'+)/rm$', views.message_rm, name='message-delete'), url(r'changepassword$', views.change_password, name='change-password'),
url(r'messages/'+ username +'$', views.messages_view, name='messages-view'), url(r'changepassword/set$', views.change_password_set, name='change-password-set'),
url(r'messages/'+ username +'/read$', views.messages_read, name='messages-read'), url(r'server$', views.server_stat, name='server-stat'),
url(r'help/rules/?$', views.help_rules, name='help-rules'),
url(r'help/faq/?$', views.help_faq, name='help-faq'),
url(r'help/legal/?$', views.help_legal, name='help-legal'),
url(r'help/contact/?$', views.help_contact, name='help-contact'),
url(r'help/login/?$', views.help_login, name='help-login'),
url(r'help/whatads/?$', views.whatads, name='what-ads'),
url(r'why/?$', views.help_why, name='help-why'),
# Help/configuration # Util, right now we are away from the primary appo
url(r'lights$', views.set_lighting, name='set-lighting'), url(r'origin$', views.origin_id, name='origin-id-get'),
url(r'complaints$', views.help_complaint, name='complaints'), # :^)
url(r'invite$', views.invites, name='invites'), #url(r'openverse.png', views.openverse_logo, name='openverse-logo'),
url(r'invite/create/$', views.create_invite, name='create_invite'),
url(r'mydata$', views.my_data, name='my-data'),
url(r'changepassword$', views.change_password, name='change-password'),
url(r'changepassword/set$', views.change_password_set, name='change-password-set'),
url(r'server$', views.server_stat, name='server-stat'),
url(r'help/rules/?$', views.help_rules, name='help-rules'),
url(r'help/faq/?$', views.help_faq, name='help-faq'),
url(r'help/legal/?$', views.help_legal, name='help-legal'),
url(r'help/contact/?$', views.help_contact, name='help-contact'),
url(r'help/login/?$', views.help_login, name='help-login'),
url(r'help/whatads/?$', views.whatads, name='what-ads'),
url(r'help/actclones/?$', views.active_clones, name='active-clones'),
url(r'help/approval/?$', views.help_approval, name='help-approval'),
url(r'why/?$', views.help_why, name='help-why'),
# "API"
url(r'posts.json$', views.post_list, name='post-list'),
# Util, right now we are away from the primary appo
url(r'origin$', views.origin_id, name='origin-id-get'),
# :^)
#url(r'openverse.png', views.openverse_logo, name='openverse-logo'),
] ]
urlpatterns += [re_path(r'^i/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT, }), ] urlpatterns += [re_path(r'^i/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT, }), ]
+95 -40
View File
@@ -1,4 +1,3 @@
from lxml import html
# Todo: move all requests to using requests instead of urllib3 # Todo: move all requests to using requests instead of urllib3
import urllib.request, urllib.error import urllib.request, urllib.error
import requests import requests
@@ -7,6 +6,7 @@ from random import choice
import json import json
import time import time
import os.path import os.path
import random
from PIL import Image, ExifTags, ImageFile from PIL import Image, ExifTags, ImageFile
from datetime import datetime from datetime import datetime
from binascii import crc32 from binascii import crc32
@@ -21,22 +21,22 @@ import re
from os import remove, rename from os import remove, rename
def HumanTime(date, full=False): def HumanTime(date, full=False):
now = time.time() now = time.time()
time_difference = now - date time_difference = now - date
time_units = {86400: 'day', 3600: 'hour', 60: 'minute'} time_units = {86400: 'day', 3600: 'hour', 60: 'minute'}
if time_difference >= 259200 or full: if time_difference >= 259200 or full:
return datetime.fromtimestamp(date).strftime('%m/%d/%Y %I:%M %p') return datetime.fromtimestamp(date).strftime('%m/%d/%Y %I:%M %p')
elif time_difference <= 59: elif time_difference <= 59:
return 'Less than a minute ago' return 'Less than a minute ago'
else: else:
for unit, unit_name in time_units.items(): for unit, unit_name in time_units.items():
if time_difference < unit: if time_difference < unit:
continue continue
else: else:
number_of_units = floor(time_difference / unit) number_of_units = floor(time_difference / unit)
if number_of_units > 1: if number_of_units > 1:
unit_name += 's' unit_name += 's'
return f'{number_of_units} {unit_name} ago' return f'{number_of_units} {unit_name} ago'
def get_mii(id): def get_mii(id):
# Using AccountWS # Using AccountWS
@@ -79,13 +79,26 @@ def recaptcha_verify(request, key):
return True return True
ImageFile.LOAD_TRUNCATED_IMAGES = True ImageFile.LOAD_TRUNCATED_IMAGES = True
# This image upload code is fucked now thanks to pillow. I gotta go through it and refine it. def image_upload(img, stream=False, drawing=False, avatar=False):
def image_upload(img, stream=False, drawing=False): if stream:
# Decode the image decodedimg = img.read()
decodedimg = img.read() if stream else base64.b64decode(img) else:
# Open the image try:
im = Image.open(io.BytesIO(decodedimg)) decodedimg = base64.b64decode(img)
# Check for EXIF data and rotate the image if necessary except ValueError:
return 1
if stream:
if not 'image' in img.content_type:
return 1
# upload svg?
#if 'svg' in mime:
#
try:
im = Image.open(io.BytesIO(decodedimg))
# OSError is probably from invalid images, SyntaxError probably from unsupported images
except (OSError, SyntaxError):
return 1
# Taken from https://coderwall.com/p/nax6gg/fix-jpeg-s-unexpectedly-rotating-when-saved-with-pil
if hasattr(im, '_getexif'): if hasattr(im, '_getexif'):
orientation = 0x0112 orientation = 0x0112
exif = im._getexif() exif = im._getexif()
@@ -98,29 +111,56 @@ def image_upload(img, stream=False, drawing=False):
} }
if orientation in rotations: if orientation in rotations:
im = im.transpose(rotations[orientation]) im = im.transpose(rotations[orientation])
# Resize the image if avatar:
im.thumbnail((800, 800)) # crop 1:1
# Check the aspect ratio if this is a drawing width, height = im.size
min_dimension = min(width, height)
crop_size = min_dimension
left = (width - crop_size) // 2
top = (height - crop_size) // 2
right = left + crop_size
bottom = top + crop_size
im = im.crop((left, top, right, bottom))
im.thumbnail((256, 256))
else:
im.thumbnail((1280, 1280))
# Let's check the aspect ratio and see if it's crazy
# IF this is a drawing
if drawing and ((im.size[0] / im.size[1]) < 0.30): if drawing and ((im.size[0] / im.size[1]) < 0.30):
return 1 return 1
# Generate a hash of the image
imhash = sha1(im.tobytes()).hexdigest() # I know some people have aneurysms when they see people actually using SHA1 in the real world, for anything in general.
# Set the file format and location # Yes, we are really using it. Sorry if that offends you. It's just fast and I don't feel I need anything more random, since we are talking about IMAGES.
target = 'webp' if stream:
hash = sha1()
for chunk in img.chunks():
hash.update(chunk)
imhash = hash.hexdigest()
else:
imhash = sha1(im.tobytes()).hexdigest()
# File saving target
target = 'png'
if stream:
# If we have a stream and either a JPEG or a WEBP, save them as those since those are a bit better than plain PNG
if 'jpeg' in img.content_type:
target = 'jpeg'
im = im.convert('RGB')
elif 'webp' in img.content_type:
target = 'webp'
floc = imhash + '.' + target floc = imhash + '.' + target
# Save the file if it doesn't already exist # If the file exists, just use it, that's what hashes are for.
if not os.path.exists(settings.MEDIA_ROOT + floc): if not os.path.exists(settings.MEDIA_ROOT + floc):
im.save(settings.MEDIA_ROOT + floc, target, quality=80, method=6) im.save(settings.MEDIA_ROOT + floc, target, optimize=True)
# Return the URL of the file
return settings.MEDIA_URL + floc return settings.MEDIA_URL + floc
# Todo: Put this into post/comment delete thingy method # Todo: Put this into post/comment delete thingy method
def image_rm(image_url): def image_rm(image_url):
if settings.image_delete_opt: if settings.IMAGE_DELETE_SETTING:
if settings.MEDIA_URL in image_url: if settings.MEDIA_URL in image_url:
sysfile = image_url.split(settings.MEDIA_URL)[1] sysfile = image_url.split(settings.MEDIA_URL)[1]
sysloc = settings.MEDIA_ROOT + sysfile sysloc = settings.MEDIA_ROOT + sysfile
if settings.image_delete_opt > 1: if settings.IMAGE_DELETE_SETTING > 1:
try: try:
remove(sysloc) remove(sysloc)
except: except:
@@ -155,12 +195,27 @@ def filterchars(str=""):
for char in forbid: for char in forbid:
if char in str: if char in str:
str = str.replace(char, " ") str = str.replace(char, " ")
if str.isspace():
return 'None'
return str return str
# Check IP for proxy. """ Not using getipintel anymore
def getipintel(addr):
# My router's IP prefix is 192.168.1.*, so this works in debug
if settings.ipintel_email and not '192.168' in addr:
try:
site = urllib.request.urlopen('https://check.getipintel.net/check.php?ip={0}&contact={1}&flags=f'
.format(addr, settings.ipintel_email))
except:
return 0
return float(site.read().decode())
else:
return 0
"""
# Now using iphub
def iphub(addr): def iphub(addr):
if settings.iphub_key and not '192.168' in addr: if settings.IPHUB_KEY and not '192.168' in addr:
get = requests.get('http://v2.api.iphub.info/ip/' + addr, headers={'X-Key': settings.iphub_key}) get = requests.get('http://v2.api.iphub.info/ip/' + addr, headers={'X-Key': settings.IPHUB_KEY})
if get.json()['block'] == 1: if get.json()['block'] == 1:
return True return True
else: else:
+1677 -1618
View File
File diff suppressed because it is too large Load Diff