1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-09 10:50:24 +00:00

Move group_avatar from group to avatar.

This commit is contained in:
xiez
2012-07-14 13:31:34 +08:00
parent 75b724a169
commit 9c71c002a0
16 changed files with 184 additions and 202 deletions

View File

@@ -44,7 +44,23 @@ class UploadAvatarForm(forms.Form):
_(u"You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d.") % _(u"You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d.") %
{ 'nb_avatars' : count, 'nb_max_avatars' : AVATAR_MAX_AVATARS_PER_USER}) { 'nb_avatars' : count, 'nb_max_avatars' : AVATAR_MAX_AVATARS_PER_USER})
return return
class GroupAvatarForm(forms.Form):
avatar = forms.ImageField()
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(
_(u"%(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:
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)})
class PrimaryAvatarForm(forms.Form): class PrimaryAvatarForm(forms.Form):

View File

@@ -27,8 +27,37 @@ from avatar.util import invalidate_cache
from avatar.settings import (AVATAR_STORAGE_DIR, AVATAR_RESIZE_METHOD, from avatar.settings import (AVATAR_STORAGE_DIR, AVATAR_RESIZE_METHOD,
AVATAR_MAX_AVATARS_PER_USER, AVATAR_THUMB_FORMAT, AVATAR_MAX_AVATARS_PER_USER, AVATAR_THUMB_FORMAT,
AVATAR_HASH_USERDIRNAMES, AVATAR_HASH_FILENAMES, AVATAR_HASH_USERDIRNAMES, AVATAR_HASH_FILENAMES,
AVATAR_THUMB_QUALITY, AUTO_GENERATE_AVATAR_SIZES) AVATAR_THUMB_QUALITY, AUTO_GENERATE_AVATAR_SIZES,
GROUP_AVATAR_STORAGE_DIR)
def group_avatar_file_path(instance=None, filename=None, size=None, ext=None):
tmppath = [GROUP_AVATAR_STORAGE_DIR]
if AVATAR_HASH_USERDIRNAMES:
tmp = md5_constructor(instance.user.username).hexdigest()
tmppath.extend([tmp[0], tmp[1], instance.group_id])
else:
tmppath.append(instance.group_id)
if not filename:
# Filename already stored in database
filename = instance.avatar.name
if ext and 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
# it won't conflict with another filename
(root, oldext) = os.path.splitext(filename)
filename = root + "." + ext
else:
# File doesn't exist yet
if AVATAR_HASH_FILENAMES:
(root, ext) = os.path.splitext(filename)
filename = md5_constructor(smart_str(filename)).hexdigest()
filename = filename + ext
if size:
tmppath.extend(['resized', str(size)])
tmppath.append(os.path.basename(filename))
return os.path.join(*tmppath)
def avatar_file_path(instance=None, filename=None, size=None, ext=None): def avatar_file_path(instance=None, filename=None, size=None, ext=None):
tmppath = [AVATAR_STORAGE_DIR] tmppath = [AVATAR_STORAGE_DIR]
@@ -133,6 +162,52 @@ class Avatar(models.Model):
ext=ext ext=ext
) )
class GroupAvatar(models.Model):
group_id = models.CharField(max_length=255)
avatar = models.ImageField(max_length=1024, upload_to=group_avatar_file_path, blank=True)
date_uploaded = models.DateTimeField(default=datetime.datetime.now)
def __unicode__(self):
return _(u'Avatar for %s') % self.group_id
def thumbnail_exists(self, size):
return self.avatar.storage.exists(self.avatar_name(size))
def create_thumbnail(self, size, quality=None):
try:
orig = self.avatar.storage.open(self.avatar.name, 'rb').read()
image = Image.open(StringIO(orig))
except IOError:
return # What should we do here? Render a "sorry, didn't work" img?
quality = quality or AVATAR_THUMB_QUALITY
(w, h) = image.size
if w != size or h != size:
if w > h:
diff = (w - h) / 2
image = image.crop((diff, 0, w - diff, h))
else:
diff = (h - w) / 2
image = image.crop((0, diff, w, h - diff))
if image.mode != "RGB":
image = image.convert("RGB")
image = image.resize((size, size), AVATAR_RESIZE_METHOD)
thumb = StringIO()
image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality)
thumb_file = ContentFile(thumb.getvalue())
else:
thumb_file = ContentFile(orig)
thumb = self.avatar.storage.save(self.avatar_name(size), thumb_file)
def avatar_url(self, size):
return self.avatar.storage.url(self.avatar_name(size))
def avatar_name(self, size):
ext = find_extension(AVATAR_THUMB_FORMAT)
return group_avatar_file_path(
instance=self,
size=size,
ext=ext
)
def create_default_thumbnails(instance=None, created=False, **kwargs): def create_default_thumbnails(instance=None, created=False, **kwargs):
if created: if created:

