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 (
- {gettext('Delete')}
- - {gettext('Publish')}
+ {/* - {gettext('Publish')}
*/}
- {gettext('Ask for review')}
);
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)))