Use django-appconf for nicer settings handling.

This commit is contained in:
Jannis Leidel 2013-09-13 17:59:52 +02:00
parent 266240250a
commit 65d5f66b9b
10 changed files with 143 additions and 121 deletions

29
avatar/conf.py Normal file
View file

@ -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,))

View file

@ -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('<img src="%s" alt="%s" width="%s" height="%s" />' %
(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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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 """<img src="%s" alt="%s" width="%s" height="%s" />""" % (

View file

@ -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:

View file

@ -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)

View file

@ -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,
)

View file

@ -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")