diff --git a/avatar/conf.py b/avatar/conf.py
new file mode 100644
index 0000000..e25ee91
--- /dev/null
+++ b/avatar/conf.py
@@ -0,0 +1,29 @@
+from django.conf import settings
+from PIL import Image
+
+from appconf import AppConf
+
+
+class AvatarConf(AppConf):
+ DEFAULT_SIZE = 80
+ RESIZE_METHOD = Image.ANTIALIAS
+ STORAGE_DIR = 'avatars'
+ GRAVATAR_BASE_URL = 'http://www.gravatar.com/avatar/'
+ GRAVATAR_BACKUP = True
+ GRAVATAR_DEFAULT = None
+ DEFAULT_URL = 'avatar/img/default.jpg'
+ MAX_AVATARS_PER_USER = 42
+ MAX_SIZE = 1024 * 1024
+ THUMB_FORMAT = 'JPEG'
+ THUMB_QUALITY = 85
+ HASH_FILENAMES = False
+ HASH_USERDIRNAMES = False
+ ALLOWED_FILE_EXTS = None
+ CACHE_TIMEOUT = 60 * 60
+ STORAGE = settings.DEFAULT_FILE_STORAGE
+ CLEANUP_DELETED = False
+ AUTO_GENERATE_SIZES = (DEFAULT_SIZE,)
+
+ def configure_auto_generate_avatar_sizes(self, value):
+ return value or getattr(settings, 'AUTO_GENERATE_AVATAR_SIZES',
+ (self.DEFAULT_SIZE,))
diff --git a/avatar/forms.py b/avatar/forms.py
index d4bc4db..c52b42a 100644
--- a/avatar/forms.py
+++ b/avatar/forms.py
@@ -7,16 +7,16 @@ from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.template.defaultfilters import filesizeformat
+from avatar.conf import settings
from avatar.models import Avatar
-from avatar.settings import (AVATAR_MAX_AVATARS_PER_USER, AVATAR_MAX_SIZE,
- AVATAR_ALLOWED_FILE_EXTS, AVATAR_DEFAULT_SIZE)
def avatar_img(avatar, size):
if not avatar.thumbnail_exists(size):
avatar.create_thumbnail(size)
return mark_safe('
' %
- (avatar.avatar_url(size), six.text_type(avatar), size, size))
+ (avatar.avatar_url(size), six.text_type(avatar),
+ size, size))
class UploadAvatarForm(forms.Form):
@@ -29,29 +29,33 @@ class UploadAvatarForm(forms.Form):
def clean_avatar(self):
data = self.cleaned_data['avatar']
- if AVATAR_ALLOWED_FILE_EXTS:
- (root, ext) = os.path.splitext(data.name.lower())
- if ext not in AVATAR_ALLOWED_FILE_EXTS:
- raise forms.ValidationError(
- _("%(ext)s is an invalid file extension. "
- "Authorized extensions are : %(valid_exts_list)s") %
- {'ext': ext, 'valid_exts_list': ", ".join(AVATAR_ALLOWED_FILE_EXTS)})
- if data.size > AVATAR_MAX_SIZE:
+
+ if settings.AVATAR_ALLOWED_FILE_EXTS:
+ root, ext = os.path.splitext(data.name.lower())
+ if ext not in settings.AVATAR_ALLOWED_FILE_EXTS:
+ valid_exts = ", ".join(settings.AVATAR_ALLOWED_FILE_EXTS)
+ error = _("%(ext)s is an invalid file extension. "
+ "Authorized extensions are : %(valid_exts_list)s")
+ raise forms.ValidationError(error %
+ {'ext': ext,
+ 'valid_exts_list': valid_exts})
+
+ if data.size > settings.AVATAR_MAX_SIZE:
error = _("Your file is too big (%(size)s), "
"the maximum allowed size is %(max_valid_size)s")
raise forms.ValidationError(error % {
'size': filesizeformat(data.size),
- 'max_valid_size': filesizeformat(AVATAR_MAX_SIZE)
+ 'max_valid_size': filesizeformat(settings.AVATAR_MAX_SIZE)
})
count = Avatar.objects.filter(user=self.user).count()
- if (AVATAR_MAX_AVATARS_PER_USER > 1 and
- count >= AVATAR_MAX_AVATARS_PER_USER):
+ if (settings.AVATAR_MAX_AVATARS_PER_USER > 1 and
+ count >= settings.AVATAR_MAX_AVATARS_PER_USER):
error = _("You already have %(nb_avatars)d avatars, "
"and the maximum allowed is %(nb_max_avatars)d.")
raise forms.ValidationError(error % {
'nb_avatars': count,
- 'nb_max_avatars': AVATAR_MAX_AVATARS_PER_USER,
+ 'nb_max_avatars': settings.AVATAR_MAX_AVATARS_PER_USER,
})
return
@@ -60,21 +64,23 @@ class PrimaryAvatarForm(forms.Form):
def __init__(self, *args, **kwargs):
kwargs.pop('user')
- size = kwargs.pop('size', AVATAR_DEFAULT_SIZE)
+ size = kwargs.pop('size', settings.AVATAR_DEFAULT_SIZE)
avatars = kwargs.pop('avatars')
super(PrimaryAvatarForm, self).__init__(*args, **kwargs)
+ choices = [(avatar.id, avatar_img(avatar, size)) for avatar in avatars]
self.fields['choice'] = forms.ChoiceField(label=_("Choices"),
- choices=[(c.id, avatar_img(c, size)) for c in avatars],
- widget=widgets.RadioSelect)
+ choices=choices,
+ widget=widgets.RadioSelect)
class DeleteAvatarForm(forms.Form):
def __init__(self, *args, **kwargs):
kwargs.pop('user')
- size = kwargs.pop('size', AVATAR_DEFAULT_SIZE)
+ size = kwargs.pop('size', settings.AVATAR_DEFAULT_SIZE)
avatars = kwargs.pop('avatars')
super(DeleteAvatarForm, self).__init__(*args, **kwargs)
+ choices = [(avatar.id, avatar_img(avatar, size)) for avatar in avatars]
self.fields['choices'] = forms.MultipleChoiceField(label=_("Choices"),
- choices=[(c.id, avatar_img(c, size)) for c in avatars],
- widget=widgets.CheckboxSelectMultiple)
+ choices=choices,
+ widget=widgets.CheckboxSelectMultiple)
diff --git a/avatar/management/commands/rebuild_avatars.py b/avatar/management/commands/rebuild_avatars.py
index 0b00835..0c1180e 100644
--- a/avatar/management/commands/rebuild_avatars.py
+++ b/avatar/management/commands/rebuild_avatars.py
@@ -1,15 +1,15 @@
from django.core.management.base import NoArgsCommand
+from django.conf import settings
from avatar.models import Avatar
-from avatar.settings import AUTO_GENERATE_AVATAR_SIZES
class Command(NoArgsCommand):
help = ("Regenerates avatar thumbnails for the sizes specified in "
- "settings.AUTO_GENERATE_AVATAR_SIZES.")
+ "settings.AVATAR_AUTO_GENERATE_SIZES.")
def handle_noargs(self, **options):
for avatar in Avatar.objects.all():
- for size in AUTO_GENERATE_AVATAR_SIZES:
+ for size in settings.AVATAR_AUTO_GENERATE_SIZES:
print("Rebuilding Avatar id=%s at size %s." % (avatar.id, size))
avatar.create_thumbnail(size)
diff --git a/avatar/models.py b/avatar/models.py
index fd20b0d..5bc3a52 100644
--- a/avatar/models.py
+++ b/avatar/models.py
@@ -3,7 +3,6 @@ import os
import hashlib
from PIL import Image
-from django.conf import settings
from django.db import models
from django.core.files import File
from django.core.files.base import ContentFile
@@ -12,27 +11,21 @@ from django.utils.translation import ugettext as _
from django.utils import six
from django.db.models import signals
-from avatar.util import get_username, force_bytes
+from avatar.conf import settings
+from avatar.util import get_username, force_bytes, invalidate_cache
try:
from django.utils.timezone import now
except ImportError:
now = datetime.datetime.now
-from avatar.util import invalidate_cache
-from avatar.settings import (AVATAR_STORAGE_DIR, AVATAR_RESIZE_METHOD,
- AVATAR_MAX_AVATARS_PER_USER, AVATAR_THUMB_FORMAT,
- AVATAR_HASH_USERDIRNAMES, AVATAR_HASH_FILENAMES,
- AVATAR_THUMB_QUALITY, AUTO_GENERATE_AVATAR_SIZES,
- AVATAR_DEFAULT_SIZE, AVATAR_STORAGE,
- AVATAR_CLEANUP_DELETED)
-avatar_storage = get_storage_class(AVATAR_STORAGE)()
+avatar_storage = get_storage_class(settings.AVATAR_STORAGE)()
def avatar_file_path(instance=None, filename=None, size=None, ext=None):
- tmppath = [AVATAR_STORAGE_DIR]
- if AVATAR_HASH_USERDIRNAMES:
+ tmppath = [settings.AVATAR_STORAGE_DIR]
+ if settings.AVATAR_HASH_USERDIRNAMES:
tmp = hashlib.md5(get_username(instance.user)).hexdigest()
tmppath.extend([tmp[0], tmp[1], get_username(instance.user)])
else:
@@ -40,7 +33,7 @@ def avatar_file_path(instance=None, filename=None, size=None, ext=None):
if not filename:
# Filename already stored in database
filename = instance.avatar.name
- if ext and AVATAR_HASH_FILENAMES:
+ if ext and settings.AVATAR_HASH_FILENAMES:
# An extension was provided, probably because the thumbnail
# is in a different format than the file. Use it. Because it's
# only enabled if AVATAR_HASH_FILENAMES is true, we can trust
@@ -49,7 +42,7 @@ def avatar_file_path(instance=None, filename=None, size=None, ext=None):
filename = root + "." + ext
else:
# File doesn't exist yet
- if AVATAR_HASH_FILENAMES:
+ if settings.AVATAR_HASH_FILENAMES:
(root, ext) = os.path.splitext(filename)
filename = hashlib.md5(force_bytes(filename)).hexdigest()
filename = filename + ext
@@ -84,7 +77,7 @@ class Avatar(models.Model):
avatars = Avatar.objects.filter(user=self.user)
if self.pk:
avatars = avatars.exclude(pk=self.pk)
- if AVATAR_MAX_AVATARS_PER_USER > 1:
+ if settings.AVATAR_MAX_AVATARS_PER_USER > 1:
if self.primary:
avatars = avatars.filter(primary=True)
avatars.update(primary=False)
@@ -101,7 +94,7 @@ class Avatar(models.Model):
try:
orig = self.avatar.storage.open(self.avatar.name, 'rb')
image = Image.open(orig)
- quality = quality or AVATAR_THUMB_QUALITY
+ quality = quality or settings.AVATAR_THUMB_QUALITY
w, h = image.size
if w != size or h != size:
if w > h:
@@ -112,9 +105,9 @@ class Avatar(models.Model):
image = image.crop((0, diff, w, h - diff))
if image.mode != "RGB":
image = image.convert("RGB")
- image = image.resize((size, size), AVATAR_RESIZE_METHOD)
+ image = image.resize((size, size), settings.AVATAR_RESIZE_METHOD)
thumb = six.BytesIO()
- image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality)
+ image.save(thumb, settings.AVATAR_THUMB_FORMAT, quality=quality)
thumb_file = ContentFile(thumb.getvalue())
else:
thumb_file = File(orig)
@@ -126,10 +119,10 @@ class Avatar(models.Model):
return self.avatar.storage.url(self.avatar_name(size))
def get_absolute_url(self):
- return self.avatar_url(AVATAR_DEFAULT_SIZE)
+ return self.avatar_url(settings.AVATAR_DEFAULT_SIZE)
def avatar_name(self, size):
- ext = find_extension(AVATAR_THUMB_FORMAT)
+ ext = find_extension(settings.AVATAR_THUMB_FORMAT)
return avatar_file_path(
instance=self,
size=size,
@@ -144,12 +137,12 @@ def invalidate_avatar_cache(sender, instance, **kwargs):
def create_default_thumbnails(sender, instance, created=False, **kwargs):
invalidate_avatar_cache(sender, instance)
if created:
- for size in AUTO_GENERATE_AVATAR_SIZES:
+ for size in settings.AVATAR_AUTO_GENERATE_SIZES:
instance.create_thumbnail(size)
def remove_avatar_images(instance=None, **kwargs):
- for size in AUTO_GENERATE_AVATAR_SIZES:
+ for size in settings.AVATAR_AUTO_GENERATE_SIZES:
if instance.thumbnail_exists(size):
instance.avatar.storage.delete(instance.avatar_name(size))
instance.avatar.storage.delete(instance.avatar.name)
@@ -158,5 +151,5 @@ def remove_avatar_images(instance=None, **kwargs):
signals.post_save.connect(create_default_thumbnails, sender=Avatar)
signals.post_delete.connect(invalidate_avatar_cache, sender=Avatar)
-if AVATAR_CLEANUP_DELETED:
+if settings.AVATAR_CLEANUP_DELETED:
signals.post_delete.connect(remove_avatar_images, sender=Avatar)
diff --git a/avatar/settings.py b/avatar/settings.py
deleted file mode 100644
index 71a3609..0000000
--- a/avatar/settings.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from django.conf import settings
-from PIL import Image
-
-AVATAR_DEFAULT_SIZE = getattr(settings, 'AVATAR_DEFAULT_SIZE', 80)
-AUTO_GENERATE_AVATAR_SIZES = getattr(settings, 'AUTO_GENERATE_AVATAR_SIZES', (AVATAR_DEFAULT_SIZE,))
-AVATAR_RESIZE_METHOD = getattr(settings, 'AVATAR_RESIZE_METHOD', Image.ANTIALIAS)
-AVATAR_STORAGE_DIR = getattr(settings, 'AVATAR_STORAGE_DIR', 'avatars')
-AVATAR_GRAVATAR_BASE_URL = getattr(settings, 'AVATAR_GRAVATAR_BASE_URL', 'http://www.gravatar.com/avatar/')
-AVATAR_GRAVATAR_BACKUP = getattr(settings, 'AVATAR_GRAVATAR_BACKUP', True)
-AVATAR_GRAVATAR_DEFAULT = getattr(settings, 'AVATAR_GRAVATAR_DEFAULT', None)
-AVATAR_DEFAULT_URL = getattr(settings, 'AVATAR_DEFAULT_URL', 'avatar/img/default.jpg')
-AVATAR_MAX_AVATARS_PER_USER = getattr(settings, 'AVATAR_MAX_AVATARS_PER_USER', 42)
-AVATAR_MAX_SIZE = getattr(settings, 'AVATAR_MAX_SIZE', 1024 * 1024)
-AVATAR_THUMB_FORMAT = getattr(settings, 'AVATAR_THUMB_FORMAT', "JPEG")
-AVATAR_THUMB_QUALITY = getattr(settings, 'AVATAR_THUMB_QUALITY', 85)
-AVATAR_HASH_FILENAMES = getattr(settings, 'AVATAR_HASH_FILENAMES', False)
-AVATAR_HASH_USERDIRNAMES = getattr(settings, 'AVATAR_HASH_USERDIRNAMES', False)
-AVATAR_ALLOWED_FILE_EXTS = getattr(settings, 'AVATAR_ALLOWED_FILE_EXTS', None)
-AVATAR_CACHE_TIMEOUT = getattr(settings, 'AVATAR_CACHE_TIMEOUT', 60 * 60)
-AVATAR_STORAGE = getattr(settings, 'AVATAR_STORAGE', settings.DEFAULT_FILE_STORAGE)
-AVATAR_CLEANUP_DELETED = getattr(settings, 'AVATAR_CLEANUP_DELETED', False)
diff --git a/avatar/templatetags/avatar_tags.py b/avatar/templatetags/avatar_tags.py
index d1b32ff..75a1a4f 100644
--- a/avatar/templatetags/avatar_tags.py
+++ b/avatar/templatetags/avatar_tags.py
@@ -12,8 +12,7 @@ from django.template.loader import render_to_string
from django.utils import six
from django.utils.translation import ugettext as _
-from avatar.settings import (AVATAR_GRAVATAR_BACKUP, AVATAR_GRAVATAR_DEFAULT,
- AVATAR_DEFAULT_SIZE, AVATAR_GRAVATAR_BASE_URL)
+from avatar.conf import settings
from avatar.util import (get_primary_avatar, get_default_avatar_url,
cache_result, get_user_model, get_user, force_bytes)
from avatar.models import Avatar
@@ -23,25 +22,25 @@ register = template.Library()
@cache_result()
@register.simple_tag
-def avatar_url(user, size=AVATAR_DEFAULT_SIZE):
+def avatar_url(user, size=settings.AVATAR_DEFAULT_SIZE):
avatar = get_primary_avatar(user, size=size)
if avatar:
return avatar.avatar_url(size)
- if AVATAR_GRAVATAR_BACKUP:
+ if settings.AVATAR_GRAVATAR_BACKUP:
params = {'s': str(size)}
- if AVATAR_GRAVATAR_DEFAULT:
- params['d'] = AVATAR_GRAVATAR_DEFAULT
+ if settings.AVATAR_GRAVATAR_DEFAULT:
+ params['d'] = settings.AVATAR_GRAVATAR_DEFAULT
path = "%s/?%s" % (hashlib.md5(force_bytes(user.email)).hexdigest(),
urlencode(params))
- return urljoin(AVATAR_GRAVATAR_BASE_URL, path)
+ return urljoin(settings.AVATAR_GRAVATAR_BASE_URL, path)
return get_default_avatar_url()
@cache_result()
@register.simple_tag
-def avatar(user, size=AVATAR_DEFAULT_SIZE, **kwargs):
+def avatar(user, size=settings.AVATAR_DEFAULT_SIZE, **kwargs):
if not isinstance(user, get_user_model()):
try:
user = get_user(user)
@@ -71,7 +70,7 @@ def has_avatar(user):
@cache_result()
@register.simple_tag
-def primary_avatar(user, size=AVATAR_DEFAULT_SIZE):
+def primary_avatar(user, size=settings.AVATAR_DEFAULT_SIZE):
"""
This tag tries to get the default avatar for a user without doing any db
requests. It achieve this by linking to a special view that will do all the
@@ -86,7 +85,7 @@ def primary_avatar(user, size=AVATAR_DEFAULT_SIZE):
@cache_result()
@register.simple_tag
-def render_avatar(avatar, size=AVATAR_DEFAULT_SIZE):
+def render_avatar(avatar, size=settings.AVATAR_DEFAULT_SIZE):
if not avatar.thumbnail_exists(size):
avatar.create_thumbnail(size)
return """
""" % (
diff --git a/avatar/util.py b/avatar/util.py
index 6f4571c..195bee6 100644
--- a/avatar/util.py
+++ b/avatar/util.py
@@ -1,6 +1,5 @@
import hashlib
-from django.conf import settings
from django.core.cache import cache
from django.utils import six
from django.template.defaultfilters import slugify
@@ -22,8 +21,8 @@ except ImportError:
else:
custom_user_model = True
-from avatar.settings import (AVATAR_DEFAULT_URL, AVATAR_CACHE_TIMEOUT,
- AUTO_GENERATE_AVATAR_SIZES, AVATAR_DEFAULT_SIZE)
+from avatar.conf import settings
+
cached_funcs = set()
@@ -56,11 +55,11 @@ def get_cache_key(user_or_username, size, prefix):
def cache_set(key, value):
- cache.set(key, value, AVATAR_CACHE_TIMEOUT)
+ cache.set(key, value, settings.AVATAR_CACHE_TIMEOUT)
return value
-def cache_result(default_size=AVATAR_DEFAULT_SIZE):
+def cache_result(default_size=settings.AVATAR_DEFAULT_SIZE):
"""
Decorator to cache the result of functions that take a ``user`` and a
``size`` value.
@@ -70,7 +69,6 @@ def cache_result(default_size=AVATAR_DEFAULT_SIZE):
prefix = func.__name__
cached_funcs.add(prefix)
key = get_cache_key(user, size or default_size, prefix=prefix)
- print key
result = cache.get(key)
if result is None:
result = func(user, size or default_size)
@@ -84,7 +82,7 @@ def invalidate_cache(user, size=None):
"""
Function to be called when saving or changing an user's avatars.
"""
- sizes = set(AUTO_GENERATE_AVATAR_SIZES)
+ sizes = set(settings.AVATAR_AUTO_GENERATE_SIZES)
if size is not None:
sizes.add(size)
for prefix in cached_funcs:
@@ -96,20 +94,23 @@ def get_default_avatar_url():
base_url = getattr(settings, 'STATIC_URL', None)
if not base_url:
base_url = getattr(settings, 'MEDIA_URL', '')
- # Don't use base_url if the default avatar url starts with http:// of https://
- if AVATAR_DEFAULT_URL.startswith('http://') or AVATAR_DEFAULT_URL.startswith('https://'):
- return AVATAR_DEFAULT_URL
+
+ # Don't use base_url if the default url starts with http:// of https://
+ if settings.AVATAR_DEFAULT_URL.startswith(('http://', 'https://')):
+ return settings.AVATAR_DEFAULT_URL
# We'll be nice and make sure there are no duplicated forward slashes
ends = base_url.endswith('/')
- begins = AVATAR_DEFAULT_URL.startswith('/')
+
+ begins = settings.AVATAR_DEFAULT_URL.startswith('/')
if ends and begins:
base_url = base_url[:-1]
elif not ends and not begins:
- return '%s/%s' % (base_url, AVATAR_DEFAULT_URL)
- return '%s%s' % (base_url, AVATAR_DEFAULT_URL)
+ return '%s/%s' % (base_url, settings.AVATAR_DEFAULT_URL)
+
+ return '%s%s' % (base_url, settings.AVATAR_DEFAULT_URL)
-def get_primary_avatar(user, size=AVATAR_DEFAULT_SIZE):
+def get_primary_avatar(user, size=settings.AVATAR_DEFAULT_SIZE):
User = get_user_model()
if not isinstance(user, User):
try:
diff --git a/avatar/views.py b/avatar/views.py
index 5a2d0b0..6e6d077 100644
--- a/avatar/views.py
+++ b/avatar/views.py
@@ -6,9 +6,9 @@ from django.utils.translation import ugettext as _
from django.contrib import messages
from django.contrib.auth.decorators import login_required
+from django.conf import settings
from avatar.forms import PrimaryAvatarForm, DeleteAvatarForm, UploadAvatarForm
from avatar.models import Avatar
-from avatar.settings import AVATAR_MAX_AVATARS_PER_USER, AVATAR_DEFAULT_SIZE
from avatar.signals import avatar_updated
from avatar.util import (get_primary_avatar, get_default_avatar_url,
get_user_model, get_user)
@@ -16,20 +16,21 @@ from avatar.util import (get_primary_avatar, get_default_avatar_url,
def _get_next(request):
"""
- The part that's the least straightforward about views in this module is how they
- determine their redirects after they have finished computation.
+ The part that's the least straightforward about views in this module is
+ how they determine their redirects after they have finished computation.
- In short, they will try and determine the next place to go in the following order:
+ In short, they will try and determine the next place to go in the
+ following order:
- 1. If there is a variable named ``next`` in the *POST* parameters, the view will
- redirect to that variable's value.
- 2. If there is a variable named ``next`` in the *GET* parameters, the view will
- redirect to that variable's value.
- 3. If Django can determine the previous page from the HTTP headers, the view will
- redirect to that previous page.
+ 1. If there is a variable named ``next`` in the *POST* parameters, the
+ view will redirect to that variable's value.
+ 2. If there is a variable named ``next`` in the *GET* parameters,
+ the view will redirect to that variable's value.
+ 3. If Django can determine the previous page from the HTTP headers,
+ the view will redirect to that previous page.
"""
next = request.POST.get('next', request.GET.get('next',
- request.META.get('HTTP_REFERER', None)))
+ request.META.get('HTTP_REFERER', None)))
if not next:
next = request.path
return next
@@ -46,11 +47,12 @@ def _get_avatars(user):
else:
avatar = None
- if AVATAR_MAX_AVATARS_PER_USER == 1:
+ if settings.AVATAR_MAX_AVATARS_PER_USER == 1:
avatars = primary_avatar
else:
- # Slice the default set now that we used the queryset for the primary avatar
- avatars = avatars[:AVATAR_MAX_AVATARS_PER_USER]
+ # Slice the default set now that we used
+ # the queryset for the primary avatar
+ avatars = avatars[:settings.AVATAR_MAX_AVATARS_PER_USER]
return (avatar, avatars)
@@ -61,7 +63,8 @@ def add(request, extra_context=None, next_override=None,
extra_context = {}
avatar, avatars = _get_avatars(request.user)
upload_avatar_form = upload_form(request.POST or None,
- request.FILES or None, user=request.user)
+ request.FILES or None,
+ user=request.user)
if request.method == "POST" and 'avatar' in request.FILES:
if upload_avatar_form.is_valid():
avatar = Avatar(user=request.user, primary=True)
@@ -94,7 +97,8 @@ def change(request, extra_context=None, next_override=None,
kwargs = {}
upload_avatar_form = upload_form(user=request.user, **kwargs)
primary_avatar_form = primary_form(request.POST or None,
- user=request.user, avatars=avatars, **kwargs)
+ user=request.user,
+ avatars=avatars, **kwargs)
if request.method == "POST":
updated = False
if 'choice' in request.POST and primary_avatar_form.is_valid():
@@ -125,7 +129,8 @@ def delete(request, extra_context=None, next_override=None, *args, **kwargs):
extra_context = {}
avatar, avatars = _get_avatars(request.user)
delete_avatar_form = DeleteAvatarForm(request.POST or None,
- user=request.user, avatars=avatars)
+ user=request.user,
+ avatars=avatars)
if request.method == 'POST':
if delete_avatar_form.is_valid():
ids = delete_avatar_form.cleaned_data['choices']
@@ -135,11 +140,14 @@ def delete(request, extra_context=None, next_override=None, *args, **kwargs):
if six.text_type(a.id) not in ids:
a.primary = True
a.save()
- avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar)
+ avatar_updated.send(sender=Avatar, user=request.user,
+ avatar=avatar)
break
Avatar.objects.filter(id__in=ids).delete()
- messages.success(request, _("Successfully deleted the requested avatars."))
+ messages.success(request,
+ _("Successfully deleted the requested avatars."))
return redirect(next_override or _get_next(request))
+
context = {
'avatar': avatar,
'avatars': avatars,
@@ -156,10 +164,13 @@ def avatar_gallery(request, username, template_name="avatar/gallery.html"):
user = get_user(username)
except get_user_model().DoesNotExist:
raise Http404
- return render(request, template_name, {
+
+ context = {
"other_user": user,
"avatars": user.avatar_set.all(),
- })
+ }
+
+ return render(request, template_name, context)
def avatar(request, username, id, template_name="avatar/avatar.html"):
@@ -207,7 +218,7 @@ def avatar(request, username, id, template_name="avatar/avatar.html"):
})
-def render_primary(request, extra_context={}, user=None, size=AVATAR_DEFAULT_SIZE, *args, **kwargs):
+def render_primary(request, user=None, size=settings.AVATAR_DEFAULT_SIZE):
size = int(size)
avatar = get_primary_avatar(user, size=size)
if avatar:
@@ -216,6 +227,8 @@ def render_primary(request, extra_context={}, user=None, size=AVATAR_DEFAULT_SIZ
# be useful in certain situations, particulary if there is a CDN and
# we want to minimize the storage usage on our static server, letting
# the CDN store those files instead
- return redirect(avatar.avatar_url(size))
+ url = avatar.avatar_url(size)
else:
- return redirect(get_default_avatar_url())
+ url = get_default_avatar_url()
+
+ return redirect(url)
diff --git a/setup.py b/setup.py
index f5b624c..40bc22f 100644
--- a/setup.py
+++ b/setup.py
@@ -52,7 +52,9 @@ setup(
'media/avatar/img/default.jpg',
],
},
- install_requires=['Pillow>=2.0'],
- include_package_data=True,
+ install_requires=[
+ 'Pillow>=2.0',
+ 'django-appconf>=0.6',
+ ],
zip_safe=False,
)
diff --git a/tests/tests.py b/tests/tests.py
index 985d2ba..1df24c1 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -4,7 +4,7 @@ from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf import settings
-from avatar.settings import AVATAR_DEFAULT_URL, AVATAR_MAX_AVATARS_PER_USER
+from avatar.conf import settings
from avatar.util import get_primary_avatar, get_user_model
from avatar.models import Avatar
from PIL import Image
@@ -72,7 +72,7 @@ class AvatarUploadTests(TestCase):
if not base_url:
base_url = settings.MEDIA_URL
self.assertTrue(base_url in loc)
- self.assertTrue(loc.endswith(AVATAR_DEFAULT_URL))
+ self.assertTrue(loc.endswith(settings.AVATAR_DEFAULT_URL))
def testNonExistingUser(self):
a = get_primary_avatar("nonexistinguser")
@@ -110,7 +110,7 @@ class AvatarUploadTests(TestCase):
self.assertEqual(avatars[0].id, primaries[0].id)
def testTooManyAvatars(self):
- for i in range(0, AVATAR_MAX_AVATARS_PER_USER):
+ for i in range(0, settings.AVATAR_MAX_AVATARS_PER_USER):
self.testNormalImageUpload()
count_before = Avatar.objects.filter(user=self.user).count()
response = upload_helper(self, "test.png")