1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-30 22:34:53 +00:00

update publish draft api

This commit is contained in:
lian 2019-05-31 15:57:32 +08:00
parent ed28451ed7
commit c75c4d76b4
3 changed files with 101 additions and 110 deletions

View File

@ -1,28 +1,23 @@
# Copyright (c) 2012-2016 Seafile Ltd.
import os
import logging
import posixpath
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 seaserv import seafile_api, edit_repo
from pysearpc import SearpcError
from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.db.models import Count
from django.http import HttpResponse
from django.utils.translation import ugettext as _
from seaserv import seafile_api
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.endpoints.utils import add_org_context
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.constants import PERMISSION_READ_WRITE
from seahub.drafts.models import Draft, DraftFileExist, DraftFileConflict
from seahub.drafts.models import Draft, DraftFileExist
from seahub.tags.models import FileUUIDMap
from seahub.views import check_folder_permission
from seahub.utils import gen_file_get_url
from seahub.drafts.utils import send_draft_publish_msg
logger = logging.getLogger(__name__)
@ -53,29 +48,45 @@ class DraftsView(APIView):
def post(self, request, org_id, format=None):
"""Create a file draft if the user has read-write permission to the origin file
"""
repo_id = request.POST.get('repo_id', '')
file_path = request.POST.get('file_path', '')
# argument check
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)
file_path = request.data.get('file_path', '')
if not file_path:
error_msg = 'file_path invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# resource check
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)
file_id = seafile_api.get_file_id_by_path(repo_id, file_path)
if not file_id:
error_msg = 'File %s not found.' % file_path
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission 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:
d = Draft.objects.add(username, repo, file_path, file_id)
# create drafts dir if does not exist
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)
# create draft
try:
d = Draft.objects.add(username, repo, file_path, file_id=file_id)
return Response(d.to_dict())
except DraftFileExist:
return api_error(status.HTTP_409_CONFLICT, 'Draft already exists.')
@ -92,39 +103,77 @@ class DraftView(APIView):
def put(self, request, pk, format=None):
"""Publish a draft if the user has read-write permission to the origin file
"""
op = request.data.get('operation', '')
if op != 'publish':
return api_error(status.HTTP_400_BAD_REQUEST,
'Operation invalid.')
Process:
1. Overwrite the origin file with the draft file.
If origin file's parent folder does NOT exist, move draft file to library's root folder.
2. Update draft database info.
3. Send draft file publish msg.
"""
# resource check
try:
d = Draft.objects.get(pk=pk)
draft = Draft.objects.get(pk=pk)
except Draft.DoesNotExist:
return api_error(status.HTTP_404_NOT_FOUND,
'Draft %s not found.' % pk)
# perm check
repo_id = d.origin_repo_id
uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid)
repo_id = draft.origin_repo_id
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)
if not uuid:
return api_error(status.HTTP_404_NOT_FOUND, 'Origin file uuid not found.')
# permission check
origin_file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(draft.origin_file_uuid)
if origin_file_uuid and seafile_api.get_dir_id_by_path(repo_id,
origin_file_uuid.parent_path):
permission = check_folder_permission(request, repo_id, origin_file_uuid.parent_path)
else:
permission = check_folder_permission(request, repo_id, '/')
perm = check_folder_permission(request, repo_id, uuid.parent_path)
if perm != PERMISSION_READ_WRITE:
if permission != PERMISSION_READ_WRITE:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# 1. Overwrite the origin file with the draft file.
# If origin file's parent folder does NOT exist, move draft file to library's root folder.
# get origin file info
origin_file_parent_path = origin_file_uuid.parent_path if origin_file_uuid else ''
# check if origin file's parent folder exists
if not seafile_api.get_dir_id_by_path(repo_id, origin_file_parent_path):
dst_parent_path = '/'
else:
dst_parent_path = origin_file_parent_path
# get draft file info
draft_file_name = os.path.basename(draft.draft_file_path)
draft_file_parent_path = os.path.dirname(draft.draft_file_path)
f = os.path.splitext(draft_file_name)[0][:-7]
file_type = os.path.splitext(draft_file_name)[-1]
dst_file_name = f + file_type
# move draft file
username = request.user.username
seafile_api.move_file(
repo_id, draft_file_parent_path, draft_file_name,
repo_id, dst_parent_path, dst_file_name,
replace=1, username=username, need_progress=0, synchronous=1
)
try:
published_file_path = d.publish(operator=username)
send_draft_publish_msg(d, username, published_file_path)
return Response({'published_file_path': published_file_path})
except DraftFileConflict:
return api_error(status.HTTP_409_CONFLICT,
'There is a conflict between the draft and the original file')
# 2. Update draft database info.
dst_file_path = posixpath.join(dst_parent_path, dst_file_name)
dst_file_id = seafile_api.get_file_id_by_path(repo_id, dst_file_path)
draft.update(dst_file_id)
# 3. Send draft file publish msg.
send_draft_publish_msg(draft, username, dst_file_path)
return Response({'published_file_path': dst_file_path})
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'

View File

@ -11,9 +11,9 @@ from seahub.base.fields import LowerCaseCharField
from seahub.base.models import TimestampedModel
from seahub.base.templatetags.seahub_tags import email2nickname, email2contact_email
from seahub.tags.models import FileUUIDMap
from seahub.utils import normalize_file_path, EMPTY_SHA1
from seahub.utils import normalize_file_path
from seahub.utils.timeutils import datetime_to_isoformat_timestr
from .utils import create_user_draft_repo, get_draft_file_name
from .utils import get_draft_file_name
class DraftFileExist(Exception):
@ -53,7 +53,7 @@ class DraftManager(models.Manager):
return drafts
def list_draft_by_username(self, username, status='open'):
"""list all user drafts
"""list all user drafts
If with_reviews is true, return the draft associated review
"""
repo_cache = {}
@ -70,7 +70,7 @@ class DraftManager(models.Manager):
return repo
data = []
qs = self.filter(username=username, status='open')
qs = self.filter(username=username, status=status)
for d in qs:
# If repo does not exist, no related items are displayed.
@ -99,10 +99,6 @@ class DraftManager(models.Manager):
return data
def create_exist_file_draft(self, repo, username, file_uuid, file_path):
# create drafts dir if does not exist
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)
# check draft file does not exists and copy origin file content to
# draft file
@ -146,10 +142,12 @@ class DraftManager(models.Manager):
return draft_file_path
def add(self, username, repo, file_path, file_exist=True, file_id=None, org_id=-1, status='open'):
file_path = normalize_file_path(file_path)
parent_path = os.path.dirname(file_path)
filename = os.path.basename(file_path)
# origin file uuid
file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(
repo.id, parent_path, filename, is_dir=False)
@ -186,6 +184,11 @@ class Draft(TimestampedModel):
# class Meta:
# unique_together = (('username', 'draft_repo_id'), )
def update(self, publish_file_version, status = 'published'):
self.publish_file_version = publish_file_version
self.status = status
self.save()
def delete(self, operator):
draft_file_name = os.path.basename(self.draft_file_path)
draft_file_path = os.path.dirname(self.draft_file_path)
@ -194,66 +197,6 @@ class Draft(TimestampedModel):
super(Draft, self).delete()
def publish(self, operator):
# check whether origin file is updated
r_repo = seafile_api.get_repo(self.origin_repo_id)
if not r_repo:
raise DraftFileConflict
file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.origin_file_uuid)
if not file_uuid:
# TODO update error msg
raise DraftFileConflict
if file_uuid.parent_path == '/':
origin_file_path = file_uuid.parent_path + file_uuid.filename
else:
origin_file_path = file_uuid.parent_path + '/' + file_uuid.filename
file_id = seafile_api.get_file_id_by_path(self.origin_repo_id,
origin_file_path)
draft_file_name = os.path.basename(self.draft_file_path)
draft_file_path = os.path.dirname(self.draft_file_path)
file_name = file_uuid.filename
if file_id:
if file_id != self.origin_file_version and self.draft_file_path != origin_file_path:
raise DraftFileConflict
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, draft_file_path, draft_file_name,
self.origin_repo_id, file_uuid.parent_path,
file_name, replace=1,
username=operator, need_progress=0, synchronous=1
)
else:
# move draft file to origin file
seafile_api.move_file(
self.origin_repo_id, draft_file_path, draft_file_name,
self.origin_repo_id, file_uuid.parent_path,
file_name, replace=1,
username=operator, need_progress=0, synchronous=1
)
published_file_path = posixpath.join(file_uuid.parent_path, file_name)
# get draft published version
file_id = seafile_api.get_file_id_by_path(self.origin_repo_id, published_file_path)
self.publish_file_version = file_id
self.status = 'published'
self.save()
return published_file_path
def to_dict(self):
uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.origin_file_uuid)
file_path = posixpath.join(uuid.parent_path, uuid.filename)

View File

@ -6,10 +6,9 @@ from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext as _
from seaserv import seafile_api
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.auth.decorators import login_required
from seahub.views import check_folder_permission
from seahub.utils import render_permission_error, render_error
from seahub.utils import render_permission_error
from seahub.drafts.models import Draft
from seahub.api2.utils import user_to_dict
from seahub.tags.models import FileUUIDMap