1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-31 14:42:10 +00:00

Refactor shared dir, update url

This commit is contained in:
zhengxie
2015-05-26 17:39:57 +08:00
parent fe94d09542
commit 78b166b5c7
7 changed files with 118 additions and 79 deletions

View File

@@ -140,7 +140,7 @@ class FileShare(models.Model):
return True if self.s_type == 'f' else False
def is_dir_share_link(self):
return False if self.is_file_link() else True
return False if self.is_file_share_link() else True
def is_encrypted(self):
return True if self.password is not None else False

View File

@@ -33,7 +33,7 @@
{% endif %}
{% endif %}
{% if not traffic_over_limit %}
<a href="?p={{path}}&dl=1" class="obv-btn">{% trans "Download" %} ({{file_size|filesizeformat}})</a>
<a href="{% if from_shared_dir %}?p={{path}}&dl=1{% else %}?dl=1{% endif %}" class="obv-btn">{% trans "Download" %} ({{file_size|filesizeformat}})</a>
{% endif %}
</div>
{% include 'snippets/file_content_html.html' %}

View File

@@ -6,6 +6,7 @@
{% block main_panel %}
<h2>{{ dir_name }}</h2>
<p>{% trans "Shared by: " %}{{ username|email2nickname }}</p>
<div class="repo-file-list-outer-container">
<div class="repo-file-list-inner-container">
<div class="repo-file-list-topbar ovhd">
@@ -13,14 +14,14 @@
{% trans "Current path: "%}
{% for name, link in zipped %}
{% if not forloop.last %}
<a href="{{ SITE_ROOT }}d/{{ token }}/?p={{ link|urlencode }}">{{ name }}</a> /
<a href="{% url "view_shared_dir" token %}?p={{ link|urlencode }}">{{ name }}</a> /
{% else %}
{{ name }}
{% endif %}
{% endfor %}
</p>
{% if not traffic_over_limit %}
<a href="{% url 'repo_download_dir' repo.id %}?p={{ path|urlencode }}&t={{ token }}" class="obv-btn fright">{% trans "ZIP"%}</a>
<a href="?p={{ path|urlencode }}&dl=1" class="obv-btn fright">{% trans "ZIP"%}</a>
{% endif %}
</div>
<table class="repo-file-list" style="table-layout:fixed;">
@@ -35,13 +36,13 @@
<tr>
<td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td>
<td>
<a href="{{ SITE_ROOT }}d/{{ token }}/?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a>
<a href="{% url "view_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.obj_name }}</a>
</td>
<td></td>
<td>
{% if not traffic_over_limit %}
<a class="op-icon vh" href="{% url 'repo_download_dir' repo.id %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}&t={{token}}" title="{% trans 'Download' %}">
<a class="op-icon vh" href="{% url "view_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}&dl=1" title="{% trans 'Download' %}">
<img src="{{MEDIA_URL}}img/download.png" alt="" />
</a>
{% endif %}
@@ -62,7 +63,7 @@
{% endif %}
<td>
<a class="normal" href="{{ SITE_ROOT }}d/{{ token }}/files/?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.props.obj_name }}</a>
<a class="normal" href="{% url "view_file_via_shared_dir" token %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{{ dirent.props.obj_name }}</a>
</td>
<td>{{ dirent.file_size|filesizeformat }}</td>

View File

@@ -1810,6 +1810,7 @@ def i18n(request):
res.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang, max_age=30*24*60*60)
return res
@login_required
def repo_download_dir(request, repo_id):
repo = get_repo(repo_id)
if not repo:
@@ -1827,30 +1828,8 @@ def repo_download_dir(request, repo_id):
else:
dirname = repo.name
allow_download = False
fileshare_token = request.GET.get('t', '')
from_shared_link = False
shared_by = None
if fileshare_token: # download dir from dir shared link
try:
fileshare = FileShare.objects.get(token=fileshare_token)
except FileShare.DoesNotExist:
raise Http404
# Can not download upper dir of shared dir.
allow_download = True if path.startswith(fileshare.path) else False
from_shared_link = True
shared_by = fileshare.username
else:
allow_download = True if check_repo_access_permission(
repo_id, request.user) else False
if from_shared_link:
# check whether owner's traffic over the limit
if user_traffic_over_limit(fileshare.username):
return render_permission_error(request,
_(u'Unable to access file: share link traffic is used up.'))
allow_download = True if check_repo_access_permission(
repo_id, request.user) else False
if allow_download:
dir_id = seafserv_threaded_rpc.get_dirid_by_path (repo.id,
repo.head_cmmt_id,
@@ -1871,16 +1850,9 @@ def repo_download_dir(request, repo_id):
'download-dir',
request.user.username)
if from_shared_link:
try:
send_message('seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' %
(repo_id, shared_by, dir_id, total_size))
except Exception, e:
logger.error('Error when sending dir-download message: %s' % str(e))
else:
return render_error(request, _(u'Unable to download "%s"') % dirname )
url = gen_file_get_url(token, dirname)
return redirect(url)

View File

