1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-10 11:21:29 +00:00

Merge pull request #2144 from haiwen/move-dir-merge

add move folder merge api
This commit is contained in:
zheng xie
2018-06-13 11:28:10 +08:00
committed by GitHub
2 changed files with 185 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
# Copyright (c) 2012-2018 Seafile Ltd.
import stat
import logging
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 django.utils.translation import ugettext as _
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.utils import api_error
from seahub.api2.views import HTTP_443_ABOVE_QUOTA
from seahub.views import check_folder_permission
from seahub.utils.repo import get_repo_owner
from seahub.settings import MAX_PATH
from seaserv import seafile_api
logger = logging.getLogger(__name__)
def get_dirent_name_list(username, repo_id, parent_path):
file_name_list = []
folder_name_list = []
path_id = seafile_api.get_dir_id_by_path(repo_id, parent_path)
dirs = seafile_api.list_dir_with_perm(repo_id, parent_path,
path_id, username, -1, -1)
for dirent in dirs:
if stat.S_ISDIR(dirent.mode):
folder_name_list.append(dirent.obj_name)
else:
file_name_list.append(dirent.obj_name)
return folder_name_list, file_name_list
def folder_name_duplicate(username, src_folder_name, dst_repo_id, dst_parent_dir):
dst_folder_name_list, dst_file_name_list = get_dirent_name_list(username,
dst_repo_id, dst_parent_dir)
if src_folder_name in dst_folder_name_list:
return True
else:
return False
def move_folder_with_merge(username,
src_repo_id, src_parent_dir, src_dirent_name,
dst_repo_id, dst_parent_dir, dst_dirent_name):
if folder_name_duplicate(username, src_dirent_name,
dst_repo_id, dst_parent_dir):
src_folder_path = posixpath.join(src_parent_dir, src_dirent_name)
dst_folder_path = posixpath.join(dst_parent_dir, dst_dirent_name)
src_sub_folder_name_list, src_sub_file_name_list = get_dirent_name_list(username,
src_repo_id, src_folder_path)
# for sub file, copy it directly
for src_sub_file_name in src_sub_file_name_list:
seafile_api.move_file(
src_repo_id, src_folder_path, src_sub_file_name,
dst_repo_id, dst_folder_path, src_sub_file_name,
replace=False, username=username, need_progress=0)
for src_sub_folder_name in src_sub_folder_name_list:
move_folder_with_merge(username,
src_repo_id, src_folder_path, src_sub_folder_name,
dst_repo_id, dst_folder_path, src_sub_folder_name)
else:
seafile_api.move_file(
src_repo_id, src_parent_dir, src_dirent_name,
dst_repo_id, dst_parent_dir, dst_dirent_name,
replace=False, username=username, need_progress=0)
class MoveFolderMergeView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle,)
def post(self, request):
""" Only support move folder.
Permission checking:
User with 'rw' permission for src/dst folder.
"""
src_repo_id = request.data.get('src_repo_id', None)
src_parent_dir = request.data.get('src_parent_dir', None)
src_folder_name = request.data.get('src_dirent_name', None)
dst_repo_id = request.data.get('dst_repo_id', None)
dst_parent_dir = request.data.get('dst_parent_dir', None)
# argument check
if not src_repo_id:
error_msg = 'src_repo_id invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not src_parent_dir:
error_msg = 'src_parent_dir invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not src_folder_name:
error_msg = 'src_dirent_name invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not dst_repo_id:
error_msg = 'dst_repo_id invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not dst_parent_dir:
error_msg = 'dst_parent_dir invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if src_repo_id == dst_repo_id and src_parent_dir == dst_parent_dir:
error_msg = _('Invalid destination path')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if len(dst_parent_dir + src_folder_name) > MAX_PATH:
error_msg = _('Destination path is too long.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# src resource check
src_repo = seafile_api.get_repo(src_repo_id)
if not src_repo:
error_msg = 'Library %s not found.' % src_repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
src_folder_path = posixpath.join(src_parent_dir, src_folder_name)
dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_folder_path)
if not dir_id:
error_msg = 'Folder %s not found.' % src_folder_path
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# dst resource check
dst_repo = seafile_api.get_repo(dst_repo_id)
if not dst_repo:
error_msg = 'Library %s not found.' % dst_repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_parent_dir):
error_msg = 'Folder %s not found.' % dst_parent_dir
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check for src folder
if check_folder_permission(request, src_repo_id, src_folder_path) != 'rw':
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# permission check for dst parent dir
if check_folder_permission(request, dst_repo_id, dst_parent_dir) != 'rw':
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
## check if above quota for dst repo
if get_repo_owner(request, src_repo_id) != get_repo_owner(request, dst_repo_id):
current_size = 0
current_size = seafile_api.get_dir_size(src_repo.store_id,
src_repo.version, dir_id)
if seafile_api.check_quota(dst_repo_id, current_size) < 0:
return api_error(HTTP_443_ABOVE_QUOTA, _(u"Out of quota."))
username = request.user.username
move_folder_with_merge(username,
src_repo_id, src_parent_dir, src_folder_name,
dst_repo_id, dst_parent_dir, src_folder_name)
seafile_api.del_file(src_repo_id, src_parent_dir, src_folder_name, username)
return Response({'success': True})

