From 4c20e496136788036f34dbe65b10e698c7ec2f43 Mon Sep 17 00:00:00 2001 From: xiez Date: Thu, 24 May 2012 20:19:14 +0800 Subject: [PATCH] Make basic avatar operations work. --- avatar/forms.py | 5 +- avatar/i18n.sh.template | 4 + avatar/locale/zh_CN/LC_MESSAGES/django.mo | Bin 0 -> 1275 bytes avatar/locale/zh_CN/LC_MESSAGES/django.po | 101 ++++++++++++++++++++ avatar/models.py | 22 +++-- avatar/templates/avatar/add.html | 4 +- avatar/templates/avatar/change.html | 17 ++-- avatar/templates/avatar/confirm_delete.html | 14 ++- avatar/templatetags/avatar_tags.py | 12 ++- avatar/util.py | 23 +++-- avatar/views.py | 28 ++++-- group/templates/group/group_info.html | 6 +- settings.py | 10 +- templates/avatar/base.html | 3 - templates/avatar/change.html | 31 ------ templates/avatar/confirm_delete.html | 18 ---- templates/myhome.html | 6 ++ thirdpart/seaserv/service.py | 6 +- 18 files changed, 203 insertions(+), 107 deletions(-) create mode 100755 avatar/i18n.sh.template create mode 100644 avatar/locale/zh_CN/LC_MESSAGES/django.mo create mode 100644 avatar/locale/zh_CN/LC_MESSAGES/django.po delete mode 100644 templates/avatar/base.html delete mode 100644 templates/avatar/change.html delete mode 100644 templates/avatar/confirm_delete.html diff --git a/avatar/forms.py b/avatar/forms.py index 1aca905069..f910e26966 100644 --- a/avatar/forms.py +++ b/avatar/forms.py @@ -22,7 +22,8 @@ class UploadAvatarForm(forms.Form): avatar = forms.ImageField() def __init__(self, *args, **kwargs): - self.user = kwargs.pop('user') +# self.user = kwargs.pop('user') + self.emailuser = kwargs.pop('user').email super(UploadAvatarForm, self).__init__(*args, **kwargs) def clean_avatar(self): @@ -37,7 +38,7 @@ class UploadAvatarForm(forms.Form): raise forms.ValidationError( _(u"Your file is too big (%(size)s), the maximum allowed size is %(max_valid_size)s") % { 'size' : filesizeformat(data.size), 'max_valid_size' : filesizeformat(AVATAR_MAX_SIZE)} ) - count = Avatar.objects.filter(user=self.user).count() + count = Avatar.objects.filter(emailuser=self.emailuser).count() if AVATAR_MAX_AVATARS_PER_USER > 1 and \ count >= AVATAR_MAX_AVATARS_PER_USER: raise forms.ValidationError( diff --git a/avatar/i18n.sh.template b/avatar/i18n.sh.template new file mode 100755 index 0000000000..e56d2b66e3 --- /dev/null +++ b/avatar/i18n.sh.template @@ -0,0 +1,4 @@ +#!/bin/sh + +django-admin.py makemessages -l zh_CN -e py,html +django-admin.py compilemessages diff --git a/avatar/locale/zh_CN/LC_MESSAGES/django.mo b/avatar/locale/zh_CN/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..a406aaed4c5b15fdd9e8c67e16b4a0f553fc2a51 GIT binary patch literal 1275 zcma)4TW=dh6doYlED*F35)TL+RfcvDP$i5xppKoCv66MJF2W6jPc z4Nqygq~X#cAu5RS&`J@sl?YH3Vzowh*wDdfAz z1>}eBM<6dCTe$Z|fBo|V(f%*U&tm@9{<@3&Ca(WNP9T?u2zdhe1LTv)7m=Sv{v8?Z z$fJlb!X9Bfh`<&E)8r9EcrLUe4Gt9fV zSJ9wr9M}reOu6{YG^|MvR;4E_5cb;~v;?bH9Vg|6kj#QS8fWUP%E=;1YitF3$$`g# z9{PJjSNcYc+o0>^!F-%5w{t)9(Un zT*vR(56TZp6;wQ>xTE`e142Uu%eLTP<2j{-Q+5?bhDTic9X{%gKHs~CIy-IGy*e-< z=J5w&=@V)uknAKy0p1qBDv!jYTxgG&f)@ksPCm7wOmwkW3oMmyRaJ6A2X3 zB44pX^S*A;OciOaK+`FBrC{VTM_()C%~+PXnwAuET*0(d2F#YTS;(hyCQO>SR3>{o zl};DU`T1#-I#mzaGD! zqqlUYk`oYpP9-K{WdHJRu)9TqbC>RXxkEbN?%i46Y=3mM^VOMXYk%v#VCP2g?u9?r z&yx0qPyL%aqzCWxn||{{zjdjzaV^;U{-4_Y^WO#ASKz#SQ<~kDc2a!Oqv+*13DnvD@10wmuHt kKhxQ5wzti7trz4bC3G^8f$< literal 0 HcmV?d00001 diff --git a/avatar/locale/zh_CN/LC_MESSAGES/django.po b/avatar/locale/zh_CN/LC_MESSAGES/django.po new file mode 100644 index 0000000000..0721fb2145 --- /dev/null +++ b/avatar/locale/zh_CN/LC_MESSAGES/django.po @@ -0,0 +1,101 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-05-24 11:16+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: forms.py:35 +#, python-format +msgid "" +"%(ext)s is an invalid file extension. Authorized extensions are : " +"%(valid_exts_list)s" +msgstr "" + +#: forms.py:39 +#, python-format +msgid "" +"Your file is too big (%(size)s), the maximum allowed size is " +"%(max_valid_size)s" +msgstr "您的文件过大(%(size)s),允许最大文件为 %(max_valid_size)s" + +#: forms.py:45 +#, python-format +msgid "" +"You already have %(nb_avatars)d avatars, and the maximum allowed is " +"%(nb_max_avatars)d." +msgstr "" + +#: forms.py:57 +msgid "choice" +msgstr "从已有头像中选择" + +#: forms.py:68 +msgid "choices" +msgstr "从已有头像中选择" + +#: models.py:79 +#, python-format +msgid "Avatar for %s" +msgstr "" + +#: templates/avatar/add.html:5 templates/avatar/change.html:6 +msgid "Your current avatar: " +msgstr "当前头像:" + +#: templates/avatar/add.html:8 templates/avatar/change.html:9 +msgid "You haven't uploaded an avatar yet. Please upload one now." +msgstr "您还没有上传自己的头像。请上传。" + +#: templates/avatar/add.html:12 templates/avatar/change.html:20 +msgid "Upload New Image" +msgstr "提交" + +#: templates/avatar/change.html:15 +msgid "Choose new Default" +msgstr "确定" + +#: templates/avatar/confirm_delete.html:6 +msgid "Please select the avatars that you would like to delete." +msgstr "请选择要删除的头像。" + +#: templates/avatar/confirm_delete.html:9 +#, python-format +msgid "" +"You have no avatars to delete. Please upload one now." +msgstr "" +"您还没有上传自己的头像。现在 上传一个。" + +#: templates/avatar/confirm_delete.html:15 +msgid "Delete These" +msgstr "删除" + +#: templates/notification/avatar_friend_updated/notice.html:2 +#, python-format +msgid "" +"%(avatar_creator)s has updated their avatar %(avatar)s." +msgstr "" + +#: templates/notification/avatar_updated/notice.html:2 +#, python-format +msgid "You have updated your avatar %(avatar)s." +msgstr "" + +#: templatetags/avatar_tags.py:48 +msgid "Default Avatar" +msgstr "" diff --git a/avatar/models.py b/avatar/models.py index 22811d3a62..0d9b93db4d 100644 --- a/avatar/models.py +++ b/avatar/models.py @@ -8,7 +8,8 @@ from django.utils.hashcompat import md5_constructor from django.utils.encoding import smart_str from django.db.models import signals -from django.contrib.auth.models import User +#from django.contrib.auth.models import User +from seahub.base.accounts import CcnetUser try: from cStringIO import StringIO @@ -33,9 +34,11 @@ def avatar_file_path(instance=None, filename=None, size=None, ext=None): tmppath = [AVATAR_STORAGE_DIR] if AVATAR_HASH_USERDIRNAMES: tmp = md5_constructor(instance.user.username).hexdigest() - tmppath.extend([tmp[0], tmp[1], instance.user.username]) +# tmppath.extend([tmp[0], tmp[1], instance.user.username]) + tmppath.extend([tmp[0], tmp[1], instance.emailuser]) else: - tmppath.append(instance.user.username) +# tmppath.append(instance.user.username) + tmppath.append(instance.emailuser) if not filename: # Filename already stored in database filename = instance.avatar.name @@ -66,16 +69,17 @@ def find_extension(format): return format class Avatar(models.Model): - user = models.ForeignKey(User) +# user = models.ForeignKey(User) + emailuser = models.CharField(max_length=255) primary = models.BooleanField(default=False) avatar = models.ImageField(max_length=1024, upload_to=avatar_file_path, blank=True) date_uploaded = models.DateTimeField(default=datetime.datetime.now) def __unicode__(self): - return _(u'Avatar for %s') % self.user + return _(u'Avatar for %s') % self.emailuser def save(self, *args, **kwargs): - avatars = Avatar.objects.filter(user=self.user) + avatars = Avatar.objects.filter(emailuser=self.emailuser) if self.pk: avatars = avatars.exclude(pk=self.pk) if AVATAR_MAX_AVATARS_PER_USER > 1: @@ -84,11 +88,11 @@ class Avatar(models.Model): avatars.update(primary=False) else: avatars.delete() - invalidate_cache(self.user) + invalidate_cache(self.emailuser) super(Avatar, self).save(*args, **kwargs) def delete(self, *args, **kwargs): - invalidate_cache(self.user) + invalidate_cache(self.emailuser) super(Avatar, self).delete(*args, **kwargs) def thumbnail_exists(self, size): @@ -96,7 +100,7 @@ class Avatar(models.Model): def create_thumbnail(self, size, quality=None): # invalidate the cache of the thumbnail with the given size first - invalidate_cache(self.user, size) + invalidate_cache(self.emailuser, size) try: orig = self.avatar.storage.open(self.avatar.name, 'rb').read() image = Image.open(StringIO(orig)) diff --git a/avatar/templates/avatar/add.html b/avatar/templates/avatar/add.html index a62df6c413..04cb418d5e 100644 --- a/avatar/templates/avatar/add.html +++ b/avatar/templates/avatar/add.html @@ -1,7 +1,7 @@ -{% extends "avatar/base.html" %} +{% extends "myhome_base.html" %} {% load i18n avatar_tags %} -{% block content %} +{% block main_panel %}

