def post(self, request, repo_id): resp = check_repo_access_permission(request, get_repo(repo_id)) if resp: return resp path = request.GET.get('p') newname = request.POST.get("newname") if not path or path[0] != '/' or not newname: return api_error(request, '400') newname = unquote(newname).decode('utf-8') if len(newname) > settings.MAX_UPLOAD_FILE_NAME_LEN: return api_error(request, '420', 'New name too long') parent_dir = os.path.dirname(path) oldname = os.path.basename(path) if oldname == newname: return api_error(request, '420', 'The new name is the same to the old') newname = check_filename_with_rename(repo_id, parent_dir, newname) try: seafserv_threaded_rpc.rename_file (repo_id, parent_dir, oldname, newname, request.user.username) except SearpcError,e: return api_error(request, '420', "SearpcError:" + e.msg)
def put(self, request, repo_id): """ Copy a single file/folder to other place. """ # check parameter for src path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: dirent = seafile_api.get_dirent_by_path(repo_id, path) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not dirent: error_msg = 'File or folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if path == '/': error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # normalize path to '/1/2/3' format # NOT ends with '/' path = normalize_file_path(path) # now get `src_dir` and `obj_name` according to normalized path src_repo_id = repo_id src_dir = os.path.dirname(path) src_obj_name = os.path.basename(path) # check parameter for dst dst_repo_id = request.data.get('dst_repo_id', src_repo_id) if dst_repo_id != src_repo_id and not seafile_api.get_repo(dst_repo_id): error_msg = 'Library %s not found.' % dst_repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dst_dir = request.data.get('dst_dir', '/') if dst_dir != '/': dst_dir = normalize_dir_path(dst_dir) if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir): error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # copy file username = request.user.username dst_obj_name = check_filename_with_rename(dst_repo_id, dst_dir, src_obj_name) try: seafile_api.copy_file(src_repo_id, src_dir, src_obj_name, dst_repo_id, dst_dir, dst_obj_name, 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) return Response({'success': True, 'dst_item_name': dst_obj_name})
def save_shared_link(request): """Save public share link to one's library. """ username = request.user.username token = request.GET.get('t', '') dst_repo_id = request.POST.get('dst_repo', '') dst_path = request.POST.get('dst_path', '') next = request.META.get('HTTP_REFERER', None) if not next: next = SITE_ROOT if not dst_repo_id or not dst_path: messages.error(request, _(u'Please choose a directory.')) return HttpResponseRedirect(next) try: fs = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 src_repo_id = fs.repo_id src_path = os.path.dirname(fs.path) obj_name = os.path.basename(fs.path) new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) seafile_api.copy_file(src_repo_id, src_path, obj_name, dst_repo_id, dst_path, new_obj_name, username, need_progress=0) messages.success(request, _(u'Successfully saved.')) return HttpResponseRedirect(next)
def save_private_file_share(request, token): """ Save private share file to someone's library. """ username = request.user.username try: pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(token) except PrivateFileDirShare.DoesNotExist: raise Http404 from_user = pfs.from_user to_user = pfs.to_user repo_id = pfs.repo_id path = pfs.path src_path = os.path.dirname(path) obj_name = os.path.basename(path.rstrip('/')) if username == from_user or username == to_user: dst_repo_id = request.POST.get('dst_repo') dst_path = request.POST.get('dst_path') new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) seafile_api.copy_file(repo_id, src_path, obj_name, dst_repo_id, dst_path, new_obj_name, username, need_progress=0) messages.success(request, _(u'Successfully saved.')) else: messages.error(request, _("You don't have permission to save %s.") % obj_name) next = request.META.get('HTTP_REFERER', None) if not next: next = SITE_ROOT return HttpResponseRedirect(next)
def cp_dir(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username): result = {} content_type = 'application/json; charset=utf-8' src_dir = os.path.join(src_path, obj_name) if dst_path.startswith(src_dir): error_msg = _(u'Can not copy directory %(src)s to its subdirectory %(des)s') \ % {'src': src_dir, 'des': dst_path} result['error'] = error_msg return HttpResponse(json.dumps(result), status=400, content_type=content_type) new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) try: msg_url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path) seafile_api.copy_file(src_repo_id, src_path, obj_name, dst_repo_id, dst_path, new_obj_name, username) msg = _(u'Successfully copied %(name)s <a href="%(url)s">view</a>') % \ {"name":obj_name, "url":msg_url} result['msg'] = msg result['success'] = True return HttpResponse(json.dumps(result), content_type=content_type) except SearpcError, e: result['error'] = str(e) return HttpResponse(json.dumps(result), status=500, content_type=content_type)
def get_draft_file_name(repo_id, file_path): file_path = normalize_file_path(file_path) file_name, file_ext = os.path.splitext(os.path.basename(file_path)) draft_file_name = "%s%s%s" % (file_name, '(draft)', file_ext) draft_file_name = check_filename_with_rename(repo_id, '/Drafts', draft_file_name) return draft_file_name
def rename_dirent(request, repo_id): """ Rename a file/dir in a repo, with ajax """ if request.method != 'POST' or not request.is_ajax(): raise Http404 result = {} username = request.user.username content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: result['error'] = _(u'Library does not exist.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # permission checking if check_repo_access_permission(repo.id, username) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # form validation form = RepoRenameDirentForm(request.POST) if form.is_valid(): oldname = form.cleaned_data["oldname"] newname = form.cleaned_data["newname"] else: result['error'] = str(form.errors.values()[0]) return HttpResponse(json.dumps(result), status=400, content_type=content_type) if newname == oldname: return HttpResponse(json.dumps({'success': True}), content_type=content_type) # argument checking parent_dir = request.GET.get('parent_dir', None) if not parent_dir: result['error'] = _('Argument missing') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # rename duplicate name newname = check_filename_with_rename(repo_id, parent_dir, newname) # rename file/dir try: seafile_api.rename_file(repo_id, parent_dir, oldname, newname, username) except SearpcError, e: result['error'] = str(e) return HttpResponse(json.dumps(result), status=500, content_type=content_type)
def test_can_create_same_name_file(self): self.login_as(self.user) file_name = os.path.basename(self.file_path.rstrip('/')) new_name = check_filename_with_rename(self.repo_id, '/', file_name) data = {'operation': 'create',} # create file resp = self.client.post(self.url + '?p=' + self.file_path, data) self.assertEqual(200, resp.status_code) json_resp = json.loads(resp.content) # check new folder has been created assert new_name == json_resp['obj_name']
def post(self, request, repo_id, format=None): # rename or move file repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') resp = check_repo_access_permission(request, repo) if resp: return resp path = request.GET.get('p', '') if not path or path[0] != '/': return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing or invalid.') operation = request.POST.get('operation', '') if operation.lower() == 'rename': newname = request.POST.get('newname', '') if not newname: return api_error(status.HTTP_400_BAD_REQUEST, 'Newname is missing') newname = unquote(newname.encode('utf-8')) if len(newname) > settings.MAX_UPLOAD_FILE_NAME_LEN: return api_error(status.HTTP_400_BAD_REQUEST, 'Newname too long') parent_dir = os.path.dirname(path) parent_dir_utf8 = parent_dir.encode('utf-8') oldname = os.path.basename(path) oldname_utf8 = oldname.encode('utf-8') if oldname == newname: return api_error(status.HTTP_409_CONFLICT, 'The new name is the same to the old') newname = check_filename_with_rename(repo_id, parent_dir, newname) newname_utf8 = newname.encode('utf-8') try: seafserv_threaded_rpc.rename_file (repo_id, parent_dir_utf8, oldname_utf8, newname, request.user.username) except SearpcError,e: return api_error(HTTP_520_OPERATION_FAILED, "Failed to rename file: %s" % e) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, repo_id, parent_dir) else: resp = Response('success', status=status.HTTP_301_MOVED_PERMANENTLY) uri = reverse('FileView', args=[repo_id], request=request) resp['Location'] = uri + '?p=' + quote(parent_dir_utf8) + quote(newname_utf8) return resp
def post(self, request, repo_id, format=None): resp = check_repo_access_permission(request, get_repo(repo_id)) if resp: return resp path = request.GET.get('p') if not path or path[0] != '/': return api_error('400') parent_dir = os.path.dirname(path) new_dir_name = os.path.basename(path) new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) try: seafserv_threaded_rpc.post_dir(repo_id, parent_dir, new_dir_name, request.user.username) except SearpcError, e: return api_error('421', e.msg)
def post(self, request, repo_id, format=None): """ create file/folder in a library """ 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) if not can_view_sys_admin_repo(repo): error_msg = 'Feature disabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) parent_dir = request.GET.get('parent_dir', '/') if not parent_dir: error_msg = 'parent_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if parent_dir[-1] != '/': parent_dir = parent_dir + '/' dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) obj_name = request.data.get('obj_name', None) if not obj_name or not seafile_api.is_valid_filename(repo_id, obj_name): error_msg = 'obj_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) obj_name = check_filename_with_rename(repo_id, parent_dir, obj_name) username = request.user.username try: seafile_api.post_dir(repo_id, parent_dir, obj_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) dirent_path = posixpath.join(parent_dir, obj_name) dirent = seafile_api.get_dirent_by_path(repo_id, dirent_path) dirent_info = get_dirent_info(dirent) return Response(dirent_info)
def post(self, request, repo_id, format=None): # new dir repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') resp = check_repo_access_permission(request, repo) if resp: return resp path = request.GET.get('p', '') if not path or path[0] != '/': return api_error(status.HTTP_400_BAD_REQUEST, "Path is missing.") if path == '/': # Can not make root dir. return api_error(status.HTTP_400_BAD_REQUEST, "Path is invalid.") if path[-1] == '/': # Cut out last '/' if possible. path = path[:-1] operation = request.POST.get('operation', '') if operation.lower() == 'mkdir': parent_dir = os.path.dirname(path) parent_dir_utf8 = parent_dir.encode('utf-8') new_dir_name = os.path.basename(path) new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) new_dir_name_utf8 = new_dir_name.encode('utf-8') try: seafserv_threaded_rpc.post_dir(repo_id, parent_dir, new_dir_name, request.user.username) except SearpcError, e: return api_error(HTTP_520_OPERATION_FAILED, 'Failed to make directory.') if request.GET.get('reloaddir', '').lower() == 'true': resp = reloaddir(request, repo_id, parent_dir) else: resp = Response('success', status=status.HTTP_201_CREATED) uri = reverse('DirView', args=[repo_id], request=request) resp['Location'] = uri + '?p=' + quote(parent_dir_utf8) + \ quote(new_dir_name_utf8) return resp
def cp_file(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username): result = {} content_type = 'application/json; charset=utf-8' new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) try: msg_url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path) seafile_api.copy_file(src_repo_id, src_path, obj_name, dst_repo_id, dst_path, new_obj_name, username) msg = _(u'Successfully copied %(name)s <a href="%(url)s">view</a>') % \ {"name":obj_name, "url":msg_url} result['msg'] = msg result['success'] = True return HttpResponse(json.dumps(result), content_type=content_type) except SearpcError, e: result['error'] = str(e) return HttpResponse(json.dumps(result), status=500, content_type=content_type)
def _decorated(request, repo_id, *args, **kwargs): if request.method != 'POST' or not request.is_ajax(): raise Http404 result = {} content_type = 'application/json; charset=utf-8' repo = get_repo(repo_id) if not repo: result['error'] = _(u'Library does not exist.') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # permission checking username = request.user.username if check_repo_access_permission(repo.id, username) != 'rw': result['error'] = _('Permission denied') return HttpResponse(json.dumps(result), status=403, content_type=content_type) # form validation form = RepoNewDirentForm(request.POST) if form.is_valid(): dirent_name = form.cleaned_data["dirent_name"] else: result['error'] = str(form.errors.values()[0]) return HttpResponse(json.dumps(result), status=400, content_type=content_type) # arguments checking parent_dir = request.GET.get('parent_dir', None) if not parent_dir: result['error'] = _('Argument missing') return HttpResponse(json.dumps(result), status=400, content_type=content_type) # rename duplicate name dirent_name = check_filename_with_rename(repo.id, parent_dir, dirent_name) return func(repo.id, parent_dir, dirent_name, username)
def test_can_rename_file_with_same_name(self): self.login_as(self.user) # check old file exist assert self.file_name == self.get_lib_file_name(self.repo_id) # create a new file new_name = randstring(6) data = {'operation': 'create',} resp = self.client.post(self.url + '?p=/' + new_name, data) self.assertEqual(200, resp.status_code) # rename new file with the same of the old file old_file_name = self.file_name checked_name = check_filename_with_rename(self.repo_id, '/', old_file_name) data = {'operation': 'rename', 'newname': checked_name} resp = self.client.post(self.url + '?p=/' + new_name, data) self.assertEqual(200, resp.status_code) json_resp = json.loads(resp.content) assert checked_name == json_resp['obj_name']
def cp_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj_dir_names, username): content_type = 'application/json; charset=utf-8' for obj_name in obj_dir_names: src_dir = os.path.join(src_path, obj_name) if dst_path.startswith(src_dir): error_msg = _(u'Can not copy directory %(src)s to its subdirectory %(des)s') \ % {'src': src_dir, 'des': dst_path} result['error'] = error_msg return HttpResponse(json.dumps(result), status=400, content_type=content_type) success = [] failed = [] url = None for obj_name in obj_file_names + obj_dir_names: new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) try: seafile_api.copy_file(src_repo_id, src_path, obj_name, dst_repo_id, dst_path, new_obj_name, username) success.append(obj_name) except SearpcError, e: failed.append(obj_name)
def post(self, request, repo_id, format=None): """ create file/folder in a library """ parent_dir = request.GET.get('parent_dir', '/') parent_dir = normalize_dir_path(parent_dir) dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) obj_name = request.data.get('obj_name', None) if not obj_name or not is_valid_dirent_name(obj_name): error_msg = 'obj_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_file = request.data.get('is_file', 'false') is_file = is_file.lower() if is_file not in ('true', 'false'): error_msg = 'is_file invalid.' username = request.user.username obj_name = check_filename_with_rename(repo_id, parent_dir, obj_name) try: if is_file == 'true': seafile_api.post_empty_file(repo_id, parent_dir, obj_name, username) else: seafile_api.post_dir(repo_id, parent_dir, obj_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) dirent_path = posixpath.join(parent_dir, obj_name) dirent = seafile_api.get_dirent_by_path(repo_id, dirent_path) dirent_info = get_dirent_info(dirent) return Response(dirent_info)
def post(self, request): src_repo_id = request.POST.get('src_repo') src_dir = unquote(request.POST.get('src_dir')).decode('utf-8') dst_repo_id = request.POST.get('dst_repo') dst_dir = unquote(request.POST.get('dst_dir')).decode('utf-8') op = request.POST.get('operation') obj_names = request.POST.get('obj_names') if not (src_repo_id and src_dir and dst_repo_id \ and dst_dir and op and obj_names): return api_error(request, '400') if src_repo_id == dst_repo_id and src_dir == dst_dir: return api_error(request, '419', 'The src_dir is same to dst_dir') names = obj_names.split(':') names = map(lambda x: unquote(x).decode('utf-8'), names) if dst_dir.startswith(src_dir): for obj_name in names: if dst_dir.startswith('/'.join([src_dir, obj_name])): return api_error(request, '419', 'Can not move a dirctory to its subdir') for obj_name in names: new_obj_name = check_filename_with_rename(dst_repo_id, dst_dir, obj_name) try: if op == 'cp': seafserv_threaded_rpc.copy_file (src_repo_id, src_dir, obj_name, dst_repo_id, dst_dir, new_obj_name, request.user.username) elif op == 'mv': seafserv_threaded_rpc.move_file (src_repo_id, src_dir, obj_name, dst_repo_id, dst_dir, new_obj_name, request.user.username) except SearpcError, e: return api_error(request, '419', "SearpcError:" + e.msg)
def test_can_rename_folder_with_same_name(self): self.login_as(self.user) # check old folder exist assert self.folder_name == self.get_lib_folder_name(self.repo_id) # create a new folder new_name = randstring(6) data = {'operation': 'mkdir',} resp = self.client.post(self.url + '?p=/' + new_name, data) self.assertEqual(200, resp.status_code) # rename new folder with the same name of old folder old_folder_name = self.folder_name checked_name = check_filename_with_rename(self.repo_id, '/', old_folder_name) data = {'operation': 'rename', 'newname': checked_name} resp = self.client.post(self.url + '?p=/' + new_name, data) self.assertEqual(200, resp.status_code) # check old file has been renamed to new_name json_resp = json.loads(resp.content) print old_folder_name, new_name, checked_name assert checked_name == json_resp['obj_name']
def test_can_copy(self): self.login_as(self.user) file_name_1 = self.create_new_file() file_name_2 = self.create_new_file() # check old file name exists in src repo assert file_name_1 in self.get_dirent_name_list(self.repo_id) assert file_name_2 in self.get_dirent_name_list(self.repo_id) dst_repo_id = self.create_new_repo() renamed_name_1 = check_filename_with_rename(dst_repo_id, '/', file_name_1) renamed_name_2 = check_filename_with_rename(dst_repo_id, '/', file_name_2) data = { 'file_names': file_name_1 + ':' + file_name_2, 'dst_repo': dst_repo_id, 'dst_dir': '/', } ### copy for first time ### resp = self.client.post(self.copy_url, data) json_resp = json.loads(resp.content) self.assertEqual(200, resp.status_code) assert json_resp[0]['repo_id'] == dst_repo_id assert json_resp[0]['parent_dir'] == '/' assert json_resp[0]['obj_name'] == renamed_name_1 assert json_resp[1]['obj_name'] == renamed_name_2 # check old file still existes assert file_name_1 in self.get_dirent_name_list(self.repo_id) assert file_name_2 in self.get_dirent_name_list(self.repo_id) # check old file has been copyd to dst repo with a new name assert renamed_name_1 in self.get_dirent_name_list(dst_repo_id) assert renamed_name_2 in self.get_dirent_name_list(dst_repo_id) ### copy for second time ### renamed_name_1 = check_filename_with_rename(dst_repo_id, '/', file_name_1) renamed_name_2 = check_filename_with_rename(dst_repo_id, '/', file_name_2) resp = self.client.post(self.copy_url, data) json_resp = json.loads(resp.content) self.assertEqual(200, resp.status_code) assert json_resp[0]['repo_id'] == dst_repo_id assert json_resp[0]['parent_dir'] == '/' assert json_resp[0]['obj_name'] == renamed_name_1 assert json_resp[1]['obj_name'] == renamed_name_2 # check old file still existes assert file_name_1 in self.get_dirent_name_list(self.repo_id) assert file_name_2 in self.get_dirent_name_list(self.repo_id) # check old file has been copyd to dst repo with a new name assert renamed_name_1 in self.get_dirent_name_list(dst_repo_id) assert renamed_name_2 in self.get_dirent_name_list(dst_repo_id) ### copy for third time ### renamed_name_1 = check_filename_with_rename(dst_repo_id, '/', file_name_1) renamed_name_2 = check_filename_with_rename(dst_repo_id, '/', file_name_2) resp = self.client.post(self.copy_url, data) json_resp = json.loads(resp.content) self.assertEqual(200, resp.status_code) assert json_resp[0]['repo_id'] == dst_repo_id assert json_resp[0]['parent_dir'] == '/' assert json_resp[0]['obj_name'] == renamed_name_1 assert json_resp[1]['obj_name'] == renamed_name_2 # check old file still existes assert file_name_1 in self.get_dirent_name_list(self.repo_id) assert file_name_2 in self.get_dirent_name_list(self.repo_id) # check old file has been copyd to dst repo with a new name assert renamed_name_1 in self.get_dirent_name_list(dst_repo_id) assert renamed_name_2 in self.get_dirent_name_list(dst_repo_id) self.remove_repo(dst_repo_id)
def post(self, request): """ Copy/move file/dir, and return task id. Permission checking: 1. move: user with 'rw' permission for current file, 'rw' permission for dst parent dir; 2. copy: user with 'r' permission for current file, 'rw' permission for dst parent dir; """ src_repo_id = request.data.get('src_repo_id', None) src_parent_dir = request.data.get('src_parent_dir', None) src_dirent_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) operation = request.data.get('operation', None) dirent_type = request.data.get('dirent_type', 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_dirent_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 not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dirent_type: error_msg = 'dirent_type invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if len(dst_parent_dir + src_dirent_name) > MAX_PATH: error_msg = _('Destination path is too long.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('move', 'copy'): error_msg = "operation can only be 'move' or 'copy'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if operation == 'move': 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) dirent_type = dirent_type.lower() if dirent_type not in ('file', 'dir'): error_msg = "operation can only be 'file' or 'dir'." 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_dirent_path = posixpath.join(src_parent_dir, src_dirent_name) file_id = None if dirent_type == 'file': file_id = seafile_api.get_file_id_by_path(src_repo_id, src_dirent_path) if not file_id: error_msg = 'File %s not found.' % src_dirent_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) dir_id = None if dirent_type == 'dir': dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_dirent_path) if not dir_id: error_msg = 'Folder %s not found.' % src_dirent_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 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) if operation == 'copy' or \ operation == 'move' and \ get_repo_owner(request, src_repo_id) != get_repo_owner(request, dst_repo_id): current_size = 0 if file_id: current_size = seafile_api.get_file_size(src_repo.store_id, src_repo.version, file_id) if dir_id: current_size = seafile_api.get_dir_size(src_repo.store_id, src_repo.version, dir_id) # check if above quota for dst repo if seafile_api.check_quota(dst_repo_id, current_size) < 0: return api_error(HTTP_443_ABOVE_QUOTA, _("Out of quota.")) new_dirent_name = check_filename_with_rename(dst_repo_id, dst_parent_dir, src_dirent_name) username = request.user.username if operation == 'move': # permission check for src parent dir if check_folder_permission(request, src_repo_id, src_parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if dirent_type == 'dir' and src_repo_id == dst_repo_id and \ dst_parent_dir.startswith(src_dirent_path + '/'): error_msg = _('Can not move directory %(src)s to its subdirectory %(des)s') \ % {'src': escape(src_dirent_path), 'des': escape(dst_parent_dir)} return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if dirent_type == 'file': # check file lock try: is_locked, locked_by_me = check_file_lock(src_repo_id, src_dirent_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) try: res = seafile_api.move_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, new_dirent_name, replace=False, username=username, need_progress=1) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if operation == 'copy': # permission check for src parent dir if parse_repo_perm(check_folder_permission( request, src_repo_id, src_parent_dir)).can_copy is False: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: res = seafile_api.copy_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, new_dirent_name, username=username, need_progress=1) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not res: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = {} if res.background: result['task_id'] = res.task_id return Response(result)
def post(self, request, token): # argument check dst_repo_id = request.POST.get('dst_repo_id', '') if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_parent_dir = request.POST.get('dst_parent_dir', '') if not dst_parent_dir: error_msg = 'dst_parent_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check try: share_link = FileShare.objects.get(token=token) except FileShare.DoesNotExist: error_msg = 'Share link %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not seafile_api.get_repo(dst_repo_id): 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 share_link_permission = share_link.get_permissions() if not share_link_permission.get('can_download', False): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) 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) # copy file if share_link.s_type == 'f': src_dirent_path = share_link.path else: path = request.POST.get('path', '') if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) src_dirent_path = posixpath.join(share_link.path, path.strip('/')) src_repo_id = share_link.repo_id src_parent_dir = os.path.dirname(src_dirent_path) src_dirent_name = os.path.basename(src_dirent_path) dst_dirent_name = check_filename_with_rename(dst_repo_id, dst_parent_dir, src_dirent_name) username = request.user.username seafile_api.copy_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, dst_dirent_name, username, need_progress=0) return Response({'success': True})
def post(self, request): """ Multi move files/folders. Permission checking: 1. User must has `rw` permission for src folder. 2. User must has `rw` permission for dst folder. Parameter: { "src_repo_id":"7460f7ac-a0ff-4585-8906-bb5a57d2e118", "dst_repo_id":"a3fa768d-0f00-4343-8b8d-07b4077881db", "paths":[ {"src_path":"/1/2/3/","dst_path":"/4/5/6/"}, {"src_path":"/a/b/c/","dst_path":"/d/e/f/"}, ] } """ # argument check path_list = request.data.get('paths', None) if not path_list: error_msg = 'paths invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) src_repo_id = request.data.get('src_repo_id', None) if not src_repo_id: error_msg = 'src_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_repo_id = request.data.get('dst_repo_id', None) if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # 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) 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) # permission check if check_folder_permission(request, src_repo_id, '/') is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if check_folder_permission(request, dst_repo_id, '/') is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] username = request.user.username for path_item in path_list: src_path = path_item['src_path'] src_path = normalize_dir_path(src_path) src_parent_dir = os.path.dirname(src_path.rstrip('/')) src_parent_dir = normalize_dir_path(src_parent_dir) src_obj_name = os.path.basename(src_path.rstrip('/')) dst_path = path_item['dst_path'] dst_path = normalize_dir_path(dst_path) dst_parent_dir = dst_path dst_obj_name = src_obj_name common_dict = { 'src_repo_id': src_repo_id, 'src_path': src_path, 'dst_repo_id': dst_repo_id, 'dst_path': dst_path, } # src/dst parameter check if src_repo_id == dst_repo_id and \ dst_path.startswith(src_path): error_dict = { 'error_msg': "The destination directory is the same as the source, or is it's subfolder." } common_dict.update(error_dict) result['failed'].append(common_dict) continue if src_path == '/': error_dict = { 'error_msg': "The source path can not be '/'." } common_dict.update(error_dict) result['failed'].append(common_dict) continue if len(dst_parent_dir + dst_obj_name) > MAX_PATH: error_dict = { 'error_msg': "'Destination path is too long." } common_dict.update(error_dict) result['failed'].append(common_dict) continue # src resource check ## as we don't know if `src_path` stands for a file or a folder, ## so we check both src_dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_path) src_file_id = seafile_api.get_file_id_by_path(src_repo_id, normalize_file_path(src_path)) if not src_dir_id and not src_file_id: error_dict = { 'error_msg': '%s not found.' % src_path } common_dict.update(error_dict) result['failed'].append(common_dict) continue # dst resource check if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_path): error_dict = { 'error_msg': 'Folder %s not found.' % dst_path } common_dict.update(error_dict) result['failed'].append(common_dict) continue # src path permission check, user must has `rw` permission for src folder. if check_folder_permission(request, src_repo_id, src_parent_dir) != 'rw': error_dict = { 'error_msg': 'Permission denied.' } common_dict.update(error_dict) result['failed'].append(common_dict) continue # dst path permission check, user must has `rw` permission for dst folder. if check_folder_permission(request, dst_repo_id, dst_path) != 'rw': error_dict = { 'error_msg': 'Permission denied.' } common_dict.update(error_dict) result['failed'].append(common_dict) continue try: dst_obj_name = check_filename_with_rename(dst_repo_id, dst_parent_dir, dst_obj_name) # replace=False, username=username, need_progress=0, synchronous=1 seafile_api.move_file(src_repo_id, src_parent_dir, src_obj_name, dst_repo_id, dst_parent_dir, dst_obj_name, False, username, 0, 1) except Exception as e: logger.error(e) error_dict = { 'error_msg': 'Internal Server Error' } common_dict.update(error_dict) result['failed'].append(common_dict) continue common_dict['dst_obj_name'] = dst_obj_name result['success'].append(common_dict) return Response(result)
def post(self, request): """ Copy/move file/dir, and return task id. Permission checking: 1. move: user with 'rw' permission for current file, 'rw' permission for dst parent dir; 2. copy: user with 'r' permission for current file, 'rw' permission for dst parent dir; """ src_repo_id = request.data.get('src_repo_id', None) src_parent_dir = request.data.get('src_parent_dir', None) src_dirent_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) operation = request.data.get('operation', None) dirent_type = request.data.get('dirent_type', 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_dirent_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 not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dirent_type: error_msg = 'dirent_type invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if len(dst_parent_dir + src_dirent_name) > MAX_PATH: error_msg = _('Destination path is too long.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('move', 'copy'): error_msg = "operation can only be 'move' or 'copy'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if operation == 'move': 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) dirent_type = dirent_type.lower() if dirent_type not in ('file', 'dir'): error_msg = "operation can only be 'file' or 'dir'." 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_dirent_path = posixpath.join(src_parent_dir, src_dirent_name) file_id = None if dirent_type == 'file': file_id = seafile_api.get_file_id_by_path(src_repo_id, src_dirent_path) if not file_id: error_msg = 'File %s not found.' % src_dirent_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) dir_id = None if dirent_type == 'dir': dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_dirent_path) if not dir_id: error_msg = 'Folder %s not found.' % src_dirent_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 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) if operation == 'copy' or \ operation == 'move' and \ get_repo_owner(request, src_repo_id) != get_repo_owner(request, dst_repo_id): current_size = 0 if file_id: current_size = seafile_api.get_file_size(src_repo.store_id, src_repo.version, file_id) if dir_id: current_size = seafile_api.get_dir_size(src_repo.store_id, src_repo.version, dir_id) # check if above quota for dst repo if seafile_api.check_quota(dst_repo_id, current_size) < 0: return api_error(HTTP_443_ABOVE_QUOTA, _(u"Out of quota.")) new_dirent_name = check_filename_with_rename(dst_repo_id, dst_parent_dir, src_dirent_name) username = request.user.username if operation == 'move': # permission check for src parent dir if check_folder_permission(request, src_repo_id, src_parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if dirent_type == 'dir' and src_repo_id == dst_repo_id and \ dst_parent_dir.startswith(src_dirent_path + '/'): error_msg = _(u'Can not move directory %(src)s to its subdirectory %(des)s') \ % {'src': escape(src_dirent_path), 'des': escape(dst_parent_dir)} return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if dirent_type == 'file': # check file lock try: is_locked, locked_by_me = check_file_lock(src_repo_id, src_dirent_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) try: res = seafile_api.move_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, new_dirent_name, replace=False, username=username, need_progress=1) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if operation == 'copy': # permission check for src parent dir if parse_repo_perm(check_folder_permission( request, src_repo_id, src_parent_dir)).can_copy is False: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: res = seafile_api.copy_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, new_dirent_name, username=username, need_progress=1) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not res: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = {} if res.background: result['task_id'] = res.task_id return Response(result)
def post(self, request): repo_id = request.data.get('repo_id') if not repo_id: error_msg = 'repo_id invalid.' return api_error(400, error_msg) file_path = request.data.get('file_path') if not file_path: error_msg = 'file_path invalid.' return api_error(400, error_msg) file_path = normalize_file_path(file_path) parent_dir = os.path.dirname(file_path) file_ext = get_file_ext(file_path) file_type = get_file_type(file_path) new_ext = get_internal_extension(file_type) if not new_ext: logger.error('[OnlyOffice] Could not generate internal extension.') error_msg = 'Internal Server Error' return api_error(500, error_msg) username = request.user.username doc_dic = get_onlyoffice_dict(request, username, repo_id, file_path) new_uri = get_converter_uri(doc_dic["doc_url"], file_ext, new_ext, doc_dic["doc_key"], False, request.data.get('file_password')) if not new_uri: logger.error('[OnlyOffice] No response from file converter.') error_msg = 'Internal Server Error' return api_error(500, error_msg) onlyoffice_resp = requests.get(new_uri, verify=VERIFY_ONLYOFFICE_CERTIFICATE) if not onlyoffice_resp: logger.error('[OnlyOffice] No response from file content url.') error_msg = 'Internal Server Error' return api_error(500, error_msg) fake_obj_id = {'parent_dir': parent_dir} upload_token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'upload-link', username) if not upload_token: logger.error('[OnlyOffice] No fileserver access token.') error_msg = 'Internal Server Error' return api_error(500, error_msg) file_name = get_file_name_without_ext(file_path) + new_ext file_name = check_filename_with_rename(repo_id, parent_dir, file_name) files = {'file': (file_name, onlyoffice_resp.content)} data = {'parent_dir': parent_dir} upload_url = gen_inner_file_upload_url('upload-api', upload_token) try: file_name.encode('ascii') except UnicodeEncodeError: def rewrite_request(prepared_request): old_content = 'filename*=' + email.utils.encode_rfc2231( file_name, 'utf-8') old_content = old_content.encode() # new_content = 'filename="{}"\r\n\r\n'.format(file_name) new_content = 'filename="{}"'.format(file_name) new_content = new_content.encode() prepared_request.body = prepared_request.body.replace( old_content, new_content) return prepared_request resp = requests.post(upload_url, files=files, data=data, auth=rewrite_request) else: resp = requests.post(upload_url, files=files, data=data) if resp.status_code != 200: logger.error('upload_url: {}'.format(upload_url)) logger.error('parameter file: {}'.format(files['file'][:100])) logger.error('parameter parent_dir: {}'.format( files['parent_dir'])) logger.error('response: {}'.format(resp.__dict__)) result = {} result['parent_dir'] = parent_dir result['file_name'] = file_name result['file_path'] = posixpath.join(parent_dir, file_name) return Response(result)
def post(self, request, repo_id, format=None): """ Create, rename, revert dir. Permission checking: 1. create: user with 'rw' permission for current dir's parent dir; 2. rename: user with 'rw' permission for current dir; 3. revert: user with 'rw' permission for current dir's parent dir; """ # argument check path = request.GET.get('p', None) if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path == '/': error_msg = 'Can not operate root dir.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 ('mkdir', 'rename', 'revert'): error_msg = "operation can only be 'mkdir', 'rename' 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) path = path.rstrip('/') username = request.user.username parent_dir = os.path.dirname(path) if operation == 'mkdir': # permission check if check_folder_permission(request, repo_id, parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # resource check parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not parent_dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) new_dir_name = os.path.basename(path) new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) try: seafile_api.post_dir(repo_id, parent_dir, new_dir_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_dir_path = posixpath.join(parent_dir, new_dir_name) dir_info = self.get_dir_info(repo_id, new_dir_path) resp = Response(dir_info) return resp if operation == 'rename': # resource check dir_id = seafile_api.get_dir_id_by_path(repo_id, path) if not dir_id: error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) old_dir_name = os.path.basename(path) new_dir_name = request.data.get('newname', None) if not new_dir_name: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if new_dir_name == old_dir_name: dir_info = self.get_dir_info(repo_id, path) resp = Response(dir_info) return resp try: # rename duplicate name new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) # rename dir seafile_api.rename_file(repo_id, parent_dir, old_dir_name, new_dir_name, username) new_dir_path = posixpath.join(parent_dir, new_dir_name) dir_info = self.get_dir_info(repo_id, new_dir_path) resp = Response(dir_info) return resp except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def put(self, request, workspace_id): """rename a table Permission: 1. owner 2. group member """ # argument check old_table_name = request.data.get('old_name') if not old_table_name: error_msg = 'old_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) new_table_name = request.data.get('new_name') if not new_table_name: error_msg = 'new_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) new_table_file_name = new_table_name + FILE_TYPE if not is_valid_dirent_name(new_table_file_name): error_msg = 'new_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if len(new_table_file_name) > MAX_UPLOAD_FILE_NAME_LEN: error_msg = 'new_name is too long.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id 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) dtable = DTables.objects.get_dtable(workspace, old_table_name) if not dtable: error_msg = 'dtable %s not found.' % old_table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) old_table_file_name = old_table_name + FILE_TYPE old_table_path = normalize_file_path(old_table_file_name) table_file_id = seafile_api.get_file_id_by_path(repo_id, old_table_path) if not table_file_id: error_msg = 'file %s not found.' % old_table_file_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if not check_dtable_permission(username, owner): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # repo status check repo_status = repo.status if repo_status != 0: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # rename table new_table_file_name = check_filename_with_rename(repo_id, '/', new_table_file_name) try: seafile_api.rename_file(repo_id, '/', old_table_file_name, new_table_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) try: dtable.name = new_table_name dtable.modifier = username dtable.save() 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({"table": dtable.to_dict()}, status=status.HTTP_200_OK)
def post(self, request): """create a table file Permission: 1. owner 2. group member """ # argument check table_owner = request.POST.get('owner') if not table_owner: error_msg = 'owner invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) table_name = request.POST.get('name') if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) table_file_name = table_name + FILE_TYPE if not is_valid_dirent_name(table_file_name): error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_owner(table_owner) if not workspace: if not request.user.permissions.can_add_repo(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) org_id = -1 if is_org_context(request): org_id = request.user.org.org_id try: if org_id > 0: repo_id = seafile_api.create_org_repo( _("My Workspace"), _("My Workspace"), "dtable@seafile", org_id ) else: repo_id = seafile_api.create_repo( _("My Workspace"), _("My Workspace"), "dtable@seafile" ) except Exception as e: logger.error(e) error_msg = 'Internal Server Error.' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) try: workspace = Workspaces.objects.create_workspace(table_owner, repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error.' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_id = workspace.repo_id 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) # permission check username = request.user.username if not check_dtable_permission(username, table_owner): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # repo status check repo_status = repo.status if repo_status != 0: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create new empty table table_file_name = check_filename_with_rename(repo_id, '/', table_file_name) try: seafile_api.post_empty_file(repo_id, '/', table_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) try: dtable = DTables.objects.create_dtable(username, workspace, table_name) 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({"table": dtable.to_dict()}, status=status.HTTP_201_CREATED)
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, 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)
def post(self, request, token): # argument check dst_repo_id = request.POST.get('dst_repo_id', '') if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dst_parent_dir = request.POST.get('dst_parent_dir', '') if not dst_parent_dir: error_msg = 'dst_parent_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check try: share_link = FileShare.objects.get(token=token) except FileShare.DoesNotExist: error_msg = 'Share link %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not seafile_api.get_repo(dst_repo_id): 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 share_link_permission = share_link.get_permissions() if not share_link_permission.get('can_download', False): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) 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) # save items username = request.user.username src_repo_id = share_link.repo_id # save file in file share link if share_link.s_type == 'f': src_dirent_path = share_link.path src_parent_dir = os.path.dirname(src_dirent_path) src_dirent_name = os.path.basename(src_dirent_path) dst_dirent_name = check_filename_with_rename( dst_repo_id, dst_parent_dir, src_dirent_name) else: # save items in folder share link src_parent_dir = request.POST.get('src_parent_dir', '') if not src_parent_dir: error_msg = 'src_parent_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) src_dirents = request.POST.getlist('src_dirents', []) if not src_dirents: error_msg = 'src_dirents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) src_parent_dir = posixpath.join(share_link.path, src_parent_dir.strip('/')) formated_src_dirents = [ dirent.strip('/') for dirent in src_dirents ] src_dirent_name = "\t".join(formated_src_dirents) dst_dirent_name = "\t".join(formated_src_dirents) try: seafile_api.copy_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, dst_dirent_name, username, need_progress=0) 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, format=None): repo_id = request.repo_api_token_obj.repo_id # argument check path = request.GET.get('path', None) if not path or path[0] != '/': error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path == '/': error_msg = 'Can not operate root dir.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 ('mkdir', 'rename', 'revert'): error_msg = "operation can only be 'mkdir', 'rename' 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) path = path.rstrip('/') username = request.user.username parent_dir = os.path.dirname(path) if operation == 'mkdir': # resource check parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) 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_by_repo_api(request, repo_id, parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) new_dir_name = os.path.basename(path) if not is_valid_dirent_name(new_dir_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') retry_count = 0 while retry_count < 10: new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) try: seafile_api.post_dir(repo_id, parent_dir, new_dir_name, username) break except SearpcError as e: if str(e) == 'file already exists': retry_count += 1 else: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) new_dir_path = posixpath.join(parent_dir, new_dir_name) dir_info = self.get_dir_info(repo_id, new_dir_path) resp = Response(dir_info) return resp if operation == 'rename': # resource check dir_id = seafile_api.get_dir_id_by_path(repo_id, path) if not dir_id: error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission_by_repo_api(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) old_dir_name = os.path.basename(path) new_dir_name = request.data.get('newname', None) if not new_dir_name: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_dirent_name(new_dir_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') if new_dir_name == old_dir_name: dir_info = self.get_dir_info(repo_id, path) resp = Response(dir_info) return resp try: # rename duplicate name new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) # rename dir seafile_api.rename_file(repo_id, parent_dir, old_dir_name, new_dir_name, username) new_dir_path = posixpath.join(parent_dir, new_dir_name) dir_info = self.get_dir_info(repo_id, new_dir_path) resp = Response(dir_info) return resp except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) 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_dir_id_by_path(repo_id, path): # dir exists in repo if check_folder_permission_by_repo_api(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: # dir NOT exists in repo if check_folder_permission_by_repo_api(request, repo_id, '/') != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.revert_dir(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): repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library not found.') path = request.GET.get('p', '') if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path == '/': error_msg = 'Can not make or rename root dir.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path[-1] == '/': path = path[:-1] username = request.user.username parent_dir = os.path.dirname(path) operation = request.POST.get('operation', '') if operation.lower() == 'mkdir': parent_dir = os.path.dirname(path) if check_folder_permission(request, repo_id, parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) create_parents = request.POST.get('create_parents', '').lower() in ('true', '1') if not create_parents: parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not parent_dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) new_dir_name = os.path.basename(path) new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) try: seafile_api.post_dir(repo_id, parent_dir, new_dir_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) else: if not is_pro_version(): error_msg = 'Feature not supported.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.mkdir_with_parents(repo_id, '/', path[1:], 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 request.GET.get('reloaddir', '').lower() == 'true': resp = reloaddir(request, repo, parent_dir) else: resp = Response({'success': True}) return resp elif operation.lower() == 'rename': dir_id = seafile_api.get_dir_id_by_path(repo_id, path) if not dir_id: error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if check_folder_permission(request, repo.id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) parent_dir = os.path.dirname(path) old_dir_name = os.path.basename(path) newname = request.POST.get('newname', '') if not newname: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if newname == old_dir_name: return Response({'success': True}) try: # rename duplicate name checked_newname = check_filename_with_rename(repo_id, parent_dir, newname) # rename dir seafile_api.rename_file(repo_id, parent_dir, old_dir_name, checked_newname, username) return Response({'success': True}) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def post(self, request, repo_id, format=None): """ Create, rename, move, copy 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; """ # argument check path = request.GET.get('p', None) if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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'): error_msg = "operation can only be 'create', 'rename', 'move' or 'copy'." 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) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create file new_file_name = os.path.basename(path) 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) 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 src_repo_id == dst_repo_id and src_dir == dst_dir: return Response('success', status=status.HTTP_200_OK) # names = obj_names.split(':') # names = map(lambda x: unquote(x).decode('utf-8'), names) # if dst_dir.startswith(src_dir): # for obj_name in names: # if dst_dir.startswith('/'.join([src_dir, obj_name])): # return api_error(status.HTTP_409_CONFLICT, # 'Can not move a dirctory to its subdir') filename = os.path.basename(path) filename_utf8 = filename.encode('utf-8') new_filename = check_filename_with_rename(dst_repo_id, dst_dir, filename) new_filename_utf8 = new_filename.encode('utf-8') try: seafserv_threaded_rpc.move_file(src_repo_id, src_dir_utf8, filename_utf8, dst_repo_id, dst_dir_utf8, new_filename_utf8, request.user.username) except SearpcError, e: return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, "SearpcError:" + e.msg) if request.GET.get('reloaddir', '').lower() == 'true': reloaddir(request, dst_repo_id, dst_dir) else: resp = Response('success', status=status.HTTP_301_MOVED_PERMANENTLY)
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): file_obj = seafile_api.get_dirent_by_path(repo_id, file_path) is_locked, locked_by_me = check_file_lock(repo_id, file_path, username) file_info = { 'type': 'file', 'repo_id': repo_id, 'parent_dir': os.path.dirname(file_path), 'obj_name': file_obj.obj_name, 'obj_id': file_obj.obj_id, 'size': file_obj.size, 'mtime': timestamp_to_isoformat_timestr(file_obj.mtime), 'is_locked': is_locked, } 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 or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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) != 'rw': 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_file_upload_url(update_token, 'update-api') # update file try: requests.post(update_url, data={ 'filename': new_file_name, 'target_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) != 'rw': error_msg = 'Permission denied.' 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) 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) # 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) != 'rw': 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) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # move file if dst_dir[ -1] != '/': # Append '/' to the end of directory if necessary dst_dir += '/' 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) # 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 not check_folder_permission(request, src_repo_id, src_dir): 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) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # copy file if dst_dir[ -1] != '/': # Append '/' to the end of directory if necessary dst_dir += '/' 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.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) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) is_locked, locked_by_me = check_file_lock( repo_id, path, username) if (is_locked, locked_by_me) == (None, None): error_msg = _("Check file lock 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, '/') != 'rw': 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): # rename, move, copy or create file 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) path = request.GET.get('p', '') if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) username = request.user.username parent_dir = os.path.dirname(path) operation = request.POST.get('operation', '') if operation.lower() == 'rename': 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) if check_folder_permission(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) newname = request.POST.get('newname', '') if not newname: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if len(newname) > 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 == newname: error_msg = 'The new name is the same to the old' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) newname = check_filename_with_rename(repo_id, parent_dir, newname) try: seafile_api.rename_file(repo_id, parent_dir, oldname, newname, 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 request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, repo, parent_dir) else: return Response({'success': True}) elif operation.lower() == 'move': 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) # check src validation src_repo_id = repo_id src_dir = os.path.dirname(path) if check_folder_permission(request, src_repo_id, src_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check dst validation dst_repo_id = request.POST.get('dst_repo', '') dst_dir = request.POST.get('dst_dir', '') if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, 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) if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # move file if dst_dir[-1] != '/': # Append '/' to the end of directory if necessary dst_dir += '/' if src_repo_id == dst_repo_id and src_dir == dst_dir: return Response({'success': True}) filename = os.path.basename(path) new_filename = 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_filename, 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) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, dst_repo, dst_dir) else: return Response({'success': True}) elif operation.lower() == 'copy': 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) # check src validation src_repo_id = repo_id src_dir = os.path.dirname(path) if check_folder_permission(request, src_repo_id, src_dir) is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check dst validation dst_repo_id = request.POST.get('dst_repo', '') dst_dir = request.POST.get('dst_dir', '') if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, 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) if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # copy file if dst_dir[-1] != '/': # Append '/' to the end of directory if necessary dst_dir += '/' if src_repo_id == dst_repo_id and src_dir == dst_dir: return Response({'success': True}) filename = os.path.basename(path) new_filename = 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_filename, 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) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, dst_repo, dst_dir) else: return Response({'success': True}) elif operation.lower() == 'create': 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) if check_folder_permission(request, repo_id, parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) new_file_name = os.path.basename(path) 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) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, repo, parent_dir) else: return Response({'success': True})
def post(self, request, repo_id, format=None): """ Create, rename, revert dir. Permission checking: 1. create: user with 'rw' permission for current dir's parent dir; 2. rename: user with 'rw' permission for current dir; 3. revert: user with 'rw' permission for current dir's parent dir; """ # argument check path = request.GET.get('p', None) if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path == '/': error_msg = 'Can not operate root dir.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 ('mkdir', 'rename', 'revert'): error_msg = "operation can only be 'mkdir', 'rename' 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) path = path.rstrip('/') username = request.user.username parent_dir = os.path.dirname(path) if operation == 'mkdir': # resource check parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) 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) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) new_dir_name = os.path.basename(path) if not is_valid_dirent_name(new_dir_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name) try: seafile_api.post_dir(repo_id, parent_dir, new_dir_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_dir_path = posixpath.join(parent_dir, new_dir_name) dir_info = self.get_dir_info(repo_id, new_dir_path) resp = Response(dir_info) return resp if operation == 'rename': # resource check dir_id = seafile_api.get_dir_id_by_path(repo_id, path) if not dir_id: error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) old_dir_name = os.path.basename(path) new_dir_name = request.data.get('newname', None) if not new_dir_name: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_dirent_name(new_dir_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') if new_dir_name == old_dir_name: dir_info = self.get_dir_info(repo_id, path) resp = Response(dir_info) return resp try: # rename duplicate name new_dir_name = check_filename_with_rename( repo_id, parent_dir, new_dir_name) # rename dir seafile_api.rename_file(repo_id, parent_dir, old_dir_name, new_dir_name, username) new_dir_path = posixpath.join(parent_dir, new_dir_name) dir_info = self.get_dir_info(repo_id, new_dir_path) resp = Response(dir_info) return resp except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def put(self, request, repo_id): """ Copy a single file/folder to other place. """ if not request.user.admin_permissions.can_manage_library(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') # check parameter for src path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: dirent = seafile_api.get_dirent_by_path(repo_id, path) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not dirent: error_msg = 'File or folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if path == '/': error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # normalize path to '/1/2/3' format # NOT ends with '/' path = normalize_file_path(path) # now get `src_dir` and `obj_name` according to normalized path src_repo_id = repo_id src_dir = os.path.dirname(path) src_obj_name = os.path.basename(path) # check parameter for dst dst_repo_id = request.data.get('dst_repo_id', src_repo_id) if dst_repo_id != src_repo_id and not seafile_api.get_repo( dst_repo_id): error_msg = 'Library %s not found.' % dst_repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dst_dir = request.data.get('dst_dir', '/') if dst_dir != '/': dst_dir = normalize_dir_path(dst_dir) if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir): error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # copy file username = request.user.username dst_obj_name = check_filename_with_rename(dst_repo_id, dst_dir, src_obj_name) try: seafile_api.copy_file(src_repo_id, src_dir, src_obj_name, dst_repo_id, dst_dir, dst_obj_name, 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) return Response({'success': True, 'dst_item_name': dst_obj_name})
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) != 'rw': 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_file_upload_url(update_token, 'update-api') # 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)
def post(self, request, repo_id, format=None): """ Create, rename, move, copy 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; """ # argument check path = request.GET.get('p', None) if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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'): error_msg = "operation can only be 'create', 'rename', 'move' or 'copy'." 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) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create file new_file_name = os.path.basename(path) 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) 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 src_repo_id == dst_repo_id and src_dir == dst_dir: return Response('success', status=status.HTTP_200_OK) # names = obj_names.split(':') # names = map(lambda x: unquote(x).decode('utf-8'), names) # if dst_dir.startswith(src_dir): # for obj_name in names: # if dst_dir.startswith('/'.join([src_dir, obj_name])): # return api_error(status.HTTP_409_CONFLICT, # 'Can not move a dirctory to its subdir') filename = os.path.basename(path) filename_utf8 = filename.encode('utf-8') new_filename = check_filename_with_rename(dst_repo_id, dst_dir, filename) new_filename_utf8 = new_filename.encode('utf-8') try: seafserv_threaded_rpc.move_file(src_repo_id, src_dir_utf8, filename_utf8, dst_repo_id, dst_dir_utf8, new_filename_utf8, request.user.username) except SearpcError, e: return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, "SearpcError:" + e.msg) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, dst_repo_id, dst_dir) else: resp = Response('success', status=status.HTTP_301_MOVED_PERMANENTLY)
def post(self, request): """ Copy/move file/dir, and return task id. Permission checking: 1. move: user with 'rw' permission for current file, 'rw' permission for dst parent dir; 2. copy: user with 'r' permission for current file, 'rw' permission for dst parent dir; """ src_repo_id = request.data.get('src_repo_id', None) src_parent_dir = request.data.get('src_parent_dir', None) src_dirent_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) operation = request.data.get('operation', None) dirent_type = request.data.get('dirent_type', 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_dirent_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 not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dirent_type: error_msg = 'dirent_type 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_dirent_name) > MAX_PATH: error_msg = _('Destination path is too long.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('move', 'copy'): error_msg = "operation can only be 'move' or 'copy'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) dirent_type = dirent_type.lower() if dirent_type not in ('file', 'dir'): error_msg = "operation can only be 'file' or 'dir'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # src resource check src_dirent_path = posixpath.join(src_parent_dir, src_dirent_name) if dirent_type == 'file': if not seafile_api.get_file_id_by_path(src_repo_id, src_dirent_path): error_msg = 'File %s not found.' % src_dirent_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if dirent_type == 'dir': if not seafile_api.get_dir_id_by_path(src_repo_id, src_dirent_path): error_msg = 'Folder %s not found.' % src_dirent_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # dst resource check 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 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) new_dirent_name = check_filename_with_rename(dst_repo_id, dst_parent_dir, src_dirent_name) username = request.user.username if operation == 'move': if dirent_type == 'dir' and src_repo_id == dst_repo_id and \ dst_parent_dir.startswith(src_dirent_path + '/'): error_msg = _(u'Can not move directory %(src)s to its subdirectory %(des)s') \ % {'src': escape(src_dirent_path), 'des': escape(dst_parent_dir)} return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check for src parent dir if check_folder_permission(request, src_repo_id, src_parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: res = seafile_api.move_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, new_dirent_name, replace=False, username=username, need_progress=1) is_dir = True if dirent_type == 'dir' else False except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if operation == 'copy': # permission check for src parent dir if not check_folder_permission(request, src_repo_id, src_parent_dir): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: res = seafile_api.copy_file(src_repo_id, src_parent_dir, src_dirent_name, dst_repo_id, dst_parent_dir, new_dirent_name, username=username, need_progress=1) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not res: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = {} if res.background: result['task_id'] = res.task_id return Response(result)
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) 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, 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_and_related_review(repo.id, path, is_draft) review_id = review['review_id'] 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 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): # rename, move, copy or create file 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) path = request.GET.get('p', '') if not path or path[0] != '/': error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) username = request.user.username parent_dir = os.path.dirname(path) operation = request.POST.get('operation', '') if operation.lower() == 'rename': 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) if check_folder_permission(request, repo_id, path) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) newname = request.POST.get('newname', '') if not newname: error_msg = 'newname invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if len(newname) > 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 == newname: error_msg = 'The new name is the same to the old' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) newname = check_filename_with_rename(repo_id, parent_dir, newname) try: seafile_api.rename_file(repo_id, parent_dir, oldname, newname, 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 request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, repo, parent_dir) else: return Response({'success': True}) elif operation.lower() == 'move': 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) # check src validation src_repo_id = repo_id src_dir = os.path.dirname(path) if check_folder_permission(request, src_repo_id, src_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check dst validation dst_repo_id = request.POST.get('dst_repo', '') dst_dir = request.POST.get('dst_dir', '') if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, 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) if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # move file if dst_dir[ -1] != '/': # Append '/' to the end of directory if necessary dst_dir += '/' if src_repo_id == dst_repo_id and src_dir == dst_dir: return Response({'success': True}) filename = os.path.basename(path) new_filename = 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_filename, 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) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, dst_repo, dst_dir) else: return Response({'success': True}) elif operation.lower() == 'copy': 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) # check src validation src_repo_id = repo_id src_dir = os.path.dirname(path) if check_folder_permission(request, src_repo_id, src_dir) is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check dst validation dst_repo_id = request.POST.get('dst_repo', '') dst_dir = request.POST.get('dst_dir', '') if not dst_repo_id: error_msg = 'dst_repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 dst_dir: error_msg = 'dst_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, 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) if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # copy file if dst_dir[ -1] != '/': # Append '/' to the end of directory if necessary dst_dir += '/' if src_repo_id == dst_repo_id and src_dir == dst_dir: return Response({'success': True}) filename = os.path.basename(path) new_filename = 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_filename, 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) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, dst_repo, dst_dir) else: return Response({'success': True}) elif operation.lower() == 'create': 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) if check_folder_permission(request, repo_id, parent_dir) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) new_file_name = os.path.basename(path) 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) if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, repo, parent_dir) else: return Response({'success': True})