def post(self, request, repo_id, format=None): """Post a comments of a file. """ # argument check path = request.GET.get('p', '/').rstrip('/') if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') comment = request.data.get('comment', '') if not comment: return api_error(status.HTTP_400_BAD_REQUEST, 'Comment can not be empty.') try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE # resource check try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') if not file_id: return api_error(status.HTTP_404_NOT_FOUND, 'File not found.') # permission check if check_folder_permission(request, repo_id, '/') is None: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') detail = request.data.get('detail', '') username = request.user.username file_comment = FileComment.objects.add_by_file_path( repo_id=repo_id, file_path=path, author=username, comment=comment, detail=detail) repo = seafile_api.get_repo(repo_id) repo_owner = get_repo_owner(request, repo.id) if is_draft_file(repo_id, path): draft = Draft.objects.filter(origin_repo_id=repo_id, draft_file_path=path) if draft: draft = draft[0] comment_draft_successful.send(sender=None, draft=draft, comment=comment, author=username) else: Draft.DoesNotExist else: comment_file_successful.send(sender=None, repo=repo, repo_owner=repo_owner, file_path=path, comment=comment, author=username) comment = file_comment.to_dict() comment.update(user_to_dict(username, request=request, avatar_size=avatar_size)) return Response(comment, status=201)
def post(self, request, repo_id, format=None): """Post a comments of a file. """ # argument check path = request.GET.get('p', '/').rstrip('/') if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') comment = request.data.get('comment', '') if not comment: return api_error(status.HTTP_400_BAD_REQUEST, 'Comment can not be empty.') try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE # resource check try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal error.') if not file_id: return api_error(status.HTTP_404_NOT_FOUND, 'File not found.') # permission check if check_folder_permission(request, repo_id, '/') is None: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') detail = request.data.get('detail', '') username = request.user.username file_comment = FileComment.objects.add_by_file_path( repo_id=repo_id, file_path=path, author=username, comment=comment, detail=detail) repo = seafile_api.get_repo(repo_id) repo_owner = get_repo_owner(request, repo.id) if is_draft_file(repo_id, path): draft = Draft.objects.get(origin_repo_id=repo_id, draft_file_path=path) comment_draft_successful.send(sender=None, draft=draft, comment=comment, author=username) else: comment_file_successful.send(sender=None, repo=repo, repo_owner=repo_owner, file_path=path, comment=comment, author=username) comment = file_comment.to_dict() comment.update(user_to_dict(username, request=request, avatar_size=avatar_size)) return Response(comment, status=201)
class FileView(APIView): """ Support uniform interface for file related operations, including create/delete/rename/view, etc. """ authentication_classes = (TokenAuthentication, SessionAuthentication) permission_classes = (IsAuthenticated, ) throttle_classes = (UserRateThrottle, ) def get_file_info(self, username, repo_id, file_path): repo = seafile_api.get_repo(repo_id) file_obj = seafile_api.get_dirent_by_path(repo_id, file_path) file_name = file_obj.obj_name file_size = file_obj.size can_preview, error_msg = can_preview_file(file_name, file_size, repo) can_edit, error_msg = can_edit_file(file_name, file_size, repo) try: is_locked, locked_by_me = check_file_lock(repo_id, file_path, username) except Exception as e: logger.error(e) is_locked = False file_info = { 'type': 'file', 'repo_id': repo_id, 'parent_dir': os.path.dirname(file_path), 'obj_name': file_name, 'obj_id': file_obj.obj_id, 'size': file_size, 'mtime': timestamp_to_isoformat_timestr(file_obj.mtime), 'is_locked': is_locked, 'can_preview': can_preview, 'can_edit': can_edit, } return file_info def get(self, request, repo_id, format=None): """ Get file info. Permission checking: 1. user with either 'r' or 'rw' permission. """ # argument check path = request.GET.get('p', None) if not path: error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check 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) try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check parent_dir = os.path.dirname(path) if check_folder_permission(request, repo_id, parent_dir) is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) file_info = self.get_file_info(request.user.username, repo_id, path) return Response(file_info) def post(self, request, repo_id, format=None): """ Create, rename, move, copy, revert file Permission checking: 1. create: user with 'rw' permission for current parent dir; 2. rename: user with 'rw' permission for current file; 3. move : user with 'rw' permission for current file, 'rw' permission for dst parent dir; 4. copy : user with 'r' permission for current file, 'rw' permission for dst parent dir; 4. revert: user with 'rw' permission for current file's parent dir; """ # argument check path = request.GET.get('p', None) if not path: error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = normalize_file_path(path) operation = request.data.get('operation', None) if not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('create', 'rename', 'move', 'copy', 'revert'): error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check 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) username = request.user.username parent_dir = os.path.dirname(path) if operation == 'create': # resource check try: parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not parent_dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create new empty file new_file_name = os.path.basename(path) if not is_valid_dirent_name(new_file_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name) try: seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # update office file by template if new_file_name.endswith('.xlsx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx') elif new_file_name.endswith('.pptx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx') elif new_file_name.endswith('.docx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx') else: empty_file_path = '' if empty_file_path: # get file server update url update_token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'update', username) if not update_token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) update_url = gen_inner_file_upload_url('update-api', update_token) # update file new_file_path = posixpath.join(parent_dir, new_file_name) try: requests.post( update_url, data={'filename': new_file_name, 'target_file': new_file_path}, files={'file': open(empty_file_path, 'rb')} ) except Exception as e: logger.error(e) new_file_path = posixpath.join(parent_dir, new_file_name) file_info = self.get_file_info(username, repo_id, new_file_path) return Response(file_info) if operation == 'rename': # argument check new_file_name = request.data.get('newname', None) if not new_file_name: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_dirent_name(new_file_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') if len(new_file_name) > MAX_UPLOAD_FILE_NAME_LEN: error_msg = 'newname is too long.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) oldname = os.path.basename(path) if oldname == new_file_name: error_msg = 'The new name is the same to the old' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check file lock try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_locked and not locked_by_me: error_msg = _("File is locked") return api_error(status.HTTP_403_FORBIDDEN, error_msg) # rename file new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name) try: seafile_api.rename_file(repo_id, parent_dir, oldname, new_file_name, username) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) new_file_path = posixpath.join(parent_dir, new_file_name) # rename draft file filetype, fileext = get_file_type_and_ext(new_file_name) if filetype == MARKDOWN or filetype == TEXT: is_draft, review_id, draft_id = is_draft_file(repo.id, path) if is_draft: try: draft = Draft.objects.get(pk=draft_id) draft.draft_file_path = new_file_path draft.save() except Draft.DoesNotExist: pass if review_id is not None: try: review = DraftReview.objects.get(pk=review_id, draft_id=draft) review.draft_file_path = new_file_path review.save() except DraftReview.DoesNotExist: pass file_info = self.get_file_info(username, repo_id, new_file_path) return Response(file_info) if operation == 'move': # argument check dst_repo_id = request.data.get('dst_repo', None) dst_dir = request.data.get('dst_dir', None) if not dst_repo_id: error_msg = 'dst_repo invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_dir = normalize_dir_path(dst_dir) # resource check for source file try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # resource check for dst repo and dir 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) dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir) if not dst_dir_id: error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check for source file src_repo_id = repo_id src_dir = os.path.dirname(path) if check_folder_permission(request, src_repo_id, src_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # permission check for dst dir if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check file lock try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_locked and not locked_by_me: error_msg = _("File is locked") return api_error(status.HTTP_403_FORBIDDEN, error_msg) # move file if src_repo_id == dst_repo_id and src_dir == dst_dir: file_info = self.get_file_info(username, repo_id, path) return Response(file_info) filename = os.path.basename(path) new_file_name = check_filename_with_rename(dst_repo_id, dst_dir, filename) try: seafile_api.move_file(src_repo_id, src_dir, filename, dst_repo_id, dst_dir, new_file_name, replace=False, username=username, need_progress=0, synchronous=1) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dst_file_path = posixpath.join(dst_dir, new_file_name) dst_file_info = self.get_file_info(username, dst_repo_id, dst_file_path) return Response(dst_file_info) if operation == 'copy': # argument check dst_repo_id = request.data.get('dst_repo', None) dst_dir = request.data.get('dst_dir', None) if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_dir = normalize_dir_path(dst_dir) # resource check for source file try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # resource check for dst repo and dir 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) dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir) if not dst_dir_id: error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check for source file src_repo_id = repo_id src_dir = os.path.dirname(path) if parse_repo_perm(check_folder_permission( request, src_repo_id, src_dir)).can_copy is False: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # permission check for dst dir if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) filename = os.path.basename(path) new_file_name = check_filename_with_rename(dst_repo_id, dst_dir, filename) try: seafile_api.copy_file(src_repo_id, src_dir, filename, dst_repo_id, dst_dir, new_file_name, username, 0, synchronous=1) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dst_file_path = posixpath.join(dst_dir, new_file_name) dst_file_info = self.get_file_info(username, dst_repo_id, dst_file_path) return Response(dst_file_info) if operation == 'revert': commit_id = request.data.get('commit_id', None) if not commit_id: error_msg = 'commit_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if seafile_api.get_file_id_by_path(repo_id, path): # file exists in repo if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check file lock try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_locked and not locked_by_me: error_msg = _("File is locked") return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: # file NOT exists in repo if check_folder_permission(request, repo_id, '/') != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.revert_file(repo_id, commit_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
def post(self, request, repo_id, format=None): """ Create, rename, move, copy, revert file Permission checking: 1. create: user with 'rw' permission for current parent dir; 2. rename: user with 'rw' permission for current file; 3. move : user with 'rw' permission for current file, 'rw' permission for dst parent dir; 4. copy : user with 'r' permission for current file, 'rw' permission for dst parent dir; 4. revert: user with 'rw' permission for current file's parent dir; """ # argument check path = request.GET.get('p', None) if not path: error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = normalize_file_path(path) operation = request.data.get('operation', None) if not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('create', 'rename', 'move', 'copy', 'revert'): error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check 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) username = request.user.username parent_dir = os.path.dirname(path) is_draft = request.POST.get('is_draft', '') if operation == 'create': # resource check try: parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not parent_dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if is_draft.lower() == 'true': file_name = os.path.basename(path) file_dir = os.path.dirname(path) draft_type = os.path.splitext(file_name)[0][-7:] file_type = os.path.splitext(file_name)[-1] if draft_type != '(draft)': f = os.path.splitext(file_name)[0] path = file_dir + '/' + f + '(draft)' + file_type # create new empty file new_file_name = os.path.basename(path) if not is_valid_dirent_name(new_file_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name) try: seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_draft.lower() == 'true': Draft.objects.add(username, repo, path, file_exist=False) # update office file by template if new_file_name.endswith('.xlsx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx') elif new_file_name.endswith('.pptx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx') elif new_file_name.endswith('.docx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx') else: empty_file_path = '' if empty_file_path: # get file server update url update_token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'update', username) if not update_token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) update_url = gen_inner_file_upload_url('update-api', update_token) # update file new_file_path = posixpath.join(parent_dir, new_file_name) try: requests.post( update_url, data={'filename': new_file_name, 'target_file': new_file_path}, files={'file': open(empty_file_path, 'rb')} ) except Exception as e: logger.error(e) new_file_path = posixpath.join(parent_dir, new_file_name) file_info = self.get_file_info(username, repo_id, new_file_path) return Response(file_info) if operation == 'rename': # argument check new_file_name = request.data.get('newname', None) if not new_file_name: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_dirent_name(new_file_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') if len(new_file_name) > MAX_UPLOAD_FILE_NAME_LEN: error_msg = 'newname is too long.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) oldname = os.path.basename(path) if oldname == new_file_name: error_msg = 'The new name is the same to the old' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check file lock try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_locked and not locked_by_me: error_msg = _("File is locked") return api_error(status.HTTP_403_FORBIDDEN, error_msg) # rename file new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name) try: seafile_api.rename_file(repo_id, parent_dir, oldname, new_file_name, username) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) new_file_path = posixpath.join(parent_dir, new_file_name) # rename draft file filetype, fileext = get_file_type_and_ext(new_file_name) if filetype == MARKDOWN or filetype == TEXT: is_draft = is_draft_file(repo.id, path) review = get_file_draft(repo.id, path, is_draft) draft_id = review['draft_id'] if is_draft: try: draft = Draft.objects.get(pk=draft_id) draft.draft_file_path = new_file_path draft.save() except Draft.DoesNotExist: pass file_info = self.get_file_info(username, repo_id, new_file_path) return Response(file_info) if operation == 'move': # argument check dst_repo_id = request.data.get('dst_repo', None) dst_dir = request.data.get('dst_dir', None) if not dst_repo_id: error_msg = 'dst_repo invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_dir = normalize_dir_path(dst_dir) # resource check for source file try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # resource check for dst repo and dir 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) dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir) if not dst_dir_id: error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check for source file src_repo_id = repo_id src_dir = os.path.dirname(path) if check_folder_permission(request, src_repo_id, src_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # permission check for dst dir if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check file lock try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_locked and not locked_by_me: error_msg = _("File is locked") return api_error(status.HTTP_403_FORBIDDEN, error_msg) # move file if src_repo_id == dst_repo_id and src_dir == dst_dir: file_info = self.get_file_info(username, repo_id, path) return Response(file_info) filename = os.path.basename(path) new_file_name = check_filename_with_rename(dst_repo_id, dst_dir, filename) try: seafile_api.move_file(src_repo_id, src_dir, filename, dst_repo_id, dst_dir, new_file_name, replace=False, username=username, need_progress=0, synchronous=1) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dst_file_path = posixpath.join(dst_dir, new_file_name) dst_file_info = self.get_file_info(username, dst_repo_id, dst_file_path) return Response(dst_file_info) if operation == 'copy': # argument check dst_repo_id = request.data.get('dst_repo', None) dst_dir = request.data.get('dst_dir', None) if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_dir = normalize_dir_path(dst_dir) # resource check for source file try: file_id = seafile_api.get_file_id_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not file_id: error_msg = 'File %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # resource check for dst repo and dir 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) dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir) if not dst_dir_id: error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check for source file src_repo_id = repo_id src_dir = os.path.dirname(path) if parse_repo_perm(check_folder_permission( request, src_repo_id, src_dir)).can_copy is False: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # permission check for dst dir if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) filename = os.path.basename(path) new_file_name = check_filename_with_rename(dst_repo_id, dst_dir, filename) try: seafile_api.copy_file(src_repo_id, src_dir, filename, dst_repo_id, dst_dir, new_file_name, username, 0, synchronous=1) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dst_file_path = posixpath.join(dst_dir, new_file_name) dst_file_info = self.get_file_info(username, dst_repo_id, dst_file_path) return Response(dst_file_info) if operation == 'revert': commit_id = request.data.get('commit_id', None) if not commit_id: error_msg = 'commit_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if seafile_api.get_file_id_by_path(repo_id, path): # file exists in repo if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check file lock try: is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_locked and not locked_by_me: error_msg = _("File is locked") return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: # file NOT exists in repo if check_folder_permission(request, repo_id, '/') != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.revert_file(repo_id, commit_id, path, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})