diff --git a/frontend/src/markdown-editor.js b/frontend/src/markdown-editor.js index 66b61b0830..2b888a647a 100644 --- a/frontend/src/markdown-editor.js +++ b/frontend/src/markdown-editor.js @@ -238,10 +238,14 @@ class EditorUtilities { window.location.href = serviceUrl + '/lib/' + res.data.origin_repo_id + '/file' + res.data.draft_file_path + '?mode=edit' }) } + + createFileReview() { + return seafileAPI.createFileReview(repoID, filePath).then(res => { + window.location.href = serviceUrl + '/drafts/review/' + res.data.id; + }) + } } - - const editorUtilities = new EditorUtilities(); class MarkdownEditor extends React.Component { diff --git a/seahub/api2/endpoints/file_review.py b/seahub/api2/endpoints/file_review.py new file mode 100644 index 0000000000..1937c2faa2 --- /dev/null +++ b/seahub/api2/endpoints/file_review.py @@ -0,0 +1,64 @@ +# Copyright (c) 2012-2016 Seafile Ltd. +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.core.urlresolvers import reverse +from django.db import IntegrityError +from seaserv import seafile_api + +from seahub.api2.authentication import TokenAuthentication +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, DraftReview, ReviewReviewer, \ + DraftFileExist, DraftReviewExist + + +class FileReviewView(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, ) + throttle_classes = (UserRateThrottle, ) + + def post(self, request): + repo_id = request.POST.get('repo_id', '') + file_path = request.POST.get('file_path', '') + + # new draft + 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) + + # perm check + perm = check_folder_permission(request, repo.id, file_path) + if perm is None: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + file_id = seafile_api.get_file_id_by_path(repo.id, file_path) + if not file_id: + return api_error(status.HTTP_404_NOT_FOUND, + "File %s not found" % file_path) + + username = request.user.username + dirent = seafile_api.get_dirent_by_path(repo_id, file_path) + + try: + d = Draft.objects.add(dirent.modifier, repo, file_path, file_id) + except (DraftFileExist, IntegrityError): + return api_error(status.HTTP_409_CONFLICT, 'Draft already exists.') + + # new review + try: + r = DraftReview.objects.add(creator=dirent.modifier, draft=d) + except (DraftReviewExist): + return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.') + + # new reviewer + if username != d.username: + ReviewReviewer.objects.add(username, r) + + return Response(r.to_dict()) diff --git a/seahub/urls.py b/seahub/urls.py index 27c5c3e1bd..6242cddf1d 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -69,6 +69,7 @@ from seahub.api2.endpoints.wikis import WikisView, WikiView from seahub.api2.endpoints.drafts import DraftsView, DraftView from seahub.api2.endpoints.draft_reviews import DraftReviewsView, DraftReviewView from seahub.api2.endpoints.draft_review_reviewer import DraftReviewReviewerView +from seahub.api2.endpoints.file_review import FileReviewView from seahub.api2.endpoints.activities import ActivitiesView from seahub.api2.endpoints.wiki_pages import WikiPageView, WikiPagesView, WikiPagesDirView, WikiPageContentView from seahub.api2.endpoints.revision_tag import TaggedItemsView, TagNamesView @@ -343,6 +344,8 @@ urlpatterns = [ url(r'^api/v2.1/review/(?P\d+)/$', DraftReviewView.as_view(), name='api-v2.1-draft-review'), url(r'^api/v2.1/review/(?P\d+)/reviewer/$', DraftReviewReviewerView.as_view(), name='api-v2.1-draft-review-reviewer'), + url(r'^api/v2.1/file-review/$', FileReviewView.as_view(), name='api-v2.1-file-review'), + ## user::activities url(r'^api/v2.1/activities/$', ActivitiesView.as_view(), name='api-v2.1-acitvity'),