From 63b36c8923dd07157c694efec78015466a75d588 Mon Sep 17 00:00:00 2001 From: zhengxie Date: Sat, 1 Jun 2013 10:04:46 +0800 Subject: [PATCH] Refactor share repo --- seahub/group/views.py | 20 +-- seahub/share/urls.py | 9 +- seahub/share/views.py | 322 +++++++++++++++++++++++------------------- 3 files changed, 193 insertions(+), 158 deletions(-) diff --git a/seahub/group/views.py b/seahub/group/views.py index 6b3cabae97..59be2dbc25 100644 --- a/seahub/group/views.py +++ b/seahub/group/views.py @@ -719,18 +719,18 @@ def group_remove_member(request, group_id, user_name): return HttpResponseRedirect(reverse('group_manage', args=[group_id])) -def add_group_repo(request, repo_id, group_id, from_email, permission): - """ - Share a repo to a group. +# def add_group_repo(request, repo_id, group_id, from_email, permission): +# """ +# Share a repo to a group. - """ - # Check whether group exists - group = get_group(group_id) - if not group: - raise Exception, _(u"Failed to share: the group doesn't exist.") +# """ +# # Check whether group exists +# group = get_group(group_id) +# if not group: +# raise Exception, _(u"Failed to share: the group doesn't exist.") - seafserv_threaded_rpc.group_share_repo(repo_id, group_id, from_email, - permission) +# seafserv_threaded_rpc.group_share_repo(repo_id, group_id, from_email, +# permission) def group_unshare_repo(request, repo_id, group_id, from_email): """ diff --git a/seahub/share/urls.py b/seahub/share/urls.py index d96bda14ea..715bbc4721 100644 --- a/seahub/share/urls.py +++ b/seahub/share/urls.py @@ -6,14 +6,15 @@ urlpatterns = patterns('', url(r'^$', share_admin, name='share_admin'), url(r'^add/$', share_repo, name='share_repo'), url(r'^remove/$', repo_remove_share, name='repo_remove_share'), - url('^remove/(?P[^/]{24,24})/$', remove_anonymous_share, name='remove_anonymous_share'), url(r'^link/get/$', get_shared_link, name='get_shared_link'), url(r'^link/remove/$', remove_shared_link, name='remove_shared_link'), url(r'^link/send/$', send_shared_link, name='send_shared_link'), - - url('^(?P[^/]{24})/$', anonymous_share_confirm, name='anonymous_share_confirm'), + url(r'^permission_admin/$', share_permission_admin, name='share_permission_admin'), - url(r'^u/(?P[^/]+)/$', user_share_list, name='user_share_list'), + + # url('^remove/(?P[^/]{24,24})/$', remove_anonymous_share, name='remove_anonymous_share'), + # url('^(?P[^/]{24})/$', anonymous_share_confirm, name='anonymous_share_confirm'), + ) diff --git a/seahub/share/views.py b/seahub/share/views.py index a8e3bf17c4..8cf62d5a68 100644 --- a/seahub/share/views.py +++ b/seahub/share/views.py @@ -10,6 +10,7 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404, \ from django.shortcuts import render_to_response from django.template import Context, loader, RequestContext from django.utils.translation import ugettext as _ +from django.views.decorators.http import require_POST from django.contrib import messages from django.contrib.sites.models import Site, RequestSite @@ -32,7 +33,6 @@ from seahub.base.accounts import User from seahub.contacts.models import Contact from seahub.contacts.signals import mail_sended from seahub.share.models import FileShare -# from seahub.message.models import UserMessage from seahub.views import validate_owner, is_registered_user from seahub.utils import render_permission_error, string2list, render_error, \ gen_token, gen_shared_link, IS_EMAIL_CONFIGURED @@ -46,14 +46,107 @@ from seahub.settings import SITE_ROOT # Get an instance of a logger logger = logging.getLogger(__name__) +def share_to_public(request, repo, permission): + """Share repo to public with given permission. + """ + repo_id = repo.id + try: + seafile_api.add_inner_pub_repo(repo_id, permission) + except Exception, e: + logger.error(e) + messages.error(request, _(u'Failed to share to all members, please try again later.')) + else: + msg = _(u'Shared to all members successfully, go check it at Shares.') % \ + (reverse('share_admin')) + messages.success(request, msg) + +def share_to_group(request, repo, from_user, group, permission): + """Share repo to group with given permission. + """ + repo_id = repo.id + group_id = group.id + group_name = group.group_name + + if repo.id in seafile_api.get_group_repoids(group.id): + msg = _(u'"%(repo)s" is already in group %(group)s. View') % { + 'repo': repo.name, 'group': group.group_name, + 'href': reverse('group_info', args=[group.id])} + messages.error(request, msg) + return + + try: + seafile_api.group_share_repo(repo_id, group_id, from_user, permission) + except Exception, e: + logger.error(e) + msg = _(u'Failed to share %(repo)s to %(group)s, please try again later.') % \ + {'repo': repo.name, 'group': group_name} + messages.error(request, msg) + else: + msg = _(u'Shared to %(group)s successfully,go check it at Shares.') % \ + {'group':group_name, 'share':reverse('share_admin')} + messages.success(request, msg) + +def share_to_user(request, repo, from_user, to_user, permission): + """Share repo to a user with given permission. + """ + repo_id = repo.id + + if is_registered_user(to_user): + try: + seafile_api.share_repo(repo_id, from_user, to_user, permission) + except Exception, e: + logger.error(e) + msg = _(u'Failed to share to %s, please try again later.') % to_user + messages.error(request, msg) + else: + # send a signal when sharing repo successful + share_repo_to_user_successful.send(sender=None, + from_user=from_user, + to_user=to_user, repo=repo) + msg = _(u'Shared to %(email)s successfully,go check it at Shares.') % \ + {'email':to_user, 'share':reverse('share_admin')} + messages.success(request, msg) + else: + msg = _(u'Failed to share to %s, as the email is not registered.') % to_user + messages.error(request, msg) + +def check_user_share_quota(username, repo, users=[], groups=[]): + """Check whether user has enough quota when share repo to users/groups. + """ + if not users and not groups: + return True + + if not seaserv.CALC_SHARE_USAGE: + return True + + check_pass = False + quota = seafile_api.get_user_quota(username) + self_usage = seafile_api.get_user_self_usage(username) + current_share_usage = seafile_api.get_user_share_usage(username) + + share_usage = 0 + if users: + share_usage += seafile_api.get_repo_size(repo.id) * (len(users)) + + if groups: + grp_members = [] + for group in groups: + grp_members += [ e.user_name for e in seaserv.get_group_members(group.id)] + grp_members = set(grp_members) + share_usage += seafile_api.get_repo_size(repo.id) * (len(grp_members) -1) + if share_usage + self_usage + current_share_usage < quota: + check_pass = True + + return check_pass + @login_required +@require_POST def share_repo(request): """ - Handle repo share request + Handle POST method to share a repo to public/groups/users based on form + data. Return to ``myhome`` page and notify user whether success or failure. """ - if request.method != 'POST': - raise Http404 - + form = RepoShareForm(request.POST) if not form.is_valid(): # TODO: may display error msg on form @@ -70,8 +163,12 @@ def share_repo(request): # Test whether user is the repo owner. if not validate_owner(request, repo_id): - return render_permission_error(request, _(u'Only the owner of the library has permission to share it.')) + msg = _(u'Only the owner of the library has permission to share it.') + messages.error(request, msg) + return HttpResponseRedirect(reverse('myhome')) + + # Parsing input values. share_to_list = string2list(email_or_group) share_to_all, share_to_group_names, share_to_users = False, [], [] for share_to in share_to_list: @@ -90,86 +187,23 @@ def share_repo(request): if group.group_name in share_to_group_names: share_to_groups.append(group) - # Check whether this user has enough quota when cal_share_usage is enabled. - # share_usage = repo_size * union(share_to_users + members_of(share_to_groups)) - if seaserv.CALC_SHARE_USAGE: - clone = list(share_to_users) - for group in share_to_groups: - clone += [ e.user_name for e in seaserv.get_group_members(group.id)] - clone = set(clone) - # Since that user is also in share_to_users when called - # ``get_group_members``, so need to minus one when counting. - share_usage = seaserv.server_repo_size(repo.id) * (len(clone) - 1) - # check quota usage - quota = seaserv.get_user_quota(from_email) - quota_usage = seaserv.get_user_quota_usage(from_email) - current_share_usage = seaserv.get_user_share_usage(from_email) - if share_usage + quota_usage + current_share_usage > quota: - messages.error(request, _('Failed to share "%s", no enough quota. Upgrade account.') % repo.name) - return HttpResponseRedirect(reverse('myhome')) - ''' Share to public ''' - if share_to_all: - # ignore 'all' if we're running in cloud mode - if not CLOUD_MODE: - try: - seafserv_threaded_rpc.set_inner_pub_repo(repo_id, permission) - except: - messages.error(request, _(u'Failed to share to all members')) - else: - msg = _(u'Shared to all members successfully, go check it at Shares.') % \ - (reverse('share_admin')) - messages.success(request, msg) + if share_to_all and not CLOUD_MODE: + share_to_public(request, repo, permission) - ''' Share to groups ''' + if not check_user_share_quota(from_email, repo, users=share_to_users, + groups=share_to_groups): + messages.error(request, _('Failed to share "%s", no enough quota. Upgrade account.') % repo.name) + return HttpResponseRedirect(reverse('myhome')) + for group in share_to_groups: - from seahub.group.views import add_group_repo - try: - add_group_repo(request, repo_id, int(group.id), from_email, - permission) - except Exception, e: - logger.error(e) - msg = _(u'Failed to share %(repo)s to %(group)s, please try again later.') % \ - {'repo': repo.name, 'group': group.group_name} - messages.error(request, msg) - else: - msg = _(u'Shared to %(group)s successfully,go check it at Share.') % \ - {'group':group.group_name, 'share':reverse('share_admin')} - messages.success(request, msg) - - ''' Share to users ''' + share_to_group(request, repo, from_email, group, permission) + for email in share_to_users: # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=email) - if not is_registered_user(email): - # Generate shared link and send mail if user has not registered. - # is_encrypted = True if repo.encrypted else False - # kwargs = {'repo_id': repo_id, - # 'repo_owner': from_email, - # 'anon_email': email, - # 'is_encrypted': is_encrypted, - # } - # anonymous_share(request, **kwargs) - msg = _(u'Failed to share to %s, as the email is not registered.') % email - messages.add_message(request, messages.ERROR, msg) - continue - else: - # Record share info to db. - try: - seafserv_threaded_rpc.add_share(repo_id, from_email, email, - permission) - except SearpcError, e: - logger.error(e) - msg = _(u'Failed to share to %s .') % email - messages.add_message(request, messages.ERROR, msg) - continue - # send a signal when sharing repo successful - share_repo_to_user_successful.send(sender=None, - from_user=from_email, - to_user=email, repo=repo) - msg = _(u'Shared to %(email)s successfully,go check it at Shares.') % \ - {'email':email, 'share':reverse('share_admin')} - messages.add_message(request, messages.INFO, msg) + share_to_user(request, repo, from_email, email, permission) + return HttpResponseRedirect(reverse('myhome')) @login_required @@ -331,82 +365,82 @@ def share_permission_admin(request): # - anonymous_share_confirm checks the link use clicked and # adds token to client COOKIE, then redirect client to repo page -def anonymous_share(request, email_template_name='repo/anonymous_share_email.html', **kwargs): - repo_id = kwargs['repo_id'] - repo_owner = kwargs['repo_owner'] - anon_email = kwargs['anon_email'] - is_encrypted = kwargs['is_encrypted'] +# def anonymous_share(request, email_template_name='repo/anonymous_share_email.html', **kwargs): +# repo_id = kwargs['repo_id'] +# repo_owner = kwargs['repo_owner'] +# anon_email = kwargs['anon_email'] +# is_encrypted = kwargs['is_encrypted'] - # Encrypt repo can not be shared to unregistered user. - if is_encrypted: - msg = _(u'Failed to share to %s, as encrypted libraries cannot be shared to emails outside the site.') % anon_email - messages.error(request, msg) - return +# # Encrypt repo can not be shared to unregistered user. +# if is_encrypted: +# msg = _(u'Failed to share to %s, as encrypted libraries cannot be shared to emails outside the site.') % anon_email +# messages.error(request, msg) +# return - token = anon_share_token_generator.make_token() +# token = anon_share_token_generator.make_token() - anon_share = AnonymousShare() - anon_share.repo_owner = repo_owner - anon_share.repo_id = repo_id - anon_share.anonymous_email = anon_email - anon_share.token = token +# anon_share = AnonymousShare() +# anon_share.repo_owner = repo_owner +# anon_share.repo_id = repo_id +# anon_share.anonymous_email = anon_email +# anon_share.token = token - try: - anon_share.save() - except: - msg = _(u'Failed to share to %s.') % anon_email - messages.add_message(request, messages.ERROR, msg) - else: - # send mail - use_https = request.is_secure() - site_name = domain = RequestSite(request).domain +# try: +# anon_share.save() +# except: +# msg = _(u'Failed to share to %s.') % anon_email +# messages.add_message(request, messages.ERROR, msg) +# else: +# # send mail +# use_https = request.is_secure() +# site_name = domain = RequestSite(request).domain - t = loader.get_template(email_template_name) - c = { - 'email': repo_owner, - 'anon_email': anon_email, - 'domain': domain, - 'site_name': site_name, - 'token': token, - 'protocol': use_https and 'https' or 'http', - } +# t = loader.get_template(email_template_name) +# c = { +# 'email': repo_owner, +# 'anon_email': anon_email, +# 'domain': domain, +# 'site_name': site_name, +# 'token': token, +# 'protocol': use_https and 'https' or 'http', +# } - try: - send_mail(_(u'You are shared with a library in Seafile'), t.render(Context(c)), None, - [anon_email], fail_silently=False) - except: - AnonymousShare.objects.filter(token=token).delete() - msg = _(u'Failed to share to %s.') % anon_email - messages.add_message(request, messages.ERROR, msg) - else: - msg = _(u'Shared to %(email)s successfully, go check it at Share.') % \ - {'email':anon_email, 'share':reverse('share_admin')} - messages.add_message(request, messages.INFO, msg) +# try: +# send_mail(_(u'You are shared with a library in Seafile'), t.render(Context(c)), None, +# [anon_email], fail_silently=False) +# except: +# AnonymousShare.objects.filter(token=token).delete() +# msg = _(u'Failed to share to %s.') % anon_email +# messages.add_message(request, messages.ERROR, msg) +# else: +# msg = _(u'Shared to %(email)s successfully, go check it at Share.') % \ +# {'email':anon_email, 'share':reverse('share_admin')} +# messages.add_message(request, messages.INFO, msg) -def anonymous_share_confirm(request, token=None): - assert token is not None # checked by URLconf +# def anonymous_share_confirm(request, token=None): +# assert token is not None # checked by URLconf - # Check whether token in db - try: - anon_share = AnonymousShare.objects.get(token=token) - except AnonymousShare.DoesNotExist: - raise Http404 - else: - res = HttpResponseRedirect(reverse('repo', args=[anon_share.repo_id])) - res.set_cookie("anontoken", token, - max_age=ANONYMOUS_SHARE_COOKIE_TIMEOUT) - return res +# # Check whether token in db +# try: +# anon_share = AnonymousShare.objects.get(token=token) +# except AnonymousShare.DoesNotExist: +# raise Http404 +# else: +# res = HttpResponseRedirect(reverse('repo', args=[anon_share.repo_id])) +# res.set_cookie("anontoken", token, +# max_age=ANONYMOUS_SHARE_COOKIE_TIMEOUT) +# return res -def remove_anonymous_share(request, token): - AnonymousShare.objects.filter(token=token).delete() +# def remove_anonymous_share(request, token): +# AnonymousShare.objects.filter(token=token).delete() - next = request.META.get('HTTP_REFERER', None) - if not next: - next = reverse('share_admin') +# next = request.META.get('HTTP_REFERER', None) +# if not next: +# next = reverse('share_admin') - messages.add_message(request, messages.INFO, _(u'Deleted successfully.')) +# messages.add_message(request, messages.INFO, _(u'Deleted successfully.')) - return HttpResponseRedirect(next) +# return HttpResponseRedirect(next) @login_required def get_shared_link(request):