@@ -631,17 +631,20 @@ def _download_file_from_share_link(request, fileshare):
repo = get_repo(fileshare.repo_id)
if not repo:
raise Http404
share_path = fileshare.path # path for dir share or file share
req_path = request.GET.get('p', '') # path for download file
if req_path:
if not req_path.startswith(share_path):
# permission check
# Construct real file path if download file in shared dir, otherwise, just
# use path in DB.
if isinstance(fileshare, FileShare) and fileshare.is_dir_share_link():
req_path = request.GET.get('p', '')
if not req_path:
messages.error(request, _(u'Unable to download file, invalid file path'))
return HttpResponseRedirect(next)
real_path = posixpath.join(fileshare.path, req_path.lstrip('/'))
else:
real_path = fileshare.path
path = req_path if req_path else share_path
filename = os.path.basename(path)
obj_id = seafile_api.get_file_id_by_path(repo.id, path)
filename = os.path.basename(real_path)
obj_id = seafile_api.get_file_id_by_path(repo.id, real_path)
if not obj_id:
messages.error(request, _(u'Unable to download file, wrong file path'))
return HttpResponseRedirect(next)
@@ -651,7 +654,7 @@ def _download_file_from_share_link(request, fileshare):
messages.error(request, _(u'Unable to download file, share link traffic is used up.'))
return HttpResponseRedirect(next)
send_file_download_msg(request, repo, path, 'share-link')
send_file_download_msg(request, repo, real_path, 'share-link')
try:
file_size = seafile_api.get_file_size(repo.store_id, repo.version,
obj_id)
@@ -845,19 +848,27 @@ def view_file_via_shared_dir(request, token):
if not repo:
raise Http404
path = request.GET.get('p', '').rstrip('/')
if not path:
# Get file path from frontend, and construct request file path
# with fileshare.path to real path, used to fetch file content by RPC.
req_path = request.GET.get('p', '').rstrip('/')
if not req_path:
raise Http404
if not path.startswith(fileshare.path): # Can not view upper dir of shared dir
raise Http404
zipped = gen_path_link(path, repo.name)
obj_id = seafile_api.get_file_id_by_path(repo_id, path)
real_path = posixpath.join(fileshare.path, req_path.lstrip('/'))
# generate dir navigator
# generate dir navigator
if fileshare.path == '/':
zipped = gen_path_link(req_path, repo.name)
else:
zipped = gen_path_link(req_path, os.path.basename(fileshare.path[:-1]))
obj_id = seafile_api.get_file_id_by_path(repo_id, real_path)
if not obj_id:
return render_error(request, _(u'File does not exist'))
file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)
filename = os.path.basename(path)
filename = os.path.basename(req_path)
filetype, fileext = get_file_type_and_ext(filename)
access_token = seafile_api.get_fileserver_access_token(repo.id, obj_id,
'view', '', use_onetime=False)
@@ -887,7 +898,7 @@ def view_file_via_shared_dir(request, token):
handle_pdf(inner_path, obj_id, fileext, ret_dict)
elif filetype == IMAGE:
current_commit = get_commits(repo_id, 0, 1)[0]
parent_dir = os.path.dirname(path)
parent_dir = os.path.dirname(req_path)
dirs = seafile_api.list_dir_by_commit_and_path(current_commit.repo_id,
current_commit.id, parent_dir)
if not dirs:
@@ -922,7 +933,8 @@ def view_file_via_shared_dir(request, token):
return render_to_response('shared_file_view.html', {
'repo': repo,
'obj_id': obj_id,
'path': path,
'from_shared_dir': True,
'path': req_path,
'file_name': filename,
'file_size': file_size,
'shared_token': token,

View File

@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import os
import posixpath
import logging
from django.core.urlresolvers import reverse
@@ -34,7 +35,7 @@ from seahub.utils import gen_file_upload_url, is_org_context, \
from seahub.settings import ENABLE_SUB_LIBRARY, FORCE_SERVER_CRYPTO, \
ENABLE_UPLOAD_FOLDER, \
ENABLE_THUMBNAIL, THUMBNAIL_ROOT, THUMBNAIL_DEFAULT_SIZE, PREVIEW_DEFAULT_SIZE
from seahub.utils import gen_file_get_url
from seahub.utils.file_types import IMAGE
from seahub.thumbnail.utils import get_thumbnail_src, allow_generate_thumbnail
@@ -359,6 +360,43 @@ def repo_history_view(request, repo_id):
}, context_instance=RequestContext(request))
########## shared dir/uploadlink
def _download_dir_from_share_link(request, fileshare, repo, real_path):
# check whether owner's traffic over the limit
if user_traffic_over_limit(fileshare.username):
return render_error(
request, _(u'Unable to access file: share link traffic is used up.'))
shared_by = fileshare.username
if fileshare.path == '/':
dirname = repo.name
else:
dirname = os.path.basename(real_path.rstrip('/'))
dir_id = seafile_api.get_dir_id_by_path(repo.id, real_path)
try:
total_size = seaserv.seafserv_threaded_rpc.get_dir_size(
repo.store_id, repo.version, dir_id)
except Exception as e:
logger.error(str(e))
return render_error(request, _(u'Internal Error'))
if total_size > seaserv.MAX_DOWNLOAD_DIR_SIZE:
return render_error(request, _(u'Unable to download directory "%s": size is too large.') % dirname)
token = seafile_api.get_fileserver_access_token(repo.id,
dir_id,
'download-dir',
request.user.username)
try:
seaserv.send_message('seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' %
(repo.id, shared_by, dir_id, total_size))
except Exception as e:
logger.error('Error when sending dir-download message: %s' % str(e))
return HttpResponseRedirect(gen_file_get_url(token, dirname))
def view_shared_dir(request, token):
assert token is not None # Checked by URLconf
@@ -387,13 +425,19 @@ def view_shared_dir(request, token):
username = fileshare.username
repo_id = fileshare.repo_id
path = request.GET.get('p', '')
path = fileshare.path if not path else path
if path[-1] != '/': # Normalize dir path
path += '/'
if not path.startswith(fileshare.path):
path = fileshare.path # Can not view upper dir of shared dir
# Get path from frontend, use '/' if missing, and construct request path
# with fileshare.path to real path, used to fetch dirents by RPC.
req_path = request.GET.get('p', '/')
if req_path[-1] != '/':
req_path += '/'
if req_path == '/':
real_path = fileshare.path
else:
real_path = posixpath.join(fileshare.path, req_path.lstrip('/'))
if real_path[-1] != '/': # Normalize dir path
real_path += '/'
repo = get_repo(repo_id)
if not repo:
@@ -403,17 +447,28 @@ def view_shared_dir(request, token):
if not seafile_api.get_dir_id_by_path(repo.id, fileshare.path):
return render_error(request, _('"%s" does not exist.') % fileshare.path)
if path == '/':
# download shared dir
if request.GET.get('dl', '') == '1':
return _download_dir_from_share_link(request, fileshare, repo,
real_path)
if fileshare.path == '/':
# use repo name as dir name if share whole library
dir_name = repo.name
else:
dir_name = os.path.basename(path[:-1])
dir_name = os.path.basename(real_path[:-1])
current_commit = seaserv.get_commits(repo_id, 0, 1)[0]
file_list, dir_list, dirent_more = get_repo_dirents(request, repo,
current_commit, path)
zipped = gen_path_link(path, repo.name)
current_commit, real_path)
if path == fileshare.path: # When user view the shared dir..
# generate dir navigator
if fileshare.path == '/':
zipped = gen_path_link(req_path, repo.name)
else:
zipped = gen_path_link(req_path, os.path.basename(fileshare.path[:-1]))
if req_path == '/': # When user view the root of shared dir..
# increase shared link view_cnt,
fileshare = FileShare.objects.get(token=token)
fileshare.view_cnt = F('view_cnt') + 1
@@ -430,7 +485,7 @@ def view_shared_dir(request, token):
return render_to_response('view_shared_dir.html', {
'repo': repo,
'token': token,
'path': path,
'path': req_path,
'username': username,
'dir_name': dir_name,
'file_list': file_list,

View File

@@ -1,3 +1,4 @@
import os
from django.core.urlresolvers import reverse
from django.test import TestCase
@@ -24,21 +25,19 @@ class SharedFileTest(TestCase, Fixtures):
resp = self.client.get(reverse('view_shared_file', args=[self.fs.token]))
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed(resp, 'shared_file_view.html')
self.assertContains(resp, self.file)
dl_url_param = '?p=%s&dl=1' % self.file
self.assertContains(resp, dl_url_param)
self.assertContains(resp, os.path.basename(self.file))
dl_url_tag = '<a href="?dl=1" class="obv-btn">'
self.assertContains(resp, dl_url_tag)
def test_can_download(self):
dl_url = reverse('view_shared_file', args=[self.fs.token]) + \
'?p=%s&dl=1' % self.file
dl_url = reverse('view_shared_file', args=[self.fs.token]) + '?dl=1'
resp = self.client.get(dl_url)
self.assertEqual(302, resp.status_code)
assert '8082/files/' in resp.get('location')
def test_can_view_raw(self):
dl_url = reverse('view_shared_file', args=[self.fs.token]) + \
'?p=%s&raw=1' % self.file
dl_url = reverse('view_shared_file', args=[self.fs.token]) + '?raw=1'
resp = self.client.get(dl_url)
self.assertEqual(302, resp.status_code)
assert '8082/files/' in resp.get('location')
@@ -65,10 +64,10 @@ class FileViaSharedDirTest(TestCase, Fixtures):
)
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed(resp, 'shared_file_view.html')
self.assertContains(resp, self.file)
dl_url_param = '?p=%s&dl=1' % self.file
self.assertContains(resp, dl_url_param)
self.assertContains(resp, os.path.basename(self.file))
dl_url_tag = '<a href="?p=%s&dl=1" class="obv-btn">' % self.file
self.assertContains(resp, dl_url_tag)
def test_can_download(self):
dl_url = reverse('view_file_via_shared_dir', args=[self.fs.token]) + \