mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-20 07:55:06 +00:00
add download multi dirents api
This commit is contained in:
parent
5a52ad7168
commit
419645fdc2
88
seahub/api2/endpoints/dirents_download_link.py
Normal file
88
seahub/api2/endpoints/dirents_download_link.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import logging
|
||||||
|
import json
|
||||||
|
import posixpath
|
||||||
|
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
|
from seahub.api2.utils import api_error
|
||||||
|
|
||||||
|
from seahub.utils import string2list, get_fileserver_root
|
||||||
|
from seahub.views import check_folder_permission
|
||||||
|
from seahub.views.file import send_file_access_msg
|
||||||
|
|
||||||
|
from seaserv import seafile_api
|
||||||
|
from pysearpc import SearpcError
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class DirentsDownloadLinkView(APIView):
|
||||||
|
"""
|
||||||
|
Download multi files/dirs.
|
||||||
|
"""
|
||||||
|
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
permission_classes = (IsAuthenticated, )
|
||||||
|
throttle_classes = (UserRateThrottle, )
|
||||||
|
|
||||||
|
def get(self, request, repo_id, format=None):
|
||||||
|
|
||||||
|
repo = seafile_api.get_repo(repo_id)
|
||||||
|
if not repo:
|
||||||
|
error_msg = 'Library %s not found.' % repo_id
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
|
# argument checking
|
||||||
|
parent_dir = request.GET.get('parent_dir', None)
|
||||||
|
dirent_name_string = request.GET.get('dirents', None)
|
||||||
|
|
||||||
|
if not parent_dir:
|
||||||
|
error_msg = 'parent_dir invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
if not dirent_name_string:
|
||||||
|
error_msg = 'dirents invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
# folder exist checking
|
||||||
|
if not seafile_api.get_dir_id_by_path(repo_id, parent_dir):
|
||||||
|
error_msg = 'Folder %s not found.' % parent_dir
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
|
# permission checking
|
||||||
|
if check_folder_permission(request, repo_id, parent_dir) is None:
|
||||||
|
error_msg = 'Permission denied.'
|
||||||
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||||
|
|
||||||
|
dirent_name_list = string2list(dirent_name_string)
|
||||||
|
dirent_list = []
|
||||||
|
for dirent_name in dirent_name_list:
|
||||||
|
dirent_list.append(dirent_name.strip('/'))
|
||||||
|
|
||||||
|
fake_obj_id = {}
|
||||||
|
fake_obj_id['file_list'] = dirent_list
|
||||||
|
fake_obj_id['parent_dir'] = parent_dir
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
try:
|
||||||
|
token = seafile_api.get_fileserver_access_token(repo_id,
|
||||||
|
json.dumps(fake_obj_id), 'download-multi', username, False)
|
||||||
|
except SearpcError as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
if len(dirent_list) > 10:
|
||||||
|
send_file_access_msg(request, repo, parent_dir, 'web')
|
||||||
|
else:
|
||||||
|
for dirent_name in dirent_list:
|
||||||
|
full_dirent_path = posixpath.join(parent_dir, dirent_name)
|
||||||
|
send_file_access_msg(request, repo, full_dirent_path, 'web')
|
||||||
|
|
||||||
|
download_url = '%s/files/%s' % (get_fileserver_root(), token)
|
||||||
|
return Response({'url': download_url})
|
@ -99,6 +99,7 @@
|
|||||||
<button id="mv-dirents" title="{% trans 'Move' %}" class="op-btn sf2-icon-move op-icon"></button>
|
<button id="mv-dirents" title="{% trans 'Move' %}" class="op-btn sf2-icon-move op-icon"></button>
|
||||||
<button id="cp-dirents" title="{% trans 'Copy' %}" class="op-btn sf2-icon-copy op-icon"></button>
|
<button id="cp-dirents" title="{% trans 'Copy' %}" class="op-btn sf2-icon-copy op-icon"></button>
|
||||||
<button id="del-dirents" title="{% trans 'Delete' %}" class="op-btn sf2-icon-delete op-icon"></button>
|
<button id="del-dirents" title="{% trans 'Delete' %}" class="op-btn sf2-icon-delete op-icon"></button>
|
||||||
|
<button id="download-dirents" title="{% trans 'Download' %}" class="op-btn sf2-icon-download op-icon"></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="basic-upload" class="inline-block">
|
<div id="basic-upload" class="inline-block">
|
||||||
<button class="op-btn basic-upload-btn" >{% trans "Upload" %}</button>
|
<button class="op-btn basic-upload-btn" >{% trans "Upload" %}</button>
|
||||||
|
@ -24,6 +24,7 @@ from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink
|
|||||||
from seahub.api2.endpoints.file import FileView
|
from seahub.api2.endpoints.file import FileView
|
||||||
from seahub.api2.endpoints.dir import DirView
|
from seahub.api2.endpoints.dir import DirView
|
||||||
from seahub.api2.endpoints.repo_set_password import RepoSetPassword
|
from seahub.api2.endpoints.repo_set_password import RepoSetPassword
|
||||||
|
from seahub.api2.endpoints.dirents_download_link import DirentsDownloadLinkView
|
||||||
from seahub.api2.endpoints.admin.login import Login
|
from seahub.api2.endpoints.admin.login import Login
|
||||||
from seahub.api2.endpoints.admin.file_audit import FileAudit
|
from seahub.api2.endpoints.admin.file_audit import FileAudit
|
||||||
from seahub.api2.endpoints.admin.file_update import FileUpdate
|
from seahub.api2.endpoints.admin.file_update import FileUpdate
|
||||||
@ -189,8 +190,9 @@ urlpatterns = patterns(
|
|||||||
url(r'^api/v2.1/share-link/(?P<token>[a-f0-9]{10})/$', ShareLink.as_view(), name='api-v2.1-share-link'),
|
url(r'^api/v2.1/share-link/(?P<token>[a-f0-9]{10})/$', ShareLink.as_view(), name='api-v2.1-share-link'),
|
||||||
url(r'^api/v2.1/upload-links/$', UploadLinks.as_view(), name='api-v2.1-upload-links'),
|
url(r'^api/v2.1/upload-links/$', UploadLinks.as_view(), name='api-v2.1-upload-links'),
|
||||||
url(r'^api/v2.1/upload-link/(?P<token>[a-f0-9]{10})/$', UploadLink.as_view(), name='api-v2.1-upload-link'),
|
url(r'^api/v2.1/upload-link/(?P<token>[a-f0-9]{10})/$', UploadLink.as_view(), name='api-v2.1-upload-link'),
|
||||||
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9-a-f]{36})/file/$', FileView.as_view(), name='api-v2.1-file-view'),
|
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/$', FileView.as_view(), name='api-v2.1-file-view'),
|
||||||
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9-a-f]{36})/dir/$', DirView.as_view(), name='api-v2.1-dir-view'),
|
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/dirents/download-link/$', DirentsDownloadLinkView.as_view(), name='api-v2.1-dirents-download-link-view'),
|
||||||
|
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/dir/$', DirView.as_view(), name='api-v2.1-dir-view'),
|
||||||
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/set-password/$', RepoSetPassword.as_view(), name="api-v2.1-repo-set-password"),
|
url(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/set-password/$', RepoSetPassword.as_view(), name="api-v2.1-repo-set-password"),
|
||||||
url(r'^api/v2.1/admin/sysinfo/$', SysInfo.as_view(), name='api-v2.1-sysinfo'),
|
url(r'^api/v2.1/admin/sysinfo/$', SysInfo.as_view(), name='api-v2.1-sysinfo'),
|
||||||
url(r'^api/v2.1/admin/devices/$', AdminDevices.as_view(), name='api-v2.1-admin-devices'),
|
url(r'^api/v2.1/admin/devices/$', AdminDevices.as_view(), name='api-v2.1-admin-devices'),
|
||||||
|
@ -466,6 +466,7 @@ define([
|
|||||||
'click #mv-dirents': 'mv',
|
'click #mv-dirents': 'mv',
|
||||||
'click #cp-dirents': 'cp',
|
'click #cp-dirents': 'cp',
|
||||||
'click #del-dirents': 'del',
|
'click #del-dirents': 'del',
|
||||||
|
'click #download-dirents': 'download',
|
||||||
'click .by-name': 'sortByName',
|
'click .by-name': 'sortByName',
|
||||||
'click .by-time': 'sortByTime',
|
'click .by-time': 'sortByTime',
|
||||||
'click .basic-upload-btn': 'uploadFile',
|
'click .basic-upload-btn': 'uploadFile',
|
||||||
@ -799,6 +800,30 @@ define([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
download: function () {
|
||||||
|
var dirents = this.dir,
|
||||||
|
selected_dirents = dirents.where({'selected':true}),
|
||||||
|
selected_names = '';
|
||||||
|
|
||||||
|
$(selected_dirents).each(function() {
|
||||||
|
selected_names += this.get('obj_name') + ',';
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: Common.getUrl({
|
||||||
|
name: 'download_dirents',
|
||||||
|
repo_id: dirents.repo_id
|
||||||
|
}) + '?parent_dir=' + encodeURIComponent(dirents.path) + '&dirents=' + encodeURIComponent(selected_names),
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
location.href = data['url'];
|
||||||
|
},
|
||||||
|
error: function (xhr) {
|
||||||
|
Common.ajaxErrorHandler(xhr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
del: function () {
|
del: function () {
|
||||||
var dirents = this.dir;
|
var dirents = this.dir;
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
@ -80,6 +80,7 @@ define([
|
|||||||
case 'unstar_file': return siteRoot + 'ajax/repo/' + options.repo_id + '/file/unstar/';
|
case 'unstar_file': return siteRoot + 'ajax/repo/' + options.repo_id + '/file/unstar/';
|
||||||
case 'del_dir': return siteRoot + 'api2/repos/' + options.repo_id + '/dir/';
|
case 'del_dir': return siteRoot + 'api2/repos/' + options.repo_id + '/dir/';
|
||||||
case 'del_file': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
|
case 'del_file': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
|
||||||
|
case 'download_dirents': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/dirents/download-link/';
|
||||||
case 'rename_dir': return siteRoot + 'api2/repos/' + options.repo_id + '/dir/';
|
case 'rename_dir': return siteRoot + 'api2/repos/' + options.repo_id + '/dir/';
|
||||||
case 'rename_file': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
|
case 'rename_file': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
|
||||||
case 'mv_dir': return siteRoot + 'ajax/repo/' + options.repo_id + '/dir/mv/';
|
case 'mv_dir': return siteRoot + 'ajax/repo/' + options.repo_id + '/dir/mv/';
|
||||||
|
66
tests/api/endpoints/test_dirents_download_link.py
Normal file
66
tests/api/endpoints/test_dirents_download_link.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
|
||||||
|
try:
|
||||||
|
from seahub.settings import LOCAL_PRO_DEV_ENV
|
||||||
|
except ImportError:
|
||||||
|
LOCAL_PRO_DEV_ENV = False
|
||||||
|
|
||||||
|
|
||||||
|
class DirentsDownloadLinkViewTest(BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.repo_id = self.repo.id
|
||||||
|
|
||||||
|
self.file_path = self.file
|
||||||
|
self.file_name = os.path.basename(self.file_path)
|
||||||
|
|
||||||
|
self.folder_path = self.folder
|
||||||
|
self.folder_name = os.path.basename(self.folder_path)
|
||||||
|
|
||||||
|
self.url = reverse('api-v2.1-dirents-download-link-view', args=[self.repo_id])
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.remove_repo()
|
||||||
|
|
||||||
|
def test_can_get_download_url(self):
|
||||||
|
self.login_as(self.user)
|
||||||
|
parent_dir = '/'
|
||||||
|
dirents = self.file_name + ',' + self.folder_name
|
||||||
|
url = self.url + '?parent_dir=%s&dirents=%s' % (parent_dir, dirents)
|
||||||
|
|
||||||
|
resp = self.client.get(url)
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert '8082' in json_resp['url']
|
||||||
|
|
||||||
|
def test_args_invalid(self):
|
||||||
|
self.login_as(self.user)
|
||||||
|
parent_dir = '/'
|
||||||
|
dirents = self.file_name + ',' + self.folder_name
|
||||||
|
|
||||||
|
url = self.url + '?prent_dir=%s&dirents=%s' % (parent_dir, dirents)
|
||||||
|
resp = self.client.get(url)
|
||||||
|
self.assertEqual(400, resp.status_code)
|
||||||
|
|
||||||
|
url = self.url + '?parent_dir=%s&dirent=%s' % (parent_dir, dirents)
|
||||||
|
resp = self.client.get(url)
|
||||||
|
self.assertEqual(400, resp.status_code)
|
||||||
|
|
||||||
|
url = self.url + '?parent_dir=%s&dirents=%s' % (parent_dir+'invalid', dirents)
|
||||||
|
resp = self.client.get(url)
|
||||||
|
self.assertEqual(404, resp.status_code)
|
||||||
|
|
||||||
|
def test_permission_invalid(self):
|
||||||
|
self.login_as(self.admin)
|
||||||
|
parent_dir = '/'
|
||||||
|
dirents = self.file_name + ',' + self.folder_name
|
||||||
|
|
||||||
|
url = self.url + '?parent_dir=%s&dirents=%s' % (parent_dir, dirents)
|
||||||
|
resp = self.client.get(url)
|
||||||
|
self.assertEqual(403, resp.status_code)
|
Loading…
Reference in New Issue
Block a user