1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-05 00:43:53 +00:00

New draft file (#2465)

This commit is contained in:
C_Q
2018-10-24 14:37:41 +08:00
committed by Daniel Pan
parent 26f9d7d9d7
commit 67e19792aa
10 changed files with 155 additions and 43 deletions

View File

@@ -16,6 +16,7 @@ class CreateFile extends React.Component {
this.state = {
parentPath: '',
childName: props.fileType,
isDraft: false,
};
this.newInput = React.createRef();
}
@@ -28,7 +29,8 @@ class CreateFile extends React.Component {
handleSubmit = () => {
let path = this.state.parentPath + this.state.childName;
this.props.onAddFile(path);
let isDraft = this.state.isDraft;
this.props.onAddFile(path, isDraft);
}
handleKeyPress = (e) => {
@@ -37,6 +39,55 @@ class CreateFile extends React.Component {
}
}
handleCheck = () => {
let pos = this.state.childName.lastIndexOf(".");
if (this.state.isDraft) {
// from draft to not draft
// case 1, normally, the file name is ended with `(draft)`, like `test(draft).md`
// case 2, the file name is not ended with `(draft)`, the user has deleted some characters, like `test(dra.md`
let p = this.state.childName.substring(pos-7, pos);
let fileName = this.state.childName.substring(0, pos-7);
let fileType = this.state.childName.substring(pos);
if (p === '(draft)') {
// remove `(draft)` from file name
this.setState({
childName: fileName + fileType,
isDraft: !this.state.isDraft
})
} else {
// don't change file name
this.setState({
isDraft: !this.state.isDraft
})
}
}
if (!this.state.isDraft) {
// from not draft to draft
// case 1, test.md ===> test(draft).md
// case 2, .md ===> (draft).md
// case 3, no '.' in the file name, don't change the file name
if (pos > 0) {
let fileName = this.state.childName.substring(0, pos);
let fileType = this.state.childName.substring(pos);
this.setState({
childName: fileName + '(draft)' + fileType,
isDraft: !this.state.isDraft
})
} else if (pos === 0 ) {
this.setState({
childName: '(draft)' + this.state.childname,
isDraft: !this.state.isdraft
})
} else {
this.setState({
isDraft: !this.state.isdraft
})
}
}
}
toggle = () => {
this.props.addFileCancel();
}
@@ -67,6 +118,13 @@ class CreateFile extends React.Component {
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input;}} id="fileName" placeholder={gettext('newName')} value={this.state.childName} onChange={this.handleChange}/>
</Col>
</FormGroup>
<FormGroup row>
<Label sm={3} check />
<Col sm={9}>
<Input type="checkbox" onChange={this.handleCheck}/>{' '}{gettext("This is a draft.")}
</Col>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>

View File

@@ -64,7 +64,8 @@ class DraftContent extends React.Component {
let draft = this.state.currentDraft;
editUtilties.createDraftReview(draft.id).then(res => {
window.open(siteRoot + 'drafts/review/' + res.data.id);
const w = window.open()
w.location = siteRoot + 'drafts/review/' + res.data.id;
}).catch((error) => {
if (error.response.status == '409') {
Toast.error('The draft review is existing.');

View File

@@ -158,9 +158,9 @@ class MainPanel extends Component {
this.setState({showFileDialog: !this.state.showFileDialog});
}
onMainAddFile = (filePath) => {
onMainAddFile = (filePath, isDraft) => {
this.setState({showFileDialog: !this.state.showFileDialog});
this.props.onMainAddFile(filePath);
this.props.onMainAddFile(filePath, isDraft);
}
onMainAddFolder = (dirPath) => {

View File

@@ -127,9 +127,9 @@ class SidePanel extends Component {
this.props.onAddFolderNode(dirPath);
}
onAddFileNode = (filePath) => {
onAddFileNode = (filePath, isDraft) => {
this.setState({showFile: !this.state.showFile});
this.props.onAddFileNode(filePath);
this.props.onAddFileNode(filePath, isDraft);
}
onRenameNode = (newName) => {

View File

@@ -252,8 +252,8 @@ class Wiki extends Component {
});
}
onAddFileNode = (filePath) => {
editorUtilities.createFile(filePath).then(res => {
onAddFileNode = (filePath, isDraft) => {
editorUtilities.createFile(filePath, isDraft).then(res => {
let tree = this.state.tree_data.clone();
let name = this.getFileNameByPath(filePath);
let index = filePath.lastIndexOf('/');

View File

@@ -38,8 +38,8 @@ class EditorUtilities {
});
}
createFile(filePath) {
return seafileAPI.createFile(repoID, filePath);
createFile(filePath, isDraft) {
return seafileAPI.createFile(repoID, filePath, isDraft);
}
deleteFile(filePath) {

View File

@@ -1,4 +1,6 @@
# Copyright (c) 2012-2016 Seafile Ltd.
import os
from rest_framework import status
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
@@ -89,7 +91,33 @@ class DraftReviewView(APIView):
return api_error(status.HTTP_409_CONFLICT,
'There is a conflict between the draft and the original file')
file_id = seafile_api.get_file_id_by_path(r.origin_repo_id, r.origin_file_path)
origin_file_path = r.origin_file_path
# if it is a new draft
# case1. '/path/test(draft).md' ---> '/path/test.md'
# case2. '/path/test(dra.md' ---> '/path/test(dra.md'
if d.draft_file_path == r.origin_file_path:
new_draft_dir = os.path.dirname(origin_file_path)
new_draft_name = os.path.basename(origin_file_path)
draft_flag = os.path.splitext(new_draft_name)[0][-7:]
# remove `(draft)` from file name
if draft_flag == '(draft)':
f = os.path.splitext(new_draft_name)[0][:-7]
file_type = os.path.splitext(new_draft_name)[-1]
new_draft_name = f + file_type
if new_draft_dir == '/':
origin_file_path = new_draft_dir + new_draft_name
else:
origin_file_path = new_draft_dir + '/' + new_draft_name
r.draft_file_path = origin_file_path
r.origin_file_path = origin_file_path
# get draft published version
file_id = seafile_api.get_file_id_by_path(r.origin_repo_id, origin_file_path)
r.publish_file_version = file_id
r.save()
d.delete()

View File

@@ -56,17 +56,17 @@ class DraftsView(APIView):
error_msg = 'Library %s not found.' % repo_id
return api_error(status.HTTP_404_NOT_FOUND, 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)
# perm check
perm = check_folder_permission(request, repo.id, file_path)
if perm != PERMISSION_READ_WRITE:
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
try:

View File

@@ -58,6 +58,7 @@ from seahub.thumbnail.utils import generate_thumbnail
from seahub.notifications.models import UserNotification
from seahub.options.models import UserOptions
from seahub.profile.models import Profile, DetailedProfile
from seahub.drafts.models import Draft
from seahub.signals import (repo_created, repo_deleted)
from seahub.share.models import FileShare, OrgFileShare, UploadLinkShare
from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \
@@ -2632,6 +2633,7 @@ class FileView(APIView):
username = request.user.username
parent_dir = os.path.dirname(path)
operation = request.POST.get('operation', '')
is_draft = request.POST.get('is_draft', '')
file_info = {}
if operation.lower() == 'rename':
@@ -2772,6 +2774,17 @@ class FileView(APIView):
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to create file.')
if is_draft.lower() == 'true':
file_name = os.path.basename(path)
file_dir = os.path.dirname(path)
draft_type = os.path.splitext(file_name)[0][-7:]
file_type = os.path.splitext(file_name)[-1]
if draft_type != '(draft)':
f = os.path.splitext(file_name)[0]
path = file_dir + '/' + f + '(draft)' + file_type
new_file_name = os.path.basename(path)
if not seafile_api.is_valid_filename('fake_repo_id', new_file_name):
@@ -2787,6 +2800,10 @@ class FileView(APIView):
return api_error(HTTP_520_OPERATION_FAILED,
'Failed to create file.')
if is_draft.lower() == 'true':
repo = seafile_api.get_repo(repo_id)
Draft.objects.add(username, repo, path, file_exist=False)
if request.GET.get('reloaddir', '').lower() == 'true':
return reloaddir(request, repo, parent_dir)
else:

View File

@@ -10,7 +10,7 @@ from seahub.base.fields import LowerCaseCharField
from seahub.base.models import TimestampedModel
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.tags.models import FileUUIDMap
from seahub.utils import normalize_file_path
from seahub.utils import normalize_file_path, EMPTY_SHA1
from seahub.utils.timeutils import datetime_to_isoformat_timestr
from .utils import create_user_draft_repo, get_draft_file_name
@@ -24,24 +24,8 @@ class DraftFileConflict(Exception):
class DraftManager(models.Manager):
def get_user_draft_repo_id(self, username):
r = self.filter(username=username).first()
if r is None:
return None
else:
return r.draft_repo_id
def add(self, username, repo, file_path, file_id=None, org_id=-1):
file_path = normalize_file_path(file_path)
parent_path = os.path.dirname(file_path)
filename = os.path.basename(file_path)
file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(
repo.id, parent_path, filename, is_dir=False)
if file_id is None:
file_id = seafile_api.get_file_id_by_path(repo.id, file_path)
# create drafts dir if any
def create_exist_file_draft(self, repo, username, file_uuid, file_path):
# create drafts dir if any
draft_dir_id = seafile_api.get_dir_id_by_path(repo.id, '/Drafts')
if draft_dir_id is None:
seafile_api.post_dir(repo.id, '/', 'Drafts', username)
@@ -56,10 +40,25 @@ class DraftManager(models.Manager):
repo.id, '/Drafts', draft_file_name,
username=username, need_progress=0, synchronous=1)
return draft_file_path
def add(self, username, repo, file_path, file_exist=True, file_id=None, org_id=-1):
file_path = normalize_file_path(file_path)
parent_path = os.path.dirname(file_path)
filename = os.path.basename(file_path)
file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(
repo.id, parent_path, filename, is_dir=False)
if file_id is None:
file_id = seafile_api.get_file_id_by_path(repo.id, file_path)
if file_exist:
file_path = self.create_exist_file_draft(repo, username, file_uuid, file_path)
draft = self.model(username=username,
origin_repo_id=repo.id, origin_file_uuid=file_uuid,
origin_file_version=file_id,
draft_file_path=draft_file_path)
draft_file_path=file_path)
draft.save(using=self._db)
return draft
@@ -80,7 +79,8 @@ class Draft(TimestampedModel):
def delete(self):
draft_file_name = os.path.basename(self.draft_file_path)
seafile_api.del_file(self.origin_repo_id, '/Drafts/',
draft_file_path = os.path.dirname(self.draft_file_path)
seafile_api.del_file(self.origin_repo_id, draft_file_path,
draft_file_name, self.username)
super(Draft, self).delete()
@@ -101,22 +101,30 @@ class Draft(TimestampedModel):
if not file_id:
raise DraftFileConflict
if file_id != self.origin_file_version:
draft_file_name = os.path.basename(self.draft_file_path)
draft_file_path = os.path.dirname(self.draft_file_path)
file_name = self.origin_file_uuid.filename
if file_id != self.origin_file_version and self.draft_file_path != origin_file_path:
raise DraftFileConflict
draft_file_name = os.path.basename(self.draft_file_path)
if self.draft_file_path == origin_file_path:
f = os.path.splitext(draft_file_name)[0][:-7]
file_type = os.path.splitext(draft_file_name)[-1]
file_name = f + file_type
# move draft file to origin file
seafile_api.move_file(
self.origin_repo_id, '/Drafts', draft_file_name,
self.origin_repo_id, draft_file_path, draft_file_name,
self.origin_repo_id, self.origin_file_uuid.parent_path,
self.origin_file_uuid.filename, replace=1,
file_name, replace=1,
username=self.username, need_progress=0, synchronous=1
)
def to_dict(self):
uuid = self.origin_file_uuid
file_path = posixpath.join(uuid.parent_path, uuid.filename) # TODO: refactor uuid
file_path = posixpath.join(uuid.parent_path, uuid.filename)
repo = seafile_api.get_repo(self.origin_repo_id)