View File

@@ -6,13 +6,21 @@ try:
except ImportError: except ImportError:
import Image import Image
### User avatar settings ###
AVATAR_DEFAULT_SIZE = getattr(settings, 'AVATAR_DEFAULT_SIZE', 80) AVATAR_DEFAULT_SIZE = getattr(settings, 'AVATAR_DEFAULT_SIZE', 80)
AVATAR_STORAGE_DIR = getattr(settings, 'AVATAR_STORAGE_DIR', 'avatars')
AVATAR_DEFAULT_URL = getattr(settings, 'AVATAR_DEFAULT_URL', 'avatar/img/default.jpg')
### Group avatars ###
GROUP_AVATAR_DEFAULT_SIZE = getattr(settings, 'GROUP_AVATAR_DEFAULT_SIZE', 48)
GROUP_AVATAR_STORAGE_DIR = getattr(settings, 'GROUP_AVATAR_STORAGE_DIR', 'avatars/groups')
GROUP_AVATAR_DEFAULT_URL = getattr(settings, 'GROUP_AVATAR_DEFAULT_URL', 'avatars/groups/default.png')
### Common settings ###
AUTO_GENERATE_AVATAR_SIZES = getattr(settings, 'AUTO_GENERATE_AVATAR_SIZES', (AVATAR_DEFAULT_SIZE,)) AUTO_GENERATE_AVATAR_SIZES = getattr(settings, 'AUTO_GENERATE_AVATAR_SIZES', (AVATAR_DEFAULT_SIZE,))
AVATAR_RESIZE_METHOD = getattr(settings, 'AVATAR_RESIZE_METHOD', Image.ANTIALIAS) AVATAR_RESIZE_METHOD = getattr(settings, 'AVATAR_RESIZE_METHOD', Image.ANTIALIAS)
AVATAR_STORAGE_DIR = getattr(settings, 'AVATAR_STORAGE_DIR', 'avatars')
AVATAR_GRAVATAR_BACKUP = getattr(settings, 'AVATAR_GRAVATAR_BACKUP', True) AVATAR_GRAVATAR_BACKUP = getattr(settings, 'AVATAR_GRAVATAR_BACKUP', True)
AVATAR_GRAVATAR_DEFAULT = getattr(settings, 'AVATAR_GRAVATAR_DEFAULT', None) 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_AVATARS_PER_USER = getattr(settings, 'AVATAR_MAX_AVATARS_PER_USER', 42)
AVATAR_MAX_SIZE = getattr(settings, 'AVATAR_MAX_SIZE', 1024 * 1024) AVATAR_MAX_SIZE = getattr(settings, 'AVATAR_MAX_SIZE', 1024 * 1024)
AVATAR_THUMB_FORMAT = getattr(settings, 'AVATAR_THUMB_FORMAT', "JPEG") AVATAR_THUMB_FORMAT = getattr(settings, 'AVATAR_THUMB_FORMAT', "JPEG")
@@ -21,3 +29,4 @@ AVATAR_HASH_FILENAMES = getattr(settings, 'AVATAR_HASH_FILENAMES', False)
AVATAR_HASH_USERDIRNAMES = getattr(settings, 'AVATAR_HASH_USERDIRNAMES', False) AVATAR_HASH_USERDIRNAMES = getattr(settings, 'AVATAR_HASH_USERDIRNAMES', False)
AVATAR_ALLOWED_FILE_EXTS = getattr(settings, 'AVATAR_ALLOWED_FILE_EXTS', None) AVATAR_ALLOWED_FILE_EXTS = getattr(settings, 'AVATAR_ALLOWED_FILE_EXTS', None)
AVATAR_CACHE_TIMEOUT = getattr(settings, 'AVATAR_CACHE_TIMEOUT', 60*60) AVATAR_CACHE_TIMEOUT = getattr(settings, 'AVATAR_CACHE_TIMEOUT', 60*60)

