1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-25 06:33:48 +00:00

Support mark folder sub items (#5638)

* add folder-items-ex-props api

* pass user-name for set folder-items ex-props

* frontend feat folder-items ex-props

* opt request seaf-io

* opt some variables

* opt some tips

* opt loading style for apply ex-props

* feat: update code

* fix confirm bug

---------

Co-authored-by: er-pai-r <18335219360@163.com>
This commit is contained in:
Alex Happy
2023-09-25 12:25:20 +08:00
committed by GitHub
parent 6ee7debdb1
commit cdf36ed154
6 changed files with 296 additions and 15 deletions

View File

@@ -4,6 +4,7 @@ import os
import stat
from datetime import datetime
import requests
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.authentication import SessionAuthentication
@@ -17,7 +18,7 @@ from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.settings import DTABLE_WEB_SERVER, SEATABLE_EX_PROPS_BASE_API_TOKEN, \
EX_PROPS_TABLE, EX_EDITABLE_COLUMNS
EX_PROPS_TABLE, EX_EDITABLE_COLUMNS, SEAF_EVENTS_IO_SERVER_URL
from seahub.tags.models import FileUUIDMap
from seahub.utils import normalize_file_path, EMPTY_SHA1
from seahub.utils.repo import parse_repo_perm
@@ -27,6 +28,29 @@ from seahub.views import check_folder_permission
logger = logging.getLogger(__name__)
def request_can_set_ex_props(repo_id, path):
url = SEAF_EVENTS_IO_SERVER_URL.strip('/') + '/can-set-ex-props'
resp = requests.post(url, json={'repo_id': repo_id, 'path': path})
return resp.json()
def add_set_folder_ex_props_task(repo_id, path, username):
url = SEAF_EVENTS_IO_SERVER_URL.strip('/') + '/set-folder-items-ex-props'
context = {
'repo_id': repo_id,
'path': path,
'文件负责人': email2nickname(username)
}
resp = requests.post(url, json=context)
return resp.json()
def query_set_ex_props_status(repo_id, path):
url = SEAF_EVENTS_IO_SERVER_URL.strip('/') + '/query-set-ex-props-status'
resp = requests.get(url, params={'repo_id': repo_id, 'path': path})
return resp.json()
def check_table(seatable_api: SeaTableAPI):
"""check EX_PROPS_TABLE is invalid or not
@@ -76,6 +100,14 @@ class ExtendedPropertiesView(APIView):
if not parse_repo_perm(check_folder_permission(request, repo_id, parent_dir)).can_edit_on_web:
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
resp_json = request_can_set_ex_props(repo_id, path)
if not resp_json.get('can_set', False):
if resp_json.get('error_type') == 'higher_being_set':
error_msg = 'Another task is running'
else:
error_msg = 'Please try again later'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# check base
try:
seatable_api = SeaTableAPI(SEATABLE_EX_PROPS_BASE_API_TOKEN, DTABLE_WEB_SERVER)
@@ -229,6 +261,14 @@ class ExtendedPropertiesView(APIView):
if not parse_repo_perm(check_folder_permission(request, repo_id, parent_dir)).can_edit_on_web:
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
resp_json = request_can_set_ex_props(repo_id, path)
if not resp_json.get('can_set', False):
if resp_json.get('error_type') == 'higher_being_set':
error_msg = 'Another task is running'
else:
error_msg = 'Please try again later'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# check base
try:
seatable_api = SeaTableAPI(SEATABLE_EX_PROPS_BASE_API_TOKEN, DTABLE_WEB_SERVER)
@@ -316,3 +356,91 @@ class ExtendedPropertiesView(APIView):
logger.exception('delete props record error: %s', e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error')
return Response({'success': True})
class FolderItemsExtendedPropertiesView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle,)
def post(self, request, repo_id):
if not all((DTABLE_WEB_SERVER, SEATABLE_EX_PROPS_BASE_API_TOKEN, EX_PROPS_TABLE)):
return api_error(status.HTTP_403_FORBIDDEN, 'Feature not enabled')
# arguments check
path = request.data.get('path')
if not path:
return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid')
path = normalize_file_path(path)
parent_dir = os.path.dirname(path)
dirent = seafile_api.get_dirent_by_path(repo_id, path)
if not dirent:
return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found' % path)
if not stat.S_ISDIR(dirent.mode):
return api_error(status.HTTP_400_BAD_REQUEST, '%s is not a folder' % path)
# permission check
if not parse_repo_perm(check_folder_permission(request, repo_id, parent_dir)).can_edit_on_web:
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
# request props from seatable
try:
seatable_api = SeaTableAPI(SEATABLE_EX_PROPS_BASE_API_TOKEN, DTABLE_WEB_SERVER)
except:
logger.error('server: %s token: %s seatable-api fail', DTABLE_WEB_SERVER, SEATABLE_EX_PROPS_BASE_API_TOKEN)
return api_error(status.HTTP_400_BAD_REQUEST, 'Props table invalid')
sql = f"SELECT * FROM `{EX_PROPS_TABLE}` WHERE `Repo ID`='{repo_id}' AND `Path`='{path}'"
try:
result = seatable_api.query(sql)
except Exception as e:
logger.exception('query sql: %s error: %s', sql, e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error')
rows = result.get('results')
if not rows:
return api_error(status.HTTP_400_BAD_REQUEST, '%s not set extended properties' % path)
resp_json = add_set_folder_ex_props_task(repo_id, path, request.user.username)
error_type = resp_json.get('error_type')
if error_type == 'higher_being_set':
error_msg = 'Another task is running'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
elif error_type == 'server_busy':
error_msg = 'Server is busy'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
elif error_type == 'sub_folder_setting':
error_msg = 'Another task is running'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
return Response({'success': True})
class FolderItemsPropertiesStatusQueryView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle,)
def get(self, request, repo_id):
if not all((DTABLE_WEB_SERVER, SEATABLE_EX_PROPS_BASE_API_TOKEN, EX_PROPS_TABLE)):
return api_error(status.HTTP_403_FORBIDDEN, 'Feature not enabled')
# arguments check
path = request.GET.get('path')
if not path:
return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid')
path = normalize_file_path(path)
parent_dir = os.path.dirname(path)
dirent = seafile_api.get_dirent_by_path(repo_id, path)
if not dirent:
return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found' % path)
if not stat.S_ISDIR(dirent.mode):
return api_error(status.HTTP_400_BAD_REQUEST, '%s is not a folder' % path)
# permission check
if not parse_repo_perm(check_folder_permission(request, repo_id, parent_dir)).can_edit_on_web:
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
resp_json = query_set_ex_props_status(repo_id, path)
return Response(resp_json)