diff bio/forms.py @ 581:ee87ea74d46b

For Django 1.4, rearranged project structure for new manage.py.
author Brian Neal <bgneal@gmail.com>
date Sat, 05 May 2012 17:10:48 -0500
parents gpp/bio/forms.py@bbbc357ac5f3
children 678a1a2ef55a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bio/forms.py	Sat May 05 17:10:48 2012 -0500
@@ -0,0 +1,124 @@
+"""
+This file contains the forms used by the bio application.
+"""
+try:
+    from cStringIO import StringIO
+except:
+    from StringIO import StringIO
+
+from django import forms
+from django.conf import settings
+from django.core.files.base import ContentFile
+from django.contrib.auth.models import User
+
+from bio.models import UserProfile
+from core.widgets import AutoCompleteUserInput
+from core.image import parse_image, downscale_image_square
+
+
+class EditUserForm(forms.ModelForm):
+    """Form for editing the fields of the User model."""
+    email = forms.EmailField(label='Email', required=True)
+    class Meta:
+        model = User
+        fields = ('first_name', 'last_name', 'email')
+
+
+class EditUserProfileForm(forms.ModelForm):
+    """Form for editing the fields of the UserProfile model."""
+    location = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
+    occupation = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
+    interests = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
+    time_zone = forms.CharField(required=False, widget=forms.HiddenInput())
+    use_24_time = forms.BooleanField(label='Show times in 24-hour mode', required=False)
+    profile_text = forms.CharField(required=False,
+        widget=forms.Textarea(attrs={'class': 'markItUp'}))
+    signature = forms.CharField(required=False,
+        widget=forms.Textarea(attrs={'class': 'markItUp'}))
+    auto_favorite = forms.BooleanField(
+        label='Automatically favorite every forum topic I create or reply to', required=False)
+    auto_subscribe = forms.BooleanField(
+        label='Automatically subscribe to every forum topic I create or reply to', required=False)
+
+    class Meta:
+        model = UserProfile
+        fields = ('location', 'birthday', 'occupation', 'interests',
+            'profile_text', 'hide_email', 'signature', 'time_zone',
+            'use_24_time', 'auto_favorite', 'auto_subscribe')
+
+    class Media:
+        css = {
+            'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] +
+                settings.GPP_THIRD_PARTY_CSS['jquery-ui'])
+        }
+        js = (settings.GPP_THIRD_PARTY_JS['markitup'] +
+            settings.GPP_THIRD_PARTY_JS['jquery-ui'] +
+            ['js/bio.js', 'js/timezone.js'])
+
+
+class UploadAvatarForm(forms.Form):
+    """Form used to change a user's avatar"""
+    avatar_file = forms.ImageField(required=False)
+    image = None
+
+    def clean_avatar_file(self):
+        f = self.cleaned_data['avatar_file']
+        if f is not None:
+            if f.size > settings.MAX_AVATAR_SIZE_BYTES:
+                raise forms.ValidationError("Please upload a file smaller than "
+                    "%s bytes." % settings.MAX_AVATAR_SIZE_BYTES)
+            try:
+                self.image = parse_image(f)
+            except IOError:
+                raise forms.ValidationError("Please upload a valid image. "
+                    "The file you uploaded was either not an image or a "
+                    "corrupted image.")
+            self.file_type = self.image.format
+        return f
+
+    def save(self):
+        """
+        Perform any down-scaling needed on the new file, then return a tuple of
+        (filename, file object). Note that the file object returned may not
+        have a name; use the returned filename instead.
+
+        """
+        if not self.cleaned_data['avatar_file']:
+            return None, None
+
+        name = self.cleaned_data['avatar_file'].name
+        dim = settings.MAX_AVATAR_SIZE_PIXELS
+        max_size = (dim, dim)
+        if self.image and self.image.size > max_size:
+            self.image = downscale_image_square(self.image, dim)
+
+            # We need to return a Django File now. To get that from here,
+            # write the image data info a StringIO and then construct a
+            # Django ContentFile from that. The ContentFile has no name,
+            # that is why we return one ourselves explicitly.
+            s = StringIO()
+            self.image.save(s, self.file_type)
+            return name, ContentFile(s.getvalue())
+
+        return name, self.cleaned_data['avatar_file']
+
+
+class SearchUsersForm(forms.Form):
+    """
+    A form to search for users.
+    """
+    username = forms.CharField(max_length=30, widget=AutoCompleteUserInput())
+
+    class Media:
+        css = {
+          'all': settings.GPP_THIRD_PARTY_CSS['jquery-ui']
+        }
+        js = settings.GPP_THIRD_PARTY_JS['jquery-ui']
+
+    def clean_username(self):
+      username = self.cleaned_data['username'].strip()
+      try:
+         User.objects.get(username=username, is_active=True)
+      except User.DoesNotExist:
+         raise forms.ValidationError("That username does not exist.")
+      return username