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:
181
seahub/api2/endpoints/move_folder_merge.py
Normal file
181
seahub/api2/endpoints/move_folder_merge.py
Normal 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})
|
@@ -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'),
|
||||
|
Reference in New Issue
Block a user