diff --git a/avatar/conf.py b/avatar/conf.py
index 0379945..9a694d3 100644
--- a/avatar/conf.py
+++ b/avatar/conf.py
@@ -17,6 +17,7 @@ class AvatarConf(AppConf):
MAX_SIZE = 1024 * 1024
THUMB_FORMAT = 'JPEG'
THUMB_QUALITY = 85
+ USERID_AS_USERDIRNAME = False
HASH_FILENAMES = False
HASH_USERDIRNAMES = False
ALLOWED_FILE_EXTS = None
diff --git a/avatar/management/commands/migrate_avatars.py b/avatar/management/commands/migrate_avatars.py
new file mode 100644
index 0000000..25bd1cc
--- /dev/null
+++ b/avatar/management/commands/migrate_avatars.py
@@ -0,0 +1,54 @@
+import os
+import shutil
+from django.core.management import call_command
+from django.core.management.base import NoArgsCommand
+from avatar.conf import settings
+from avatar.models import Avatar, avatar_file_path
+from django.core.files import File
+
+
+class Command(NoArgsCommand):
+ help = ("Check if avatar userdirname folder correspond "
+ "with actual userdirname pattern "
+ "affect with options like AVATAR_USERID_AS_USERDIRNAME "
+ "or AVATAR_HASH_USERDIRNAMES.")
+
+ def handle_noargs(self, **options):
+ # define path to avatar folders
+ avatar_path = os.path.join(settings.MEDIA_URL,
+ settings.AVATAR_STORAGE_DIR)
+
+ have_change = False
+ for avatar in Avatar.objects.all():
+ # get actuel path of avatar
+ new_path = os.path.join(settings.MEDIA_URL,
+ avatar_file_path(avatar))
+ original_path = avatar.avatar.url
+ if new_path != original_path:
+ print("Move Avatar id=%s from %s to %s." % (avatar.id,
+ original_path,
+ new_path))
+
+ # if different path: we copy + generate new thumbnails + clean
+ media_path = original_path.replace(settings.MEDIA_URL, "")
+ media_path = os.path.join(settings.MEDIA_ROOT, media_path)
+ # copy original avatar into new folder
+ avatar.avatar.save(os.path.basename(new_path),
+ File(open(media_path)))
+ avatar.save()
+
+ # delete old folder and thumbnails
+ i = original_path.find('/', len(avatar_path) + 1)
+ folder = original_path[0:i]
+ if folder[0:1] == "/":
+ folder = folder[1:]
+ folder = os.path.join(settings.BASE_DIR, folder)
+ print("Delete useless folder %s" % folder)
+ shutil.rmtree(folder)
+ have_change = True
+
+ # generate all default thumbnails in new folder
+ if have_change:
+ call_command('rebuild_avatars')
+ else:
+ print("No change ;)")
diff --git a/avatar/models.py b/avatar/models.py
index 7b76ac8..46148be 100644
--- a/avatar/models.py
+++ b/avatar/models.py
@@ -25,11 +25,14 @@ avatar_storage = get_storage_class(settings.AVATAR_STORAGE)()
def avatar_file_path(instance=None, filename=None, size=None, ext=None):
tmppath = [settings.AVATAR_STORAGE_DIR]
+ userdirname = get_username(instance.user)
+ if settings.AVATAR_USERID_AS_USERDIRNAME:
+ userdirname = str(instance.user_id)
if settings.AVATAR_HASH_USERDIRNAMES:
- tmp = hashlib.md5(get_username(instance.user)).hexdigest()
- tmppath.extend([tmp[0], tmp[1], get_username(instance.user)])
+ tmp = hashlib.md5(userdirname).hexdigest()
+ tmppath.extend([tmp[0], tmp[1], userdirname])
else:
- tmppath.append(get_username(instance.user))
+ tmppath.append(userdirname)
if not filename:
# Filename already stored in database
filename = instance.avatar.name
diff --git a/docs/index.txt b/docs/index.txt
index 3eed185..1315e67 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -32,19 +32,19 @@ that are required. A minimal integration can work like this:
1. List this application in the ``INSTALLED_APPS`` portion of your settings
file. Your settings file will look something like::
-
+
INSTALLED_APPS = (
# ...
'avatar',
)
2. Update your database::
-
+
python manage.py syncdb
3. Add the avatar urls to the end of your root urlconf. Your urlconf
will look something like::
-
+
urlpatterns = patterns('',
# ...
(r'^avatar/', include('avatar.urls')),
@@ -52,20 +52,20 @@ that are required. A minimal integration can work like this:
4. Somewhere in your template navigation scheme, link to the change avatar
page::
-
+
Change your avatar
5. Wherever you want to display an avatar for a user, first load the avatar
template tags::
-
+
{% load avatar_tags %}
-
+
Then, use the ``avatar`` tag to display an avatar of a default size::
-
+
{% avatar user %}
-
+
Or specify a size (in pixels) explicitly::
-
+
{% avatar user 65 %}
Template tags and filter
@@ -112,6 +112,12 @@ AVATAR_STORAGE_DIR
non-filesystem storage device, this will simply be appended to the beginning
of the file name.
+AVATAR_USERID_AS_USERDIRNAME
+ By default, ``User.username`` will be use as directory name under ``AVATAR_STORAGE_DIR`.
+ If set to ``True``, ``User.id`` wil be use instead of ``User.username``.
+ Usefull if user can change his username into app to avoid duplicate content.
+ Defaults to ``False``.
+
AVATAR_GRAVATAR_BACKUP
A boolean determining whether to default to the Gravatar service if no
``Avatar`` instance is found in the system for the given user. Defaults to
@@ -127,22 +133,30 @@ AVATAR_GRAVATAR_FIELD
user's gravatar in ``user.gravatar``.
AVATAR_ALLOWED_MIMETYPES
- Limit allowed avatar image uploads by their actual content payload and what
- image codecs we wish to support. This limits website user content site
- attack vectors against image codec buffer overflow and similar bugs.
- `You must have python-imaging library installed `_.
- Suggested safe setting: ``("image/png", "image/gif", "image/jpeg")``.
- When enabled you'll get the following error on the form upload *File content is invalid.
- Detected: image/tiff Allowed content types are: image/png, image/gif, image/jpg*.
+ Limit allowed avatar image uploads by their actual content payload and what
+ image codecs we wish to support. This limits website user content site
+ attack vectors against image codec buffer overflow and similar bugs.
+ `You must have python-imaging library installed `_.
+ Suggested safe setting: ``("image/png", "image/gif", "image/jpeg")``.
+ When enabled you'll get the following error on the form upload *File content is invalid.
+ Detected: image/tiff Allowed content types are: image/png, image/gif, image/jpg*.
Management Commands
-------------------
-This application does include one management command: ``rebuild_avatars``. It
-takes no arguments and, when run, re-renders all of the thumbnails for all of
-the avatars for the pixel sizes specified in the ``AUTO_GENERATE_AVATAR_SIZES``
-setting.
+This application does include two management command: ``rebuild_avatars`` and ``migrate_avatars``.
+
+rebuild_avatars
+ It takes no arguments and, when run, re-renders all of the thumbnails for all of
+ the avatars for the pixel sizes specified in the ``AUTO_GENERATE_AVATAR_SIZES``
+ setting.
+
+migrate_avatars
+ It takes no arguments and, when run, check all avatar userdirname folders.
+ If folder doesn't correspond with actual userdirname pattern (affect with options like
+ ``AVATAR_USERID_AS_USERDIRNAME`` or ``AVATAR_HASH_USERDIRNAMES``), it move avatar files to the right place,
+ call ``rebuild_avatars`` and delete useless folders.
.. _pip: http://www.pip-installer.org/