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:
@@ -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)
|
||||
|
Reference in New Issue
Block a user