View File

@@ -1,5 +1,5 @@
{% extends "myhome_base.html" %} {% extends "myhome_base.html" %}
{% load group_tags %} {% load group_avatar_tags %}
{% block nav_group_class %}class="cur"{% endblock %} {% block nav_group_class %}class="cur"{% endblock %}

View File

@@ -1,35 +1,35 @@
import urllib # import urllib
from django.conf import settings from django.conf import settings
from django import template from django import template
from django.utils.hashcompat import md5_constructor # from django.utils.hashcompat import md5_constructor
from django.core.urlresolvers import reverse # from django.core.urlresolvers import reverse
from group.settings import (AVATAR_DEFAULT_SIZE, AVATAR_DEFAULT_URL) from avatar.settings import (GROUP_AVATAR_DEFAULT_SIZE, GROUP_AVATAR_DEFAULT_URL)
from group.models import Avatar from avatar.models import GroupAvatar
register = template.Library() register = template.Library()
def get_default_avatar_url(): def get_default_group_avatar_url():
base_url = getattr(settings, 'STATIC_URL', None) base_url = getattr(settings, 'STATIC_URL', None)
if not base_url: if not base_url:
base_url = getattr(settings, 'MEDIA_URL', '') base_url = getattr(settings, 'MEDIA_URL', '')
# Don't use base_url if the default avatar url starts with http:// of https:// # 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://'): if GROUP_AVATAR_DEFAULT_URL.startswith('http://') or GROUP_AVATAR_DEFAULT_URL.startswith('https://'):
return AVATAR_DEFAULT_URL return GROUP_AVATAR_DEFAULT_URL
# We'll be nice and make sure there are no duplicated forward slashes # We'll be nice and make sure there are no duplicated forward slashes
ends = base_url.endswith('/') ends = base_url.endswith('/')
begins = AVATAR_DEFAULT_URL.startswith('/') begins = GROUP_AVATAR_DEFAULT_URL.startswith('/')
if ends and begins: if ends and begins:
base_url = base_url[:-1] base_url = base_url[:-1]
elif not ends and not begins: elif not ends and not begins:
return '%s/%s' % (base_url, AVATAR_DEFAULT_URL) return '%s/%s' % (base_url, GROUP_AVATAR_DEFAULT_URL)
return '%s%s' % (base_url, AVATAR_DEFAULT_URL) return '%s%s' % (base_url, GROUP_AVATAR_DEFAULT_URL)
@register.simple_tag @register.simple_tag
def grp_avatar_url(group_id, size=AVATAR_DEFAULT_SIZE): def grp_avatar_url(group_id, size=GROUP_AVATAR_DEFAULT_SIZE):
grp_avatars = Avatar.objects.filter(group_id=group_id) grp_avatars = GroupAvatar.objects.filter(group_id=group_id)
if grp_avatars: if grp_avatars:
avatar = grp_avatars.order_by('-date_uploaded')[0] avatar = grp_avatars.order_by('-date_uploaded')[0]
else: else:
@@ -40,6 +40,6 @@ def grp_avatar_url(group_id, size=AVATAR_DEFAULT_SIZE):
avatar.create_thumbnail(size) avatar.create_thumbnail(size)
avatar_src = avatar.avatar_url(size) avatar_src = avatar.avatar_url(size)
else: else:
avatar_src = get_default_avatar_url() avatar_src = get_default_group_avatar_url()
return avatar_src return avatar_src

