From 3e81a5b8a86764f854b100352e515eae5081d39a Mon Sep 17 00:00:00 2001 From: lian Date: Tue, 4 Jul 2017 14:07:26 +0800 Subject: [PATCH] add dir detail api --- seahub/api2/endpoints/dir.py | 65 +++++++++++++++++++++++++++- seahub/urls.py | 3 +- tests/api/endpoints/test_dir_view.py | 49 +++++++++++++++++++++ 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/seahub/api2/endpoints/dir.py b/seahub/api2/endpoints/dir.py index 5dec7d5219..8e41878a78 100644 --- a/seahub/api2/endpoints/dir.py +++ b/seahub/api2/endpoints/dir.py @@ -16,7 +16,8 @@ from seahub.api2.views import get_dir_recursively, \ get_dir_entrys_by_id from seahub.views import check_folder_permission -from seahub.utils import check_filename_with_rename, is_valid_dirent_name +from seahub.utils import check_filename_with_rename, is_valid_dirent_name, \ + normalize_dir_path from seahub.utils.timeutils import timestamp_to_isoformat_timestr from seaserv import seafile_api @@ -297,3 +298,65 @@ class DirView(APIView): return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True}) + + +class DirDetailView(APIView): + """ Get detailed info of a folder. + """ + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, ) + throttle_classes = (UserRateThrottle, ) + + def get(self, request, repo_id): + """ Get dir info. + + Permission checking: + 1. user with either 'r' or 'rw' permission. + """ + + # parameter check + path = request.GET.get('path', None) + if not path: + error_msg = 'path invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + path = normalize_dir_path(path) + if path == '/': + error_msg = 'path 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) + + 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 not check_folder_permission(request, repo_id, path): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + try: + dir_obj = seafile_api.get_dirent_by_path(repo_id, path) + count_info = seafile_api.get_file_count_info_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) + + dir_info = { + 'repo_id': repo_id, + 'path': path, + 'name': dir_obj.obj_name, + 'file_count': count_info.file_count, + 'dir_count': count_info.dir_count, + 'size': count_info.size, + 'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime), + } + + return Response(dir_info) diff --git a/seahub/urls.py b/seahub/urls.py index 2995c08357..a098e45c1c 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -28,7 +28,7 @@ from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink from seahub.api2.endpoints.repos_batch import ReposBatchView from seahub.api2.endpoints.repos import RepoView from seahub.api2.endpoints.file import FileView -from seahub.api2.endpoints.dir import DirView +from seahub.api2.endpoints.dir import DirView, DirDetailView from seahub.api2.endpoints.repo_trash import RepoTrash from seahub.api2.endpoints.deleted_repos import DeletedRepos from seahub.api2.endpoints.repo_history import RepoHistory @@ -214,6 +214,7 @@ urlpatterns = patterns( url(r'^api/v2.1/deleted-repos/$', DeletedRepos.as_view(), name='api2-v2.1-deleted-repos'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file/$', FileView.as_view(), name='api-v2.1-file-view'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/dir/$', DirView.as_view(), name='api-v2.1-dir-view'), + url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/dir/detail/$', DirDetailView.as_view(), name='api-v2.1-dir-detail-view'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/trash/$', RepoTrash.as_view(), name='api-v2.1-repo-trash'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/history/$', RepoHistory.as_view(), name='api-v2.1-repo-history'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/set-password/$', RepoSetPassword.as_view(), name="api-v2.1-repo-set-password"), diff --git a/tests/api/endpoints/test_dir_view.py b/tests/api/endpoints/test_dir_view.py index ea25484463..ee226829b7 100644 --- a/tests/api/endpoints/test_dir_view.py +++ b/tests/api/endpoints/test_dir_view.py @@ -364,3 +364,52 @@ class DirViewTest(BaseTestCase): resp = self.client.delete(self.url + '?p=' + self.folder_path, {}, 'application/x-www-form-urlencoded') self.assertEqual(403, resp.status_code) + + +class DirDetailViewTest(BaseTestCase): + + def setUp(self): + self.repo_id = self.repo.id + self.folder_path = self.folder + self.folder_name = os.path.basename(self.folder_path) + + self.user_name = self.user.username + self.admin_name = self.admin.username + + self.url = reverse('api-v2.1-dir-detail-view', args=[self.repo_id]) + + def tearDown(self): + self.remove_repo() + + def test_can_get_dir_detail(self): + + seafile_api.post_dir(self.repo_id, self.folder_path, randstring(3), + self.user_name) + seafile_api.post_empty_file(self.repo_id, self.folder_path, randstring(3), + self.user_name) + + self.login_as(self.user) + resp = self.client.get(self.url + '?path=%s' % self.folder_path) + self.assertEqual(200, resp.status_code) + json_resp = json.loads(resp.content) + + assert json_resp['name'] == self.folder_name + assert json_resp['file_count'] == 1 + assert json_resp['dir_count'] == 1 + + def test_get_dir_detail_with_invalid_perm(self): + + self.login_as(self.admin) + + resp = self.client.get(self.url + '?path=%s' % self.folder_path) + self.assertEqual(403, resp.status_code) + + def test_get_dir_detail_without_path_parameter(self): + + self.login_as(self.user) + + resp = self.client.get(self.url) + self.assertEqual(400, resp.status_code) + + resp = self.client.get(self.url + '?path=/') + self.assertEqual(400, resp.status_code)