1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-19 07:27:56 +00:00

add download multi dirents api

This commit is contained in:
lian 2016-04-28 15:16:58 +08:00
parent 5a52ad7168
commit 419645fdc2
6 changed files with 185 additions and 2 deletions

View 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})

View File

@ -99,6 +99,7 @@
<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="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 id="basic-upload" class="inline-block">
<button class="op-btn basic-upload-btn" >{% trans "Upload" %}</button>

View File

@ -24,6 +24,7 @@ from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink
from seahub.api2.endpoints.file import FileView
from seahub.api2.endpoints.dir import DirView
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.file_audit import FileAudit
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/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/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-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})/file/$', FileView.as_view(), name='api-v2.1-file-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/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'),

View File

@ -466,6 +466,7 @@ define([
'click #mv-dirents': 'mv',
'click #cp-dirents': 'cp',
'click #del-dirents': 'del',
'click #download-dirents': 'download',
'click .by-name': 'sortByName',
'click .by-time': 'sortByTime',
'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 () {
var dirents = this.dir;
var _this = this;

View File

@ -80,6 +80,7 @@ define([
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_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_file': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
case 'mv_dir': return siteRoot + 'ajax/repo/' + options.repo_id + '/dir/mv/';

View 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)