from urllib import urlencode
from urllib2 import urlopen, HTTPError
from hashlib import md5

from django.db import models
from django.conf import settings
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile


class CustomUser(...):  # however you choose to subclass the user
    ...
    email = models.EmailField(max_length=254, unique=True)
    photo = models.ImageField(upload_to='users/photos', blank=True)
    slug = models.SlugField(unique=True, blank=True)
    ...

    def save(CustomUser, self).save(*args, **kwargs)
        """
        Overrides CustomUser's save() method. Assumes that CustomUser has
        self.photo, self.email, and self.slug fields. Adjust code as
        necessary for your model.
        """
        if not self.photo:
            base_url = 'http://{0}'.format(Site.objects.get_current().domain)
            default_photo = 'users/photos/generic_profile_photo.png'  # use your own
            default_photo_url = base_url + settings.MEDIA_URL + default_photo  # alternatively you can just use 'mm' here
            gravatar_base = 'http://www.gravatar.com/avatar/'
            gravatar_email = md5(self.email.lower()).hexdigest()
            gravatar_default = urlencode({'d': default_photo_url})
            gravatar_query = '{0}{1}?{2}'.format(gravatar_base, gravatar_email, gravatar_default)
    
            try:
                tmp_photo = NamedTemporaryFile(delete=True)
                retr_photo = urlopen(gravatar_query)
                content_type = retr_photo.headers.getheader('Content-Type', None)
                file_type = None
                if content_type:
                    if content_type == 'image/jpeg':
                        file_type = 'jpg'
                    elif content_type == 'image/png':
                        file_type = 'png'
                    elif content_type == 'image/bmp':
                        file_type = 'bmp'
                    elif content_type == 'image/gif':
                        file_type = 'gif'
                    elif content_type == 'image/tiff':
                        file_type = 'tiff'
                tmp_photo.write(retr_photo.read())
                tmp_photo.flush()
                # I'm using self.slug here to name the file, but it's not necessary
                self.photo.save('users/photos/{0}.{1}'.format(self.slug, file_type if file_type else 'png'),
                                File(tmp_photo), save=True)
            except HTTPError:  # as little can go wrong with users, so any HTTPError should just default
                self.photo = default_photo
        super(DJ, self).save(*args, **kwargs)