1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-09 10:50:24 +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.copy_move_task import CopyMoveTaskView
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.invitation import InvitationView
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/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/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/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'),