{% trans "Your current avatar: " %}

{% avatar user %} {% if not avatars %} diff --git a/avatar/templates/avatar/change.html b/avatar/templates/avatar/change.html index 321da0dc58..f3c9c8a014 100644 --- a/avatar/templates/avatar/change.html +++ b/avatar/templates/avatar/change.html @@ -1,21 +1,26 @@ -{% extends "avatar/base.html" %} +{% extends "myhome_base.html" %} {% load i18n avatar_tags %} -{% block content %} +{% block main_panel %} +

添加或修改头像

{% trans "Your current avatar: " %}

{% avatar user %} {% if not avatars %}

{% trans "You haven't uploaded an avatar yet. Please upload one now." %}

{% else %}
-
    - {{ primary_avatar_form.as_ul }} -
+ + {% for boundfield in primary_avatar_form %} + {{ boundfield }} + {% endfor %}

{% csrf_token %}

{% endif %}
- {{ upload_avatar_form.as_p }} + + {% for boundfield in upload_avatar_form %} + {{ boundfield }} + {% endfor %}

{% csrf_token %}

{% endblock %} diff --git a/avatar/templates/avatar/confirm_delete.html b/avatar/templates/avatar/confirm_delete.html index 5c54a7d9ca..fc64173fcf 100644 --- a/avatar/templates/avatar/confirm_delete.html +++ b/avatar/templates/avatar/confirm_delete.html @@ -1,16 +1,20 @@ -{% extends "avatar/base.html" %} +{% extends "myhome_base.html" %} {% load i18n %} -{% block content %} +{% block main_panel %} + +

