annotate gpp/bio/forms.py @ 162:6a5bdcf93ad3

Fix #48; shoutbox was no longer escaping user input on display.
author Brian Neal <bgneal@gmail.com>
date Tue, 22 Dec 2009 03:55:37 +0000
parents ab7830b067b3
children 2baadae33f2e
rev   line source
gremmie@1 1 """
gremmie@1 2 This file contains the forms used by the bio application.
gremmie@1 3 """
gremmie@1 4 from PIL import ImageFile
gremmie@1 5 from PIL import Image
gremmie@1 6
gremmie@1 7 try:
gremmie@1 8 from cStringIO import StringIO
gremmie@1 9 except:
gremmie@1 10 from StringIO import StringIO
gremmie@1 11
gremmie@1 12 from django import forms
gremmie@1 13 from django.conf import settings
gremmie@1 14 from django.core.files.base import ContentFile
gremmie@1 15 from django.contrib.auth.models import User
gremmie@1 16
gremmie@1 17 from bio.models import UserProfile
bgneal@149 18 from core.widgets import AutoCompleteUserInput
gremmie@1 19
gremmie@1 20
gremmie@1 21 class EditUserForm(forms.ModelForm):
gremmie@1 22 """Form for editing the fields of the User model."""
gremmie@1 23 email = forms.EmailField(label='Email', required=True)
gremmie@1 24 class Meta:
gremmie@1 25 model = User
gremmie@1 26 fields = ('first_name', 'last_name', 'email')
gremmie@1 27
gremmie@1 28
gremmie@1 29 class EditUserProfileForm(forms.ModelForm):
gremmie@1 30 """Form for editing the fields of the UserProfile model."""
gremmie@1 31 location = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
gremmie@1 32 occupation = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
gremmie@1 33 interests = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
bgneal@70 34 time_zone = forms.CharField(required=False, widget=forms.HiddenInput())
bgneal@120 35 use_24_time = forms.BooleanField(label='Show times in 24-hour mode', required=False)
bgneal@133 36 profile_text = forms.CharField(required=False,
bgneal@133 37 widget=forms.Textarea(attrs={'class': 'markItUp'}))
bgneal@133 38 signature = forms.CharField(required=False,
bgneal@133 39 widget=forms.Textarea(attrs={'class': 'markItUp'}))
gremmie@1 40
gremmie@1 41 class Meta:
gremmie@1 42 model = UserProfile
bgneal@120 43 exclude = ('user', 'avatar', 'profile_html', 'signature_html', 'forum_post_count')
gremmie@1 44
gremmie@1 45 class Media:
gremmie@1 46 css = {
bgneal@6 47 'all': settings.GPP_THIRD_PARTY_CSS['markitup'] + \
bgneal@6 48 settings.GPP_THIRD_PARTY_CSS['jquery-ui']
gremmie@1 49 }
bgneal@12 50 js = settings.GPP_THIRD_PARTY_JS['markitup'] + \
bgneal@6 51 settings.GPP_THIRD_PARTY_JS['jquery-ui'] + \
bgneal@70 52 ('js/bio.js', 'js/timezone.js')
gremmie@1 53
gremmie@1 54
gremmie@1 55 def get_image(file):
gremmie@1 56 """
gremmie@1 57 Returns a PIL Image from the supplied file.
gremmie@1 58 Throws ValidationError if the file does not parse as an image file.
gremmie@1 59 """
gremmie@1 60 parser = ImageFile.Parser()
gremmie@1 61 for chunk in file.chunks():
gremmie@1 62 parser.feed(chunk)
gremmie@1 63 try:
gremmie@1 64 image = parser.close()
gremmie@1 65 return image
gremmie@1 66 except IOError:
gremmie@1 67 pass
gremmie@1 68 raise forms.ValidationError("Upload a valid image. " +
gremmie@1 69 "The file you uploaded was either not an image or a corrupted image.")
gremmie@1 70
gremmie@1 71
gremmie@1 72 def scale_image(image, size):
gremmie@1 73 """Scales an image file if necessary."""
gremmie@1 74
gremmie@1 75 # don't upscale
gremmie@1 76 if (size, size) >= image.size:
gremmie@1 77 return image
gremmie@1 78
gremmie@1 79 (w, h) = image.size
gremmie@1 80 if w > h:
gremmie@1 81 diff = (w - h) / 2
gremmie@1 82 image = image.crop((diff, 0, w - diff, h))
gremmie@1 83 elif h > w:
gremmie@1 84 diff = (h - w) / 2
gremmie@1 85 image = image.crop((0, diff, w, h - diff))
gremmie@1 86 image = image.resize((size, size), Image.ANTIALIAS)
gremmie@1 87 return image
gremmie@1 88
gremmie@1 89
gremmie@1 90 class UploadAvatarForm(forms.Form):
gremmie@1 91 """Form used to change a user's avatar"""
gremmie@1 92 avatar_file = forms.ImageField(required=False)
gremmie@1 93 image = None
gremmie@1 94
gremmie@1 95 def clean_avatar_file(self):
gremmie@1 96 file = self.cleaned_data['avatar_file']
gremmie@1 97 if file is not None:
gremmie@1 98 if file.size > settings.MAX_AVATAR_SIZE_BYTES:
gremmie@1 99 raise forms.ValidationError("Please upload a file smaller than %s bytes." % \
gremmie@1 100 settings.MAX_AVATAR_SIZE)
gremmie@1 101 self.image = get_image(file)
gremmie@1 102 self.format = self.image.format
gremmie@1 103 return file
gremmie@1 104
gremmie@1 105 def get_file(self):
gremmie@1 106 if self.image is not None:
gremmie@1 107 self.image = scale_image(self.image, settings.MAX_AVATAR_SIZE_PIXELS)
gremmie@1 108 s = StringIO()
gremmie@1 109 self.image.save(s, self.format)
gremmie@1 110 return ContentFile(s.getvalue())
gremmie@1 111 return None
gremmie@1 112
gremmie@1 113 def get_filename(self):
gremmie@1 114 return self.cleaned_data['avatar_file'].name
gremmie@1 115
bgneal@149 116
bgneal@149 117 class SearchUsersForm(forms.Form):
bgneal@149 118 """
bgneal@149 119 A form to search for users.
bgneal@149 120 """
bgneal@149 121 username = forms.CharField(max_length=30, widget=AutoCompleteUserInput())
bgneal@149 122
bgneal@149 123 def clean_username(self):
bgneal@149 124 username = self.cleaned_data['username']
bgneal@149 125 try:
bgneal@149 126 User.objects.get(username=username, is_active=True)
bgneal@149 127 except User.DoesNotExist:
bgneal@149 128 raise forms.ValidationError("That username does not exist.")
bgneal@149 129 return username