1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 10:26:17 +00:00

backend finished

This commit is contained in:
Junxiang Huang
2024-06-07 17:42:27 +08:00
parent ca83ef90dc
commit 1f202e8796
5 changed files with 693 additions and 0 deletions

View File

@@ -0,0 +1,669 @@
import logging, requests, stat, posixpath, jwt, time
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from seahub.api2.utils import api_error, to_python_boolean
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.authentication import TokenAuthentication
from seahub.repo_metadata_enable.models import RepoMetadataEnable
from seahub.settings import ENABLE_METADATA_MANAGEMENT, MATEDATA_SERVER_URL, METEDATA_SERVER_SECRET_KEY
from seahub.views import check_folder_permission
from seahub.utils.timeutils import timestamp_to_isoformat_timestr
from seaserv import seafile_api
logger = logging.getLogger(__name__)
class __structure_table(object):
def __init__(self, id, name):
self.id = id
self.name = name
class __structure_column(object):
def __init__(self, key, name, type):
self.key = key
self.name = name
self.type = type
def to_build_column_dict(self):
return {
'name': self.name,
'type': self.type
}
TABLE = __structure_table('0001', 'Table1')
COLUMN_ID = __structure_column('0', '_id', 'text')
COLUMN_CREATOR = __structure_column('16', 'creator', 'text')
COLUMN_CREATE_TIME = __structure_column('17', 'create_time', 'date')
COLUMN_MODIFIER = __structure_column('18', 'modifier', 'text')
COLUMN_MODIFY_TIME = __structure_column('19', 'modify_time', 'date')
COLUMN_CURRENT_DIR = __structure_column('20', 'current_dir', 'text')
COLUMN_NAME = __structure_column('21', 'name', 'text')
COLUMN_IS_DIR = __structure_column('22', 'is_dir', 'text')
def gen_headers(repo_id):
payload = {
'exp': int(time.time()) + 300,
'base_id': repo_id
}
token = jwt.encode(payload, METEDATA_SERVER_SECRET_KEY, algorithm='HS256')
return {"Authorization": "Bearer %s" % token}
def scan_library(repo_id, current_dir = '/'):
'''
scan a library recursively
'''
dirents = seafile_api.list_dir_by_path(repo_id, current_dir) #this one only shows is_dir and name without modifier
scan_result = []
for tmp_dirent in dirents:
is_dir = stat.S_ISDIR(tmp_dirent.mode)
dirent = seafile_api.get_dirent_by_path(repo_id, posixpath.join(current_dir, tmp_dirent.obj_name))
scan_result.append([
'' if is_dir else dirent.modifier, #creator, the dir has not creator
timestamp_to_isoformat_timestr(dirent.mtime), #ctime
'' if is_dir else dirent.modifier, #modifier, the dir has not modifier
timestamp_to_isoformat_timestr(dirent.mtime), #mtime
current_dir,
dirent.obj_name, #name
'True' if is_dir else 'False'
])
if is_dir:
scan_result += scan_library(repo_id, posixpath.join(current_dir, dirent.obj_name))
return scan_result
def check_and_rollback(response, repo_id, headers):
if response.status_code >= 200 and response.status_code < 300:
return
else:
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}'
requests.delete(url, headers=headers)
if isinstance(response.reason, bytes):
try:
reason = response.reason.decode("utf-8")
except UnicodeDecodeError:
reason = response.reason.decode("iso-8859-1")
else:
reason = response.reason
return response.status_code, reason
def initial_metadata_base(repo_id):
headers = gen_headers(repo_id)
#create a metadata base for repo_id
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}'
response = requests.post(url, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
# Add columns: creator, create_time, modifier, modify_time, current_dir, name
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/columns'
data = {
'table_id': TABLE.id,
'column': COLUMN_CREATOR.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
data = {
'table_id': TABLE.id,
'column': COLUMN_CREATE_TIME.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
data = {
'table_id': TABLE.id,
'column': COLUMN_MODIFIER.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
data = {
'table_id': TABLE.id,
'column': COLUMN_MODIFY_TIME.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
data = {
'table_id': TABLE.id,
'column': COLUMN_CURRENT_DIR.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
data = {
'table_id': TABLE.id,
'column': COLUMN_NAME.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
data = {
'table_id': TABLE.id,
'column': COLUMN_IS_DIR.to_build_column_dict()
}
response = requests.post(url, json=data, headers=headers)
response.raise_for_status
if err := check_and_rollback(response, repo_id, headers):
return err
#scan files and dirs
rows = scan_library(repo_id)
#insert current metadata to md server from root dir
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/rows'
data = {
'table_id': TABLE.id,
'column_keys': [
COLUMN_CREATOR.key,
COLUMN_CREATE_TIME.key,
COLUMN_MODIFIER.key,
COLUMN_MODIFY_TIME.key,
COLUMN_CURRENT_DIR.key,
COLUMN_NAME.key,
COLUMN_IS_DIR.key
],
'rows': rows
}
response = requests.post(url, json=data, headers=headers)
if err := check_and_rollback(response, repo_id, headers):
return err
class MetadataManager(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id):
'''
check the repo has enabled the metadata manager or not
'''
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# recource 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)
# permission check
permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
try:
return Response({
'enable': True if RepoMetadataEnable.objects.filter(repo_id=repo_id) else False
})
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def post(self, request, repo_id):
'''
enable a new repo's metadata manager
'''
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# check dose the repo have opened metadata manager
if RepoMetadataEnable.objects.filter(repo_id=repo_id):
error_msg = f'The metadata module is enable for repo {repo_id}.'
return api_error(status.HTTP_409_CONFLICT, error_msg)
# recource 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)
# permission check
permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
err = initial_metadata_base(repo_id)
if err:
status_code, reason = err
logger.error(f'Metadata initial err, {status_code}: {reason}')
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {status_code}: {reason}')
try:
repo_metadata_enable = RepoMetadataEnable(repo_id=repo_id)
repo_metadata_enable.save()
return Response({
'success': True
})
except Exception as e:
#rollback
headers = gen_headers(repo_id)
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}'
requests.delete(url, headers=headers)
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def delete(self, request, repo_id):
'''
remove a repo's metadata manager
'''
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# recource 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)
# permission check
permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# check dose the repo have opened metadata manager
enable_recode = RepoMetadataEnable.objects.filter(repo_id=repo_id)
if not enable_recode:
error_msg = f'The repo {repo_id} has not enable the metadata manager.'
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
try:
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}'
headers = gen_headers(repo_id)
response = requests.delete(url, headers=headers)
if response.status_code < 200 or response.status_code > 299:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')
enable_recode.delete()
return Response({
'success': True
})
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
class MetadataManagerRecords(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def get(self, request, repo_id):
'''
fetch a metadata results
request body:
parent_dir: optional, if not specify, search from all dirs
name: optional, if not specify, search from all objects
page: optional, the current page
perpage: optional, if use page, default is 25
is_dir: optional, True or False
'''
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
#args check
parent_dir = request.data.get('parent_dir')
name = request.data.get('name')
page = request.data.get('page')
perpage = request.data.get('perpage')
is_dir = request.data.get('is_dir')
if page:
try:
page = int(page)
except ValueError:
error_msg = 'Page is not vaild.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if perpage:
try:
perpage = int(perpage)
except ValueError:
error_msg = 'Perpage is not vaild.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
else:
perpage = 25
if is_dir:
try:
is_dir = to_python_boolean(is_dir)
except:
error_msg = 'is_dir is not vaild.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# metadata enable check
if not RepoMetadataEnable.objects.filter(repo_id=repo_id):
error_msg = f'The metadata module is not enable for repo {repo_id}.'
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# recource 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)
# permission check
permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
sql = f'SELECT `{COLUMN_ID.name}`, `{COLUMN_CREATOR.name}`, `{COLUMN_CREATE_TIME.name}`, `{COLUMN_MODIFIER.name}`, `{COLUMN_MODIFY_TIME.name}`, `{COLUMN_CURRENT_DIR.name}`, `{COLUMN_NAME.name}`, `{COLUMN_IS_DIR.name}` FROM `{TABLE.name}`'
if parent_dir:
sql += f' WHERE `{COLUMN_CURRENT_DIR.name}` = "{parent_dir}"'
if name:
sql += f' AND `{COLUMN_NAME.name}` = "{name}"'
if is_dir:
sql += f' AND `{COLUMN_IS_DIR.name}` = "{is_dir}"'
elif name:
sql += f' WHERE `{COLUMN_NAME.name}` = "{name}"'
if is_dir:
sql += f' AND `{COLUMN_IS_DIR.name}` = "{is_dir}"'
elif is_dir:
sql += f' WHERE `{COLUMN_IS_DIR.name}` = "{is_dir}"'
if page:
sql += f' LIMIT {(page - 1) * perpage}, {page * perpage}'
sql += ';'
#query_result
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/query'
headers = gen_headers(repo_id)
response = requests.post(url, json={'sql': sql}, headers=headers)
if response.status_code < 200 or response.status_code > 299:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')
response_results = response.json()['results']
if response_results:
results = [
{
COLUMN_ID.name: result[0],
COLUMN_CREATOR.name: result[1],
COLUMN_CREATE_TIME.name: result[2],
COLUMN_MODIFIER.name: result[3],
COLUMN_MODIFY_TIME.name: result[4],
COLUMN_CURRENT_DIR.name: result[5],
COLUMN_NAME.name: result[6],
COLUMN_IS_DIR.name: True if result[7] == 'True' else False
}
for result in response_results
]
else:
results = []
return Response({
'results': results
})
def post(self, request, repo_id):
'''
add a metadata results
request body:
parent_dir: required, if not specify, search from all dirs
name: required, if not specify, search from all objects
'''
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# args check
parent_dir = request.data.get('parent_dir')
name = request.data.get('name')
if not parent_dir:
error_msg = 'parent_dir is not specified.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not name:
error_msg = 'name is not specified.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# metadata enable check
if not RepoMetadataEnable.objects.filter(repo_id=repo_id):
error_msg = f'The metadata module is not enable for repo {repo_id}.'
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# recource 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)
# permission check
permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# dirent check
dirent_path = posixpath.join(parent_dir, name)
dirent = seafile_api.get_dirent_by_path(repo_id, dirent_path)
if not dirent:
error_msg = 'dirent %s not found.' % dirent_path
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# check the current dirent exists or not
is_dir = stat.S_ISDIR(dirent.mode)
sql = f'SELECT `{COLUMN_ID.name}` FROM `{TABLE.name}` WHERE `{COLUMN_CURRENT_DIR.name}` = "{parent_dir}" AND `{COLUMN_NAME.name}` = "{name}" AND `{COLUMN_IS_DIR.name}` = "{True if is_dir else False}";'
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/query'
headers = gen_headers(repo_id)
response = requests.post(url, json={'sql': sql}, headers=headers)
if response.status_code < 200 or response.status_code > 299:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')
query_result = response.json().get('results')
if query_result:
error_msg = 'dirent %s has inserted in metadata base.' % dirent_path
return api_error(status.HTTP_409_CONFLICT, error_msg)
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/rows'
data = {
'table_id': TABLE.id,
'column_keys': [
COLUMN_CREATOR.key,
COLUMN_CREATE_TIME.key,
COLUMN_MODIFIER.key,
COLUMN_MODIFY_TIME.key,
COLUMN_CURRENT_DIR.key,
COLUMN_NAME.key,
COLUMN_IS_DIR.key
],
'rows': [[
'' if is_dir else dirent.modifier, #creator, the dir has not creator
timestamp_to_isoformat_timestr(dirent.mtime), #ctime
'' if is_dir else dirent.modifier, #modifier, the dir has not modifier
timestamp_to_isoformat_timestr(dirent.mtime), #mtime
parent_dir,
dirent.obj_name, #name
'True' if is_dir else 'False'
]]
}
response = requests.post(url, json=data, headers=headers)
if response.status_code >= 200 and response.status_code <= 299:
return Response({
'success': True
})
else:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')
class MetadataManagerRecord(APIView):
#authentication_classes = (TokenAuthentication, SessionAuthentication)
#permission_classes = (IsAuthenticated, )
throttle_classes = (UserRateThrottle, )
def put(self, request, repo_id, record_id):
'''
modify a metadata base recode by the record_id
for simplfying the precudures, all parameters are required
request body:
creator, required
create_time, required
modifier, required,
modify_time, required
current_dir, required
name, required
'''
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
creator = request.data.get('creator')
create_time = request.data.get('create_time')
modifier = request.data.get('modifier')
modify_time = request.data.get('modify_time')
current_dir = request.data.get('current_dir')
name = request.data.get('name')
#args check
for body_key in ('creator', 'create_time', 'modifier', 'modify_time', 'current_dir', 'name'):
if eval(body_key) is None:
error_msg = f"{body_key} is not specified"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# metadata enable check
if not RepoMetadataEnable.objects.filter(repo_id=repo_id):
error_msg = f'The metadata module is not enable for repo {repo_id}.'
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# recource 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)
# permission check
permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# dirent check
dirent_path = posixpath.join(current_dir, name)
dirent = seafile_api.get_dirent_by_path(repo_id, dirent_path)
if not dirent:
error_msg = 'dirent %s not found.' % dirent_path
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# check the current dirent exists or not
is_dir = stat.S_ISDIR(dirent.mode)
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/query'
sql = f'SELECT `{COLUMN_ID.name}` FROM `{TABLE.name}` WHERE `{COLUMN_CURRENT_DIR.name}` = "{current_dir}" AND `{COLUMN_NAME.name}` = "{name}" AND `{COLUMN_ID.name}` != "{record_id}" AND `{COLUMN_IS_DIR.name}` = "{True if is_dir else False}";'
headers = gen_headers(repo_id)
response = requests.post(url, json={'sql': sql}, headers=headers)
if response.status_code < 200 or response.status_code > 299:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code} in querying result: {response.reason}')
query_result = response.json().get('results')
if query_result:
error_msg = f'The {"folder" if is_dir else "file"} {dirent_path} is exists in the metadata base'
return api_error(status.HTTP_409_CONFLICT, error_msg)
# dirent type originality check
sql = f'SELECT `{COLUMN_ID.name}` FROM `{TABLE.name}` WHERE `{COLUMN_ID.name}` = "{record_id}" AND `{COLUMN_IS_DIR.name}` != "{True if is_dir else False}";'
response = requests.post(url, json={'sql': sql}, headers=headers)
if response.status_code < 200 or response.status_code > 299:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')
query_result = response.json().get('results')
if query_result:
error_msg = f'The type of new dirent {dirent_path} is not matched with the original type'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/rows'
data = {
'table_id': TABLE.id,
'column_keys': [
COLUMN_ID.key,
COLUMN_CREATOR.key,
COLUMN_CREATE_TIME.key,
COLUMN_MODIFIER.key,
COLUMN_MODIFY_TIME.key,
COLUMN_CURRENT_DIR.key,
COLUMN_NAME.key
],
'rows': [[
record_id,
creator,
create_time,
modifier,
modify_time,
current_dir,
name
]]
}
response = requests.put(url, json=data, headers=headers)
if response.status_code >= 200 and response.status_code < 299:
return Response({
'success': True
})
else:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')
def delete(self, request, repo_id, record_id):
if not ENABLE_METADATA_MANAGEMENT or not MATEDATA_SERVER_URL:
error_msg = "Function is not supported"
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# metadata enable check
if not RepoMetadataEnable.objects.filter(repo_id=repo_id):
error_msg = f'The metadata module is not enable for repo {repo_id}.'
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# recource 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)
# permission check
'''permission = check_folder_permission(request, repo_id, '/')
if not permission:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
'''
url = f'{MATEDATA_SERVER_URL}/api/v1/base/{repo_id}/rows'
data = {
'table_id': TABLE.id,
'row_ids': [
record_id
]
}
headers = gen_headers(repo_id)
response = requests.delete(url, json=data, headers=headers)
if response.status_code >= 200 and response.status_code <= 299:
return Response({
'success': True
})
else:
return api_error(status.HTTP_503_SERVICE_UNAVAILABLE, f'error from metadata server with code {response.status_code}: {response.reason}')

View File

View File

@@ -0,0 +1,11 @@
import logging
from django.db import models
logger = logging.getLogger(__name__)
class RepoMetadataEnable(models.Model):
repo_id = models.CharField(max_length=36, db_index=True)
class Meta:
db_table = 'repo_metadata_enable'

View File

@@ -269,6 +269,7 @@ INSTALLED_APPS = [
'seahub.dingtalk', 'seahub.dingtalk',
'seahub.file_participants', 'seahub.file_participants',
'seahub.repo_api_tokens', 'seahub.repo_api_tokens',
'seahub.repo_metadata_enable',
'seahub.abuse_reports', 'seahub.abuse_reports',
'seahub.repo_auto_delete', 'seahub.repo_auto_delete',
'seahub.ocm', 'seahub.ocm',
@@ -887,6 +888,13 @@ SEATABLE_EX_PROPS_BASE_API_TOKEN = ''
EX_PROPS_TABLE = '' EX_PROPS_TABLE = ''
EX_EDITABLE_COLUMNS = [] EX_EDITABLE_COLUMNS = []
##############################
# metadata server properties #
##############################
ENABLE_METADATA_MANAGEMENT = False
MATEDATA_SERVER_URL = None
METEDATA_SERVER_SECRET_KEY = ''
d = os.path.dirname d = os.path.dirname
EVENTS_CONFIG_FILE = os.environ.get( EVENTS_CONFIG_FILE = os.environ.get(
'EVENTS_CONFIG_FILE', 'EVENTS_CONFIG_FILE',

View File

@@ -206,6 +206,8 @@ from seahub.ai.apis import LibrarySdocIndexes, Search, LibrarySdocIndex, TaskSta
from seahub.wiki2.views import wiki_view from seahub.wiki2.views import wiki_view
from seahub.api2.endpoints.wiki2 import Wikis2View, Wiki2View, Wiki2ConfigView, Wiki2PagesView, Wiki2PageView from seahub.api2.endpoints.wiki2 import Wikis2View, Wiki2View, Wiki2ConfigView, Wiki2PagesView, Wiki2PageView
from seahub.api2.endpoints.subscription import SubscriptionView, SubscriptionPlansView, SubscriptionLogsView from seahub.api2.endpoints.subscription import SubscriptionView, SubscriptionPlansView, SubscriptionLogsView
from seahub.api2.endpoints.metadata_manager import MetadataManagerRecords, MetadataManager, MetadataManagerRecord
urlpatterns = [ urlpatterns = [
path('accounts/', include('seahub.base.registration_urls')), path('accounts/', include('seahub.base.registration_urls')),
@@ -434,6 +436,9 @@ urlpatterns = [
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/participants/$', FileParticipantsView.as_view(), name='api-v2.1-file-participants'), re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/participants/$', FileParticipantsView.as_view(), name='api-v2.1-file-participants'),
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/participant/$', FileParticipantView.as_view(), name='api-v2.1-file-participant'), re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/file/participant/$', FileParticipantView.as_view(), name='api-v2.1-file-participant'),
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/related-users/$', RepoRelatedUsersView.as_view(), name='api-v2.1-related-user'), re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/related-users/$', RepoRelatedUsersView.as_view(), name='api-v2.1-related-user'),
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/$', MetadataManager.as_view(), name='api-v2.1-metadata'),
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/records/$', MetadataManagerRecords.as_view(), name='api-v2.1-metadata-records'),
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/metadata/records/(?P<record_id>[A-Za-z0-9_]+)/$', MetadataManagerRecord.as_view(), name='api-v2.1-metadata-record'),
## user:file:extended-props ## user:file:extended-props
re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/extended-properties/$', ExtendedPropertiesView.as_view(), name='api-v2.1-extended-properties'), re_path(r'^api/v2.1/repos/(?P<repo_id>[-0-9a-f]{36})/extended-properties/$', ExtendedPropertiesView.as_view(), name='api-v2.1-extended-properties'),