gremmie@1: """
gremmie@1: This file contains the forms used by the bio application.
gremmie@1: """
gremmie@1: from PIL import ImageFile
gremmie@1: from PIL import Image
gremmie@1: 
gremmie@1: try:
gremmie@1:     from cStringIO import StringIO
gremmie@1: except:
gremmie@1:     from StringIO import StringIO
gremmie@1: 
gremmie@1: from django import forms
gremmie@1: from django.conf import settings
gremmie@1: from django.core.files.base import ContentFile
gremmie@1: from django.contrib.auth.models import User
gremmie@1: 
gremmie@1: from bio.models import UserProfile
gremmie@1: 
gremmie@1: 
gremmie@1: class EditUserForm(forms.ModelForm):
gremmie@1:     """Form for editing the fields of the User model."""
gremmie@1:     email = forms.EmailField(label='Email', required=True)
gremmie@1:     class Meta:
gremmie@1:         model = User
gremmie@1:         fields = ('first_name', 'last_name', 'email')
gremmie@1: 
gremmie@1: 
gremmie@1: class EditUserProfileForm(forms.ModelForm):
gremmie@1:     """Form for editing the fields of the UserProfile model."""
gremmie@1:     location = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
gremmie@1:     occupation = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
gremmie@1:     interests = forms.CharField(required=False, widget=forms.TextInput(attrs={'size' : 64 }))
bgneal@70:     time_zone = forms.CharField(required=False, widget=forms.HiddenInput())
bgneal@120:     use_24_time = forms.BooleanField(label='Show times in 24-hour mode', required=False)
gremmie@1: 
gremmie@1:     class Meta:
gremmie@1:         model = UserProfile
bgneal@120:         exclude = ('user', 'avatar', 'profile_html', 'signature_html', 'forum_post_count')
gremmie@1: 
gremmie@1:     class Media:
gremmie@1:         css = {
bgneal@6:             'all': settings.GPP_THIRD_PARTY_CSS['markitup'] + \
bgneal@6:                 settings.GPP_THIRD_PARTY_CSS['jquery-ui']
gremmie@1:         }
bgneal@12:         js = settings.GPP_THIRD_PARTY_JS['markitup'] + \
bgneal@6:             settings.GPP_THIRD_PARTY_JS['jquery-ui'] + \
bgneal@70:             ('js/bio.js', 'js/timezone.js')
gremmie@1: 
gremmie@1: 
gremmie@1: def get_image(file):
gremmie@1:     """
gremmie@1:     Returns a PIL Image from the supplied file.
gremmie@1:     Throws ValidationError if the file does not parse as an image file.
gremmie@1:     """
gremmie@1:     parser = ImageFile.Parser()
gremmie@1:     for chunk in file.chunks():
gremmie@1:         parser.feed(chunk)
gremmie@1:     try:
gremmie@1:         image = parser.close()
gremmie@1:         return image
gremmie@1:     except IOError:
gremmie@1:         pass
gremmie@1:     raise forms.ValidationError("Upload a valid image. " +
gremmie@1:             "The file you uploaded was either not an image or a corrupted image.")
gremmie@1: 
gremmie@1: 
gremmie@1: def scale_image(image, size):
gremmie@1:     """Scales an image file if necessary."""
gremmie@1: 
gremmie@1:     # don't upscale
gremmie@1:     if (size, size) >= image.size:
gremmie@1:         return image
gremmie@1: 
gremmie@1:     (w, h) = image.size
gremmie@1:     if w > h:
gremmie@1:         diff = (w - h) / 2
gremmie@1:         image = image.crop((diff, 0, w - diff, h))
gremmie@1:     elif h > w:
gremmie@1:         diff = (h - w) / 2
gremmie@1:         image = image.crop((0, diff, w, h - diff))
gremmie@1:     image = image.resize((size, size), Image.ANTIALIAS)
gremmie@1:     return image
gremmie@1: 
gremmie@1: 
gremmie@1: class UploadAvatarForm(forms.Form):
gremmie@1:     """Form used to change a user's avatar"""
gremmie@1:     avatar_file = forms.ImageField(required=False)
gremmie@1:     image = None
gremmie@1: 
gremmie@1:     def clean_avatar_file(self):
gremmie@1:         file = self.cleaned_data['avatar_file']
gremmie@1:         if file is not None:
gremmie@1:             if file.size > settings.MAX_AVATAR_SIZE_BYTES:
gremmie@1:                 raise forms.ValidationError("Please upload a file smaller than %s bytes." % \
gremmie@1:                         settings.MAX_AVATAR_SIZE)
gremmie@1:             self.image = get_image(file)
gremmie@1:             self.format = self.image.format
gremmie@1:         return file
gremmie@1: 
gremmie@1:     def get_file(self):
gremmie@1:         if self.image is not None:
gremmie@1:             self.image = scale_image(self.image, settings.MAX_AVATAR_SIZE_PIXELS)
gremmie@1:             s = StringIO()
gremmie@1:             self.image.save(s, self.format)
gremmie@1:             return ContentFile(s.getvalue())
gremmie@1:         return None
gremmie@1: 
gremmie@1:     def get_filename(self):
gremmie@1:         return self.cleaned_data['avatar_file'].name
gremmie@1: