1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-07 18:13:56 +00:00
seahub/seahub/api2/endpoints/drafts.py

200 lines
7.2 KiB
Python
Raw Normal View History

2018-09-15 08:14:17 +00:00
# Copyright (c) 2012-2016 Seafile Ltd.
2019-05-31 07:57:32 +00:00
import os
2018-09-15 08:14:17 +00:00
import logging
2019-05-31 07:57:32 +00:00
import posixpath
2018-09-15 08:14:17 +00:00
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
2019-05-31 07:57:32 +00:00
from seaserv import seafile_api
2018-09-15 08:14:17 +00:00
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
2018-11-15 04:43:30 +00:00
from seahub.constants import PERMISSION_READ_WRITE
2019-05-31 07:57:32 +00:00
from seahub.drafts.models import Draft, DraftFileExist
from seahub.tags.models import FileUUIDMap
2018-09-15 08:14:17 +00:00
from seahub.views import check_folder_permission
from seahub.drafts.utils import send_draft_publish_msg
2018-09-15 08:14:17 +00:00
logger = logging.getLogger(__name__)
2018-10-15 07:51:29 +00:00
HTTP_520_OPERATION_FAILED = 520
2018-09-15 08:14:17 +00:00
class DraftsView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, format=None):
"""List all user drafts.
"""
username = request.user.username
2018-12-28 15:22:49 +00:00
data = Draft.objects.list_draft_by_username(username)
2018-09-15 08:14:17 +00:00
2018-11-01 09:52:59 +00:00
draft_counts = len(data)
result = {}
result['data'] = data
result['draft_counts'] = draft_counts
2018-12-28 15:22:49 +00:00
2018-11-01 09:52:59 +00:00
return Response(result)
2018-09-15 08:14:17 +00:00
@add_org_context
def post(self, request, org_id, format=None):
2019-04-19 07:15:20 +00:00
"""Create a file draft if the user has read-write permission to the origin file
2018-09-15 08:14:17 +00:00
"""
2019-05-31 07:57:32 +00:00
# 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
2018-09-15 08:14:17 +00:00
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)
2019-05-31 07:57:32 +00:00
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)
2019-04-19 07:15:20 +00:00
if perm != PERMISSION_READ_WRITE:
2018-09-15 08:14:17 +00:00
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
2018-11-15 04:43:30 +00:00
username = request.user.username
2018-09-15 08:14:17 +00:00
2019-05-31 07:57:32 +00:00
# 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)
2018-09-15 08:14:17 +00:00
return Response(d.to_dict())
2018-12-20 03:58:03 +00:00
except DraftFileExist:
2018-09-15 08:14:17 +00:00
return api_error(status.HTTP_409_CONFLICT, 'Draft already exists.')
2018-12-20 03:58:03 +00:00
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
2018-09-15 08:14:17 +00:00
class DraftView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def put(self, request, pk, format=None):
2018-11-15 04:43:30 +00:00
"""Publish a draft if the user has read-write permission to the origin file
2019-05-31 07:57:32 +00:00
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.
2018-09-15 08:14:17 +00:00
"""
2019-05-31 07:57:32 +00:00
# resource check
2018-09-15 08:14:17 +00:00
try:
2019-05-31 07:57:32 +00:00
draft = Draft.objects.get(pk=pk)
2018-09-15 08:14:17 +00:00
except Draft.DoesNotExist:
return api_error(status.HTTP_404_NOT_FOUND,
'Draft %s not found.' % pk)
2019-05-31 07:57:32 +00:00
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)
2019-05-31 07:57:32 +00:00
# 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, '/')
2018-11-15 04:43:30 +00:00
2019-05-31 07:57:32 +00:00
if permission != PERMISSION_READ_WRITE:
2018-11-15 04:43:30 +00:00
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
2018-09-15 08:14:17 +00:00
2019-05-31 07:57:32 +00:00
# 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
2018-12-05 05:31:16 +00:00
username = request.user.username
2019-05-31 07:57:32 +00:00
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
)
2018-09-15 08:14:17 +00:00
try:
2019-05-31 07:57:32 +00:00
# 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})
2018-12-20 04:12:20 +00:00
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
2018-09-15 08:14:17 +00:00
def delete(self, request, pk, format=None):
2018-11-15 04:43:30 +00:00
"""Delete a draft if user is draft owner
2018-09-15 08:14:17 +00:00
"""
2018-12-05 05:31:16 +00:00
username = request.user.username
2018-09-15 08:14:17 +00:00
try:
d = Draft.objects.get(pk=pk)
except Draft.DoesNotExist:
return api_error(status.HTTP_404_NOT_FOUND,
'Draft %s not found.' % pk)
# perm check
2018-12-05 05:31:16 +00:00
if d.username != username:
2018-09-15 08:14:17 +00:00
return api_error(status.HTTP_403_FORBIDDEN,
'Permission denied.')
2018-12-05 05:31:16 +00:00
d.delete(operator=username)
2018-09-15 08:14:17 +00:00
return Response(status.HTTP_200_OK)