diff --git a/seahub/api2/endpoints/activities.py b/seahub/api2/endpoints/activities.py index 36d9dbd98f..8582e3a0e8 100644 --- a/seahub/api2/endpoints/activities.py +++ b/seahub/api2/endpoints/activities.py @@ -17,7 +17,6 @@ from seahub.api2.throttling import UserRateThrottle from seahub.api2.authentication import TokenAuthentication from seahub.base.templatetags.seahub_tags import email2nickname from seahub.avatar.templatetags.avatar_tags import api_avatar_url -from seahub.drafts.models import Draft logger = logging.getLogger(__name__) @@ -81,19 +80,6 @@ class ActivitiesView(APIView): d['old_name'] = os.path.basename(e.old_path) elif e.op_type == 'publish': d['old_path'] = e.old_path - elif d['name'].endswith('(draft).md'): - if e.op_type in ('create', 'edit') and e.obj_type == 'file': - try: - draft = Draft.objects.filter(username=e.op_user, - origin_repo_id=e.repo_id, - draft_file_path=e.path) - if draft: - draft = draft[0] - d['draft_id'] = draft.id - else: - Draft.DoesNotExist - except Draft.DoesNotExist: - pass events_list.append(d) diff --git a/seahub/api2/endpoints/admin/user_activities.py b/seahub/api2/endpoints/admin/user_activities.py index 0f7fbb4c81..057063840b 100644 --- a/seahub/api2/endpoints/admin/user_activities.py +++ b/seahub/api2/endpoints/admin/user_activities.py @@ -18,7 +18,6 @@ from seahub.api2.throttling import UserRateThrottle from seahub.api2.authentication import TokenAuthentication from seahub.base.templatetags.seahub_tags import email2nickname from seahub.avatar.templatetags.avatar_tags import api_avatar_url -from seahub.drafts.models import Draft logger = logging.getLogger(__name__) @@ -98,20 +97,6 @@ class UserActivitiesView(APIView): d['old_name'] = os.path.basename(e.old_path) elif e.op_type == 'publish': d['old_path'] = e.old_path - elif d['name'].endswith('(draft).md'): - if e.op_type in ('create', 'edit') and e.obj_type == 'file': - try: - draft = Draft.objects.filter(username=e.op_user, - origin_repo_id=e.repo_id, - draft_file_path=e.path) - if draft: - draft = draft[0] - d['draft_id'] = draft.id - else: - Draft.DoesNotExist - except Draft.DoesNotExist: - pass - events_list.append(d) response = {'events': events_list} diff --git a/seahub/api2/endpoints/admin/users.py b/seahub/api2/endpoints/admin/users.py index 9cc328ff4a..5093bfb6e7 100644 --- a/seahub/api2/endpoints/admin/users.py +++ b/seahub/api2/endpoints/admin/users.py @@ -1901,26 +1901,6 @@ class AdminUpdateUserCcnetEmail(APIView): except Exception as e: logger.error(e) - try: - from seahub.drafts.models import Draft - draft_list = Draft.objects.filter(username=old_ccnet_email) - for draft in draft_list: - draft.username = new_ccnet_email - draft.save() - logger.debug('the drafts_draft table in seahub database was successfully updated') - except Exception as e: - logger.error(e) - - try: - from seahub.drafts.models import DraftReviewer - draftreviewer_list = DraftReviewer.objects.filter(reviewer=old_ccnet_email) - for draftreviewer in draftreviewer_list: - draftreviewer.reviewer = new_ccnet_email - draftreviewer.save() - logger.debug('the drafts_draftreviewer table in seahub database was successfully updated') - except Exception as e: - logger.error(e) - try: from seahub.file_participants.models import FileParticipant fileparticipant_list = FileParticipant.objects.filter(username=old_ccnet_email) diff --git a/seahub/api2/endpoints/draft_reviewer.py b/seahub/api2/endpoints/draft_reviewer.py deleted file mode 100644 index b581aeac93..0000000000 --- a/seahub/api2/endpoints/draft_reviewer.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright (c) 2012-2016 Seafile Ltd. -import posixpath - -from rest_framework import status -from rest_framework.authentication import SessionAuthentication -from rest_framework.permissions import IsAuthenticated -from rest_framework.response import Response -from rest_framework.views import APIView - -from django.utils.translation import gettext as _ - -from seaserv import seafile_api -from seahub.api2.authentication import TokenAuthentication -from seahub.api2.throttling import UserRateThrottle -from seahub.api2.utils import api_error, user_to_dict - -from seahub.base.templatetags.seahub_tags import email2nickname -from seahub.base.accounts import User -from seahub.tags.models import FileUUIDMap -from seahub.views import check_folder_permission -from seahub.utils import is_valid_username -from seahub.drafts.models import Draft, DraftReviewer -from seahub.drafts.signals import request_reviewer_successful - - -class DraftReviewerView(APIView): - authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated, ) - throttle_classes = (UserRateThrottle, ) - - def get(self, request, pk, format=None): - try: - d = Draft.objects.get(pk=pk) - except Draft.DoesNotExist: - return api_error(status.HTTP_404_NOT_FOUND, - 'Draft %s not found' % pk) - - # format user result - try: - avatar_size = int(request.GET.get('avatar_size', 32)) - except ValueError: - avatar_size = 32 - - # get reviewer list - reviewers = [] - for x in d.draftreviewer_set.all(): - reviewer = user_to_dict(x.reviewer, request=request) - reviewers.append(reviewer) - - return Response({'reviewers': reviewers}) - - def post(self, request, pk, format=None): - """add draft reviewer - """ - try: - d = Draft.objects.get(pk=pk) - except Draft.DoesNotExist: - return api_error(status.HTTP_404_NOT_FOUND, - 'Draft %s not found' % pk) - - result = {} - result['failed'] = [] - result['success'] = [] - - reviewers = request.data.getlist('reviewer') - for reviewer in reviewers: - if not is_valid_username(reviewer): - result['failed'].append({ - 'email': reviewer, - 'error_msg': _('username invalid.') - }) - continue - - try: - User.objects.get(email=reviewer) - except User.DoesNotExist: - result['failed'].append({ - 'email': reviewer, - 'error_msg': _('User %s not found.') % reviewer - }) - continue - - # can't share to owner - if reviewer == d.username: - error_msg = 'Draft can not be asked owner to review.' - result['failed'].append({ - 'email': reviewer, - 'error_msg': error_msg - }) - continue - - uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid) - origin_file_path = posixpath.join(uuid.parent_path, uuid.filename) - # check perm - if seafile_api.check_permission_by_path(d.origin_repo_id, origin_file_path, reviewer) != 'rw': - error_msg = _('Permission denied.') - result['failed'].append({ - 'email': reviewer, - 'error_msg': error_msg - }) - continue - - if DraftReviewer.objects.filter(draft=d, reviewer=reviewer): - error_msg = 'Reviewer %s has existed.' % reviewer - result['failed'].append({ - 'email': reviewer, - 'error_msg': error_msg - }) - continue - - result['success'].append({ - "user_info": { - "name": reviewer, - "nickname": email2nickname(reviewer) - } - }) - - DraftReviewer.objects.add(reviewer, d) - - request_reviewer_successful.send(sender=None, from_user=request.user.username, - to_user=reviewer, draft_id=d.id) - - return Response(result) - - def delete(self, request, pk): - """Delete a reviewer - """ - try: - d = Draft.objects.get(pk=pk) - except Draft.DoesNotExist: - return api_error(status.HTTP_404_NOT_FOUND, - 'Draft %s not found' % pk) - - perm = check_folder_permission(request, d.origin_repo_id, '/') - - if perm is None: - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - reviewer = request.GET.get('username') - - if reviewer is None: - return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % reviewer) - - try: - reviewer = DraftReviewer.objects.get(reviewer=reviewer, draft=d) - except DraftReviewer.DoesNotExist: - return Response(status.HTTP_200_OK) - - reviewer.delete() - - return Response(status.HTTP_200_OK) diff --git a/seahub/api2/endpoints/drafts.py b/seahub/api2/endpoints/drafts.py deleted file mode 100644 index e7468e2b73..0000000000 --- a/seahub/api2/endpoints/drafts.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright (c) 2012-2016 Seafile Ltd. -import os -import json -import logging -import posixpath - -from rest_framework import status -from rest_framework.authentication import SessionAuthentication -from rest_framework.permissions import IsAuthenticated -from rest_framework.response import Response -from rest_framework.views import APIView -from seaserv import seafile_api - -from seahub.api2.authentication import TokenAuthentication -from seahub.api2.endpoints.utils import add_org_context -from seahub.api2.throttling import UserRateThrottle -from seahub.api2.utils import api_error -from seahub.constants import PERMISSION_READ_WRITE -from seahub.drafts.models import Draft, DraftFileExist -from seahub.tags.models import FileUUIDMap -from seahub.views import check_folder_permission -from seahub.drafts.utils import send_draft_publish_msg - -logger = logging.getLogger(__name__) - -HTTP_520_OPERATION_FAILED = 520 - - -class DraftsView(APIView): - authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated, ) - throttle_classes = (UserRateThrottle, ) - - def get(self, request, format=None): - """List all user drafts. - """ - username = request.user.username - data = Draft.objects.list_draft_by_username(username) - - draft_counts = len(data) - - result = {} - result['data'] = data - result['draft_counts'] = draft_counts - - return Response(result) - - @add_org_context - def post(self, request, org_id, format=None): - """Create a file draft if the user has read-write permission to the origin file - """ - - # argument check - repo_id = request.data.get('repo_id', '') - if not repo_id: - error_msg = 'repo_id invalid.' - return api_error(status.HTTP_400_BAD_REQUEST, error_msg) - - file_path = request.data.get('file_path', '') - if not file_path: - error_msg = 'file_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) - - file_id = seafile_api.get_file_id_by_path(repo_id, file_path) - if not file_id: - error_msg = 'File %s not found.' % file_path - return api_error(status.HTTP_404_NOT_FOUND, error_msg) - - # permission check - perm = check_folder_permission(request, repo_id, file_path) - if perm != PERMISSION_READ_WRITE: - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - username = request.user.username - - # create drafts dir if does not exist - draft_dir_id = seafile_api.get_dir_id_by_path(repo_id, '/Drafts') - if draft_dir_id is None: - seafile_api.post_dir(repo_id, '/', 'Drafts', username) - - # create draft - try: - d = Draft.objects.add(username, repo, file_path, file_id=file_id) - return Response(d.to_dict()) - except DraftFileExist: - return api_error(status.HTTP_409_CONFLICT, 'Draft already exists.') - except Exception as e: - logger.error(e) - error_msg = 'Internal Server Error' - return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) - - -class DraftView(APIView): - authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated, ) - throttle_classes = (UserRateThrottle, ) - - def put(self, request, pk, format=None): - """Publish a draft if the user has read-write permission to the origin file - - Process: - 1. Overwrite the origin file with the draft file. - If origin file's parent folder does NOT exist, move draft file to library's root folder. - 2. Update draft database info. - 3. Send draft file publish msg. - """ - - # resource check - try: - draft = Draft.objects.get(pk=pk) - except Draft.DoesNotExist: - return api_error(status.HTTP_404_NOT_FOUND, - 'Draft %s not found.' % pk) - - repo_id = draft.origin_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 - origin_file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(draft.origin_file_uuid) - if origin_file_uuid and seafile_api.get_dir_id_by_path(repo_id, - origin_file_uuid.parent_path): - permission = check_folder_permission(request, repo_id, origin_file_uuid.parent_path) - else: - permission = check_folder_permission(request, repo_id, '/') - - if permission != PERMISSION_READ_WRITE: - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - # 1. Overwrite the origin file with the draft file. - # If origin file's parent folder does NOT exist, move draft file to library's root folder. - - # get origin file info - origin_file_parent_path = origin_file_uuid.parent_path if origin_file_uuid else '' - - # check if origin file's parent folder exists - if not seafile_api.get_dir_id_by_path(repo_id, origin_file_parent_path): - dst_parent_path = '/' - else: - dst_parent_path = origin_file_parent_path - - # get draft file info - draft_file_name = os.path.basename(draft.draft_file_path) - draft_file_parent_path = os.path.dirname(draft.draft_file_path) - - f = os.path.splitext(draft_file_name)[0][:-7] - file_type = os.path.splitext(draft_file_name)[-1] - dst_file_name = f + file_type - - # move draft file - username = request.user.username - seafile_api.move_file(repo_id, draft_file_parent_path, - json.dumps([draft_file_name]), - repo_id, dst_parent_path, - json.dumps([dst_file_name]), - replace=1, username=username, - need_progress=0, synchronous=1) - - try: - # 2. Update draft database info. - dst_file_path = posixpath.join(dst_parent_path, dst_file_name) - dst_file_id = seafile_api.get_file_id_by_path(repo_id, dst_file_path) - draft.update(dst_file_id) - - # 3. Send draft file publish msg. - send_draft_publish_msg(draft, username, dst_file_path) - - result = {} - result['published_file_path'] = dst_file_path - result['draft_status'] = draft.status - return Response(result) - except Exception as e: - logger.error(e) - error_msg = 'Internal Server Error' - return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) - - def delete(self, request, pk, format=None): - """Delete a draft if user is draft owner or has repo rw permission - """ - username = request.user.username - try: - d = Draft.objects.get(pk=pk) - except Draft.DoesNotExist: - return api_error(status.HTTP_404_NOT_FOUND, - 'Draft %s not found.' % pk) - - # perm check - if d.username != username: - perm = check_folder_permission(request, d.origin_repo_id, '/') - if perm != PERMISSION_READ_WRITE: - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - d.delete(operator=username) - - return Response(status.HTTP_200_OK) diff --git a/seahub/api2/endpoints/file.py b/seahub/api2/endpoints/file.py index 740189688e..8d33e30f4e 100644 --- a/seahub/api2/endpoints/file.py +++ b/seahub/api2/endpoints/file.py @@ -37,10 +37,6 @@ from seahub.base.models import FileComment from seahub.settings import MAX_UPLOAD_FILE_NAME_LEN, OFFICE_TEMPLATE_ROOT from seahub.api2.endpoints.utils import convert_file, sdoc_convert_to_docx from seahub.seadoc.utils import get_seadoc_file_uuid - -from seahub.drafts.models import Draft -from seahub.drafts.utils import is_draft_file, get_file_draft - from seaserv import seafile_api from pysearpc import SearpcError @@ -170,8 +166,6 @@ class FileView(APIView): username = request.user.username parent_dir = os.path.dirname(path) - is_draft = request.POST.get('is_draft', '') - if operation == 'create': # resource check @@ -191,17 +185,6 @@ class FileView(APIView): 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) @@ -223,9 +206,6 @@ class FileView(APIView): 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) - LANGUAGE_DICT = { 'cs': 'cs-CZ', 'de': 'de-DE', @@ -349,18 +329,6 @@ class FileView(APIView): # rename draft file filetype, fileext = get_file_type_and_ext(new_file_name) - if filetype == MARKDOWN or filetype == TEXT: - is_draft = is_draft_file(repo.id, path) - review = get_file_draft(repo.id, path, is_draft) - draft_id = review['draft_id'] - if is_draft: - try: - draft = Draft.objects.get(pk=draft_id) - draft.draft_file_path = new_file_path - draft.save() - except Draft.DoesNotExist: - pass - file_info = self.get_file_info(username, repo_id, new_file_path) return Response(file_info) diff --git a/seahub/api2/endpoints/file_comments.py b/seahub/api2/endpoints/file_comments.py deleted file mode 100644 index e2d8416f39..0000000000 --- a/seahub/api2/endpoints/file_comments.py +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright (c) 2012-2016 Seafile Ltd. -import logging - -from rest_framework import status -from rest_framework.authentication import SessionAuthentication -from rest_framework.permissions import IsAuthenticated -from rest_framework.response import Response -from rest_framework.views import APIView -from seaserv import seafile_api -from pysearpc import SearpcError -from django.urls import reverse - -from seahub.api2.authentication import TokenAuthentication -from seahub.api2.permissions import IsRepoAccessible -from seahub.api2.throttling import UserRateThrottle -from seahub.api2.utils import api_error, user_to_dict, to_python_boolean -from seahub.avatar.settings import AVATAR_DEFAULT_SIZE -from seahub.base.models import FileComment -from seahub.utils.repo import get_repo_owner -from seahub.signals import comment_file_successful -from seahub.drafts.signals import comment_draft_successful -from seahub.drafts.utils import is_draft_file -from seahub.drafts.models import Draft -from seahub.api2.endpoints.utils import generate_links_header_for_paginator -from seahub.views import check_folder_permission - -logger = logging.getLogger(__name__) - - -class FileCommentsView(APIView): - authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated, IsRepoAccessible) - throttle_classes = (UserRateThrottle, ) - - def get(self, request, repo_id, format=None): - """List all comments of a file. - """ - path = request.GET.get('p', '/').rstrip('/') - if not path: - return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') - - resolved = request.GET.get('resolved', None) - if resolved not in ('true', 'false', None): - error_msg = 'resolved invalid.' - return api_error(status.HTTP_400_BAD_REQUEST, error_msg) - - # permission check - if check_folder_permission(request, repo_id, '/') is None: - return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') - - try: - page = int(request.GET.get('page', '1')) - per_page = int(request.GET.get('per_page', '25')) - except ValueError: - page = 1 - per_page = 25 - - start = (page - 1) * per_page - end = page * per_page - - total_count = FileComment.objects.get_by_file_path(repo_id, path).count() - comments = [] - - if resolved is None: - file_comments = FileComment.objects.get_by_file_path(repo_id, path)[start: end] - else: - comment_resolved = to_python_boolean(resolved) - file_comments = FileComment.objects.get_by_file_path(repo_id, path).filter(resolved=comment_resolved)[start: end] - - for file_comment in file_comments: - comment = file_comment.to_dict() - comment.update(user_to_dict(file_comment.author, request=request)) - comments.append(comment) - - result = {'comments': comments, 'total_count': total_count} - resp = Response(result) - base_url = reverse('api2-file-comments', args=[repo_id]) - links_header = generate_links_header_for_paginator(base_url, page, - per_page, total_count) - resp['Links'] = links_header - return resp - - def post(self, request, repo_id, format=None): - """Post a comments of a file. - """ - # argument check - path = request.GET.get('p', '/').rstrip('/') - if not path: - return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') - - comment = request.data.get('comment', '') - if not comment: - return api_error(status.HTTP_400_BAD_REQUEST, 'Comment can not be empty.') - - try: - avatar_size = int(request.GET.get('avatar_size', - AVATAR_DEFAULT_SIZE)) - except ValueError: - avatar_size = AVATAR_DEFAULT_SIZE - - # resource check - try: - file_id = seafile_api.get_file_id_by_path(repo_id, path) - except SearpcError as e: - logger.error(e) - return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, - 'Internal Server Error') - if not file_id: - return api_error(status.HTTP_404_NOT_FOUND, 'File not found.') - - # permission check - if check_folder_permission(request, repo_id, '/') is None: - return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') - - detail = request.data.get('detail', '') - username = request.user.username - file_comment = FileComment.objects.add_by_file_path( - repo_id=repo_id, file_path=path, author=username, comment=comment, detail=detail) - repo = seafile_api.get_repo(repo_id) - repo_owner = get_repo_owner(request, repo.id) - - if is_draft_file(repo_id, path): - draft = Draft.objects.filter(origin_repo_id=repo_id, draft_file_path=path) - if draft: - draft = draft[0] - comment_draft_successful.send(sender=None, - draft=draft, - comment=comment, - author=username) - else: - Draft.DoesNotExist - else: - comment_file_successful.send(sender=None, - repo=repo, - repo_owner=repo_owner, - file_path=path, - comment=comment, - author=username) - - comment = file_comment.to_dict() - comment.update(user_to_dict(username, request=request)) - return Response(comment, status=201) diff --git a/seahub/api2/endpoints/recent_added_files.py b/seahub/api2/endpoints/recent_added_files.py index 83d9deb547..fbba0a816f 100644 --- a/seahub/api2/endpoints/recent_added_files.py +++ b/seahub/api2/endpoints/recent_added_files.py @@ -12,7 +12,6 @@ from seahub.api2.throttling import UserRateThrottle from seahub.api2.authentication import TokenAuthentication from seahub.utils import EVENTS_ENABLED, get_user_activities_by_timestamp from seahub.api2.utils import api_error -from seahub.drafts.models import Draft logger = logging.getLogger(__name__) @@ -59,22 +58,6 @@ class RecentAddedFilesView(APIView): file_dict = dict(repo_id=event.repo_id) file_dict['path'] = event.path file_dict['added_time'] = event.timestamp - - if event.path.endswith('(draft).md'): - try: - draft = Draft.objects.filter( - username=event.op_user, - origin_repo_id=event.repo_id, - draft_file_path=event.path - ) - if draft: - draft = draft[0] - file_dict['draft_id'] = draft.id - else: - logger.warning('draft %s not found' % event.path) - except Draft.DoesNotExist: - pass - recent_added_files.append(file_dict) return Response({'recent_added_files': recent_added_files}) diff --git a/seahub/api2/endpoints/repo_draft_info.py b/seahub/api2/endpoints/repo_draft_info.py index 2c4bf44f5c..e1a46426be 100644 --- a/seahub/api2/endpoints/repo_draft_info.py +++ b/seahub/api2/endpoints/repo_draft_info.py @@ -15,57 +15,5 @@ from seahub.api2.throttling import UserRateThrottle from seahub.api2.utils import api_error from seahub.views import check_folder_permission -from seahub.drafts.models import Draft logger = logging.getLogger(__name__) - - -class RepoDraftCounts(APIView): - authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated, ) - throttle_classes = (UserRateThrottle, ) - - def get(self, request, repo_id, format=None): - 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) - - # check perm - perm = check_folder_permission(request, repo_id, '/') - if not perm: - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - result = {} - - # get draft counts - result['draft_counts'] = Draft.objects.get_draft_counts_by_repo_id(repo_id) - - return Response(result) - - -class RepoDraftInfo(APIView): - authentication_classes = (TokenAuthentication, SessionAuthentication) - permission_classes = (IsAuthenticated, ) - throttle_classes = (UserRateThrottle, ) - - def get(self, request, repo_id, format=None): - 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) - - # check perm - perm = check_folder_permission(request, repo_id, '/') - if not perm: - error_msg = 'Permission denied.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) - - result = {} - - # list draft - drafts = Draft.objects.list_draft_by_repo_id(repo_id) - result['drafts'] = drafts - - return Response(result) diff --git a/seahub/api2/endpoints/share_links.py b/seahub/api2/endpoints/share_links.py index 0f554e2448..944a9ccd93 100644 --- a/seahub/api2/endpoints/share_links.py +++ b/seahub/api2/endpoints/share_links.py @@ -1120,14 +1120,13 @@ class ShareLinkUploadDone(APIView): share_link = None upload_link = None - try: - share_link = FileShare.objects.get_valid_dir_link_by_token(token=token) - except FileShare.DoesNotExist: - upload_link = UploadLinkShare.objects.get(token=token) - except UploadLinkShare.DoesNotExist: + share_link = FileShare.objects.get_valid_dir_link_by_token(token=token) + upload_link = UploadLinkShare.objects.filter(token=token).first() + + if not (share_link or upload_link): error_msg = 'token %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) - + if share_link: # check if login required @@ -1182,7 +1181,7 @@ class ShareLinkUploadDone(APIView): if upload_link.is_expired(): error_msg = 'Upload link is expired' return api_error(status.HTTP_403_FORBIDDEN, error_msg) - + repo_id = upload_link.repo_id repo = seafile_api.get_repo(repo_id) if not repo: @@ -1196,7 +1195,7 @@ class ShareLinkUploadDone(APIView): link_owner) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) - + # send signal dirent_path = request.data.get('file_path') if not dirent_path: diff --git a/seahub/api2/endpoints/via_repo_token.py b/seahub/api2/endpoints/via_repo_token.py index 31c4f34b1e..a9db942280 100644 --- a/seahub/api2/endpoints/via_repo_token.py +++ b/seahub/api2/endpoints/via_repo_token.py @@ -19,8 +19,6 @@ from urllib.parse import quote from seahub.api2.authentication import RepoAPITokenAuthentication from seahub.base.models import FileComment -from seahub.drafts.models import Draft -from seahub.drafts.utils import is_draft_file, get_file_draft from seahub.repo_api_tokens.utils import get_dir_file_info_list from seahub.api2.throttling import UserRateThrottle from seahub.api2.utils import api_error, to_python_boolean @@ -817,9 +815,6 @@ class ViaRepoTokenFile(APIView): username = '' parent_dir = os.path.dirname(path) - - is_draft = request.POST.get('is_draft', '') - if operation == 'create': # resource check @@ -839,17 +834,6 @@ class ViaRepoTokenFile(APIView): 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) @@ -871,9 +855,6 @@ class ViaRepoTokenFile(APIView): 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) - LANGUAGE_DICT = { 'cs': 'cs-CZ', 'de': 'de-DE', diff --git a/seahub/api2/urls.py b/seahub/api2/urls.py index b8b07f9d06..79a364bff1 100644 --- a/seahub/api2/urls.py +++ b/seahub/api2/urls.py @@ -9,9 +9,6 @@ from .endpoints.dir_shared_items import DirSharedItemsEndpoint from .endpoints.admin.account import Account from .endpoints.shared_upload_links import SharedUploadLinksView from .endpoints.be_shared_repo import BeSharedRepo -from .endpoints.file_comment import FileCommentView -from .endpoints.file_comments import FileCommentsView -from .endpoints.file_comments_counts import FileCommentsCounts from .endpoints.search_user import SearchUser from .endpoints.send_share_link_email import SendShareLinkView from .endpoints.send_upload_link_email import SendUploadLinkView @@ -57,9 +54,6 @@ urlpatterns = [ re_path(r'^repos/(?P[-0-9-a-f]{36})/file/$', FileView.as_view(), name='FileView'), re_path(r'^repos/(?P[-0-9-a-f]{36})/file/metadata/$', FileMetaDataView.as_view(), name='FileMetaDataView'), re_path(r'^repos/(?P[-0-9a-f]{36})/files/(?P[0-9a-f]{40})/blks/(?P[0-9a-f]{40})/download-link/$', FileBlockDownloadLinkView.as_view()), - re_path(r'^repos/(?P[-0-9-a-f]{36})/file/comments/$', FileCommentsView.as_view(), name='api2-file-comments'), - re_path(r'^repos/(?P[-0-9-a-f]{36})/file/comments/counts/$', FileCommentsCounts.as_view(), name='api2-file-comments-counts'), - re_path(r'^repos/(?P[-0-9-a-f]{36})/file/comments/(?P\d+)/$', FileCommentView.as_view(), name='api2-file-comment'), re_path(r'^repos/(?P[-0-9-a-f]{36})/file/detail/$', FileDetailView.as_view()), re_path(r'^repos/(?P[-0-9-a-f]{36})/file/history/$', FileHistory.as_view()), re_path(r'^repos/(?P[-0-9-a-f]{36})/file/revision/$', FileRevision.as_view()), diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 88bccf5c12..26c139a94c 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -62,9 +62,6 @@ from seahub.thumbnail.utils import generate_thumbnail from seahub.notifications.models import UserNotification from seahub.options.models import UserOptions from seahub.profile.models import Profile, DetailedProfile -from seahub.drafts.models import Draft -from seahub.drafts.utils import get_file_draft, \ - is_draft_file, has_draft_file from seahub.signals import (repo_created, repo_deleted, repo_transfer) from seahub.share.models import FileShare, OrgFileShare, UploadLinkShare from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \ @@ -3041,7 +3038,6 @@ class FileView(APIView): username = request.user.username parent_dir = os.path.dirname(path) operation = request.POST.get('operation', '') - is_draft = request.POST.get('is_draft', '') file_info = {} if operation.lower() == 'rename': @@ -3186,17 +3182,6 @@ class FileView(APIView): return api_error(status.HTTP_403_FORBIDDEN, 'You do not have permission to create file.') - 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 - new_file_name = os.path.basename(path) if not is_valid_dirent_name(new_file_name): @@ -3212,9 +3197,6 @@ class FileView(APIView): return api_error(HTTP_520_OPERATION_FAILED, 'Failed to create file.') - if is_draft.lower() == 'true': - Draft.objects.add(username, repo, path, file_exist=False) - if request.GET.get('reloaddir', '').lower() == 'true': return reloaddir(request, repo, parent_dir) else: @@ -3385,18 +3367,10 @@ class FileDetailView(APIView): file_type, file_ext = get_file_type_and_ext(file_name) if file_type == MARKDOWN: - is_draft = is_draft_file(repo_id, path) - - has_draft = False - if not is_draft: - has_draft = has_draft_file(repo_id, path) - - draft = get_file_draft(repo_id, path, is_draft, has_draft) - - entry['is_draft'] = is_draft - entry['has_draft'] = has_draft - entry['draft_file_path'] = draft['draft_file_path'] - entry['draft_id'] = draft['draft_id'] + entry['is_draft'] = False + entry['has_draft'] = False + entry['draft_file_path'] = '' + entry['draft_id'] = None # fetch file contributors and latest contributor try: diff --git a/seahub/drafts/__init__.py b/seahub/drafts/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/seahub/drafts/migrations/0001_initial.py b/seahub/drafts/migrations/0001_initial.py deleted file mode 100644 index 4c99dc0904..0000000000 --- a/seahub/drafts/migrations/0001_initial.py +++ /dev/null @@ -1,43 +0,0 @@ -# Generated by Django 4.2.2 on 2024-08-27 14:16 - -from django.db import migrations, models -import django.db.models.deletion -import seahub.base.fields - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Draft', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True, db_index=True)), - ('updated_at', models.DateTimeField(auto_now=True, db_index=True)), - ('username', seahub.base.fields.LowerCaseCharField(db_index=True, max_length=255)), - ('status', models.CharField(default='open', max_length=20)), - ('draft_file_path', models.CharField(max_length=1024)), - ('origin_repo_id', models.CharField(db_index=True, max_length=36)), - ('origin_file_uuid', models.UUIDField(unique=True)), - ('origin_file_version', models.CharField(max_length=100)), - ('publish_file_version', models.CharField(max_length=100, null=True)), - ], - options={ - 'ordering': ['-created_at', '-updated_at'], - 'abstract': False, - }, - ), - migrations.CreateModel( - name='DraftReviewer', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('reviewer', seahub.base.fields.LowerCaseCharField(db_index=True, max_length=255)), - ('draft', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='drafts.draft')), - ], - ), - ] diff --git a/seahub/drafts/migrations/__init__.py b/seahub/drafts/migrations/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/seahub/drafts/models.py b/seahub/drafts/models.py deleted file mode 100644 index 2dc87621d5..0000000000 --- a/seahub/drafts/models.py +++ /dev/null @@ -1,243 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import json -import posixpath - -from django.db import models -from seaserv import seafile_api - -from seahub.base.fields import LowerCaseCharField -from seahub.base.models import TimestampedModel -from seahub.base.templatetags.seahub_tags import email2nickname, email2contact_email -from seahub.tags.models import FileUUIDMap -from seahub.utils import normalize_file_path -from seahub.utils.timeutils import datetime_to_isoformat_timestr -from .utils import get_draft_file_name - - -class DraftFileExist(Exception): - pass - - -class DraftFileConflict(Exception): - pass - - -class OriginalFileConflict(Exception): - pass - - -class DraftManager(models.Manager): - def get_draft_counts_by_repo_id(self, repo_id, status='open'): - num = self.filter(origin_repo_id=repo_id, status='open').count() - - return num - - def list_draft_by_repo_id(self, repo_id, status='open'): - """list draft by repo id - """ - drafts = [] - qs = self.filter(origin_repo_id=repo_id, status=status) - - for d in qs: - draft = {} - draft['id'] = d.id - draft['owner_nickname'] = email2nickname(d.username) - draft['origin_repo_id'] = d.origin_repo_id - draft['draft_file_path'] = d.draft_file_path - draft['created_at'] = datetime_to_isoformat_timestr(d.created_at) - - drafts.append(draft) - - return drafts - - def list_draft_by_username(self, username, status='open'): - """list all user drafts - If with_reviews is true, return the draft associated review - """ - repo_cache = {} - - def get_repo_with_cache(repo_id, repo_cache): - """return repo object - Avoid loading the same repo multiple times - """ - if repo_id in repo_cache: - return repo_cache[repo_id] - - repo = seafile_api.get_repo(repo_id) - repo_cache[repo_id] = repo - return repo - - data = [] - qs = self.filter(username=username, status=status) - - for d in qs: - # If repo does not exist, no related items are displayed. - repo = get_repo_with_cache(d.origin_repo_id, repo_cache) - if not repo: - continue - - uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid) - file_path = posixpath.join(uuid.parent_path, uuid.filename) - - draft = {} - draft['id'] = d.id - draft['owner'] = d.username - draft['repo_name'] = repo.name - draft['owner_nickname'] = email2nickname(d.username) - draft['origin_repo_id'] = d.origin_repo_id - draft['origin_file_path'] = file_path - draft['origin_file_version'] = d.origin_file_version - draft['draft_file_path'] = d.draft_file_path - draft['created_at'] = datetime_to_isoformat_timestr(d.created_at) - draft['updated_at'] = datetime_to_isoformat_timestr(d.updated_at) - draft['status'] = d.status - - data.append(draft) - - return data - - def create_exist_file_draft(self, repo, username, file_uuid, file_path): - - # check draft file does not exists and copy origin file content to - # draft file - draft_file_name = get_draft_file_name(repo.id, file_path) - draft_file_path = '/Drafts/' + draft_file_name - - try: - # Determine if there is a draft of the file - d = self.get(origin_file_uuid=file_uuid.uuid) - except Draft.DoesNotExist: - try: - # Determine if there is a draft with the same name as - # the generated draft file path - d_2 = self.get(origin_repo_id=repo.id, draft_file_path=draft_file_path) - d_2.delete(operator=username) - except Draft.DoesNotExist: - pass - - # copy file to draft dir - seafile_api.copy_file(repo.id, file_uuid.parent_path, - json.dumps([file_uuid.filename]), - repo.id, '/Drafts', - json.dumps([draft_file_name]), - username=username, need_progress=0, synchronous=1) - - return draft_file_path - - if d: - file_id = seafile_api.get_file_id_by_path(repo.id, d.draft_file_path) - # If the database entry exists and the draft file exists, - # then raise DraftFileExist - if file_id: - raise DraftFileExist - # If the database entry exists and the draft file does not exist, - # delete the database entry - else: - d.delete(operator=username) - - # copy file to draft dir - seafile_api.copy_file(repo.id, file_uuid.parent_path, - json.dumps([file_uuid.filename]), - repo.id, '/Drafts', - json.dumps([draft_file_name]), - username=username, need_progress=0, synchronous=1) - - return draft_file_path - - def add(self, username, repo, file_path, - file_exist=True, file_id=None, org_id=-1, status='open'): - file_path = normalize_file_path(file_path) - parent_path = os.path.dirname(file_path) - filename = os.path.basename(file_path) - - # origin file uuid - file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap( - repo.id, parent_path, filename, is_dir=False) - - if file_id is None: - file_id = seafile_api.get_file_id_by_path(repo.id, file_path) - - if file_exist: - file_path = self.create_exist_file_draft(repo, username, file_uuid, file_path) - - draft = self.model(username=username, - origin_repo_id=repo.id, - origin_file_uuid=file_uuid.uuid, - status=status, - origin_file_version=file_id, - draft_file_path=file_path) - draft.save(using=self._db) - return draft - - -class Draft(TimestampedModel): - """Draft models enable user save file as drafts, and publish later. - """ - username = LowerCaseCharField(max_length=255, db_index=True) - status = models.CharField(max_length=20, default='open') - draft_file_path = models.CharField(max_length=1024) - origin_repo_id = models.CharField(max_length=36, db_index=True) - origin_file_uuid = models.UUIDField(unique=True) - origin_file_version = models.CharField(max_length=100) - publish_file_version = models.CharField(max_length=100, null=True) - - objects = DraftManager() - - # class Meta: - # unique_together = (('username', 'draft_repo_id'), ) - - def update(self, publish_file_version, status='published'): - self.publish_file_version = publish_file_version - self.status = status - self.save() - - def delete(self, operator): - draft_file_name = os.path.basename(self.draft_file_path) - draft_file_path = os.path.dirname(self.draft_file_path) - seafile_api.del_file(self.origin_repo_id, draft_file_path, - json.dumps([draft_file_name]), operator) - - super(Draft, self).delete() - - def to_dict(self): - uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.origin_file_uuid) - file_path = posixpath.join(uuid.parent_path, uuid.filename) - - return { - 'id': self.pk, - 'owner': self.username, - 'owner_nickname': email2nickname(self.username), - 'origin_repo_id': self.origin_repo_id, - 'origin_file_path': file_path, - 'origin_file_version': self.origin_file_version, - 'draft_file_path': self.draft_file_path, - 'created_at': datetime_to_isoformat_timestr(self.created_at), - 'updated_at': datetime_to_isoformat_timestr(self.updated_at), - } - - -class DraftReviewerManager(models.Manager): - def add(self, reviewer, draft): - reviewer = self.model(reviewer=reviewer, draft=draft) - reviewer.save(using=self._db) - - return reviewer - - -class DraftReviewer(models.Model): - """ - Model used to record review reviewer. - """ - reviewer = LowerCaseCharField(max_length=255, db_index=True) - draft = models.ForeignKey('Draft', on_delete=models.CASCADE) - - objects = DraftReviewerManager() - - def to_dict(self): - return { - 'name': email2nickname(self.reviewer), - 'email': self.reviewer, - 'contact_email': email2contact_email(self.reviewer) - } diff --git a/seahub/drafts/signals.py b/seahub/drafts/signals.py deleted file mode 100644 index 6704f93cb4..0000000000 --- a/seahub/drafts/signals.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2012-2018 Seafile Ltd. -import django.dispatch - -comment_draft_successful = django.dispatch.Signal() -request_reviewer_successful = django.dispatch.Signal() -update_review_successful = django.dispatch.Signal() diff --git a/seahub/drafts/urls.py b/seahub/drafts/urls.py deleted file mode 100644 index 9a067eaf87..0000000000 --- a/seahub/drafts/urls.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2012-2016 Seafile Ltd. -from django.urls import path - -from .views import draft, drafts - -urlpatterns = [ - path('', drafts, name='drafts'), - path('/', draft, name='draft'), -] diff --git a/seahub/drafts/utils.py b/seahub/drafts/utils.py deleted file mode 100644 index 64594fc8a1..0000000000 --- a/seahub/drafts/utils.py +++ /dev/null @@ -1,135 +0,0 @@ -import hashlib -import os -import logging -import posixpath -import json - -from seaserv import seafile_api - -from seahub.utils import normalize_file_path, check_filename_with_rename -from seahub.tags.models import FileUUIDMap - - -logger = logging.getLogger(__name__) - - -def create_user_draft_repo(username, org_id=-1): - repo_name = 'Drafts' - if org_id and org_id > 0: - repo_id = seafile_api.create_org_repo(repo_name, '', username, org_id) - else: - repo_id = seafile_api.create_repo(repo_name, '', username) - return repo_id - - -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 is_draft_file(repo_id, file_path): - is_draft = False - file_path = normalize_file_path(file_path) - - from .models import Draft - try: - draft = Draft.objects.filter(origin_repo_id=repo_id, draft_file_path=file_path) - if draft: - is_draft = True - except Draft.DoesNotExist: - pass - - return is_draft - - -def has_draft_file(repo_id, file_path): - has_draft = False - file_path = normalize_file_path(file_path) - parent_path = os.path.dirname(file_path) - filename = os.path.basename(file_path) - - file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_path( - repo_id, parent_path, filename, is_dir=False) - - from .models import Draft - if file_uuid: - try: - d = Draft.objects.filter(origin_file_uuid=file_uuid.uuid) - if d: - d = d[0] - file_id = seafile_api.get_file_id_by_path(repo_id, d.draft_file_path) - if file_id: - has_draft = True - else: - Draft.DoesNotExist - except Draft.DoesNotExist: - pass - - return has_draft - - -def get_file_draft(repo_id, file_path, is_draft=False, has_draft=False): - draft = {} - draft['draft_id'] = None - draft['draft_file_path'] = '' - draft['draft_origin_file_path'] = '' - - from .models import Draft - - if is_draft: - d = Draft.objects.filter(origin_repo_id=repo_id, draft_file_path=file_path) - if d: - d = d[0] - uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid) - file_path = posixpath.join(uuid.parent_path, uuid.filename) - draft['draft_id'] = d.id - draft['draft_file_path'] = d.draft_file_path - draft['draft_origin_file_path'] = file_path - else: - Draft.DoesNotExist - - if has_draft: - file_path = normalize_file_path(file_path) - parent_path = os.path.dirname(file_path) - filename = os.path.basename(file_path) - - file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_path( - repo_id, parent_path, filename, is_dir=False) - - d = Draft.objects.filter(origin_file_uuid=file_uuid.uuid) - if d: - d = d[0] - draft['draft_id'] = d.id - draft['draft_file_path'] = d.draft_file_path - else: - Draft.DoesNotExist - - return draft - - -def send_draft_publish_msg(draft, username, path): - """ - send draft publish msg to seafevents - """ - - repo_id = draft.origin_repo_id - old_path = draft.draft_file_path - - msg = { - 'msg_type': 'publish', - 'obj_type': draft, - 'repo_id': repo_id, - 'user_name': username, - 'path': path, - 'old_path': old_path, - } - - try: - seafile_api.publish_event('seahub.draft', json.dumps(msg)) - except Exception as e: - logger.error("Error when sending draft publish message: %s" % str(e)) diff --git a/seahub/drafts/views.py b/seahub/drafts/views.py deleted file mode 100644 index 000fbe70c7..0000000000 --- a/seahub/drafts/views.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -import os -import posixpath - -from django.shortcuts import render, get_object_or_404 -from django.utils.translation import gettext as _ -from seaserv import seafile_api - -from seahub.auth.decorators import login_required -from seahub.views import check_folder_permission -from seahub.utils import render_permission_error -from seahub.drafts.models import Draft -from seahub.api2.utils import user_to_dict -from seahub.tags.models import FileUUIDMap - - -@login_required -def drafts(request): - return render(request, "react_app.html") - - -@login_required -def draft(request, pk): - d = get_object_or_404(Draft, pk=pk) - - # check perm - uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid) - origin_repo_id = d.origin_repo_id - permission = check_folder_permission(request, origin_repo_id, '/') - if not permission: - return render_permission_error(request, _('Permission denied.')) - - origin_file_path = posixpath.join(uuid.parent_path, uuid.filename) - origin_file = seafile_api.get_file_id_by_path(origin_repo_id, origin_file_path) - origin_file_exists = True - if not origin_file: - origin_file_exists = False - - draft_file = seafile_api.get_file_id_by_path(origin_repo_id, d.draft_file_path) - draft_file_exists = True - if not draft_file: - draft_file_exists = False - - draft_file_name = os.path.basename(d.draft_file_path) - - author_info = user_to_dict(d.username) - - return render(request, "draft.html", { - "draft_id": d.id, - "draft_repo_id": origin_repo_id, - "draft_origin_file_path": origin_file_path, - "draft_file_path": d.draft_file_path, - "draft_file_name": draft_file_name, - "permission": permission, - "author": author_info['user_name'], - "author_avatar_url": author_info['avatar_url'], - "origin_file_exists": origin_file_exists, - "draft_file_exists": draft_file_exists, - "draft_status": d.status, - "publish_file_version": d.publish_file_version, - "origin_file_version": d.origin_file_version - }) diff --git a/seahub/notifications/models.py b/seahub/notifications/models.py index 09118cfa46..33f70b4be2 100644 --- a/seahub/notifications/models.py +++ b/seahub/notifications/models.py @@ -21,7 +21,6 @@ from seahub.base.templatetags.seahub_tags import email2nickname from seahub.invitations.models import Invitation from seahub.utils import normalize_cache_key, get_site_scheme_and_netloc from seahub.constants import HASH_URLS -from seahub.drafts.models import DraftReviewer from seahub.file_participants.utils import list_file_participants # Get an instance of a logger @@ -988,14 +987,11 @@ class UserNotification(models.Model): ########## handle signals from django.dispatch import receiver -from seahub.signals import upload_file_successful, upload_folder_successful,\ - comment_file_successful, repo_transfer +from seahub.signals import upload_file_successful, upload_folder_successful, repo_transfer from seahub.group.signals import group_join_request, add_user_to_group from seahub.share.signals import share_repo_to_user_successful, \ share_repo_to_group_successful, change_repo_perm_successful, delete_repo_perm_successful from seahub.invitations.signals import accept_guest_invitation_successful -from seahub.drafts.signals import comment_draft_successful, \ - request_reviewer_successful from seahub.adfs_auth.signals import saml_sso_failed @@ -1120,47 +1116,6 @@ def add_user_to_group_cb(sender, **kwargs): UserNotification.objects.set_add_user_to_group_notice(to_user=added_user, detail=detail) -@receiver(comment_file_successful) -def comment_file_successful_cb(sender, **kwargs): - """ send notification to file participants - """ - repo = kwargs['repo'] - repo_owner = kwargs['repo_owner'] - file_path = kwargs['file_path'] - comment = kwargs['comment'] - author = kwargs['author'] - - notify_users = list_file_participants(repo.id, file_path) - notify_users = [x for x in notify_users if x != author] - for u in notify_users: - detail = file_comment_msg_to_json(repo.id, file_path, author, comment) - UserNotification.objects.add_file_comment_msg(u, detail) - -@receiver(comment_draft_successful) -def comment_draft_successful_cb(sender, **kwargs): - draft = kwargs['draft'] - comment = kwargs['comment'] - author = kwargs['author'] - - detail = draft_comment_msg_to_json(draft.id, author, comment) - - if draft.username != author: - UserNotification.objects.add_draft_comment_msg(draft.username, detail) - - reviewers = DraftReviewer.objects.filter(draft=draft) - for r in reviewers: - if r.reviewer != author: - UserNotification.objects.add_draft_comment_msg(r.reviewer, detail) - -@receiver(request_reviewer_successful) -def requeset_reviewer_successful_cb(sender, **kwargs): - from_user = kwargs['from_user'] - draft_id = kwargs['draft_id'] - to_user = kwargs['to_user'] - - detail = request_reviewer_msg_to_json(draft_id, from_user, to_user) - - UserNotification.objects.add_request_reviewer_msg(to_user, detail) @receiver(accept_guest_invitation_successful) def accept_guest_invitation_successful_cb(sender, **kwargs): diff --git a/seahub/settings.py b/seahub/settings.py index 9cfd12d23e..64dad3d546 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -245,7 +245,7 @@ INSTALLED_APPS = [ 'seahub.api2', 'seahub.avatar', 'seahub.contacts', - 'seahub.drafts', + # 'seahub.drafts', 'seahub.institutions', 'seahub.invitations', 'seahub.wiki', diff --git a/seahub/urls.py b/seahub/urls.py index e0e2c4666a..508a7fb9a4 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -93,9 +93,6 @@ from seahub.api2.endpoints.notifications import NotificationsView, NotificationV from seahub.api2.endpoints.repo_file_uploaded_bytes import RepoFileUploadedBytesView from seahub.api2.endpoints.user_avatar import UserAvatarView from seahub.api2.endpoints.wikis import WikisView, WikiView -from seahub.api2.endpoints.drafts import DraftsView, DraftView -from seahub.api2.endpoints.draft_reviewer import DraftReviewerView -from seahub.api2.endpoints.repo_draft_info import RepoDraftInfo, RepoDraftCounts from seahub.api2.endpoints.activities import ActivitiesView from seahub.api2.endpoints.wiki_pages import WikiPagesDirView, WikiPageContentView from seahub.api2.endpoints.revision_tag import TaggedItemsView, TagNamesView @@ -557,12 +554,7 @@ urlpatterns = [ re_path(r'^api/v2.1/wiki2/search/$', WikiSearch.as_view(), name='api-v2.1-wiki2-search'), re_path(r'^api/v2.1/convert-wiki/$', WikiConvertView.as_view(), name='api-v2.1-wiki-convert'), ## user::drafts - re_path(r'^api/v2.1/drafts/$', DraftsView.as_view(), name='api-v2.1-drafts'), - re_path(r'^api/v2.1/drafts/(?P\d+)/$', DraftView.as_view(), name='api-v2.1-draft'), - - re_path(r'^api/v2.1/drafts/(?P\d+)/reviewer/$', DraftReviewerView.as_view(), name='api-v2.1-draft-reviewer'), - re_path(r'^api/v2.1/repo/(?P[-0-9a-f]{36})/drafts/$', RepoDraftInfo.as_view(), name='api-v2.1-repo-drafts'), - re_path(r'^api/v2.1/repo/(?P[-0-9a-f]{36})/draft-counts/$', RepoDraftCounts.as_view(), name='api-v2.1-repo-draft-counts'), + ## user::activities re_path(r'^api/v2.1/activities/$', ActivitiesView.as_view(), name='api-v2.1-acitvity'), @@ -760,7 +752,7 @@ urlpatterns = [ path('work-weixin/', include('seahub.work_weixin.urls')), path('weixin/', include('seahub.weixin.urls')), # Must specify a namespace if specifying app_name. - path('drafts/', include(('seahub.drafts.urls', 'drafts'), namespace='drafts')), + # path('drafts/', include(('seahub.drafts.urls', 'drafts'), namespace='drafts')), ## admin::address book re_path(r'^api/v2.1/admin/address-book/groups/$', AdminAddressBookGroups.as_view(), name='api-v2.1-admin-address-book-groups'), diff --git a/seahub/views/file.py b/seahub/views/file.py index 90182069a9..69543a6ab8 100644 --- a/seahub/views/file.py +++ b/seahub/views/file.py @@ -71,8 +71,6 @@ from seahub.utils.repo import is_repo_owner, parse_repo_perm from seahub.group.utils import is_group_member from seahub.thumbnail.utils import extract_xmind_image, get_thumbnail_src, \ XMIND_IMAGE_SIZE, get_share_link_thumbnail_src, get_thumbnail_image_path -from seahub.drafts.utils import get_file_draft, \ - is_draft_file, has_draft_file from seahub.seadoc.utils import get_seadoc_file_uuid, gen_seadoc_access_token, is_seadoc_revision from seahub.seadoc.models import SeadocRevision diff --git a/tests/api/endpoints/test_drafts.py b/tests/api/endpoints/test_drafts.py deleted file mode 100644 index b4442ecc84..0000000000 --- a/tests/api/endpoints/test_drafts.py +++ /dev/null @@ -1,78 +0,0 @@ -import json - -from django.urls import reverse - -from seaserv import seafile_api -from seahub.drafts.models import Draft -from seahub.test_utils import BaseTestCase - - -class DraftsViewTest(BaseTestCase): - def setUp(self): - self.url = reverse('api-v2.1-drafts') - self.login_as(self.user) - - def test_can_list(self): - resp = self.client.get(self.url) - self.assertEqual(200, resp.status_code) - - json_resp = json.loads(resp.content) - - def test_can_create(self): - assert len(Draft.objects.all()) == 0 - - resp = self.client.post(self.url, { - 'repo_id': self.repo.id, - 'file_path': self.file, - }) - - self.assertEqual(200, resp.status_code) - assert len(Draft.objects.all()) == 1 - - json_resp = json.loads(resp.content) - assert json_resp['owner'] == self.user.username - assert json_resp['origin_repo_id'] == self.repo.id - - def test_create_same_file(self): - resp = self.client.post(self.url, { - 'repo_id': self.repo.id, - 'file_path': self.file, - }) - - self.assertEqual(200, resp.status_code) - - resp = self.client.post(self.url, { - 'repo_id': self.repo.id, - 'file_path': self.file, - }) - - self.assertEqual(409, resp.status_code) - - -class DraftViewTest(BaseTestCase): - def setUp(self): - seafile_api.post_dir(self.repo.id, '/', 'Drafts', self.user.username) - draft = Draft.objects.add(self.user.username, self.repo, self.file) - self.url = reverse('api-v2.1-draft', args=[draft.id]) - - self.login_as(self.user) - - def test_can_delete(self): - assert len(Draft.objects.all()) == 1 - - resp = self.client.delete(self.url) - self.assertEqual(200, resp.status_code) - - assert len(Draft.objects.all()) == 0 - - def test_can_publish(self): - assert len(Draft.objects.all()) == 1 - - resp = self.client.put( - self.url, - 'operation=publish', - 'application/x-www-form-urlencoded', - ) - self.assertEqual(200, resp.status_code) - - assert len(Draft.objects.all()) == 1 diff --git a/tests/api/endpoints/test_file_comment.py b/tests/api/endpoints/test_file_comment.py deleted file mode 100644 index 5b1da732be..0000000000 --- a/tests/api/endpoints/test_file_comment.py +++ /dev/null @@ -1,104 +0,0 @@ -import json - -from django.urls import reverse - -from seahub.base.models import FileComment -from seahub.test_utils import BaseTestCase - -class FileCommentTest(BaseTestCase): - def setUp(self): - self.tmp_user = self.create_user() - - self.tmp_repo_1_id = self.create_repo( - name='tmp-repo-1', desc='', username=self.tmp_user.username, passwd=None) - self.file1 = self.create_file(repo_id=self.tmp_repo_1_id, parent_dir='/', - filename='test1.txt', - username=self.tmp_user.username) - - self.tmp_repo_2_id = self.create_repo( - name='tmp-repo-2', desc='', username=self.user.username, passwd=None) - self.file2 = self.create_file(repo_id=self.tmp_repo_2_id, parent_dir='/', - filename='test2.txt', - username=self.user.username) - - o = FileComment.objects.add_by_file_path(repo_id=self.repo.id, - file_path=self.file, - author=self.tmp_user.username, - comment='test comment') - o1 = FileComment.objects.add_by_file_path(repo_id=self.tmp_repo_1_id, - file_path='/test1.txt', - author=self.tmp_user.username, - comment='test comment1') - o2 = FileComment.objects.add_by_file_path(repo_id=self.tmp_repo_2_id, - file_path='/test2.txt', - author=self.user.username, - comment='test comment2') - self.login_as(self.user) - - self.endpoint = reverse('api2-file-comment', args=[self.repo.id, o.pk]) + '?p=' + self.file - self.endpoint1 = reverse('api2-file-comment', args=[self.repo.id, o1.pk]) + '?p=' + '/test1.txt' - self.endpoint2 = reverse('api2-file-comment', args=[self.repo.id, o2.pk]) + '?p=' + '/test2.txt' - - def tearDown(self): - self.remove_repo() - self.remove_repo(repo_id=self.tmp_repo_1_id) - self.remove_repo(repo_id=self.tmp_repo_2_id) - self.remove_user() - self.remove_user(self.tmp_user.email) - FileComment.objects.all().delete() - - def test_can_get(self): - resp = self.client.get(self.endpoint) - self.assertEqual(200, resp.status_code) - - json_resp = json.loads(resp.content) - assert json_resp['repo_id'] == self.repo.id - assert json_resp['parent_path'] == '/' - assert json_resp['item_name'] == 'test.txt' - assert json_resp['user_email'] == self.tmp_user.email - assert 'avatars' in json_resp['avatar_url'] - - def test_can_not_get_other_repo_file_comment(self): - resp = self.client.get(self.endpoint1) - self.assertEqual(404, resp.status_code) - - def test_can_not_get_other_user_file_comment(self): - resp = self.client.get(self.endpoint2) - self.assertEqual(404, resp.status_code) - - def test_can_get_with_avatar_size(self): - resp = self.client.get(self.endpoint + '&avatar_size=20') - self.assertEqual(200, resp.status_code) - - json_resp = json.loads(resp.content) - assert json_resp['parent_path'] == '/' - assert json_resp['item_name'] == 'test.txt' - assert json_resp['user_email'] == self.tmp_user.email - assert 'avatars' in json_resp['avatar_url'] - - def test_can_delete(self): - assert len(FileComment.objects.all()) == 3 - resp = self.client.delete(self.endpoint) - self.assertEqual(204, resp.status_code) - assert len(FileComment.objects.all()) == 2 - - def test_can_not_delete_other_repo_file_comment(self): - assert len(FileComment.objects.all()) == 3 - resp = self.client.delete(self.endpoint1) - self.assertEqual(404, resp.status_code) - assert len(FileComment.objects.all()) == 3 - - def test_can_not_delete_other_user_file_comment(self): - assert len(FileComment.objects.all()) == 3 - resp = self.client.delete(self.endpoint2) - self.assertEqual(404, resp.status_code) - assert len(FileComment.objects.all()) == 3 - - def test_invalid_user_can_not_delete(self): - self.logout() - self.login_as(self.admin) - - assert len(FileComment.objects.all()) == 3 - resp = self.client.delete(self.endpoint) - self.assertEqual(403, resp.status_code) - assert len(FileComment.objects.all()) == 3 diff --git a/tests/api/endpoints/test_file_comments.py b/tests/api/endpoints/test_file_comments.py deleted file mode 100644 index bbad22e5eb..0000000000 --- a/tests/api/endpoints/test_file_comments.py +++ /dev/null @@ -1,103 +0,0 @@ -import json - -from django.urls import reverse -import seaserv -from seaserv import seafile_api, ccnet_api - -from seahub.base.models import FileComment -from seahub.notifications.models import UserNotification -from seahub.test_utils import BaseTestCase -from seahub.file_participants.models import FileParticipant -from seahub.tags.models import FileUUIDMap - -class FileCommentsTest(BaseTestCase): - def setUp(self): - self.tmp_user = self.create_user() - - self.login_as(self.user) - self.endpoint = reverse('api2-file-comments', args=[self.repo.id]) + '?p=' + self.file - - def tearDown(self): - self.remove_repo() - self.remove_user(self.tmp_user.email) - - def test_can_list(self): - for i in range(10): - o = FileComment.objects.add_by_file_path(repo_id=self.repo.id, - file_path=self.file, - author=self.tmp_user.username, - comment='test comment'+str(i)) - resp = self.client.get(self.endpoint + '&page=2&per_page=5') - self.assertEqual(200, resp.status_code) - - json_resp = json.loads(resp.content) - link = reverse('api2-file-comments', args=[self.repo.id]) + '?page=1&per_page=5' - assert link in resp.headers.get('links') - assert len(json_resp['comments']) == 5 - assert json_resp['comments'][0]['comment'] == 'test comment5' - assert json_resp['comments'][0]['user_email'] == self.tmp_user.email - assert 'avatars' in json_resp['comments'][0]['avatar_url'] - assert json_resp['total_count'] == 10 - - def test_can_list_with_avatar_size(self): - o = FileComment.objects.add_by_file_path(repo_id=self.repo.id, - file_path=self.file, - author=self.tmp_user.username, - comment='test comment') - resp = self.client.get(self.endpoint + '&avatar_size=20') - self.assertEqual(200, resp.status_code) - - json_resp = json.loads(resp.content) - assert len(json_resp['comments']) == 1 - assert json_resp['comments'][0]['comment'] == o.comment - assert json_resp['comments'][0]['user_email'] == self.tmp_user.email - assert 'avatars' in json_resp['comments'][0]['avatar_url'] - assert json_resp['total_count'] == 1 - - def test_can_post(self): - resp = self.client.post(self.endpoint, { - 'comment': 'new comment' - }) - self.assertEqual(201, resp.status_code) - - json_resp = json.loads(resp.content) - assert json_resp['comment'] == 'new comment' - assert 'avatars' in json_resp['avatar_url'] - - def test_can_post_with_avatar_size(self): - resp = self.client.post(self.endpoint + '&avatar_size=20', { - 'comment': 'new comment' - }) - self.assertEqual(201, resp.status_code) - - json_resp = json.loads(resp.content) - assert json_resp['comment'] == 'new comment' - assert 'avatars' in json_resp['avatar_url'] - - def test_invalid_user(self): - self.logout() - self.login_as(self.admin) - - resp = self.client.get(self.endpoint) - self.assertEqual(403, resp.status_code) - - resp = self.client.post(self.endpoint, { - 'comment': 'new comment' - }) - self.assertEqual(403, resp.status_code) - - def test_can_notify_participant(self): - assert len(UserNotification.objects.all()) == 0 - - # share repo and add participant - seafile_api.share_repo(self.repo.id, self.user.username, self.admin.username, 'rw') - file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap_by_path(self.repo.id, self.file, False) - FileParticipant.objects.add_participant(file_uuid, self.admin.username) - - resp = self.client.post(self.endpoint, { - 'comment': 'new comment' - }) - self.assertEqual(201, resp.status_code) - - assert len(UserNotification.objects.all()) == 1 - assert UserNotification.objects.all()[0].to_user == self.admin.username diff --git a/tests/api/endpoints/test_file_comments_counts.py b/tests/api/endpoints/test_file_comments_counts.py deleted file mode 100644 index 07eebe2f92..0000000000 --- a/tests/api/endpoints/test_file_comments_counts.py +++ /dev/null @@ -1,60 +0,0 @@ -import json - -from django.urls import reverse - -from seahub.base.models import FileComment -from seahub.test_utils import BaseTestCase - -class FileCommentsCountsTest(BaseTestCase): - def setUp(self): - self.login_as(self.user) - self.endpoint = reverse('api2-file-comments-counts', args=[self.repo.id]) + '?p=/' - - self.file2 = self.create_file(repo_id=self.repo.id, parent_dir='/', - filename='test2.txt', - username=self.user.username) - - def tearDown(self): - self.remove_repo() - - def test_can_get(self): - FileComment.objects.add_by_file_path(repo_id=self.repo.id, - file_path=self.file, - author=self.user.username, - comment='test comment') - - FileComment.objects.add_by_file_path(repo_id=self.repo.id, - file_path=self.file, - author=self.user.username, - comment='reply test comment') - - FileComment.objects.add_by_file_path(repo_id=self.repo.id, - file_path=self.file2, - author=self.user.username, - comment='test comment on other file') - - resp = self.client.get(self.endpoint) - self.assertEqual(200, resp.status_code) - - json_resp = json.loads(resp.content) - assert len(json_resp) == 2 - for d in json_resp: - if list(d.keys())[0] == 'test.txt': - assert d['test.txt'] == 2 - - if list(d.keys())[0] == 'test2.txt': - assert d['test2.txt'] == 1 - - # def test_can_get_file(self): - # FileComment.objects.add_by_file_path(repo_id=self.repo.id, - # file_path=self.file2, - # author=self.user.username, - # comment='test comment on other file') - - # FileComment.objects.add_by_file_path(repo_id=self.repo.id, - # file_path=self.file2, - # author=self.user.username, - # comment='test comment on other file123') - # self.file_request= reverse('api2-file-comments-counts', args=[self.repo.id]) + '?p=' + self.file2 - # resp = self.client.get(self.file_request) - # self.assertEqual(404, resp.status_code) diff --git a/tests/seahub/drafts/__init__.py b/tests/seahub/drafts/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/seahub/drafts/test_models.py b/tests/seahub/drafts/test_models.py deleted file mode 100644 index 27f7d712ad..0000000000 --- a/tests/seahub/drafts/test_models.py +++ /dev/null @@ -1,103 +0,0 @@ -from django.urls import reverse -from seahub.drafts.models import Draft -from seahub.test_utils import BaseTestCase - -from seaserv import seafile_api - - -class DraftManagerTest(BaseTestCase): - - def setUp(self): - seafile_api.post_dir(self.repo.id, '/', 'Drafts', self.user.username) - - def test_list_draft_by_username(self): - assert len(Draft.objects.all()) == 0 - Draft.objects.add(self.user.username, self.repo, self.file) - - draft_list = Draft.objects.list_draft_by_username(self.user.username) - - assert len(draft_list) == 1 - - def test_list_draft_by_username_with_invalid_repo(self): - self.login_as(self.user) - assert len(Draft.objects.all()) == 0 - Draft.objects.add(self.user.username, self.repo, self.file) - - url = reverse('api2-repo', args=[self.repo.id]) - resp = self.client.delete(url, {}, 'application/x-www-form-urlencoded') - - self.assertEqual(200, resp.status_code) - - draft_list = Draft.objects.list_draft_by_username(self.user.username) - - assert len(draft_list) == 0 - assert len(Draft.objects.all()) == 1 - - def test_list_draft_by_username_with_invalid_origin_file(self): - self.login_as(self.user) - assert len(Draft.objects.all()) == 0 - - url = reverse('api-v2.1-drafts') - resp = self.client.post(url, { - 'repo_id': self.repo.id, - 'file_path': self.file, - }) - - self.assertEqual(200, resp.status_code) - - file_url = reverse('api-v2.1-file-view', args=[self.repo.id]) - d_resp = self.client.delete(file_url + '?p=' + self.file, - {}, 'application/x-www-form-urlencoded') - - self.assertEqual(200, d_resp.status_code) - - draft_list = Draft.objects.list_draft_by_username(self.user.username) - - assert len(draft_list) == 1 - assert len(Draft.objects.all()) == 1 - - def test_add(self): - assert len(Draft.objects.all()) == 0 - draft = Draft.objects.add(self.user.username, self.repo, self.file) - - assert draft is not None - assert len(Draft.objects.all()) == 1 - - d = draft.to_dict() - assert d['origin_repo_id'] == self.repo.id - assert d['origin_file_path'] == self.file - assert len(d['draft_file_path']) > 0 - - def test_add_another_file(self): - file2 = self.create_file(repo_id=self.repo.id, - parent_dir='/', - filename='test2.txt', - username=self.user.username) - - assert len(Draft.objects.all()) == 0 - draft = Draft.objects.add(self.user.username, self.repo, self.file) - assert draft is not None - assert len(Draft.objects.all()) == 1 - - draft2 = Draft.objects.add(self.user.username, self.repo, file2) - assert draft2 is not None - assert len(Draft.objects.all()) == 2 - - -class DraftTest(BaseTestCase): - def setUp(self): - seafile_api.post_dir(self.repo.id, '/', 'Drafts', self.user.username) - - def test_delete(self): - assert len(Draft.objects.all()) == 0 - d = Draft.objects.add(self.user.username, self.repo, self.file) - - assert d is not None - assert len(Draft.objects.all()) == 1 - assert seafile_api.get_file_id_by_path(d.origin_repo_id, d.draft_file_path) is not None - - d = Draft.objects.all()[0] - d.delete(self.user.username) - - assert len(Draft.objects.all()) == 0 - assert seafile_api.get_file_id_by_path(d.origin_repo_id, d.draft_file_path) is None