diff --git a/seahub/api2/endpoints/file_comments.py b/seahub/api2/endpoints/file_comments.py index 1a4deb83ef..e14932ae9f 100644 --- a/seahub/api2/endpoints/file_comments.py +++ b/seahub/api2/endpoints/file_comments.py @@ -1,6 +1,6 @@ # Copyright (c) 2012-2016 Seafile Ltd. import logging - +import json from rest_framework import status from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated @@ -22,52 +22,354 @@ from seahub.signals import comment_file_successful from seahub.api2.endpoints.utils import generate_links_header_for_paginator from seahub.views import check_folder_permission -from seahub.seadoc.models import SeadocCommentReply +from seahub.seadoc.models import SeadocCommentReply, SeadocNotification from seahub.file_participants.models import FileParticipant from seahub.utils.timeutils import utc_to_local, datetime_to_isoformat_timestr, datetime_to_timestamp 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.') +# +# file_uuid = request.GET.get('docuuid', None) +# 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) +# +# 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] +# +# reply_queryset = SeadocCommentReply.objects.list_by_doc_uuid(file_uuid) +# +# for file_comment in file_comments: +# comment = file_comment.to_dict(reply_queryset) +# 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. +# """ +# 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 +# +# 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.') +# +# 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) +# +# +# comment = file_comment.to_dict() +# comment.update(user_to_dict(username, request=request)) +# return Response(comment, status=201) +# +# +# class FileCommentRepliesView(APIView): +# authentication_classes = () +# throttle_classes = (UserRateThrottle,) +# +# def get(self, request, repo_id, file_uuid, comment_id): +# """list replies +# """ +# # auth = request.headers.get('authorization', '').split() +# # if not is_valid_seadoc_access_token(auth, file_uuid): +# # error_msg = 'Permission denied.' +# # return api_error(status.HTTP_403_FORBIDDEN, error_msg) +# +# start = None +# end = None +# page = request.GET.get('page', '') +# if page: +# 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 +# +# # resource check +# file_comment = FileComment.objects.filter( +# id=comment_id, uuid=file_uuid).first() +# if not file_comment: +# return api_error(status.HTTP_404_NOT_FOUND, 'comment not found.') +# +# total_count = SeadocCommentReply.objects.list_by_comment_id(comment_id).count() +# replies = [] +# reply_queryset = SeadocCommentReply.objects.list_by_comment_id(comment_id)[start: end] +# for reply in reply_queryset: +# data = reply.to_dict() +# data.update( +# user_to_dict(reply.author, request=request)) +# replies.append(data) +# +# result = {'replies': replies, 'total_count': total_count} +# return Response(result) +# +# def post(self, request, repo_id, file_uuid, comment_id): +# """post a reply +# """ +# # argument check +# # auth = request.headers.get('authorization', '').split() +# # is_valid, payload = is_valid_seadoc_access_token(auth, file_uuid, return_payload=True) +# # if not is_valid: +# # error_msg = 'Permission denied.' +# # return api_error(status.HTTP_403_FORBIDDEN, error_msg) +# +# reply_content = request.data.get('reply', '') +# type_content = request.data.get('type', 'reply') +# author = request.data.get('author', '') +# username = author +# +# if reply_content is None: +# return api_error(status.HTTP_400_BAD_REQUEST, 'reply invalid.') +# if not username: +# return api_error(status.HTTP_400_BAD_REQUEST, 'author invalid.') +# +# # resource check +# file_comment = FileComment.objects.filter( +# id=comment_id, uuid=file_uuid).first() +# if not file_comment: +# return api_error(status.HTTP_404_NOT_FOUND, 'comment not found.') +# +# reply = SeadocCommentReply.objects.create( +# author=username, +# reply=str(reply_content), +# type=str(type_content), +# comment_id=comment_id, +# doc_uuid=file_uuid, +# ) +# data = reply.to_dict() +# data.update(user_to_dict(reply.author, request=request)) +# +# # notification +# to_users = set() +# participant_queryset = FileParticipant.objects.get_participants(file_uuid) +# for participant in participant_queryset: +# to_users.add(participant.username) +# to_users.discard(username) # remove author +# to_users = list(to_users) +# detail = { +# 'author': username, +# 'comment_id': int(comment_id), +# 'reply_id': reply.pk, +# 'reply': str(reply_content), +# 'msg_type': 'reply', +# 'created_at': datetime_to_isoformat_timestr(reply.created_at), +# 'updated_at': datetime_to_isoformat_timestr(reply.updated_at), +# 'is_resolved': type(reply_content) is bool and reply_content is True, +# 'resolve_comment': file_comment.comment.strip() +# } +# detail.update(user_to_dict(username, request=request)) +# +# # new_notifications = [] +# # for to_user in to_users: +# # new_notifications.append( +# # SeadocNotification( +# # doc_uuid=file_uuid, +# # username=to_user, +# # msg_type='reply', +# # detail=json.dumps(detail), +# # )) +# # try: +# # SeadocNotification.objects.bulk_create(new_notifications) +# # except Exception as e: +# # logger.error(e) +# # error_msg = 'Internal Server Error' +# # return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) +# +# notification = detail +# notification['to_users'] = to_users +# data['notification'] = notification +# return Response(data) +# +# +# class FileCommentReplyView(APIView): +# authentication_classes = () +# throttle_classes = (UserRateThrottle,) +# +# def get(self, request, repo_id, file_uuid, comment_id, reply_id): +# """Get a comment reply +# """ +# # auth = request.headers.get('authorization', '').split() +# # if not is_valid_seadoc_access_token(auth, file_uuid): +# # error_msg = 'Permission denied.' +# # return api_error(status.HTTP_403_FORBIDDEN, error_msg) +# +# # resource check +# file_comment = FileComment.objects.filter( +# id=comment_id, uuid=file_uuid).first() +# if not file_comment: +# return api_error(status.HTTP_404_NOT_FOUND, 'comment not found.') +# +# reply = SeadocCommentReply.objects.filter( +# id=reply_id, doc_uuid=file_uuid, comment_id=comment_id).first() +# if not reply: +# return api_error(status.HTTP_404_NOT_FOUND, 'reply not found.') +# +# data = reply.to_dict() +# data.update( +# user_to_dict(reply.author, request=request)) +# return Response(data) +# +# def delete(self, request, repo_id, file_uuid, comment_id, reply_id): +# """Delete a comment reply +# """ +# # auth = request.headers.get('authorization', '').split() +# # if not is_valid_seadoc_access_token(auth, file_uuid): +# # error_msg = 'Permission denied.' +# # return api_error(status.HTTP_403_FORBIDDEN, error_msg) +# +# # resource check +# file_comment = FileComment.objects.filter( +# id=comment_id, uuid=file_uuid).first() +# if not file_comment: +# return api_error(status.HTTP_404_NOT_FOUND, 'comment not found.') +# +# reply = SeadocCommentReply.objects.filter( +# id=reply_id, doc_uuid=file_uuid, comment_id=comment_id).first() +# if not reply: +# return api_error(status.HTTP_404_NOT_FOUND, 'reply not found.') +# reply.delete() +# return Response({'success': True}) +# +# def put(self, request, repo_id, file_uuid, comment_id, reply_id): +# """Update a comment reply +# """ +# # auth = request.headers.get('authorization', '').split() +# # if not is_valid_seadoc_access_token(auth, file_uuid): +# # error_msg = 'Permission denied.' +# # return api_error(status.HTTP_403_FORBIDDEN, error_msg) +# +# # argument check +# reply_content = request.data.get('reply') +# if reply_content is None: +# return api_error(status.HTTP_400_BAD_REQUEST, 'reply invalid.') +# +# # resource check +# file_comment = FileComment.objects.filter( +# id=comment_id, uuid=file_uuid).first() +# if not file_comment: +# return api_error(status.HTTP_404_NOT_FOUND, 'comment not found.') +# +# reply = SeadocCommentReply.objects.filter( +# id=reply_id, doc_uuid=file_uuid, comment_id=comment_id).first() +# if not reply: +# return api_error(status.HTTP_404_NOT_FOUND, 'reply not found.') +# +# # save +# reply.reply = str(reply_content) +# reply.updated_at = timezone.now() +# reply.save() +# +# data = reply.to_dict() +# data.update( +# user_to_dict(reply.author, request=request)) +# return Response(data) + + class FileCommentsView(APIView): authentication_classes = (TokenAuthentication, SessionAuthentication) permission_classes = (IsAuthenticated, IsRepoAccessible) - throttle_classes = (UserRateThrottle, ) + throttle_classes = (UserRateThrottle,) - def get(self, request, repo_id, format=None): - """List all comments of a file. + def get(self, request, repo_id, file_uuid): + """list comments of a sdoc, same as FileCommentsView """ - path = request.GET.get('p', '/').rstrip('/') - if not path: - return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.') - file_uuid = request.GET.get('docuuid', None) 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) - if check_folder_permission(request, repo_id, '/') is None: - return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') + start = None + end = None + page = request.GET.get('page', '') + if page: + 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 - 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() + total_count = FileComment.objects.list_by_file_uuid(file_uuid).count() comments = [] if resolved is None: - file_comments = FileComment.objects.get_by_file_path(repo_id, path)[start: end] + file_comments = FileComment.objects.list_by_file_uuid(file_uuid)[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] + file_comments = ( + FileComment.objects + .list_by_file_uuid(file_uuid) + .filter(resolved=comment_resolved) + [start:end] + ) reply_queryset = SeadocCommentReply.objects.list_by_doc_uuid(file_uuid) @@ -77,67 +379,141 @@ class FileCommentsView(APIView): 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 + return Response(result) - def post(self, request, repo_id, format=None): - """Post a comments of a file. - """ - 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 - - 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.') - - 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) + def post(self, request, repo_id, file_uuid): - comment_file_successful.send(sender=None, repo=repo, repo_owner=repo_owner, file_path=path, comment=comment, author=username) + comment = request.data.get('comment', '') + detail = request.data.get('detail', '') + author = request.data.get('author', '') + username = request.user.username + if comment is None: + return api_error(status.HTTP_400_BAD_REQUEST, 'comment invalid.') + if not username: + return api_error(status.HTTP_400_BAD_REQUEST, 'author invalid.') + file_comment = FileComment.objects.add_by_file_uuid( + file_uuid, username, comment, detail) comment = file_comment.to_dict() comment.update(user_to_dict(username, request=request)) - return Response(comment, status=201) + + # notification + to_users = set() + participant_queryset = FileParticipant.objects.get_participants(file_uuid) + for participant in participant_queryset: + to_users.add(participant.username) + to_users.discard(username) # remove author + to_users = list(to_users) + detail = { + 'author': username, + 'comment_id': int(file_comment.id), + 'comment': str(file_comment.comment), + 'msg_type': 'comment', + 'created_at': datetime_to_isoformat_timestr(file_comment.created_at), + 'updated_at': datetime_to_isoformat_timestr(file_comment.updated_at), + } + detail.update(user_to_dict(username, request=request)) + + new_notifications = [] + for to_user in to_users: + new_notifications.append( + SeadocNotification( + doc_uuid=file_uuid, + username=to_user, + msg_type='comment', + detail=json.dumps(detail), + )) + try: + SeadocNotification.objects.bulk_create(new_notifications) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + # + notification = detail + notification['to_users'] = to_users + comment['notification'] = notification + return Response(comment) -class FileCommentRepliesView(APIView): - authentication_classes = () +class FileCommentView(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, IsRepoAccessible) throttle_classes = (UserRateThrottle,) def get(self, request, repo_id, file_uuid, comment_id): - """list replies - """ - # auth = request.headers.get('authorization', '').split() - # if not is_valid_seadoc_access_token(auth, file_uuid): - # error_msg = 'Permission denied.' - # return api_error(status.HTTP_403_FORBIDDEN, error_msg) + # resource check + try: + file_comment = FileComment.objects.get(pk=comment_id) + except FileComment.DoesNotExist: + return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong comment id') + if str(file_comment.uuid.uuid) != file_uuid: + return api_error(status.HTTP_404_NOT_FOUND, 'comment not found: %s' % comment_id) + comment = file_comment.to_dict() + comment.update(user_to_dict( + file_comment.author, request=request)) + return Response(comment) + + def delete(self, request, file_uuid, comment_id): + + # resource check + try: + file_comment = FileComment.objects.get(pk=comment_id) + except FileComment.DoesNotExist: + return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong comment id') + if str(file_comment.uuid.uuid) != file_uuid: + return api_error(status.HTTP_404_NOT_FOUND, 'comment not found: %s' % comment_id) + + file_comment.delete() + SeadocCommentReply.objects.filter(comment_id=comment_id).delete() + return Response({'success': True}) + + def put(self, request, repo_id, file_uuid, comment_id): + + # argument check + resolved = request.data.get('resolved') + if resolved not in ('true', 'false', None): + error_msg = 'resolved invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + detail = request.data.get('detail') + comment = request.data.get('comment') + + # resource check + try: + file_comment = FileComment.objects.get(pk=comment_id) + except FileComment.DoesNotExist: + error_msg = 'FileComment %s not found.' % comment_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + if str(file_comment.uuid.uuid) != file_uuid: + return api_error(status.HTTP_404_NOT_FOUND, 'comment not found: %s' % comment_id) + + if resolved is not None: + # do not refresh updated_at + comment_resolved = to_python_boolean(resolved) + file_comment.resolved = comment_resolved + file_comment.save(update_fields=['resolved']) + + if detail is not None or comment is not None: + if detail is not None: + file_comment.detail = detail + if comment is not None: + file_comment.comment = comment + # save + file_comment.updated_at = timezone.now() + file_comment.save() + + comment = file_comment.to_dict() + comment.update(user_to_dict(file_comment.author, request=request)) + return Response(comment) + + +class FileCommentRepliesView(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, IsRepoAccessible) + throttle_classes = (UserRateThrottle,) + + def get(self, request, repo_id, file_uuid, comment_id): start = None end = None page = request.GET.get('page', '') @@ -170,20 +546,13 @@ class FileCommentRepliesView(APIView): return Response(result) def post(self, request, repo_id, file_uuid, comment_id): - """post a reply + """post a comment reply of a sdoc. """ - # argument check - # auth = request.headers.get('authorization', '').split() - # is_valid, payload = is_valid_seadoc_access_token(auth, file_uuid, return_payload=True) - # if not is_valid: - # error_msg = 'Permission denied.' - # return api_error(status.HTTP_403_FORBIDDEN, error_msg) reply_content = request.data.get('reply', '') type_content = request.data.get('type', 'reply') author = request.data.get('author', '') - username = author - + username = request.user.username or author if reply_content is None: return api_error(status.HTTP_400_BAD_REQUEST, 'reply invalid.') if not username: @@ -203,7 +572,8 @@ class FileCommentRepliesView(APIView): doc_uuid=file_uuid, ) data = reply.to_dict() - data.update(user_to_dict(reply.author, request=request)) + data.update( + user_to_dict(reply.author, request=request)) # notification to_users = set() @@ -225,22 +595,22 @@ class FileCommentRepliesView(APIView): } detail.update(user_to_dict(username, request=request)) - # new_notifications = [] - # for to_user in to_users: - # new_notifications.append( - # SeadocNotification( - # doc_uuid=file_uuid, - # username=to_user, - # msg_type='reply', - # detail=json.dumps(detail), - # )) - # try: - # SeadocNotification.objects.bulk_create(new_notifications) - # except Exception as e: - # logger.error(e) - # error_msg = 'Internal Server Error' - # return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) - + new_notifications = [] + for to_user in to_users: + new_notifications.append( + SeadocNotification( + doc_uuid=file_uuid, + username=to_user, + msg_type='reply', + detail=json.dumps(detail), + )) + try: + SeadocNotification.objects.bulk_create(new_notifications) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + # notification = detail notification['to_users'] = to_users data['notification'] = notification @@ -248,17 +618,13 @@ class FileCommentRepliesView(APIView): class FileCommentReplyView(APIView): - authentication_classes = () + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, IsRepoAccessible) throttle_classes = (UserRateThrottle,) def get(self, request, repo_id, file_uuid, comment_id, reply_id): """Get a comment reply """ - # auth = request.headers.get('authorization', '').split() - # if not is_valid_seadoc_access_token(auth, file_uuid): - # error_msg = 'Permission denied.' - # return api_error(status.HTTP_403_FORBIDDEN, error_msg) - # resource check file_comment = FileComment.objects.filter( id=comment_id, uuid=file_uuid).first() @@ -276,12 +642,6 @@ class FileCommentReplyView(APIView): return Response(data) def delete(self, request, repo_id, file_uuid, comment_id, reply_id): - """Delete a comment reply - """ - # auth = request.headers.get('authorization', '').split() - # if not is_valid_seadoc_access_token(auth, file_uuid): - # error_msg = 'Permission denied.' - # return api_error(status.HTTP_403_FORBIDDEN, error_msg) # resource check file_comment = FileComment.objects.filter( @@ -297,13 +657,6 @@ class FileCommentReplyView(APIView): return Response({'success': True}) def put(self, request, repo_id, file_uuid, comment_id, reply_id): - """Update a comment reply - """ - # auth = request.headers.get('authorization', '').split() - # if not is_valid_seadoc_access_token(auth, file_uuid): - # error_msg = 'Permission denied.' - # return api_error(status.HTTP_403_FORBIDDEN, error_msg) - # argument check reply_content = request.data.get('reply') if reply_content is None: @@ -328,4 +681,4 @@ class FileCommentReplyView(APIView): data = reply.to_dict() data.update( user_to_dict(reply.author, request=request)) - return Response(data) + return Response(data) \ No newline at end of file diff --git a/seahub/api2/urls.py b/seahub/api2/urls.py index 6ef38ffea3..ffccbb0c4e 100644 --- a/seahub/api2/urls.py +++ b/seahub/api2/urls.py @@ -57,11 +57,11 @@ 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/comments/(?P[-0-9a-f]{36})/(?P\d+)/replies/$', FileCommentRepliesView.as_view(), name='file_comment_replies'), - re_path(r'^repos/(?P[-0-9-a-f]{36})/file/comments/(?P[-0-9a-f]{36})/(?P\d+)/replies/(?P\d+)/$', FileCommentReplyView.as_view(), name='file_comment_reply'), + # 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/comments/(?P[-0-9a-f]{36})/(?P\d+)/replies/$', FileCommentRepliesView.as_view(), name='file_comment_replies'), + # re_path(r'^repos/(?P[-0-9-a-f]{36})/file/comments/(?P[-0-9a-f]{36})/(?P\d+)/replies/(?P\d+)/$', FileCommentReplyView.as_view(), name='file_comment_reply'), 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/urls.py b/seahub/urls.py index b0f1a2a0eb..fea6c94cdf 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -3,6 +3,8 @@ from django.urls import include, path, re_path from django.views.generic import TemplateView from seahub.ai.apis import ImageCaption, GenerateSummary, GenerateFileTags, OCR, Translate, WritingAssistant +from seahub.api2.endpoints.file_comments import FileCommentsView, FileCommentView, FileCommentRepliesView, \ + FileCommentReplyView from seahub.api2.endpoints.share_link_auth import ShareLinkUserAuthView, ShareLinkEmailAuthView from seahub.api2.endpoints.internal_api import InternalUserListView, InternalCheckShareLinkAccess, \ InternalCheckFileOperationAccess, CheckThumbnailAccess, CheckShareLinkThumbnailAccess @@ -477,7 +479,15 @@ urlpatterns = [ re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/share-info/$', RepoShareInfoView.as_view(), name='api-v2.1-repo-share-info-view'), re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/image-rotate/$', RepoImageRotateView.as_view(), name='api-v2.1-repo-image-rotate-view'), re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/office-suite/$', OfficeSuiteConfig.as_view(), name='api-v2.1-repo-office-suite'), - + + + ## user: repo file comments + re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file/(?P[-0-9a-f]{36})/comments/$', FileCommentsView.as_view(), name='api-v2.1-file-comments'), + re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file/(?P[-0-9a-f]{36})/comments/(?P\d+)/$', FileCommentView.as_view(), name='api-v2.1-file-comment'), + re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file/(?P[-0-9a-f]{36})/comments/(?P\d+)/replies/$', FileCommentRepliesView.as_view(), name='api-v2.1-file-comment-replies'), + re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/file/(?P[-0-9a-f]{36})/comments/(?P\d+)/replies/(?P\d+)/$', FileCommentReplyView.as_view(), name='api-v2.1-file-comment-repolies'), + + ## user:: repo-api-tokens re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/repo-api-tokens/$', RepoAPITokensView.as_view(), name='api-v2.1-repo-api-tokens'), re_path(r'^api/v2.1/repos/(?P[-0-9a-f]{36})/repo-api-tokens/(?P.*)/$', RepoAPITokenView.as_view(), name='api-v2.1-repo-api-token'),