Sith/core/views/forms.py

205 lines
7.8 KiB
Python
Raw Normal View History

2015-11-24 13:01:10 +00:00
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, UserChangeForm
2015-11-18 16:09:06 +00:00
from django import forms
from django.db import transaction
from django.core.exceptions import ValidationError
2015-11-18 16:09:06 +00:00
from django.contrib.auth import logout, login, authenticate
from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput
2016-08-10 03:48:06 +00:00
from django.utils.translation import ugettext as _
2016-08-13 03:33:09 +00:00
from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget
2015-11-18 16:09:06 +00:00
import logging
from core.models import User, Page, RealGroup, SithFile
2016-08-13 03:33:09 +00:00
# Widgets
class SelectSingle(Select):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_single"
else:
attrs = {'class': "select_single"}
return super(SelectSingle, self).render(name, value, attrs)
class SelectMultiple(Select):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_multiple"
else:
attrs = {'class': "select_multiple"}
return super(SelectMultiple, self).render(name, value, attrs)
class SelectDate(DateInput):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_date"
else:
attrs = {'class': "select_date"}
return super(SelectDate, self).render(name, value, attrs)
class SelectFile(TextInput):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_file"
else:
attrs = {'class': "select_file"}
output = '%(content)s<div name="%(name)s" class="choose_file_widget" title="%(title)s"></div>' % {
'content': super(SelectFile, self).render(name, value, attrs),
'title': _("Choose file"),
'name': name,
}
output += '<span name="' + name + '" class="choose_file_button">' + _("Choose file") + '</span>'
return output
class SelectUser(TextInput):
def render(self, name, value, attrs=None):
if attrs:
attrs['class'] = "select_user"
else:
attrs = {'class': "select_user"}
output = '%(content)s<div name="%(name)s" class="choose_user_widget" title="%(title)s"></div>' % {
'content': super(SelectUser, self).render(name, value, attrs),
'title': _("Choose user"),
'name': name,
}
output += '<span name="' + name + '" class="choose_user_button">' + _("Choose user") + '</span>'
return output
# Forms
2015-11-18 08:44:06 +00:00
class RegisteringForm(UserCreationForm):
error_css_class = 'error'
required_css_class = 'required'
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
2015-11-18 16:09:06 +00:00
def save(self, commit=True):
user = super(RegisteringForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.generate_username()
if commit:
user.save()
return user
2016-08-13 03:33:09 +00:00
# Image utils
from io import BytesIO
from PIL import Image
def scale_dimension(width, height, long_edge):
if width > height:
ratio = long_edge * 1. / width
else:
ratio = long_edge * 1. / height
return int(width * ratio), int(height * ratio)
def resize_image(im, edge, format):
from django.core.files.base import ContentFile
(w, h) = im.size
(width, height) = scale_dimension(w, h, long_edge=edge)
content = BytesIO()
im.resize((width, height), Image.ANTIALIAS).save(fp=content, format=format, dpi=[72, 72])
return ContentFile(content.getvalue())
class UserProfileForm(forms.ModelForm):
"""
Form handling the user profile, managing the files
This form is actually pretty bad and was made in the rush before the migration. It should be refactored.
TODO: refactor this form
"""
class Meta:
model = User
fields = ['first_name', 'last_name', 'nick_name', 'email', 'date_of_birth', 'profile_pict', 'avatar_pict',
2016-08-13 03:33:09 +00:00
'scrub_pict', 'sex', 'second_email', 'address', 'parent_address', 'phone', 'parent_phone',
'tshirt_size', 'role', 'department', 'dpt_option', 'semester', 'quote', 'school', 'promo',
'forum_signature']
widgets = {
'date_of_birth': SelectDate,
'profile_pict': forms.ClearableFileInput,
'avatar_pict': forms.ClearableFileInput,
'scrub_pict': forms.ClearableFileInput,
2016-08-13 03:33:09 +00:00
'phone': PhoneNumberInternationalFallbackWidget,
'parent_phone': PhoneNumberInternationalFallbackWidget,
}
labels = {
'profile_pict': _("Profile: you need to be visible on the picture, in order to be recognized (e.g. by the barmen)"),
'avatar_pict': _("Avatar: used on the forum"),
'scrub_pict': _("Scrub: let other know how your scrub looks like!"),
}
def __init__(self, *arg, **kwargs):
super(UserProfileForm, self).__init__(*arg, **kwargs)
def full_clean(self):
super(UserProfileForm, self).full_clean()
def generate_name(self, field_name, f):
field_name = field_name[:-4]
return field_name + str(self.instance.id) + "." + f.content_type.split('/')[-1]
def process(self, files):
avatar = self.instance.avatar_pict
profile = self.instance.profile_pict
scrub = self.instance.scrub_pict
self.full_clean()
self.cleaned_data['avatar_pict'] = avatar
self.cleaned_data['profile_pict'] = profile
self.cleaned_data['scrub_pict'] = scrub
parent = SithFile.objects.filter(parent=None, name="profiles").first()
for field,f in files:
with transaction.atomic():
try:
2016-08-13 03:33:09 +00:00
im = Image.open(BytesIO(f.read()))
new_file = SithFile(parent=parent, name=self.generate_name(field, f),
file=resize_image(im, 400, f.content_type.split('/')[-1]),
owner=self.instance, is_folder=False, mime_type=f.content_type, size=f._size)
new_file.file.name = new_file.name
old = SithFile.objects.filter(parent=parent, name=new_file.name).first()
if old:
old.delete()
new_file.clean()
new_file.save()
self.cleaned_data[field] = new_file
self._errors.pop(field, None)
except ValidationError as e:
self._errors.pop(field, None)
self.add_error(field, _("Error uploading file %(file_name)s: %(msg)s") %
{'file_name': f, 'msg': str(e.message)})
2016-08-13 03:33:09 +00:00
except IOError:
self._errors.pop(field, None)
self.add_error(field, _("Error uploading file %(file_name)s: %(msg)s") %
{'file_name': f, 'msg': _("Bad image format, only jpeg, png, and gif are accepted")})
self._post_clean()
2015-11-18 16:09:06 +00:00
2015-12-09 10:01:11 +00:00
class UserPropForm(forms.ModelForm):
2015-11-24 13:01:10 +00:00
error_css_class = 'error'
required_css_class = 'required'
class Meta:
model = User
fields = ['groups']
2015-12-14 09:49:15 +00:00
help_texts = {
'groups': "Which groups this user belongs to",
}
2015-11-26 15:32:56 +00:00
widgets = {
'groups': CheckboxSelectMultiple,
}
2015-11-24 13:01:10 +00:00
class PagePropForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
class Meta:
model = Page
2016-02-05 15:59:42 +00:00
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ]
widgets = {
2016-02-05 15:59:42 +00:00
'edit_groups': CheckboxSelectMultiple,
'view_groups': CheckboxSelectMultiple,
}
2015-11-27 15:09:47 +00:00
def __init__(self, *arg, **kwargs):
super(PagePropForm, self).__init__(*arg, **kwargs)
2016-02-05 15:59:42 +00:00
self.fields['edit_groups'].required = False
self.fields['view_groups'].required = False
2015-11-27 15:09:47 +00:00