1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-08 10:22:46 +00:00

sdocStartRevise

This commit is contained in:
skywalker
2023-06-28 14:48:59 +08:00
committed by er-pai-r
parent 0da16303f5
commit 5abb686efb
10 changed files with 250 additions and 54 deletions

View File

@@ -150,6 +150,15 @@ class DirentGridView extends React.Component{
case 'Lock':
this.onLockItem(currentObject);
break;
case 'Mask as draft':
this.onMaskAsDraft(currentObject);
break;
case 'Unmask as draft':
this.onUnmaskAsDraft(currentObject);
break;
case 'Start revise':
this.onStartRevise(currentObject);
break;
case 'Comment':
this.onCommentItem();
break;
@@ -262,6 +271,40 @@ class DirentGridView extends React.Component{
});
}
onMaskAsDraft = (currentObject) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(currentObject);
seafileAPI.sdocMaskAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(currentObject, 'is_sdoc_draft', true);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onUnmaskAsDraft = (currentObject) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(currentObject);
seafileAPI.sdocUnmaskAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(currentObject, 'is_sdoc_draft', false);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onStartRevise = (currentObject) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(currentObject);
seafileAPI.sdocStartRevise(repoID, filePath).then((res) => {
let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(res.data.file_path);
window.open(url);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onCommentItem = () => {
this.props.showDirentDetail('comments');
}

View File

@@ -270,6 +270,9 @@ class DirentListItem extends React.Component {
case 'Unmask as draft':
this.onUnmaskAsDraft();
break;
case 'Start revise':
this.onStartRevise();
break;
case 'Comment':
this.props.onDirentClick(this.props.dirent);
this.props.showDirentDetail('comments');
@@ -381,6 +384,18 @@ class DirentListItem extends React.Component {
});
}
onStartRevise = () => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(this.props.dirent);
seafileAPI.sdocStartRevise(repoID, filePath).then((res) => {
let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(res.data.file_path);
window.open(url);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onHistory = () => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(this.props.dirent);

View File

@@ -121,6 +121,40 @@ class MultipleDirOperationToolbar extends React.Component {
});
}
onMaskAsDraft = (dirent) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(dirent);
seafileAPI.sdocMaskAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(dirent, 'is_sdoc_draft', true);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onUnmaskAsDraft = (dirent) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(dirent);
seafileAPI.sdocUnmaskAsDraft(repoID, filePath).then((res) => {
this.props.updateDirent(dirent, 'is_sdoc_draft', false);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onStartRevise = (dirent) => {
let repoID = this.props.repoID;
let filePath = this.getDirentPath(dirent);
seafileAPI.sdocStartRevise(repoID, filePath).then((res) => {
let url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(res.data.file_path);
window.open(url);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
onCommentItem = () => {
this.props.showDirentDetail('comments');
}
@@ -171,6 +205,15 @@ class MultipleDirOperationToolbar extends React.Component {
case 'Unlock':
this.unlockFile(dirent);
break;
case 'Mask as draft':
this.onMaskAsDraft(dirent);
break;
case 'Unmask as draft':
this.onUnmaskAsDraft(dirent);
break;
case 'Start revise':
this.onStartRevise(dirent);
break;
case 'Comment':
this.onCommentItem();
break;

View File

@@ -18,6 +18,7 @@ const TextTranslation = {
'UNLOCK' : {key : 'Unlock', value : gettext('Unlock')},
'MASK_AS_DRAFT' : {key : 'Mask as draft', value : gettext('Mark as draft')},
'UNMASK_AS_DRAFT' : {key : 'Unmask as draft', value : gettext('Unmark as draft')},
'START_REVISE' : {key : 'Start revise', value : gettext('Start revise')},
'COMMENT' : {key : 'Comment', value : gettext('Comment')},
'HISTORY' : {key : 'History', value : gettext('History')},
'ACCESS_LOG' : {key : 'Access Log', value : gettext('Access Log')},

View File

@@ -527,7 +527,7 @@ export const Utils = {
getFileOperationList: function(isRepoOwner, currentRepoInfo, dirent, isContextmenu) {
let list = [];
const { SHARE, DOWNLOAD, DELETE, RENAME, MOVE, COPY, TAGS, UNLOCK, LOCK, MASK_AS_DRAFT, UNMASK_AS_DRAFT,
COMMENT, HISTORY, ACCESS_LOG, OPEN_VIA_CLIENT, ONLYOFFICE_CONVERT } = TextTranslation;
START_REVISE, COMMENT, HISTORY, ACCESS_LOG, OPEN_VIA_CLIENT, ONLYOFFICE_CONVERT } = TextTranslation;
const permission = dirent.permission;
const { isCustomPermission, customPermission } = Utils.getUserPermission(permission);
@@ -600,6 +600,7 @@ export const Utils = {
} else {
list.push(MASK_AS_DRAFT);
}
list.push(START_REVISE);
}
if (enableFileComment) {
list.push(COMMENT);

View File

@@ -40,6 +40,7 @@ from seahub.base.templatetags.seahub_tags import email2nickname, \
from seahub.utils.timeutils import utc_datetime_to_isoformat_timestr, timestamp_to_isoformat_timestr
from seahub.base.models import FileComment
from seahub.constants import PERMISSION_READ_WRITE
from seahub.seadoc.sdoc_server_api import SdocServerAPI
logger = logging.getLogger(__name__)
@@ -516,13 +517,22 @@ class SeadocDrafts(APIView):
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id):
def get(self, request):
"""list drafts
"""
username = request.user.username
# argument check
owned = request.GET.get('owned')
repo_id = request.GET.get('repo_id')
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
limit = per_page + 1
if repo_id:
# resource check
repo = seafile_api.get_repo(repo_id)
if not repo:
@@ -535,17 +545,16 @@ class SeadocDrafts(APIView):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
#
if owned:
draft_queryset = SeadocDraft.objects.filter(
repo_id=repo_id, username=username)
# all
draft_queryset = SeadocDraft.objects.list_by_repo_id(repo_id, start, limit)
count = SeadocDraft.objects.filter(repo_id=repo_id).count()
else:
draft_queryset = SeadocDraft.objects.list_by_repo_id(repo_id)
# owned
draft_queryset = SeadocDraft.objects.list_by_username(username, start, limit)
count = SeadocDraft.objects.filter(username=username).count()
drafts = [draft.to_dict() for draft in draft_queryset]
return Response({'drafts': drafts})
return Response({'drafts': drafts, 'count': count})
class SeadocMaskAsDraft(APIView):
@@ -825,11 +834,15 @@ class SeadocRevisions(APIView):
"""
username = request.user.username
# argument check
owned = request.GET.get('owned')
repo_id = request.GET.get('repo_id')
if not repo_id or not owned:
error_msg = 'repo_id or owned invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
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
limit = per_page + 1
if repo_id:
# resource check
@@ -843,14 +856,22 @@ class SeadocRevisions(APIView):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
revision_queryset = SeadocRevision.objects.list_by_repo_id(repo_id)
#
elif owned:
revision_queryset = SeadocRevision.objects.list_by_username(username)
revision_queryset = SeadocRevision.objects.list_by_repo_id(repo_id, start, limit)
count = SeadocRevision.objects.filter(repo_id=repo_id).count()
else:
# owned
revision_queryset = SeadocRevision.objects.list_by_username(username, start, limit)
count = SeadocRevision.objects.filter(username=username).count()
revisions = [revision.to_dict() for revision in revision_queryset]
uuid_set = set()
for item in revision_queryset:
uuid_set.add(item.doc_uuid)
uuid_set.add(item.origin_doc_uuid)
return Response({'revisions': revisions})
fileuuidmap_queryset = FileUUIDMap.objects.filter(uuid__in=list(uuid_set))
revisions = [revision.to_dict(fileuuidmap_queryset) for revision in revision_queryset]
return Response({'revisions': revisions, 'count': count})
def post(self, request):
"""create
@@ -861,7 +882,7 @@ class SeadocRevisions(APIView):
if not path:
error_msg = 'p invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
repo_id = request.GET.get('repo_id')
repo_id = request.data.get('repo_id')
if not repo_id:
error_msg = 'repo_id invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
@@ -910,8 +931,9 @@ class SeadocRevisions(APIView):
revision_uuid_map = FileUUIDMap(
uuid=revision_file_uuid,
repo_id=repo_id,
parent_path=parent_dir,
parent_path='/Revisions',
filename=revision_filename,
is_dir=False,
)
revision_uuid_map.save()
@@ -919,7 +941,7 @@ class SeadocRevisions(APIView):
doc_uuid=revision_file_uuid,
origin_doc_uuid=origin_file_uuid,
repo_id=repo_id,
origin_file_path=path,
origin_doc_path=path,
username=username,
origin_file_version=origin_file_id,
)
@@ -942,6 +964,9 @@ class SeadocPublishRevision(APIView):
if not revision:
error_msg = 'Revision %s not found.' % file_uuid
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if revision.is_published:
error_msg = 'Revision %s is already published.' % file_uuid
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
repo_id = revision.repo_id
repo = seafile_api.get_repo(repo_id)
@@ -973,6 +998,7 @@ class SeadocPublishRevision(APIView):
else:
origin_file_parent_path = os.path.dirname(revision.origin_doc_path)
origin_file_filename = os.path.basename(revision.origin_doc_path)
origin_file_path = posixpath.join(origin_file_parent_path, origin_file_filename)
# check if origin file's parent folder exists
if not seafile_api.get_dir_id_by_path(repo_id, origin_file_parent_path):
@@ -982,7 +1008,7 @@ class SeadocPublishRevision(APIView):
# get revision file info
revision_file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(file_uuid)
revision_parent_path = revision_file_uuid.parent_pat
revision_parent_path = revision_file_uuid.parent_path
revision_filename = revision_file_uuid.filename
# move revision file
@@ -994,7 +1020,13 @@ class SeadocPublishRevision(APIView):
replace=1, username=username,
need_progress=0, synchronous=1)
dst_file_id = seafile_api.get_file_id_by_path(repo_id, origin_file_filename)
revision = SeadocRevision.objects.publish(
file_uuid, username, dst_file_id)
dst_file_id = seafile_api.get_file_id_by_path(repo_id, origin_file_path)
SeadocRevision.objects.publish(file_uuid, username, dst_file_id)
# refresh origin doc
sdoc_server_api = SdocServerAPI(
revision.origin_doc_uuid, origin_file_filename, username)
sdoc_server_api.refresh_doc()
revision = SeadocRevision.objects.get_by_doc_uuid(file_uuid)
return Response(revision.to_dict())

View File

@@ -1,4 +1,5 @@
import os
import posixpath
from django.db import models
@@ -52,11 +53,11 @@ class SeadocDraftManager(models.Manager):
def list_by_doc_uuids(self, doc_uuid_list):
return self.filter(doc_uuid__in=doc_uuid_list)
def list_by_username(self, username):
return self.filter(username=username)
def list_by_username(self, username, start, limit):
return self.filter(username=username)[start:limit]
def list_by_repo_id(self, repo_id):
return self.filter(repo_id=repo_id)
def list_by_repo_id(self, repo_id, start, limit):
return self.filter(repo_id=repo_id)[start:limit]
class SeadocDraft(models.Model):
@@ -89,11 +90,11 @@ class SeadocRevisionManager(models.Manager):
def list_by_origin_doc_uuid(self, origin_doc_uuid):
return self.filter(origin_doc_uuid=origin_doc_uuid)
def list_by_username(self, username):
return self.filter(username=username)
def list_by_username(self, username, start, limit):
return self.filter(username=username)[start:limit]
def list_by_repo_id(self, repo_id):
return self.filter(repo_id=repo_id)
def list_by_repo_id(self, repo_id, start, limit):
return self.filter(repo_id=repo_id)[start:limit]
def publish(self, doc_uuid, publisher, publish_file_version):
return self.filter(doc_uuid=doc_uuid).update(
@@ -123,24 +124,44 @@ class SeadocRevision(models.Model):
class Meta:
db_table = 'sdoc_revision'
def to_dict(self):
def to_dict(self, fileuuidmap_queryset=None):
from seahub.tags.models import FileUUIDMap
file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.origin_doc_uuid)
if file_uuid:
origin_parent_path = file_uuid.parent_path
origin_filename = file_uuid.filename
if fileuuidmap_queryset:
origin_doc_uuid = fileuuidmap_queryset.filter(uuid=self.origin_doc_uuid).first()
else:
origin_doc_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.origin_doc_uuid)
if origin_doc_uuid:
origin_parent_path = origin_doc_uuid.parent_path
origin_filename = origin_doc_uuid.filename
else:
origin_parent_path = os.path.dirname(self.origin_doc_path)
origin_filename = os.path.basename(self.origin_doc_path)
origin_file_path = posixpath.join(origin_parent_path, origin_filename)
if fileuuidmap_queryset:
doc_uuid = fileuuidmap_queryset.filter(uuid=self.doc_uuid).first()
else:
doc_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.doc_uuid)
if doc_uuid:
parent_path = doc_uuid.parent_path
filename = doc_uuid.filename
else:
parent_path = '/Revisions'
filename = self.doc_uuid + '.sdoc'
file_path = posixpath.join(parent_path, filename)
return {
'username': self.username,
'nickname': email2nickname(self.username),
'repo_id': self.repo_id,
'doc_uuid': self.doc_uuid,
'parent_path': parent_path,
'filename': filename,
'file_path': file_path,
'origin_doc_uuid': self.origin_doc_uuid,
'origin_parent_path': origin_parent_path,
'origin_filename': origin_filename,
'origin_file_path': origin_file_path,
'origin_file_version': self.origin_file_version,
'publish_file_version': self.publish_file_version,
'publisher': self.publisher,

View File

@@ -0,0 +1,38 @@
import json
import requests
from seahub.settings import SEADOC_SERVER_URL
from seahub.seadoc.utils import gen_seadoc_access_token
def parse_response(response):
if response.status_code >= 400:
raise ConnectionError(response.status_code, response.text)
else:
try:
data = json.loads(response.text)
return data
except:
pass
class SdocServerAPI(object):
def __init__(self, doc_uuid, filename, username):
self.doc_uuid = doc_uuid
self.filename = filename
self.username = username
self.headers = None
self.sdoc_server_url = SEADOC_SERVER_URL.rstrip('/')
self.timeout = 30
self._init()
def _init(self):
sdoc_server_access_token = gen_seadoc_access_token(
self.doc_uuid, self.filename, self.username)
self.headers = {'Authorization': 'Token ' + sdoc_server_access_token}
def refresh_doc(self):
url = self.sdoc_server_url + '/api/v1/docs/' + self.doc_uuid + '/internal-refresh-doc/?from=seahub'
response = requests.post(url, headers=self.headers)
return parse_response(response)

View File

@@ -12,10 +12,10 @@ urlpatterns = [
re_path(r'^download-image/(?P<file_uuid>[-0-9a-f]{36})/(?P<filename>.*)$', SeadocDownloadImage.as_view(), name='seadoc_download_image'),
re_path(r'^copy-history-file/(?P<repo_id>[-0-9a-f]{36})/$', SeadocCopyHistoryFile.as_view(), name='seadoc_copy_history_file'),
re_path(r'^history/(?P<file_uuid>[-0-9a-f]{36})/$', SeadocHistory.as_view(), name='seadoc_history'),
re_path(r'^drafts/(?P<repo_id>[-0-9a-f]{36})/$', SeadocDrafts.as_view(), name='seadoc_drafts'),
re_path(r'^drafts/$', SeadocDrafts.as_view(), name='seadoc_drafts'),
re_path(r'^mask-as-draft/(?P<repo_id>[-0-9a-f]{36})/$', SeadocMaskAsDraft.as_view(), name='seadoc_mask_as_draft'),
re_path(r'^comments/(?P<file_uuid>[-0-9a-f]{36})/$', SeadocCommentsView.as_view(), name='seadoc_comments'),
re_path(r'^comment/(?P<file_uuid>[-0-9a-f]{36})/(?P<comment_id>\d+)/$', SeadocCommentView.as_view(), name='seadoc_comment'),
re_path(r'^revisions/$', SeadocRevisions.as_view(), name='seadoc_revisions'),
re_path(r'^publish-revision/$', SeadocPublishRevision.as_view(), name='seadoc_publish_revision'),
re_path(r'^publish-revision/(?P<file_uuid>[-0-9a-f]{36})/$', SeadocPublishRevision.as_view(), name='seadoc_publish_revision'),
]

View File

@@ -1403,12 +1403,14 @@ CREATE TABLE `sdoc_revision` (
`repo_id` varchar(36) NOT NULL,
`doc_uuid` varchar(36) NOT NULL,
`origin_doc_uuid` varchar(36) NOT NULL,
`origin_doc_path` longtext NOT NULL,
`origin_file_version` varchar(100) NOT NULL,
`publish_file_version` varchar(100) DEFAULT NULL,
`username` varchar(255) NOT NULL,
`publisher` varchar(255) DEFAULT NULL,
`is_published` tinyint(1) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`is_published` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `sdoc_revise_doc_uuid` (`doc_uuid`),
KEY `sdoc_revision_repo_id` (`repo_id`),