From 2470dd76225d378231dffcd367b046a6a298a0d1 Mon Sep 17 00:00:00 2001 From: wangjianhui Date: Fri, 16 Nov 2018 14:56:44 +0800 Subject: [PATCH] tag-filter-file and modify-permission-check --- seahub/api2/endpoints/file_tag.py | 2 +- seahub/api2/endpoints/repo_tags.py | 41 +++++++++++++++---- seahub/api2/endpoints/tag_filter_file.py | 50 ++++++++++++++++++++++++ seahub/urls.py | 2 + seahub/utils/file_tags.py | 31 +++++++++++++++ 5 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 seahub/api2/endpoints/tag_filter_file.py diff --git a/seahub/api2/endpoints/file_tag.py b/seahub/api2/endpoints/file_tag.py index 906323b035..4ffee45a79 100644 --- a/seahub/api2/endpoints/file_tag.py +++ b/seahub/api2/endpoints/file_tag.py @@ -52,7 +52,7 @@ class RepoFileTagsView(APIView): return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check - if check_folder_permission(request, repo_id, '/') is None: + if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) diff --git a/seahub/api2/endpoints/repo_tags.py b/seahub/api2/endpoints/repo_tags.py index 081dd7e562..20efd06732 100644 --- a/seahub/api2/endpoints/repo_tags.py +++ b/seahub/api2/endpoints/repo_tags.py @@ -1,5 +1,6 @@ # _*_ coding:utf-8 _*_ import logging +from collections import defaultdict from rest_framework.views import APIView from rest_framework.response import Response @@ -10,7 +11,8 @@ from rest_framework import status from seahub.api2.authentication import TokenAuthentication from seahub.api2.throttling import UserRateThrottle from seahub.repo_tags.models import RepoTags -from seahub.api2.utils import api_error +from seahub.file_tags.models import FileTags +from seahub.api2.utils import api_error, to_python_boolean from seahub.views import check_folder_permission from seahub.constants import PERMISSION_READ_WRITE @@ -27,6 +29,13 @@ class RepoTagsView(APIView): def get(self, request, repo_id): """list all repo_tags by repo_id. """ + # argument check + include_file_count = request.GET.get('include_file_count', 'true') + if include_file_count not in ['true', 'false']: + error_msg = 'include_file_count invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + include_file_count = to_python_boolean(include_file_count) + # resource check repo = seafile_api.get_repo(repo_id) if not repo: @@ -34,22 +43,40 @@ class RepoTagsView(APIView): return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check - if check_folder_permission(request, repo_id, '/') is None: + if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) - tags = [] + # get files tags + files_count = defaultdict(int) + if include_file_count: + try: + files_tags = FileTags.objects.select_related('repo_tag').filter(repo_tag__repo_id=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) + for file_tag in files_tags: + files_count[file_tag.repo_tag_id] += 1 + + repo_tags = [] try: - tag_list = RepoTags.objects.get_all_by_repo_id(repo_id) + repo_tag_list = RepoTags.objects.get_all_by_repo_id(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) - for tag in tag_list: - tags.append(tag.to_dict()) + for repo_tag in repo_tag_list: + res = repo_tag.to_dict() + repo_tag_id = res["repo_tag_id"] + if files_count.has_key(repo_tag_id): + res["files_count"] = files_count[repo_tag_id] + else: + res["files_count"] = 0 + repo_tags.append(res) - return Response({"repo_tags": tags}, status=status.HTTP_200_OK) + return Response({"repo_tags": repo_tags}, status=status.HTTP_200_OK) def post(self, request, repo_id): """add one repo_tag. diff --git a/seahub/api2/endpoints/tag_filter_file.py b/seahub/api2/endpoints/tag_filter_file.py new file mode 100644 index 0000000000..1d0911a5c8 --- /dev/null +++ b/seahub/api2/endpoints/tag_filter_file.py @@ -0,0 +1,50 @@ +# _*_ coding:utf-8 _*_ +import logging + +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.authentication import SessionAuthentication +from rest_framework.permissions import IsAuthenticated +from rest_framework import status + +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.throttling import UserRateThrottle +from seahub.repo_tags.models import RepoTags +from seahub.utils.file_tags import get_tagged_files +from seahub.api2.utils import api_error +from seahub.views import check_folder_permission + +from seaserv import seafile_api + +logger = logging.getLogger(__name__) + + +class TaggedFilesView(APIView): + + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated,) + throttle_classes = (UserRateThrottle,) + + def get(self, request, repo_id, repo_tag_id): + """list tagged files by repo tag + """ + # 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) + + repo_tag = RepoTags.objects.get_repo_tag_by_id(repo_tag_id) + if not repo_tag: + error_msg = 'repo_tag %s not found.' % repo_tag_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # permission check + if not check_folder_permission(request, repo_id, '/'): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + # get tagged files dict + tagged_files = get_tagged_files(repo, repo_tag_id) + + return Response(tagged_files, status=status.HTTP_200_OK) diff --git a/seahub/urls.py b/seahub/urls.py index 51b57758ca..cfa188d588 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -76,6 +76,7 @@ from seahub.api2.endpoints.revision_tag import TaggedItemsView, TagNamesView from seahub.api2.endpoints.user import User from seahub.api2.endpoints.repo_tags import RepoTagsView, RepoTagView from seahub.api2.endpoints.file_tag import RepoFileTagsView, RepoFileTagView +from seahub.api2.endpoints.tag_filter_file import TaggedFilesView # Admin from seahub.api2.endpoints.admin.revision_tag import AdminTaggedItemsView @@ -299,6 +300,7 @@ urlpatterns = [ url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/repo-tags/(?P\d+)/$', RepoTagView.as_view(), name='api-v2.1-repo-tag'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file-tags/$', RepoFileTagsView.as_view(), name='api-v2.1-file-tags'), url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file-tags/(?P\d+)/$', RepoFileTagView.as_view(), name='api-v2.1-file-tag'), + url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/tagged-files/(?P\d+)/$', TaggedFilesView.as_view(), name='api-v2.1-tagged-files'), # Deprecated url(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/tags/$', FileTagsView.as_view(), name="api-v2.1-filetags-view"), diff --git a/seahub/utils/file_tags.py b/seahub/utils/file_tags.py index e623f0e149..b6ffa587f2 100644 --- a/seahub/utils/file_tags.py +++ b/seahub/utils/file_tags.py @@ -1,7 +1,12 @@ # -*- coding: utf-8 -*- import logging +import posixpath from collections import defaultdict +from seaserv import seafile_api + +from seahub.base.templatetags.seahub_tags import email2nickname, email2contact_email +from seahub.utils.timeutils import timestamp_to_isoformat_timestr from seahub.file_tags.models import FileTags @@ -24,3 +29,29 @@ def get_files_tags_in_dir(repo_id, path): files_tags_in_dir[file_tag.file_uuid.filename].append(file_tag_dict) return files_tags_in_dir + + +def get_tagged_files(repo, repo_tag_id): + + # get tagged files + tagged_file_objs = FileTags.objects.filter( + repo_tag__id=repo_tag_id).select_related('repo_tag', 'file_uuid') + + tagged_files = defaultdict(list) + for tagged_file_obj in tagged_file_objs: + parent_path = tagged_file_obj.file_uuid.parent_path + filename = tagged_file_obj.file_uuid.filename + file_path = posixpath.join(parent_path, filename) + + tagged_file = dict() + file_obj = seafile_api.get_dirent_by_path(repo.store_id, file_path) + tagged_file["parent_path"] = parent_path + tagged_file["filename"] = filename + tagged_file["size"] = file_obj.size + tagged_file["last_modified"] = timestamp_to_isoformat_timestr(file_obj.mtime) + tagged_file["modifier_email"] = file_obj.modifier + tagged_file["modifier_contact_email"] = email2contact_email(file_obj.modifier) + tagged_file["modifier_name"] = email2nickname(file_obj.modifier) + tagged_files["tagged_files"].append(tagged_file) + + return tagged_files