View File

@@ -2,6 +2,7 @@ from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('avatar.views', urlpatterns = patterns('avatar.views',
url('^add/$', 'add', name='avatar_add'), url('^add/$', 'add', name='avatar_add'),
url('^group/add/$', 'group_add', name='avatar_group_add'),
# url('^change/$', 'change', name='avatar_change'), # url('^change/$', 'change', name='avatar_change'),
# url('^delete/$', 'delete', name='avatar_delete'), # url('^delete/$', 'delete', name='avatar_delete'),
url('^render_primary/(?P<user>[^/]+)/(?P<size>[\d]+)/$', 'render_primary', name='avatar_render_primary'), url('^render_primary/(?P<user>[^/]+)/(?P<size>[\d]+)/$', 'render_primary', name='avatar_render_primary'),

View File

@@ -1,18 +1,21 @@
# encoding: utf-8
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from avatar.forms import PrimaryAvatarForm, DeleteAvatarForm, UploadAvatarForm,\
GroupAvatarForm
from avatar.forms import PrimaryAvatarForm, DeleteAvatarForm, UploadAvatarForm from avatar.models import Avatar, GroupAvatar
from avatar.models import Avatar
from avatar.settings import AVATAR_MAX_AVATARS_PER_USER, AVATAR_DEFAULT_SIZE from avatar.settings import AVATAR_MAX_AVATARS_PER_USER, AVATAR_DEFAULT_SIZE
from avatar.signals import avatar_updated 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 invalidate_cache
from seahub.utils import go_error, go_permission_error
from auth.decorators import login_required
from seaserv import ccnet_threaded_rpc, check_group_staff
def _get_next(request): def _get_next(request):
""" """
@@ -85,6 +88,36 @@ def add(request, extra_context=None, next_override=None,
) )
) )
@login_required
def group_add(request):
group_id = request.GET.get('gid', '')
try:
group_id_int = int(group_id)
except ValueError:
return go_error(request, u'group id 不是有效参数')
if not check_group_staff(group_id_int, request.user):
return go_permission_error(request, u'只有小组管理员有权设置小组图标')
group = ccnet_threaded_rpc.get_group(group_id_int)
if not group:
return HttpResponseRedirect(reverse('group_list', args=[]))
form = GroupAvatarForm(request.POST or None, request.FILES or None)
if request.method == 'POST' and 'avatar' in request.FILES:
if form.is_valid():
image_file = request.FILES['avatar']
avatar = GroupAvatar()
avatar.group_id = group_id
avatar.avatar.save(image_file.name, image_file)
avatar.save()
return render_to_response('avatar/set_avatar.html', {
'group' : group,
'form' : form,
}, context_instance=RequestContext(request))
@login_required @login_required
def change(request, extra_context=None, next_override=None, def change(request, extra_context=None, next_override=None,
upload_form=UploadAvatarForm, primary_form=PrimaryAvatarForm, upload_form=UploadAvatarForm, primary_form=PrimaryAvatarForm,

View File

@@ -1,10 +1,6 @@
import os import os
from django import forms from django import forms
from django.utils.translation import ugettext as _
from django.template.defaultfilters import filesizeformat
from group.settings import ( AVATAR_MAX_SIZE, AVATAR_ALLOWED_FILE_EXTS)
class MessageForm(forms.Form): class MessageForm(forms.Form):
message = forms.CharField(max_length=500) message = forms.CharField(max_length=500)
@@ -12,19 +8,3 @@ class MessageForm(forms.Form):
class MessageReplyForm(forms.Form): class MessageReplyForm(forms.Form):
message = forms.CharField(max_length=150) message = forms.CharField(max_length=150)
class AvatarForm(forms.Form):
avatar = forms.ImageField()
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(
_(u"%(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:
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)})

View File

@@ -1,26 +1,7 @@
import datetime import datetime
import os import os
from django.core.files.base import ContentFile
from django.utils.translation import ugettext as _
from django.utils.hashcompat import md5_constructor
from django.db import models from django.db import models
from group.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)
try:
from cStringIO import StringIO
dir(StringIO) # Placate PyFlakes
except ImportError:
from StringIO import StringIO
try:
from PIL import Image
dir(Image) # Placate PyFlakes
except ImportError:
import Image
class GroupMessage(models.Model): class GroupMessage(models.Model):
group_id = models.IntegerField() group_id = models.IntegerField()
@@ -33,86 +14,3 @@ class MessageReply(models.Model):
from_email = models.EmailField() from_email = models.EmailField()
message = models.CharField(max_length=150) message = models.CharField(max_length=150)
timestamp = models.DateTimeField(default=datetime.datetime.now) timestamp = models.DateTimeField(default=datetime.datetime.now)
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.group_id])
else:
tmppath.append(instance.group_id)
if not filename:
# Filename already stored in database
filename = instance.avatar.name
if ext and 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
# it won't conflict with another filename
(root, oldext) = os.path.splitext(filename)
filename = root + "." + ext
else:
# File doesn't exist yet
if AVATAR_HASH_FILENAMES:
(root, ext) = os.path.splitext(filename)
filename = md5_constructor(smart_str(filename)).hexdigest()
filename = filename + ext
if size:
tmppath.extend(['resized', str(size)])
tmppath.append(os.path.basename(filename))
return os.path.join(*tmppath)
def find_extension(format):
format = format.lower()
if format == 'jpeg':
format = 'jpg'
return format
class Avatar(models.Model):
group_id = models.CharField(max_length=255)
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.group_id
def thumbnail_exists(self, size):
return self.avatar.storage.exists(self.avatar_name(size))
def create_thumbnail(self, size, quality=None):
try:
orig = self.avatar.storage.open(self.avatar.name, 'rb').read()
image = Image.open(StringIO(orig))
except IOError:
return # What should we do here? Render a "sorry, didn't work" img?
quality = quality or AVATAR_THUMB_QUALITY
(w, h) = image.size
if w != size or h != size:
if w > h:
diff = (w - h) / 2
image = image.crop((diff, 0, w - diff, h))
else:
diff = (h - w) / 2
image = image.crop((0, diff, w, h - diff))
if image.mode != "RGB":
image = image.convert("RGB")
image = image.resize((size, size), AVATAR_RESIZE_METHOD)
thumb = StringIO()
image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality)
thumb_file = ContentFile(thumb.getvalue())
else:
thumb_file = ContentFile(orig)
thumb = self.avatar.storage.save(self.avatar_name(size), thumb_file)
def avatar_url(self, size):
return self.avatar.storage.url(self.avatar_name(size))
def avatar_name(self, size):
ext = find_extension(AVATAR_THUMB_FORMAT)
return avatar_file_path(
instance=self,
size=size,
ext=ext
)

