From 405dfc9eeba85e178c72bf3f385246cd7e6c1e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=81=A5=E8=BE=89?= <40563566+WangJianhui666@users.noreply.github.com> Date: Mon, 21 Jan 2019 15:38:34 +0800 Subject: [PATCH] display draft&review activities (#2851) * dispaly draft&review activities * repalce obj_id with old_path * use [for loop] filter events * repair code * prohibit [publish draft] --- .../draft-list-view/draft-list-menu.js | 2 +- .../src/pages/dashboard/files-activities.js | 67 ++++++++++++++++++- seahub/api2/endpoints/activities.py | 3 + seahub/api2/endpoints/draft_reviews.py | 7 ++ seahub/api2/endpoints/file_review.py | 4 ++ seahub/drafts/utils.py | 41 ++++++++++++ 6 files changed, 121 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/draft-list-view/draft-list-menu.js b/frontend/src/components/draft-list-view/draft-list-menu.js index 5aba025601..083870aa3f 100644 --- a/frontend/src/components/draft-list-view/draft-list-menu.js +++ b/frontend/src/components/draft-list-view/draft-list-menu.js @@ -23,7 +23,7 @@ class DraftListMenu extends React.Component { return ( ); diff --git a/frontend/src/pages/dashboard/files-activities.js b/frontend/src/pages/dashboard/files-activities.js index 5f00d220fb..97ccf500c6 100644 --- a/frontend/src/pages/dashboard/files-activities.js +++ b/frontend/src/pages/dashboard/files-activities.js @@ -82,15 +82,42 @@ class TableBody extends Component { details = {libLink}; break; } + } else if (item.obj_type == 'review') { + let fileURL = `${siteRoot}drafts/review/${item.review_id}`; + let fileLink = {item.name}; + switch(item.op_type) { + case 'open': + op = gettext('Open review'); + details = {fileLink}
{smallLibLink}; + break; + case 'closed': + op = gettext('Close review'); + details = {fileLink}
{smallLibLink}; + break; + case 'finished': + op = gettext('Publish draft'); + details = {fileLink}
{smallLibLink}; + break; + } } else if (item.obj_type == 'file') { let fileURL = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`; let fileLink = {item.name}; switch(item.op_type) { case 'create': + if (item.name.endsWith("(draft).md")) { + op = gettext('Created draft'); + details = {fileLink}
{smallLibLink}; + break; + } op = gettext('Created file'); details = {fileLink}
{smallLibLink}; break; case 'delete': + if (item.name.endsWith("(draft).md")) { + op = gettext('Deleted draft'); + details = {item.name}
{smallLibLink}; + break; + } op = gettext('Deleted file'); details = {item.name}
{smallLibLink}; break; @@ -108,6 +135,11 @@ class TableBody extends Component { details = {item.old_path} => {filePathLink}
{smallLibLink}; break; case 'edit': // update + if (item.name.endsWith("(draft).md")) { + op = gettext('Updated draft'); + details = {fileLink}
{smallLibLink}; + break; + } op = gettext('Updated file'); details = {fileLink}
{smallLibLink}; break; @@ -177,6 +209,8 @@ class FilesActivities extends Component { items: [], }; this.avatarSize = 72; + this.curPathList = []; + this.oldPathList = []; } componentDidMount() { @@ -184,7 +218,7 @@ class FilesActivities extends Component { seafileAPI.listActivities(currentPage, this.avatarSize).then(res => { // {"events":[...]} this.setState({ - items: res.data.events, + items: this.filterSuperfluousEvents(res.data.events), currentPage: currentPage + 1, isFirstLoading: false, hasMore: true, @@ -199,13 +233,42 @@ class FilesActivities extends Component { }); } + filterSuperfluousEvents = (events) => { + events.map((item) => { + if (item.op_type === "finished") { + this.curPathList.push(item.path); + this.oldPathList.push(item.old_path); + } + }); + let actuallyEvents = []; + for (var i = 0; i < events.length; i++) { + if (events[i].obj_type === 'file') { + if (events[i].op_type === 'delete' && this.oldPathList.includes(events[i].path)) { + this.oldPathList.splice(this.oldPathList.indexOf(events[i].path), 1); + continue; + } else if (events[i].op_type === 'edit' && this.curPathList.includes(events[i].path)) { + this.curPathList.splice(this.curPathList.indexOf(events[i].path), 1); + continue; + } else if (events[i].op_type === 'rename' && this.oldPathList.includes(events[i].old_path)) { + this.oldPathList.splice(this.oldPathList.indexOf(events[i].old_path), 1); + continue; + } else { + actuallyEvents.push(events[i]); + } + } else { + actuallyEvents.push(events[i]); + } + } + return actuallyEvents; + } + getMore() { let currentPage = this.state.currentPage; seafileAPI.listActivities(currentPage, this.avatarSize).then(res => { // {"events":[...]} this.setState({ isLoadingMore: false, - items: [...this.state.items, ...res.data.events], + items: [...this.state.items, ...this.filterSuperfluousEvents(res.data.events)], currentPage: currentPage + 1, hasMore: res.data.events.length === 0 ? false : true }); diff --git a/seahub/api2/endpoints/activities.py b/seahub/api2/endpoints/activities.py index b98f6f896d..c9fb09b4d3 100644 --- a/seahub/api2/endpoints/activities.py +++ b/seahub/api2/endpoints/activities.py @@ -83,6 +83,9 @@ class ActivitiesView(APIView): elif e.op_type == 'rename' and e.obj_type in ['dir', 'file']: d['old_path'] = e.old_path d['old_name'] = os.path.basename(e.old_path) + elif e.obj_type == 'review': + d['old_path'] = e.old_path + d['review_id'] = e.review_id events_list.append(d) diff --git a/seahub/api2/endpoints/draft_reviews.py b/seahub/api2/endpoints/draft_reviews.py index 8a16871f9a..66153289a4 100644 --- a/seahub/api2/endpoints/draft_reviews.py +++ b/seahub/api2/endpoints/draft_reviews.py @@ -20,6 +20,7 @@ from seahub.views import check_folder_permission from seahub.drafts.models import Draft, DraftReview, DraftReviewExist, \ DraftFileConflict, ReviewReviewer, OriginalFileConflict from seahub.drafts.signals import update_review_successful +from seahub.drafts.utils import send_review_status_msg class DraftReviewsView(APIView): @@ -82,6 +83,9 @@ class DraftReviewsView(APIView): except (DraftReviewExist): return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.') + # send review status change message + send_review_status_msg(request, d_r) + return Response(d_r.to_dict()) @@ -154,6 +158,9 @@ class DraftReviewView(APIView): update_review_successful.send(sender=None, from_user=username, to_user=r.creator, review_id=r.id, status=st) + # send review status change message + send_review_status_msg(request, r) + result = r.to_dict() return Response(result) diff --git a/seahub/api2/endpoints/file_review.py b/seahub/api2/endpoints/file_review.py index 1937c2faa2..40938f26e7 100644 --- a/seahub/api2/endpoints/file_review.py +++ b/seahub/api2/endpoints/file_review.py @@ -13,6 +13,7 @@ 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.utils import send_review_status_msg from seahub.drafts.models import Draft, DraftReview, ReviewReviewer, \ DraftFileExist, DraftReviewExist @@ -57,6 +58,9 @@ class FileReviewView(APIView): except (DraftReviewExist): return api_error(status.HTTP_409_CONFLICT, 'Draft review already exists.') + # send review status change message + send_review_status_msg(request, r) + # new reviewer if username != d.username: ReviewReviewer.objects.add(username, r) diff --git a/seahub/drafts/utils.py b/seahub/drafts/utils.py index 3eb916ff84..418b3cab71 100644 --- a/seahub/drafts/utils.py +++ b/seahub/drafts/utils.py @@ -1,12 +1,18 @@ import hashlib import os +import logging +import posixpath from seaserv import seafile_api +from seaserv import send_message 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 > 0: @@ -109,3 +115,38 @@ def get_file_draft_and_related_review(repo_id, file_path, is_draft=False, has_dr review['draft_file_path'] = d.draft_file_path return review + + +def send_review_status_msg(request, review): + """ + send review status change to seafevents + """ + status = review.status.lower() + if status not in ['open', 'finished', 'closed']: + logger.warn('Invalid status in review status msg: %s' % status) + return + + repo_id = review.origin_repo_id + op_user = review.creator + review_id = review.id + draft_flag = os.path.splitext(os.path.basename(review.draft_file_path))[0][-7:] + if draft_flag == '(draft)': + old_path = review.draft_file_path + if status == 'finished': + publish_path = posixpath.join(review.origin_file_uuid.parent_path, review.origin_file_uuid.filename) + else: + publish_path = None + else: + old_path = posixpath.join(review.origin_file_uuid.parent_path, review.origin_file_uuid.filename) + publish_path = review.draft_file_path if status == 'finished' else None + path = publish_path if publish_path else old_path + + username = request.user.username + + msg = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s' % (status, repo_id, op_user, "review", path, review_id, old_path, username) + msg_utf8 = msg.encode('utf-8') + + try: + send_message('seahub.review', msg_utf8) + except Exception as e: + logger.error("Error when sending %s message: %s" % (status, str(e)))