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:
@@ -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
|
||||
|
@@ -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' %}
|
||||
|
@@ -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>
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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]) + \
|
Reference in New Issue
Block a user