View File

@@ -1,23 +1,23 @@
from django.conf import settings # from django.conf import settings
try: # try:
from PIL import Image # from PIL import Image
dir(Image) # Placate PyFlakes # dir(Image) # Placate PyFlakes
except ImportError: # except ImportError:
import Image # import Image
AVATAR_DEFAULT_SIZE = 48 # AVATAR_DEFAULT_SIZE = 48
AUTO_GENERATE_AVATAR_SIZES = (80, 48) # AUTO_GENERATE_AVATAR_SIZES = (80, 48)
AVATAR_RESIZE_METHOD = getattr(settings, 'AVATAR_RESIZE_METHOD', Image.ANTIALIAS) # AVATAR_RESIZE_METHOD = getattr(settings, 'AVATAR_RESIZE_METHOD', Image.ANTIALIAS)
AVATAR_STORAGE_DIR = 'avatars/groups' # AVATAR_STORAGE_DIR = 'avatars/groups'
AVATAR_GRAVATAR_BACKUP = getattr(settings, 'AVATAR_GRAVATAR_BACKUP', True) # AVATAR_GRAVATAR_BACKUP = getattr(settings, 'AVATAR_GRAVATAR_BACKUP', True)
AVATAR_GRAVATAR_DEFAULT = getattr(settings, 'AVATAR_GRAVATAR_DEFAULT', None) # AVATAR_GRAVATAR_DEFAULT = getattr(settings, 'AVATAR_GRAVATAR_DEFAULT', None)
AVATAR_DEFAULT_URL = 'avatars/groups/default.png' # AVATAR_DEFAULT_URL = 'avatars/groups/default.png'
AVATAR_MAX_AVATARS_PER_USER = getattr(settings, 'AVATAR_MAX_AVATARS_PER_USER', 42) # AVATAR_MAX_AVATARS_PER_USER = getattr(settings, 'AVATAR_MAX_AVATARS_PER_USER', 42)
AVATAR_MAX_SIZE = getattr(settings, 'AVATAR_MAX_SIZE', 1024 * 1024) # AVATAR_MAX_SIZE = getattr(settings, 'AVATAR_MAX_SIZE', 1024 * 1024)
AVATAR_THUMB_FORMAT = getattr(settings, 'AVATAR_THUMB_FORMAT', "JPEG") # AVATAR_THUMB_FORMAT = getattr(settings, 'AVATAR_THUMB_FORMAT', "JPEG")
AVATAR_THUMB_QUALITY = getattr(settings, 'AVATAR_THUMB_QUALITY', 85) # AVATAR_THUMB_QUALITY = getattr(settings, 'AVATAR_THUMB_QUALITY', 85)
AVATAR_HASH_FILENAMES = getattr(settings, 'AVATAR_HASH_FILENAMES', False) # AVATAR_HASH_FILENAMES = getattr(settings, 'AVATAR_HASH_FILENAMES', False)
AVATAR_HASH_USERDIRNAMES = getattr(settings, 'AVATAR_HASH_USERDIRNAMES', False) # AVATAR_HASH_USERDIRNAMES = getattr(settings, 'AVATAR_HASH_USERDIRNAMES', False)
AVATAR_ALLOWED_FILE_EXTS = getattr(settings, 'AVATAR_ALLOWED_FILE_EXTS', None) # AVATAR_ALLOWED_FILE_EXTS = getattr(settings, 'AVATAR_ALLOWED_FILE_EXTS', None)
AVATAR_CACHE_TIMEOUT = getattr(settings, 'AVATAR_CACHE_TIMEOUT', 60*60) # AVATAR_CACHE_TIMEOUT = getattr(settings, 'AVATAR_CACHE_TIMEOUT', 60*60)