View File

@@ -46,6 +46,7 @@ from seahub.api2.endpoints.share_link_zip_task import ShareLinkZipTaskView
from seahub.api2.endpoints.query_zip_progress import QueryZipProgressView from seahub.api2.endpoints.query_zip_progress import QueryZipProgressView
from seahub.api2.endpoints.copy_move_task import CopyMoveTaskView from seahub.api2.endpoints.copy_move_task import CopyMoveTaskView
from seahub.api2.endpoints.query_copy_move_progress import QueryCopyMoveProgressView from seahub.api2.endpoints.query_copy_move_progress import QueryCopyMoveProgressView
from seahub.api2.endpoints.move_folder_merge import MoveFolderMergeView
from seahub.api2.endpoints.invitations import InvitationsView, InvitationsBatchView from seahub.api2.endpoints.invitations import InvitationsView, InvitationsBatchView
from seahub.api2.endpoints.invitation import InvitationView from seahub.api2.endpoints.invitation import InvitationView
from seahub.api2.endpoints.notifications import NotificationsView, NotificationView from seahub.api2.endpoints.notifications import NotificationsView, NotificationView
@@ -270,6 +271,9 @@ urlpatterns = patterns(
url(r'^api/v2.1/query-zip-progress/$', QueryZipProgressView.as_view(), name='api-v2.1-query-zip-progress'), url(r'^api/v2.1/query-zip-progress/$', QueryZipProgressView.as_view(), name='api-v2.1-query-zip-progress'),
url(r'^api/v2.1/copy-move-task/$', CopyMoveTaskView.as_view(), name='api-v2.1-copy-move-task'), url(r'^api/v2.1/copy-move-task/$', CopyMoveTaskView.as_view(), name='api-v2.1-copy-move-task'),
url(r'^api/v2.1/query-copy-move-progress/$', QueryCopyMoveProgressView.as_view(), name='api-v2.1-query-copy-move-progress'), url(r'^api/v2.1/query-copy-move-progress/$', QueryCopyMoveProgressView.as_view(), name='api-v2.1-query-copy-move-progress'),
url(r'^api/v2.1/move-folder-merge/$', MoveFolderMergeView.as_view(), name='api-v2.1-move-folder-merge'),
url(r'^api/v2.1/notifications/$', NotificationsView.as_view(), name='api-v2.1-notifications'), url(r'^api/v2.1/notifications/$', NotificationsView.as_view(), name='api-v2.1-notifications'),
url(r'^api/v2.1/notification/$', NotificationView.as_view(), name='api-v2.1-notification'), url(r'^api/v2.1/notification/$', NotificationView.as_view(), name='api-v2.1-notification'),
url(r'^api/v2.1/user-enabled-modules/$', UserEnabledModulesView.as_view(), name='api-v2.1-user-enabled-module'), url(r'^api/v2.1/user-enabled-modules/$', UserEnabledModulesView.as_view(), name='api-v2.1-user-enabled-module'),