1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-04-28 03:10:45 +00:00

Cleaned share related code

This commit is contained in:
zhengxie 2012-11-06 11:12:49 +08:00
parent d2d38fd348
commit 73418cc45d
11 changed files with 206 additions and 201 deletions

View File

@ -40,17 +40,6 @@ class AddUserForm(forms.Form):
raise forms.ValidationError(_("The two password fields didn't match."))
return self.cleaned_data
class FileLinkShareForm(forms.Form):
"""
Form for sharing file shared link to emails.
"""
email = forms.CharField(max_length=512, error_messages={
'required': _("Email is required"),
'max_length': _("Email is not longer than 512 characters"),
})
file_shared_link = forms.CharField()
class FileCommentForm(forms.Form):
"""
Form for leave comments on file.

View File

@ -100,7 +100,7 @@
<img src="{{ MEDIA_URL }}img/download-20.png" class="download op-icon vh" data="{{ SITE_ROOT }}seafile_access_check/?repo_id={{ repo.props.id }}" alt="{% trans "Download" %}" title="{% trans "Download" %}" />
{% endif %}
{% if is_staff or repo.share_from_me %}
<img src="{{ MEDIA_URL }}img/delete-20.png" class="cancel-share op-icon vh" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.id }}&from={{ repo.owner }}&gid={{ group.id }}" title="{% trans "Unshare" %}" alt="{% trans "Unshare" %}" />
<img src="{{ MEDIA_URL }}img/delete-20.png" class="cancel-share op-icon vh" data="{% url 'repo_remove_share' %}?repo_id={{ repo.props.id }}&from={{ repo.owner }}&gid={{ group.id }}" title="{% trans "Unshare" %}" alt="{% trans "Unshare" %}" />
{% endif %}
</td>
</tr>

View File

@ -1,4 +1,5 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
class RepoShareForm(forms.Form):
"""
@ -8,3 +9,15 @@ class RepoShareForm(forms.Form):
email_or_group = forms.CharField(max_length=512)
repo_id = forms.CharField(max_length=36)
permission = forms.ChoiceField(choices=(('rw', 'read-write'), ('r', 'read-only')))
class FileLinkShareForm(forms.Form):
"""
Form for sharing file shared link to emails.
"""
email = forms.CharField(max_length=512, error_messages={
'required': _("Email is required"),
'max_length': _("Email is not longer than 512 characters"),
})
file_shared_link = forms.CharField()

View File

@ -2,7 +2,7 @@
{% load seahub_tags i18n %}
{% load url from future %}
{% block nav_shareadmin_class %}class="cur"{% endblock %}
{% block nav_share_class %}class="cur"{% endblock %}
{% if org %}
{% block title_panel %}
@ -53,10 +53,10 @@
<td>{{ repo.props.repo_desc }}</td>
<td>
{% if repo.props.share_type == 'group' %}
<a href="#" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.repo_id }}&from={{ request.user }}&gid={{ repo.props.group_id }}" class="cancel-share op">{% trans "Unshare"%}</a>
<a href="#" data="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user }}&gid={{ repo.props.group_id }}" class="cancel-share op">{% trans "Unshare"%}</a>
{% endif %}
{% if repo.props.share_type == 'personal' %}
<a href="#" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.repo_id }}&from={{ request.user }}&to={{ repo.props.user }}" class="cancel-share op">{% trans "Unshare"%}</a>
<a href="#" data="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ request.user }}&to={{ repo.props.user }}" class="cancel-share op">{% trans "Unshare"%}</a>
{% endif %}
{% if repo.props.share_type == 'public' %}
{% if not org %}
@ -92,7 +92,7 @@
<td>{{ fs.view_cnt }}</td>
<td>
<a href="#" class="op view-link" data="{{ fs.token }}">{% trans "View" %}</a>
<a class="op" href="{{ SITE_ROOT }}sharedlink/remove/?t={{ fs.token }}">{% trans "Remove"%}</a>
<a class="op" href="{% url 'remove_shared_link' %}?t={{ fs.token }}">{% trans "Remove"%}</a>
</td>
</tr>
{% endfor %}