View File

@@ -10,7 +10,7 @@
<div class="side fright"> <div class="side fright">
<h3>操作</h3> <h3>操作</h3>
<ul class="with-bg"> <ul class="with-bg">
<li><a href="{{ SITE_ROOT }}group/{{ group.id }}/set_avatar/">设置小组图标</a></li> <li><a href="{{ SITE_ROOT }}avatar/group/add/?gid={{ group.id }}">设置小组图标</a></li>
<li><a id="group-remove" href="#" data="{{ SITE_ROOT }}group/{{ group.id }}/?op=delete">解散小组</a></li> <li><a id="group-remove" href="#" data="{{ SITE_ROOT }}group/{{ group.id }}/?op=delete">解散小组</a></li>
<li><a href="{{ SITE_ROOT }}group/{{ group.id }}/">返回小组</a></li> <li><a href="{{ SITE_ROOT }}group/{{ group.id }}/">返回小组</a></li>
</ul> </ul>

View File

@@ -1,5 +1,5 @@
{% extends "myhome_base.html" %} {% extends "myhome_base.html" %}
{% load seahub_tags group_tags %} {% load seahub_tags group_avatar_tags %}
{% block nav_group_class %}class="cur"{% endblock %} {% block nav_group_class %}class="cur"{% endblock %}
{% block left_panel %} {% block left_panel %}

