mirror of
https://github.com/Mistake35/Cedar-Django.git
synced 2026-07-18 00:21:14 +10:00
Changes to the community editor, goofy ahh new image compression thingy in forms.py
This commit is contained in:
+61
-12
@@ -1,27 +1,76 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
|
import uuid
|
||||||
|
from PIL import Image
|
||||||
|
import io
|
||||||
from .models import *
|
from .models import *
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
from django.contrib.auth.password_validation import validate_password
|
from django.contrib.auth.password_validation import validate_password
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.timezone import timedelta
|
from django.utils.timezone import timedelta
|
||||||
from closedverse import settings
|
from closedverse import settings
|
||||||
|
|
||||||
|
# will be used for community icons and profile pictures
|
||||||
|
def compress_and_resize_icon(image):
|
||||||
|
im = Image.open(image)
|
||||||
|
im = im.convert('RGB') # Convert to RGB
|
||||||
|
|
||||||
|
# Crop to 1:1 aspect ratio
|
||||||
|
width, height = im.size
|
||||||
|
min_dimension = min(width, height)
|
||||||
|
left = (width - min_dimension) / 2
|
||||||
|
top = (height - min_dimension) / 2
|
||||||
|
right = (width + min_dimension) / 2
|
||||||
|
bottom = (height + min_dimension) / 2
|
||||||
|
im = im.crop((left, top, right, bottom))
|
||||||
|
|
||||||
|
# Resize to 100 by 100 or smaller
|
||||||
|
im.thumbnail((100, 100))
|
||||||
|
|
||||||
|
# Compress the image
|
||||||
|
output = io.BytesIO()
|
||||||
|
im.save(output, format='WEBP', quality=85)
|
||||||
|
output.seek(0)
|
||||||
|
random_name = f"{uuid.uuid4()}.webp"
|
||||||
|
return ContentFile(output.read(), name=random_name)
|
||||||
|
|
||||||
|
def compress_and_resize_content(image):
|
||||||
|
im = Image.open(image)
|
||||||
|
im = im.convert('RGB')
|
||||||
|
|
||||||
|
# Resize to 1,200 by 1,200 or smaller
|
||||||
|
im.thumbnail((1200, 1200))
|
||||||
|
|
||||||
|
# Compress the image
|
||||||
|
output = io.BytesIO()
|
||||||
|
im.save(output, format='WEBP', quality=85)
|
||||||
|
output.seek(0)
|
||||||
|
random_name = f"{uuid.uuid4()}.webp"
|
||||||
|
return ContentFile(output.read(), name=random_name)
|
||||||
|
|
||||||
# I do want to move each and every form over to here. Not only will this trivialize making new forms, this will also make it more secure or something.
|
# I do want to move each and every form over to here. Not only will this trivialize making new forms, this will also make it more secure or something.
|
||||||
class CommunitySettingForm(forms.ModelForm):
|
class CommunitySettingForm(forms.ModelForm):
|
||||||
community_name = forms.CharField(max_length=64,required=True)
|
description = forms.CharField(max_length = 2200,required=False, widget=forms.Textarea(attrs={'class': 'textarea'}))
|
||||||
community_description = forms.CharField(max_length = 2200,required=False)
|
def clean_ico(self):
|
||||||
community_platform = forms.IntegerField(max_value = 7, min_value = 0, required = True)
|
ico = self.cleaned_data.get('ico')
|
||||||
force_login = forms.BooleanField(required = False)
|
if ico:
|
||||||
community_icon = forms.ImageField(required = False)
|
return compress_and_resize_icon(image=ico)
|
||||||
community_banner = forms.ImageField(required = False)
|
return ico
|
||||||
|
|
||||||
|
def clean_banner(self):
|
||||||
|
banner = self.cleaned_data.get('banner')
|
||||||
|
if banner:
|
||||||
|
return compress_and_resize_content(image=banner)
|
||||||
|
return banner
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Community
|
model = Community
|
||||||
fields = (
|
fields = (
|
||||||
'community_name',
|
'name',
|
||||||
'community_description',
|
'description',
|
||||||
'community_platform',
|
'platform',
|
||||||
'force_login',
|
'require_auth',
|
||||||
'community_icon',
|
'ico',
|
||||||
'community_banner'
|
'banner',
|
||||||
)
|
)
|
||||||
|
|
||||||
class Settomgs_Change_Password(forms.Form):
|
class Settomgs_Change_Password(forms.Form):
|
||||||
|
|||||||
@@ -668,7 +668,7 @@ class Community(models.Model):
|
|||||||
banner = models.ImageField(null=True, blank=True)
|
banner = models.ImageField(null=True, blank=True)
|
||||||
# Type: 0 - general, 1 - game, 2 - special
|
# Type: 0 - general, 1 - game, 2 - special
|
||||||
type = models.SmallIntegerField(default=0, help_text='The category the community belongs in, setting this to None will remove the community.', choices=((0, 'General'), (1, 'Game'), (2, 'Special'), (3, 'User Community'), (4, 'Hide')))
|
type = models.SmallIntegerField(default=0, help_text='The category the community belongs in, setting this to None will remove the community.', choices=((0, 'General'), (1, 'Game'), (2, 'Special'), (3, 'User Community'), (4, 'Hide')))
|
||||||
platform = models.SmallIntegerField(default=0, choices=((0, 'none'), (1, '3ds'), (2, 'wii u'), (3, 'switch'), (4, 'both'), (5, 'PC'), (6, 'Xbox'), (7, 'Playstation')))
|
platform = models.SmallIntegerField(default=0, choices=((0, 'None'), (1, '3DS'), (2, 'Wii U'), (3, 'Switch'), (4, '3DS and Wii U'), (5, 'PC'), (6, 'Xbox'), (7, 'Playstation')))
|
||||||
tags = models.CharField(blank=True, help_text='Provides special functionality for specific communities.', null=True, max_length=255, choices=(('announcements', 'main announcement community'), ('changelog', 'main changelog'), ('activity', 'Activity Feed posting community'), ('general', 'General Discussion Community')))
|
tags = models.CharField(blank=True, help_text='Provides special functionality for specific communities.', null=True, max_length=255, choices=(('announcements', 'main announcement community'), ('changelog', 'main changelog'), ('activity', 'Activity Feed posting community'), ('general', 'General Discussion Community')))
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
updated = models.DateTimeField(auto_now=True)
|
updated = models.DateTimeField(auto_now=True)
|
||||||
|
|||||||
@@ -7,35 +7,47 @@
|
|||||||
<li class="setting-community-name">
|
<li class="setting-community-name">
|
||||||
<p class="settings-label">Set name:</p>
|
<p class="settings-label">Set name:</p>
|
||||||
<div class="center center-input">
|
<div class="center center-input">
|
||||||
<input type="text" name="community_name" maxlength="32" placeholder="New Name" value="{{ community.name }}">
|
{{ form.name }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="setting-community-description">
|
<li class="setting-community-description">
|
||||||
<p class="settings-label">Community description:</p>
|
<p class="settings-label">Community description:</p>
|
||||||
<textarea class="textarea" name="community_description" maxlength="2200" placeholder="Community description">{{ community.description }}</textarea>
|
{{ form.description }}
|
||||||
|
</li>
|
||||||
|
{% if request.user.has_freedom %}
|
||||||
|
<li class="setting-community-icon">
|
||||||
|
<label class="file-button-container">
|
||||||
|
<p class="input-label">Community icon:</p>
|
||||||
|
<span class="button file-upload-button">Upload a new icon</span>
|
||||||
|
<input accept="image/gif, image/png, image/webp, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" name="ico" id="upload-file">
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li class="setting-community-banner">
|
||||||
|
<label class="file-button-container">
|
||||||
|
<p class="input-label">Community banner:</p>
|
||||||
|
<span class="button file-upload-button">Upload a new banner</span>
|
||||||
|
<input accept="image/gif, image/png, image/webp, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" name="banner" id="upload-file">
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
<li>
|
||||||
|
<p> </p>
|
||||||
|
{{ form.require_auth }}Require login:
|
||||||
|
<p class="note">If this is on, users will need to sign in to view your community.</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p class="settings-label"><label for="community_platform">Platform</label></p>
|
<p class="settings-label">Platform</p>
|
||||||
<div class="select-content">
|
<div class="select-content">
|
||||||
<div class="select-button">
|
<div class="select-button">
|
||||||
<select name="community_platform" id="community_platform">
|
{{ form.platform }}
|
||||||
<option value="0"{% if community.platform == 0 %} selected{% endif %}>None</option>
|
|
||||||
<option value="1"{% if community.platform == 1 %} selected{% endif %}>3DS</option>
|
|
||||||
<option value="2"{% if community.platform == 2 %} selected{% endif %}>Wii U</option>
|
|
||||||
<option value="3"{% if community.platform == 3 %} selected{% endif %}>Switch</option>
|
|
||||||
<option value="4"{% if community.platform == 4 %} selected{% endif %}>3DS and Wii U</option>
|
|
||||||
<option value="5"{% if community.platform == 5 %} selected{% endif %}>PC</option>
|
|
||||||
<option value="6"{% if community.platform == 6 %} selected{% endif %}>Xbox</option>
|
|
||||||
<option value="7"{% if community.platform == 7 %} selected{% endif %}>Playstation</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="note">If your community is for a video game, you can set the platform here. This will show an icon corresponding to what platform you pick.</p>
|
||||||
</li>
|
</li>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-buttons">
|
<div class="form-buttons">
|
||||||
<input type="submit" class="black-button apply-button" value="Save">
|
<input type="submit" class="black-button apply-button" value="Save">
|
||||||
<p class="note">You have {{ tokens }} token(s) remaining</p>
|
<p class="note">You have {{ tokens }} token(s) remaining</p>
|
||||||
<p class="note">I'm too lazy to add the remaining settings in here for now, but you can change them after making the community. Oh yeah, also if your community gets removed by a staff member, you won't get your token back, so don't make communities that break the rules or whatever.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</form></div></div>
|
</form></div></div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -10,49 +10,39 @@
|
|||||||
<li class="setting-community-name">
|
<li class="setting-community-name">
|
||||||
<p class="settings-label">Set name:</p>
|
<p class="settings-label">Set name:</p>
|
||||||
<div class="center center-input">
|
<div class="center center-input">
|
||||||
<input type="text" name="community_name" maxlength="64" placeholder="New Name" value="{{ community.name }}">
|
{{ form.name }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="setting-community-description">
|
<li class="setting-community-description">
|
||||||
<p class="settings-label">Community description:</p>
|
<p class="settings-label">Community description:</p>
|
||||||
<textarea class="textarea" name="community_description" maxlength="2200" placeholder="Community description">{{ community.description }}</textarea>
|
{{ form.description }}
|
||||||
</li>
|
</li>
|
||||||
{% if request.user.has_freedom %}
|
{% if request.user.has_freedom %}
|
||||||
<li class="setting-community-icon">
|
<li class="setting-community-icon">
|
||||||
<label class="file-button-container">
|
<label class="file-button-container">
|
||||||
<p class="input-label">Community icon:</p>
|
<p class="input-label">Community icon:</p>
|
||||||
<span class="button file-upload-button">Upload a new icon</span>
|
<span class="button file-upload-button">Upload a new icon</span>
|
||||||
<input accept="image/gif, image/png, image/webp, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" name="community_icon" id="upload-file">
|
<input accept="image/gif, image/png, image/webp, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" name="ico" id="upload-file">
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
<li class="setting-community-banner">
|
<li class="setting-community-banner">
|
||||||
<label class="file-button-container">
|
<label class="file-button-container">
|
||||||
<p class="input-label">Community banner:</p>
|
<p class="input-label">Community banner:</p>
|
||||||
<span class="button file-upload-button">Upload a new banner</span>
|
<span class="button file-upload-button">Upload a new banner</span>
|
||||||
<input accept="image/gif, image/png, image/webp, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" name="community_banner" onchange="loadFile(event)" id="upload-file">
|
<input accept="image/gif, image/png, image/webp, image/jpeg, image/jpg, image/svg+xml, image/bmp" type="file" style="display: none;" name="banner" id="upload-file">
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
<input type="checkbox" name="force_login" {% if community.require_auth %}checked{% endif %}>Require login:
|
{{ form.require_auth }}Require login:
|
||||||
<p class="note">If this is on, users will need to sign in to view your community.</p>
|
<p class="note">If this is on, users will need to sign in to view your community.</p>
|
||||||
<p class="note">I plan on removing this feature as it's implemented in an extremely janky way. Or at least improving it, so you are no longer forced to sign in to view yeahs from anyone. The whole idea behind this feature is to prevent web crawling or unauthorized third parties from seeing content without an account.</p>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p class="settings-label">Platform</p>
|
<p class="settings-label">Platform</p>
|
||||||
<div class="select-content">
|
<div class="select-content">
|
||||||
<div class="select-button">
|
<div class="select-button">
|
||||||
<select name="community_platform" id="community_platform">
|
{{ form.platform }}
|
||||||
<option value="0"{% if community.platform == 0 %} selected{% endif %}>None</option>
|
|
||||||
<option value="1"{% if community.platform == 1 %} selected{% endif %}>3DS</option>
|
|
||||||
<option value="2"{% if community.platform == 2 %} selected{% endif %}>Wii U</option>
|
|
||||||
<option value="3"{% if community.platform == 3 %} selected{% endif %}>Switch</option>
|
|
||||||
<option value="4"{% if community.platform == 4 %} selected{% endif %}>3DS and Wii U</option>
|
|
||||||
<option value="5"{% if community.platform == 5 %} selected{% endif %}>PC</option>
|
|
||||||
<option value="6"{% if community.platform == 6 %} selected{% endif %}>Xbox</option>
|
|
||||||
<option value="7"{% if community.platform == 7 %} selected{% endif %}>Playstation</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="note">If your community is for a video game, you can set the platform here. This will show an icon corresponding to what platform you pick.</p>
|
<p class="note">If your community is for a video game, you can set the platform here. This will show an icon corresponding to what platform you pick.</p>
|
||||||
|
|||||||
+19
-28
@@ -992,8 +992,10 @@ def community_tools(request, community):
|
|||||||
can_edit = the_community.can_edit_community(request)
|
can_edit = the_community.can_edit_community(request)
|
||||||
if not can_edit:
|
if not can_edit:
|
||||||
raise Http404()
|
raise Http404()
|
||||||
|
form = CommunitySettingForm(instance=the_community)
|
||||||
return render(request, 'closedverse_main/community_tools.html', {
|
return render(request, 'closedverse_main/community_tools.html', {
|
||||||
'title': 'Community tools',
|
'title': 'Community tools',
|
||||||
|
'form': form,
|
||||||
'community': the_community,
|
'community': the_community,
|
||||||
'activity_feed': activity_feed,
|
'activity_feed': activity_feed,
|
||||||
})
|
})
|
||||||
@@ -1006,22 +1008,11 @@ def community_tools_set(request, community):
|
|||||||
can_edit = the_community.can_edit_community(request)
|
can_edit = the_community.can_edit_community(request)
|
||||||
if not can_edit:
|
if not can_edit:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
form = CommunitySettingForm(request.POST, request.FILES, request , instance=the_community)
|
form = CommunitySettingForm(request.POST, request.FILES, instance=the_community)
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return json_response(form.errors.as_text())
|
return json_response(form.errors.as_text())
|
||||||
community = form.save(commit=False)
|
form.save()
|
||||||
community.name = form.cleaned_data.get('community_name')
|
AuditLog.objects.create(type=4, community=the_community, user=the_community.creator, by=request.user)
|
||||||
community.description = form.cleaned_data.get('community_description')
|
|
||||||
community.platform = form.cleaned_data.get('community_platform')
|
|
||||||
community.require_auth = True if form.cleaned_data.get('force_login') else False
|
|
||||||
if form.cleaned_data.get('community_icon'):
|
|
||||||
upload = util.image_upload(form.cleaned_data.get('community_icon'), True, icon=True)
|
|
||||||
community.ico = upload
|
|
||||||
if form.cleaned_data.get('community_banner'):
|
|
||||||
upload = util.image_upload(form.cleaned_data.get('community_banner'), True, banner=True)
|
|
||||||
community.banner = upload
|
|
||||||
community.save()
|
|
||||||
AuditLog.objects.create(type=4, community=community, user=community.creator, by=request.user)
|
|
||||||
return HttpResponse()
|
return HttpResponse()
|
||||||
else:
|
else:
|
||||||
raise Http404()
|
raise Http404()
|
||||||
@@ -1032,28 +1023,28 @@ def community_create(request):
|
|||||||
raise Http404()
|
raise Http404()
|
||||||
if request.user.c_tokens < 1:
|
if request.user.c_tokens < 1:
|
||||||
raise Http404()
|
raise Http404()
|
||||||
|
form = CommunitySettingForm()
|
||||||
return render(request, 'closedverse_main/community_create.html', {
|
return render(request, 'closedverse_main/community_create.html', {
|
||||||
'title': 'Create a community',
|
'title': 'Create a community',
|
||||||
|
'form': form,
|
||||||
'tokens': request.user.c_tokens,
|
'tokens': request.user.c_tokens,
|
||||||
})
|
})
|
||||||
def community_create_action(request):
|
def community_create_action(request):
|
||||||
user = request.user
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
if not request.user.is_authenticated:
|
if not request.user.is_authenticated:
|
||||||
raise Http404()
|
return HttpResponseForbidden()
|
||||||
if user.c_tokens < 1:
|
if request.user.c_tokens < 1:
|
||||||
return json_response("You don't have any tokens left")
|
return HttpResponseForbidden()
|
||||||
if len(request.POST.get('community_name')) == 0 or len(request.POST.get('community_name')) >= 100:
|
form = CommunitySettingForm(request.POST, request.FILES)
|
||||||
return json_response('Your community name is either too short or too long.')
|
if not form.is_valid():
|
||||||
if len(request.POST.get('community_description')) >= 1024:
|
return json_response(form.errors.as_text())
|
||||||
return json_response('Your community description is too long.')
|
community = form.save()
|
||||||
if int(request.POST.get('community_platform')) >= 8:
|
community.type = 3
|
||||||
return json_response('Invalid Platform type.')
|
community.creator = request.user
|
||||||
get = request.POST.get
|
community.save()
|
||||||
user.c_tokens -= 1
|
|
||||||
user.save()
|
|
||||||
community = Community.objects.create(name=get('community_name'), description=get('community_description'), type=3, platform=get('community_platform'), creator=user)
|
|
||||||
return json_response('Community has been created, check the front page!', 'Done')
|
return json_response('Community has been created, check the front page!', 'Done')
|
||||||
|
else:
|
||||||
|
raise Http404()
|
||||||
@login_required
|
@login_required
|
||||||
def post_create(request, community):
|
def post_create(request, community):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
|||||||
Reference in New Issue
Block a user