View File

@ -3,8 +3,15 @@ from django.conf.urls.defaults import *
from views import *
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<token>[^/]{24,24})/$', remove_anonymous_share, name='remove_anonymous_share'),
url('^(?P<token>[^/]{24,24})/$', anonymous_share_confirm, name='anonymous_share_confirm'),
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<token>[^/]{24})/$', anonymous_share_confirm, name='anonymous_share_confirm'),
url(r'^permission_admin/$', share_permission_admin, name='share_permission_admin'),
)

View File

@ -14,16 +14,18 @@ from django.contrib.sites.models import Site, RequestSite
from pysearpc import SearpcError
from seaserv import seafserv_threaded_rpc, get_repo, ccnet_rpc, \
ccnet_threaded_rpc, get_personal_groups, list_personal_shared_repos, \
is_personal_repo
is_personal_repo, check_group_staff, is_org_group, get_org_id_by_group, \
del_org_group_repo
from forms import RepoShareForm
from forms import RepoShareForm, FileLinkShareForm
from models import AnonymousShare
from settings import ANONYMOUS_SHARE_COOKIE_TIMEOUT
from tokens import anon_share_token_generator
from seahub.contacts.signals import mail_sended
from seahub.share.models import FileShare
from seahub.views import validate_owner, is_registered_user
from seahub.utils import render_permission_error, string2list
from seahub.utils import render_permission_error, string2list, render_error, \
gen_token
try:
from seahub.settings import CLOUD_MODE
@ -133,6 +135,51 @@ def share_repo(request):
return HttpResponseRedirect(reverse('myhome'))
@login_required
def repo_remove_share(request):
"""
If repo is shared from one person to another person, only these two peson
can remove share.
If repo is shared from one person to a group, then only the one share the
repo and group staff can remove share.
"""
repo_id = request.GET.get('repo_id', '')
group_id = request.GET.get('gid', '')
from_email = request.GET.get('from', '')
# if request params don't have 'gid', then remove repos that share to
# to other person; else, remove repos that share to groups
if not group_id:
to_email = request.GET.get('to', '')
if request.user.username != from_email and \
request.user.username != to_email:
return render_permission_error(request, _(u'Failed to remove share'))
seafserv_threaded_rpc.remove_share(repo_id, from_email, to_email)
else:
try:
group_id_int = int(group_id)
except:
return render_error(request, _(u'group id is not valid'))
if not check_group_staff(group_id_int, request.user) \
and request.user.username != from_email:
return render_permission_error(request, _(u'Failed to remove share'))
if is_org_group(group_id_int):
org_id = get_org_id_by_group(group_id_int)
del_org_group_repo(repo_id, org_id, group_id_int)
else:
from group.views import group_unshare_repo
group_unshare_repo(request, repo_id, group_id_int, from_email)
messages.success(request, _('Successfully removed share'))
next = request.META.get('HTTP_REFERER', None)
if not next:
next = settings.SITE_ROOT
return HttpResponseRedirect(next)
@login_required
def share_admin(request):
"""
@ -320,3 +367,111 @@ def remove_anonymous_share(request, token):
return HttpResponseRedirect(next)
@login_required
def get_shared_link(request):
"""
Handle ajax request to generate file shared link.
"""
if not request.is_ajax():
raise Http404
content_type = 'application/json; charset=utf-8'
repo_id = request.GET.get('repo_id')
obj_id = request.GET.get('obj_id')
path = request.GET.get('p', '/')
if path[-1] == '/':
path = path[:-1]
l = FileShare.objects.filter(repo_id=repo_id).filter(
username=request.user.username).filter(path=path)
if len(l) > 0:
fileshare = l[0]
token = fileshare.token
else:
token = gen_token(max_length=10)
fs = FileShare()
fs.username = request.user.username
fs.repo_id = repo_id
fs.path = path
fs.token = token
try:
fs.save()
except IntegrityError, e:
err = _('Failed to get shared link, please retry.')
data = json.dumps([{'error': err}])
return HttpResponse(data, status=500, content_type=content_type)
data = json.dumps([{'token': token}])
return HttpResponse(data, status=200, content_type=content_type)
@login_required
def remove_shared_link(request):
"""
Handle request to remove file shared link.
"""
token = request.GET.get('t', '')
if not request.is_ajax():
FileShare.objects.filter(token=token).delete()
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse('share_admin')
messages.success(request, _(u'Removed successfully'))
return HttpResponseRedirect(next)
content_type = 'application/json; charset=utf-8'
FileShare.objects.filter(token=token).delete()
msg = _('Removed successfully')
data = json.dumps([{'msg': msg}])
return HttpResponse(data, status=200, content_type=content_type)
@login_required
def send_shared_link(request):
"""
Handle ajax post request to send file shared link.
"""
if not request.is_ajax() and not request.method == 'POST':
raise Http404
result = {}
content_type = 'application/json; charset=utf-8'
form = FileLinkShareForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
file_shared_link = form.cleaned_data['file_shared_link']
t = loader.get_template('shared_link_email.html')
to_email_list = string2list(email)
for to_email in to_email_list:
# Add email to contacts.
mail_sended.send(sender=None, user=request.user.username,
email=to_email)
c = {
'email': request.user.username,
'to_email': to_email,
'file_shared_link': file_shared_link,
}
try:
send_mail(_(u'Your friend sharing a file to you on Seafile'),
t.render(Context(c)), None, [to_email],
fail_silently=False)
except:
data = json.dumps({'error':_(u'Failed to send mail')})
return HttpResponse(data, status=500, content_type=content_type)
data = json.dumps("success")
return HttpResponse(data, status=200, content_type=content_type)
else:
return HttpResponseBadRequest(json.dumps(form.errors),
content_type=content_type)

View File

@ -11,7 +11,7 @@
<a href="{{ SITE_ROOT }}groups/" {% block nav_group_class %}{% endblock %}>{% trans "Groups" %}</a>
</li>
<li>
<a href="{{ SITE_ROOT }}shareadmin/" {% block nav_shareadmin_class %}{% endblock %}>{% trans "Share" %}</a>
<a href="{{ SITE_ROOT }}share/" {% block nav_share_class %}{% endblock %}>{% trans "Share" %}</a>
</li>
<li>
<a href="{{ SITE_ROOT }}contacts/" {% block nav_contacts_class %}{% endblock %}>{% trans "Contacts" %}</a>

View File

@ -69,9 +69,9 @@
{% if not view_history %}
<div class="file-op fright">
<input id="shared-link" class="hide" type="text" readonly="readonly" value="{{ file_shared_link }}" />
<button data="{{ SITE_ROOT }}sharedlink/get/?repo_id={{ repo.id }}&p={{ path|urlencode }}&file_name={{ file_name }}" id="get-shared-link">{% trans "Share link"%}</button>
<button data="{% url 'get_shared_link' %}?repo_id={{ repo.id }}&p={{ path|urlencode }}&file_name={{ file_name }}" id="get-shared-link">{% trans "Share link"%}</button>
<button id="send-shared-link" class="hide">{% trans "Send"%}</button>
<button data="{{ SITE_ROOT }}sharedlink/remove/?t={{ fileshare.token }}" id="rm-shared-link" class="hide">{% trans "Delete"%}</button>
<button data="{% url 'remove_shared_link' %}?t={{ fileshare.token }}" id="rm-shared-link" class="hide">{% trans "Delete"%}</button>
{% if is_starred %}
<button id="star" data="starred">{% trans "Unstar"%}</button>
{% else %}
@ -135,8 +135,8 @@
{% if not view_history %}
<form id="link-send-form" action="" method="post" name="link-send-form" class="hide">
<label>{% trans "Emails(seperated with ,)"%}</label><br />
<textarea id="email" name="email"></textarea><br />
<label>{% trans "Emails"%}</label><br />
<textarea id="email" name="email" placeholder="{% trans "Emails, Seperate by ','"%}"></textarea><br />
<input type="hidden" name="file_shared_link" value="{{ file_shared_link }}" />
<input type="submit" value="{% trans "Submit"%}" class="submit" />
<p class="error hide"></p>
@ -242,7 +242,8 @@ $('#get-shared-link').click(function() {
shared_link = '{{ protocol }}://{{ domain }}{{ SITE_ROOT }}f/' + t + '/';
$('#shared-link').val(shared_link);
setLinkWidth();
$('#rm-shared-link').attr('data', '{{ SITE_ROOT }}sharedlink/remove/?t='+t);
var remove_link = '{% url 'remove_shared_link' %}';
$('#rm-shared-link').attr('data', remove_link + '?t=' + t);
$('input[name="file_shared_link"]').val(shared_link);
showLink();
}
@ -290,7 +291,7 @@ $("#link-send-form").submit(function(event) {
$.ajax({
type: "POST",
url: "{% url 'seahub.views.send_shared_link' %}",
url: "{% url 'send_shared_link' %}",
dataType: 'json',
cache: false,
contentType: 'application/json; charset=utf-8',

View File

@ -81,7 +81,7 @@
{% if repo.user_perm == 'rw' %}
<img src="{{ MEDIA_URL }}img/download-20.png" data="{{ repo.props.repo_id }}" class="download-btn op-icon vh" title="{% trans "Download" %}" alt="{% trans "Download" %}" />
{% endif %}
<img src="{{ MEDIA_URL }}img/delete-20.png" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.repo_id }}&from={{ repo.props.user }}&to={{ request.user }}" class="unshare-btn op-icon vh" title="{% trans "Leave Share" %}" alt="{% trans "Leave Share" %}" />
<img src="{{ MEDIA_URL }}img/delete-20.png" data="{% url 'repo_remove_share' %}?repo_id={{ repo.props.repo_id }}&from={{ repo.props.user }}&to={{ request.user }}" class="unshare-btn op-icon vh" title="{% trans "Leave Share" %}" alt="{% trans "Leave Share" %}" />
</td>
</tr>
{% endfor %}

19
urls.py
View File

@ -4,7 +4,6 @@ from django.views.generic.simple import direct_to_template
from seahub.views import *
from notifications.views import notification_list
from share.views import share_admin
from group.views import GroupListView
# Uncomment the next two lines to enable the admin:
@ -31,15 +30,6 @@ urlpatterns = patterns('',
url(r'^home/public/reply/new/$', innerpub_msg_reply_new, name='innerpub_msg_reply_new'),
url(r'^home/owner/(?P<owner_name>[^/]+)/$', ownerhome, name='ownerhome'),
(r'^share/', include('share.urls')),
(r'^api/', include('api.urls')),
url(r'^shareadmin/$', share_admin, name='share_admin'),
(r'^shareadmin/removeshare/$', repo_remove_share),
(r'^sharedlink/get/$', get_shared_link),
(r'^sharedlink/remove/$', remove_shared_link),
(r'^sharedlink/send/$', send_shared_link),
url(r'^f/(?P<token>[^/]+)/$', view_shared_file, name='view_shared_file'),
(r'^repo/new_dir/$', repo_new_dir),
(r'^repo/new_file/$', repo_new_file),
(r'^repo/create/$', repo_create),
@ -68,6 +58,7 @@ urlpatterns = patterns('',
(r'^repo/(?P<repo_id>[^/]+)/file/edit/$', repo_file_edit),
url(r'^repo/(?P<repo_id>[^/]+)/(?P<obj_id>[^/]+)/$', repo_access_file, name='repo_access_file'),
url(r'^f/(?P<token>[^/]+)/$', view_shared_file, name='view_shared_file'),
(r'^file_upload_progress_page/$', file_upload_progress_page),
(r'^publicrepo/create/$', public_repo_create),
(r'^file_comment/$', file_comment),
@ -86,18 +77,18 @@ urlpatterns = patterns('',
(r'^useradmin/activate/(?P<user_id>[^/]+)/$', activate_user),
(r'^useradmin/password/reset/(?P<user_id>[^/]+)/$', user_reset),
### Apps ###
### Apps ###
(r'^api/', include('api.urls')),
(r'^avatar/', include('avatar.urls')),
(r'^notification/', include('notifications.urls')),
url(r'^sys/notificationadmin/', notification_list, name='notification_list'),
(r'^contacts/', include('contacts.urls')),
(r'^group/', include('seahub.group.urls')),
url(r'^groups/', GroupListView.as_view(), name='group_list'),
# url(r'^deptgroups/', DeptGroupListView.as_view(), name='dept_group_list'),
# url(r'^projgroups/', ProjGroupListView.as_view(), name='proj_group_list'),
(r'^profile/', include('seahub.profile.urls')),
(r'^share/', include('share.urls')),
### SeaHub admin ###
### system admin ###
(r'^sys/seafadmin/$', sys_seafadmin),
url(r'^sys/useradmin/$', sys_useradmin, name='sys_useradmin'),
url(r'^sys/orgadmin/$', sys_org_admin, name='sys_org_admin'),

167
views.py
View File

@ -59,11 +59,11 @@ from group.models import GroupMessage, MessageAttachment
from group.signals import grpmsg_added
from notifications.models import UserNotification
from profile.models import Profile
from forms import AddUserForm, FileLinkShareForm, RepoCreateForm, \
RepoNewDirForm, RepoNewFileForm, FileCommentForm, RepoRenameFileForm, \
RepoPassowrdForm, SharedRepoCreateForm, SetUserQuotaForm
from forms import AddUserForm, RepoCreateForm, RepoNewDirForm, RepoNewFileForm,\
FileCommentForm, RepoRenameFileForm, RepoPassowrdForm, SharedRepoCreateForm,\
SetUserQuotaForm
from utils import render_permission_error, render_error, list_to_string, \
get_httpserver_root, get_ccnetapplet_root, gen_token, \
get_httpserver_root, get_ccnetapplet_root, \
calculate_repo_last_modify, valid_previewed_file, \
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \
get_file_revision_id_size, get_ccnet_server_addr_port, \
@ -1423,15 +1423,15 @@ def repo_file_get(raw_path):
try:
file_response = urllib2.urlopen(raw_path)
if long(file_response.headers['Content-Length']) > FILE_PREVIEW_MAX_SIZE:
err = '文件超过10M无法在线查看。'
err = _(u'File size surpasses 10M, can not be previewed online.')
return err, '', '', ''
else:
content = file_response.read()
except urllib2.HTTPError, e:
err = 'HTTPError: 无法在线打开该文件'
err = _(u'HTTPError: failed to open file online')
return err, '', '', ''
except urllib2.URLError as e:
err = 'URLError: 无法在线打开该文件'
err = _(u'URLError: failed to open file online')
return err, '', '', ''
else:
try:
@ -1734,50 +1734,6 @@ def seafile_access_check(request):
},
context_instance=RequestContext(request))
@login_required
def repo_remove_share(request):
"""
If repo is shared from one person to another person, only these two peson
can remove share.
If repo is shared from one person to a group, then only the one share the
repo and group staff can remove share.
"""
repo_id = request.GET.get('repo_id', '')
group_id = request.GET.get('gid')
from_email = request.GET.get('from', '')
# if request params don't have 'gid', then remove repos that share to
# to other person; else, remove repos that share to groups
if not group_id:
to_email = request.GET.get('to', '')
if request.user.username != from_email and \
request.user.username != to_email:
return render_permission_error(request, _(u'Remove share failed'))
seafserv_threaded_rpc.remove_share(repo_id, from_email, to_email)
else:
try:
group_id_int = int(group_id)
except:
return render_error(request, _(u'group id is not valid'))
if not check_group_staff(group_id_int, request.user) \
and request.user.username != from_email:
return render_permission_error(request, _(u'Remove share failed'))
if is_org_group(group_id_int):
org_id = get_org_id_by_group(group_id_int)
del_org_group_repo(repo_id, org_id, group_id_int)
else:
from group.views import group_unshare_repo
group_unshare_repo(request, repo_id, group_id_int, from_email)
messages.success(request, _('Remove share successful'))
next = request.META.get('HTTP_REFERER', None)
if not next:
next = settings.SITE_ROOT
return HttpResponseRedirect(next)
@login_required
@sys_staff_required
@ -2431,46 +2387,6 @@ def file_revisions(request, repo_id):
except Exception, e:
return render_error(request, str(e))
@login_required
def get_shared_link(request):
"""
Handle ajax request to generate file shared link.
"""
if not request.is_ajax():
raise Http404
content_type = 'application/json; charset=utf-8'
repo_id = request.GET.get('repo_id')
obj_id = request.GET.get('obj_id')
path = request.GET.get('p', '/')
if path[-1] == '/':
path = path[:-1]
l = FileShare.objects.filter(repo_id=repo_id).filter(\
username=request.user.username).filter(path=path)
if len(l) > 0:
fileshare = l[0]
token = fileshare.token
else:
token = gen_token(max_length=10)
fs = FileShare()
fs.username = request.user.username
fs.repo_id = repo_id
fs.path = path
fs.token = token
try:
fs.save()
except IntegrityError, e:
err = '获取分享链接失败,请重新获取'
data = json.dumps([{'error': err}])
return HttpResponse(data, status=500, content_type=content_type)
data = json.dumps([{'token': token}])
return HttpResponse(data, status=200, content_type=content_type)
def view_shared_file(request, token):
"""
Preview file via shared link.
@ -2498,7 +2414,7 @@ def view_shared_file(request, token):
obj_id = None
if not obj_id:
return render_error(request, '文件不存在')
return render_error(request, _(u'File not exists'))
repo = get_repo(repo_id)
if not repo:
@ -2549,73 +2465,6 @@ def view_shared_file(request, token):
'DOCUMENT_CONVERTOR_ROOT': DOCUMENT_CONVERTOR_ROOT,
}, context_instance=RequestContext(request))
@login_required
def remove_shared_link(request):
"""
Handle request to remove file shared link.
"""
token = request.GET.get('t', '')
if not request.is_ajax():
FileShare.objects.filter(token=token).delete()
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse('share_admin')
messages.success(request, _(u'Remove successful'))
return HttpResponseRedirect(next)
content_type = 'application/json; charset=utf-8'
FileShare.objects.filter(token=token).delete()
msg = _('Remove successful')
data = json.dumps([{'msg': msg}])
return HttpResponse(data, status=200, content_type=content_type)
@login_required
def send_shared_link(request):
"""
Handle ajax post request to send file shared link.
"""
if not request.is_ajax() and not request.method == 'POST':
raise Http404
result = {}
content_type = 'application/json; charset=utf-8'
form = FileLinkShareForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
file_shared_link = form.cleaned_data['file_shared_link']
t = loader.get_template('shared_link_email.html')
to_email_list = string2list(email)
for to_email in to_email_list:
# Add email to contacts.
mail_sended.send(sender=None, user=request.user.username,
email=to_email)
c = {
'email': request.user.username,
'to_email': to_email,
'file_shared_link': file_shared_link,
}
try:
send_mail(_(u'Your friend sharing a file to you on Seafile'),
t.render(Context(c)), None, [to_email],
fail_silently=False)
except:
data = json.dumps({'error':_(u'Failed to send mail')})
return HttpResponse(data, status=500, content_type=content_type)
data = json.dumps("success")
return HttpResponse(data, status=200, content_type=content_type)
else:
return HttpResponseBadRequest(json.dumps(form.errors),
content_type=content_type)
def flash_prepare(raw_path, obj_id, doctype):
curl = DOCUMENT_CONVERTOR_ROOT + 'convert'