删除头像

{% if not avatars %} {% url avatar_change as avatar_change_url %}

{% blocktrans %}You have no avatars to delete. Please upload one now.{% endblocktrans %}

{% else %}
-
    - {{ delete_avatar_form.as_ul }} -
+ 请选择要删除的头像: + {% for boundfield in delete_avatar_form %} + {{ boundfield }} + {% endfor %}

{% csrf_token %}

{% endif %} diff --git a/avatar/templatetags/avatar_tags.py b/avatar/templatetags/avatar_tags.py index 201e5661d4..8621b8bbcb 100644 --- a/avatar/templatetags/avatar_tags.py +++ b/avatar/templatetags/avatar_tags.py @@ -5,7 +5,9 @@ from django.utils.translation import ugettext as _ from django.utils.hashcompat import md5_constructor from django.core.urlresolvers import reverse -from django.contrib.auth.models import User +#from django.contrib.auth.models import User +from seahub.base.accounts import CcnetUser +from seaserv import get_ccnetuser from avatar.settings import (AVATAR_GRAVATAR_BACKUP, AVATAR_GRAVATAR_DEFAULT, AVATAR_DEFAULT_SIZE) @@ -34,12 +36,14 @@ def avatar_url(user, size=AVATAR_DEFAULT_SIZE): @cache_result @register.simple_tag def avatar(user, size=AVATAR_DEFAULT_SIZE): - if not isinstance(user, User): + if not isinstance(user, CcnetUser): try: - user = User.objects.get(username=user) +# user = User.objects.get(username=user) + user = get_ccnetuser(username=user) alt = unicode(user) url = avatar_url(user, size) - except User.DoesNotExist: +# except User.DoesNotExist: + except: url = get_default_avatar_url() alt = _("Default Avatar") else: diff --git a/avatar/util.py b/avatar/util.py index ddce817b4f..de2f238a70 100644 --- a/avatar/util.py +++ b/avatar/util.py @@ -1,7 +1,10 @@ from django.conf import settings from django.core.cache import cache -from django.contrib.auth.models import User +#from django.contrib.auth.models import User +from seahub.base.accounts import CcnetUser + +from seaserv import get_ccnetuser from avatar.settings import (AVATAR_DEFAULT_URL, AVATAR_CACHE_TIMEOUT, AUTO_GENERATE_AVATAR_SIZES, AVATAR_DEFAULT_SIZE) @@ -12,7 +15,7 @@ def get_cache_key(user_or_username, size, prefix): """ Returns a cache key consisten of a username and image size. """ - if isinstance(user_or_username, User): + if isinstance(user_or_username, CcnetUser): user_or_username = user_or_username.username return '%s_%s_%s' % (prefix, user_or_username, size) @@ -44,6 +47,10 @@ def invalidate_cache(user, size=None): cache.delete(get_cache_key(user, size, prefix)) def get_default_avatar_url(): + """(e.g.) + base_url = '/media/' + AVATAR_DEFAULT_URL = '/avatars/default.png' + """ base_url = getattr(settings, 'STATIC_URL', None) if not base_url: base_url = getattr(settings, 'MEDIA_URL', '') @@ -60,17 +67,21 @@ def get_default_avatar_url(): return '%s%s' % (base_url, AVATAR_DEFAULT_URL) def get_primary_avatar(user, size=AVATAR_DEFAULT_SIZE): - if not isinstance(user, User): + if not isinstance(user, CcnetUser): try: - user = User.objects.get(username=user) - except User.DoesNotExist: +# user = User.objects.get(username=user) + user = get_ccnetuser(username=user) +# except User.DoesNotExist: + except: return None try: # Order by -primary first; this means if a primary=True avatar exists # it will be first, and then ordered by date uploaded, otherwise a # primary=False avatar will be first. Exactly the fallback behavior we # want. - avatar = user.avatar_set.order_by("-primary", "-date_uploaded")[0] +# avatar = user.avatar_set.order_by("-primary", "-date_uploaded")[0] + from seahub.avatar.models import Avatar + avatar = Avatar.objects.filter(emailuser=user.email, primary=1)[0] except IndexError: avatar = None if avatar: diff --git a/avatar/views.py b/avatar/views.py index 68ae338c61..d08adf0daf 100644 --- a/avatar/views.py +++ b/avatar/views.py @@ -10,7 +10,8 @@ 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 +from avatar.util import get_primary_avatar, get_default_avatar_url, \ + invalidate_cache def _get_next(request): @@ -35,7 +36,8 @@ def _get_next(request): def _get_avatars(user): # Default set. Needs to be sliced, but that's it. Keep the natural order. - avatars = user.avatar_set.all() +# avatars = user.avatar_set.all() + avatars = Avatar.objects.filter(emailuser=user.email) # Current avatar primary_avatar = avatars.order_by('-primary')[:1] @@ -62,14 +64,14 @@ def add(request, extra_context=None, next_override=None, if request.method == "POST" and 'avatar' in request.FILES: if upload_avatar_form.is_valid(): avatar = Avatar( - user = request.user, + emailuser = request.user.username, primary = True, ) image_file = request.FILES['avatar'] avatar.avatar.save(image_file.name, image_file) avatar.save() - request.user.message_set.create( - message=_("Successfully uploaded a new avatar.")) +# request.user.message_set.create( +# message=_("Successfully uploaded a new avatar.")) avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar) return HttpResponseRedirect(next_override or _get_next(request)) return render_to_response( @@ -106,8 +108,8 @@ def change(request, extra_context=None, next_override=None, avatar.primary = True avatar.save() updated = True - request.user.message_set.create( - message=_("Successfully updated your avatar.")) +# request.user.message_set.create( +# message=_("Successfully updated your avatar.")) if updated: avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar) return HttpResponseRedirect(next_override or _get_next(request)) @@ -142,9 +144,15 @@ def delete(request, extra_context=None, next_override=None, *args, **kwargs): a.save() avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar) break - Avatar.objects.filter(id__in=ids).delete() - request.user.message_set.create( - message=_("Successfully deleted the requested avatars.")) + + # NOTE: `Avatar.objects.filter(id__in=ids).delete()` will NOT work + # correctly. Sinct delete() on QuerySet will not call delete + # method on avatar object. + for a in Avatar.objects.filter(id__in=ids): + a.delete() + +# request.user.message_set.create( +# message=_("Successfully deleted the requested avatars.")) return HttpResponseRedirect(next_override or _get_next(request)) return render_to_response( 'avatar/confirm_delete.html', diff --git a/group/templates/group/group_info.html b/group/templates/group/group_info.html index 7bbfbcfb9d..891678a950 100644 --- a/group/templates/group/group_info.html +++ b/group/templates/group/group_info.html @@ -1,5 +1,5 @@ {% extends "myhome_base.html" %} -{% load seahub_tags %} +{% load seahub_tags avatar_tags %} {% block nav_group_class %}class="cur"{% endblock %} @@ -8,14 +8,14 @@

