1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-03 16:10:26 +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 return True if self.s_type == 'f' else False
def is_dir_share_link(self): 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): def is_encrypted(self):
return True if self.password is not None else False return True if self.password is not None else False

View File

@@ -33,7 +33,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if not traffic_over_limit %} {% 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 %} {% endif %}
</div> </div>
{% include 'snippets/file_content_html.html' %} {% include 'snippets/file_content_html.html' %}

View File

@@ -6,6 +6,7 @@
{% block main_panel %} {% block main_panel %}
<h2>{{ dir_name }}</h2> <h2>{{ dir_name }}</h2>
<p>{% trans "Shared by: " %}{{ username|email2nickname }}</p> <p>{% trans "Shared by: " %}{{ username|email2nickname }}</p>
<div class="repo-file-list-outer-container"> <div class="repo-file-list-outer-container">
<div class="repo-file-list-inner-container"> <div class="repo-file-list-inner-container">
<div class="repo-file-list-topbar ovhd"> <div class="repo-file-list-topbar ovhd">
@@ -13,14 +14,14 @@
{% trans "Current path: "%} {% trans "Current path: "%}
{% for name, link in zipped %} {% for name, link in zipped %}
{% if not forloop.last %} {% 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 %} {% else %}
{{ name }} {{ name }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</p> </p>
{% if not traffic_over_limit %} {% 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 %} {% endif %}
</div> </div>
<table class="repo-file-list" style="table-layout:fixed;"> <table class="repo-file-list" style="table-layout:fixed;">
@@ -35,13 +36,13 @@
<tr> <tr>
<td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td> <td class="alc"><img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans "Directory icon"%}" /></td>
<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> <td></td>
<td> <td>
{% if not traffic_over_limit %} {% 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="" /> <img src="{{MEDIA_URL}}img/download.png" alt="" />
</a> </a>
{% endif %} {% endif %}
@@ -62,7 +63,7 @@
{% endif %} {% endif %}
<td> <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>
<td>{{ dirent.file_size|filesizeformat }}</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) res.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang, max_age=30*24*60*60)
return res return res
@login_required
def repo_download_dir(request, repo_id): def repo_download_dir(request, repo_id):
repo = get_repo(repo_id) repo = get_repo(repo_id)
if not repo: if not repo:
@@ -1827,30 +1828,8 @@ def repo_download_dir(request, repo_id):
else: else:
dirname = repo.name dirname = repo.name
allow_download = False allow_download = True if check_repo_access_permission(
fileshare_token = request.GET.get('t', '') repo_id, request.user) else False
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.'))
if allow_download: if allow_download:
dir_id = seafserv_threaded_rpc.get_dirid_by_path (repo.id, dir_id = seafserv_threaded_rpc.get_dirid_by_path (repo.id,
repo.head_cmmt_id, repo.head_cmmt_id,
@@ -1871,16 +1850,9 @@ def repo_download_dir(request, repo_id):
'download-dir', 'download-dir',
request.user.username) 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: else:
return render_error(request, _(u'Unable to download "%s"') % dirname ) return render_error(request, _(u'Unable to download "%s"') % dirname )
url = gen_file_get_url(token, dirname) url = gen_file_get_url(token, dirname)
return redirect(url) return redirect(url)

View File

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

View File

@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import posixpath
import logging import logging
from django.core.urlresolvers import reverse 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, \ from seahub.settings import ENABLE_SUB_LIBRARY, FORCE_SERVER_CRYPTO, \
ENABLE_UPLOAD_FOLDER, \ ENABLE_UPLOAD_FOLDER, \
ENABLE_THUMBNAIL, THUMBNAIL_ROOT, THUMBNAIL_DEFAULT_SIZE, PREVIEW_DEFAULT_SIZE 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.utils.file_types import IMAGE
from seahub.thumbnail.utils import get_thumbnail_src, allow_generate_thumbnail 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)) }, context_instance=RequestContext(request))
########## shared dir/uploadlink ########## 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): def view_shared_dir(request, token):
assert token is not None # Checked by URLconf assert token is not None # Checked by URLconf
@@ -387,13 +425,19 @@ def view_shared_dir(request, token):
username = fileshare.username username = fileshare.username
repo_id = fileshare.repo_id 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): # Get path from frontend, use '/' if missing, and construct request path
path = fileshare.path # Can not view upper dir of shared dir # 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) repo = get_repo(repo_id)
if not repo: 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): if not seafile_api.get_dir_id_by_path(repo.id, fileshare.path):
return render_error(request, _('"%s" does not exist.') % 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 dir_name = repo.name
else: 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] current_commit = seaserv.get_commits(repo_id, 0, 1)[0]
file_list, dir_list, dirent_more = get_repo_dirents(request, repo, file_list, dir_list, dirent_more = get_repo_dirents(request, repo,
current_commit, path) current_commit, real_path)
zipped = gen_path_link(path, repo.name)
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, # increase shared link view_cnt,
fileshare = FileShare.objects.get(token=token) fileshare = FileShare.objects.get(token=token)
fileshare.view_cnt = F('view_cnt') + 1 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', { return render_to_response('view_shared_dir.html', {
'repo': repo, 'repo': repo,
'token': token, 'token': token,
'path': path, 'path': req_path,
'username': username, 'username': username,
'dir_name': dir_name, 'dir_name': dir_name,
'file_list': file_list, 'file_list': file_list,

View File

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