mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-25 14:50:29 +00:00
update api validation
This commit is contained in:
@@ -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)
|
@@ -57,11 +57,11 @@ urlpatterns = [
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/$', FileView.as_view(), name='FileView'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/metadata/$', FileMetaDataView.as_view(), name='FileMetaDataView'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9a-f]{36})/files/(?P<file_id>[0-9a-f]{40})/blks/(?P<block_id>[0-9a-f]{40})/download-link/$', FileBlockDownloadLinkView.as_view()),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/$', FileCommentsView.as_view(), name='api2-file-comments'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/counts/$', FileCommentsCounts.as_view(), name='api2-file-comments-counts'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<comment_id>\d+)/$', FileCommentView.as_view(), name='api2-file-comment'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<file_uuid>[-0-9a-f]{36})/(?P<comment_id>\d+)/replies/$', FileCommentRepliesView.as_view(), name='file_comment_replies'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<file_uuid>[-0-9a-f]{36})/(?P<comment_id>\d+)/replies/(?P<reply_id>\d+)/$', FileCommentReplyView.as_view(), name='file_comment_reply'),
|
||||
# re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/$', FileCommentsView.as_view(), name='api2-file-comments'),
|
||||
# re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/counts/$', FileCommentsCounts.as_view(), name='api2-file-comments-counts'),
|
||||
# re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<comment_id>\d+)/$', FileCommentView.as_view(), name='api2-file-comment'),
|
||||
# re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<file_uuid>[-0-9a-f]{36})/(?P<comment_id>\d+)/replies/$', FileCommentRepliesView.as_view(), name='file_comment_replies'),
|
||||
# re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/comments/(?P<file_uuid>[-0-9a-f]{36})/(?P<comment_id>\d+)/replies/(?P<reply_id>\d+)/$', FileCommentReplyView.as_view(), name='file_comment_reply'),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/detail/$', FileDetailView.as_view()),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/history/$', FileHistory.as_view()),
|
||||
re_path(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/revision/$', FileRevision.as_view()),
|
||||
|
@@ -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<repo_id>[-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<repo_id>[-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<repo_id>[-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<repo_id>[-0-9a-f]{36})/file/(?P<file_uuid>[-0-9a-f]{36})/comments/$', FileCommentsView.as_view(), name='api-v2.1-file-comments'),
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/(?P<file_uuid>[-0-9a-f]{36})/comments/(?P<comment_id>\d+)/$', FileCommentView.as_view(), name='api-v2.1-file-comment'),
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/(?P<file_uuid>[-0-9a-f]{36})/comments/(?P<comment_id>\d+)/replies/$', FileCommentRepliesView.as_view(), name='api-v2.1-file-comment-replies'),
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/(?P<file_uuid>[-0-9a-f]{36})/comments/(?P<comment_id>\d+)/replies/(?P<reply_id>\d+)/$', FileCommentReplyView.as_view(), name='api-v2.1-file-comment-repolies'),
|
||||
|
||||
|
||||
## user:: repo-api-tokens
|
||||
re_path(r'^api/v2.1/repos/(?P<repo_id>[-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<repo_id>[-0-9a-f]{36})/repo-api-tokens/(?P<app_name>.*)/$', RepoAPITokenView.as_view(), name='api-v2.1-repo-api-token'),
|
||||
|
Reference in New Issue
Block a user