管理员

    {% for member in managers %} -
  • {{ member.short_username }}的图标{{ member.short_username }}
  • +
  • {% avatar member.user_name 16 %}{{ member.short_username }}
  • {% endfor %}

    成员

    {% if common_members %}
      {% for member in common_members %} -
    • {{ member.short_username }}的图标{{ member.short_username }}
    • +
    • {% avatar member.user_name 16 %}{{ member.short_username }}
    • {% endfor %}
    {% else %} diff --git a/settings.py b/settings.py index e496404113..95c08a116e 100644 --- a/settings.py +++ b/settings.py @@ -26,7 +26,7 @@ TIME_ZONE = 'Asia/Shanghai' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'zh-CN' +LANGUAGE_CODE = 'zh_CN' SITE_ID = 1 @@ -174,10 +174,10 @@ else: globals()[attr] = getattr(local_settings, attr) #avatar -#AVATAR_STORAGE_DIR = 'avatars' - -#AVATAR_GRAVATAR_BACKUP = False -#AVATAR_DEFAULT_URL = MEDIA_URL + '/avatars/default.png' +AVATAR_STORAGE_DIR = 'avatars' +AVATAR_GRAVATAR_BACKUP = False +AVATAR_DEFAULT_URL = '/avatars/default.png' +AUTO_GENERATE_AVATAR_SIZES = (80, 16) LOGIN_URL = SITE_ROOT + 'accounts/login' diff --git a/templates/avatar/base.html b/templates/avatar/base.html deleted file mode 100644 index f15b3aac49..0000000000 --- a/templates/avatar/base.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "accounts.html" %} -{% block title %}个人头像{% endblock %} - diff --git a/templates/avatar/change.html b/templates/avatar/change.html deleted file mode 100644 index 80a8bf3d87..0000000000 --- a/templates/avatar/change.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "avatar/base.html" %} -{% load avatar_tags %} - -{% block content %} -
    -

    添加或修改头像

    -
    -

    当前头像:

    - {% avatar user %} -
    -
    - {% if not avatars %} -

    您还没有自己的头像。

    - {% else %} -

    从已有头像中选择:

    -
    -
      - {{ primary_avatar_form.as_ul }} -
    -
    - -
    - {% endif %} -

    上传新头像:

    -
    -
    - -
    -
    -
    -{% endblock %} diff --git a/templates/avatar/confirm_delete.html b/templates/avatar/confirm_delete.html deleted file mode 100644 index 024b8dd02c..0000000000 --- a/templates/avatar/confirm_delete.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "avatar/base.html" %} - -{% block content %} -
    -

    删除头像

    - {% if not avatars %} -

    您还没有上传自己的头像。现在 上传一个.

    - {% else %} -
    -
      - {{ delete_avatar_form.as_ul }} -
    -
    - -
    - {% endif %} -
    -{% endblock %} diff --git a/templates/myhome.html b/templates/myhome.html index a97dbf7107..110f45fd01 100644 --- a/templates/myhome.html +++ b/templates/myhome.html @@ -1,7 +1,13 @@ {% extends "myhome_base.html" %} +{% load avatar_tags %} {% block nav_myhome_class %}class="cur"{% endblock %} {% block left_panel %} +

    个人头像

    +{% avatar request.user 80 %} +

    修改 +删除

    +

    已用空间

    {{ quota_usage|filesizeformat }} / 2 GB

    diff --git a/thirdpart/seaserv/service.py b/thirdpart/seaserv/service.py index 9bc6be7fbe..a199f019d3 100644 --- a/thirdpart/seaserv/service.py +++ b/thirdpart/seaserv/service.py @@ -298,11 +298,11 @@ def get_user(user_id): def get_ccnetuser(username=None, userid=None): # Get emailuser from db - if username != None: + if username: emailuser = ccnet_rpc.get_emailuser(username) - if userid != None: + if userid: emailuser = ccnet_rpc.get_emailuser_by_id(userid) - if emailuser == None: + if not emailuser: return None # And convert to ccnetuser