View File

@@ -1,13 +1,12 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
from views import group_list, group_info, group_member_operations, \ from views import group_list, group_info, group_member_operations, \
group_members, msg_reply, msg_reply_new, set_avatar group_members, msg_reply, msg_reply_new
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^(?P<group_id>[\d]+)/$', group_info, name='group_info'), url(r'^(?P<group_id>[\d]+)/$', group_info, name='group_info'),
url(r'^reply/(?P<msg_id>[\d]+)/$', msg_reply, name='msg_reply'), url(r'^reply/(?P<msg_id>[\d]+)/$', msg_reply, name='msg_reply'),
url(r'^reply/new/$', msg_reply_new, name='msg_reply_new'), url(r'^reply/new/$', msg_reply_new, name='msg_reply_new'),
url(r'^(?P<group_id>[\d]+)/set_avatar/$', set_avatar, name='set_avatar'),
url(r'^(?P<group_id>[\d]+)/members/$', group_members, name='group_members'), url(r'^(?P<group_id>[\d]+)/members/$', group_members, name='group_members'),
(r'^(?P<group_id>[\d]+)/member/(?P<user_name>[^/]+)/$', group_member_operations), (r'^(?P<group_id>[\d]+)/member/(?P<user_name>[^/]+)/$', group_member_operations),
) )

View File

@@ -10,8 +10,8 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, seafserv_threaded_rpc, get_re
get_group_repoids, check_group_staff, get_commits get_group_repoids, check_group_staff, get_commits
from pysearpc import SearpcError from pysearpc import SearpcError
from models import GroupMessage, MessageReply, Avatar from models import GroupMessage, MessageReply
from forms import MessageForm, MessageReplyForm, AvatarForm from forms import MessageForm, MessageReplyForm
from signals import grpmsg_added, grpmsg_reply_added from signals import grpmsg_added, grpmsg_reply_added
from seahub.contacts.models import Contact from seahub.contacts.models import Contact
from seahub.notifications.models import UserNotification from seahub.notifications.models import UserNotification
@@ -457,32 +457,3 @@ def group_unshare_repo(request, repo_id, group_id, from_email):
if seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, from_email) != 0: if seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, from_email) != 0:
return go_error(request, u'共享失败:内部错误') return go_error(request, u'共享失败:内部错误')
@login_required
def set_avatar(request, group_id):
try:
group_id_int = int(group_id)
except ValueError:
return go_error(request, u'group id 不是有效参数')
if not check_group_staff(group_id_int, request.user):
return go_permission_error(request, u'只有小组管理员有权设置小组图标')
group = ccnet_threaded_rpc.get_group(group_id_int)
if not group:
return HttpResponseRedirect(reverse('group_list', args=[]))
form = AvatarForm(request.POST or None, request.FILES or None)
if request.method == 'POST' and 'avatar' in request.FILES:
if form.is_valid():
image_file = request.FILES['avatar']
avatar = Avatar()
avatar.avatar.save(image_file.name, image_file)
avatar.group_id = group_id
avatar.save()
return render_to_response('group/set_avatar.html', {
'group' : group,
'form' : form,
}, context_instance=RequestContext(request))

View File

@@ -1,5 +1,5 @@
{% extends "myhome_base.html" %} {% extends "myhome_base.html" %}
{% load seahub_tags avatar_tags group_tags %} {% load seahub_tags avatar_tags group_avatar_tags %}
{% block nav_myhome_class %}class="cur"{% endblock %} {% block nav_myhome_class %}class="cur"{% endblock %}
{% block left_panel %} {% block left_panel %}