import jwt import time import requests import json import random from urllib.parse import urljoin from datetime import datetime from seahub.settings import SECRET_KEY, SEAFEVENTS_SERVER_URL from seahub.views import check_folder_permission from seahub.utils.timeutils import datetime_to_isoformat_timestr from seaserv import seafile_api FACES_SAVE_PATH = '_Internal/Faces' def add_init_metadata_task(params): payload = {'exp': int(time.time()) + 300, } token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') headers = {"Authorization": "Token %s" % token} url = urljoin(SEAFEVENTS_SERVER_URL, '/add-init-metadata-task') resp = requests.get(url, params=params, headers=headers) return json.loads(resp.content)['task_id'] def add_init_face_recognition_task(params): payload = {'exp': int(time.time()) + 300, } token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') headers = {"Authorization": "Token %s" % token} url = urljoin(SEAFEVENTS_SERVER_URL, '/add-init-face-recognition-task') resp = requests.get(url, params=params, headers=headers) return json.loads(resp.content)['task_id'] def extract_file_details(params): payload = {'exp': int(time.time()) + 300, } token = jwt.encode(payload, SECRET_KEY, algorithm='HS256') headers = {"Authorization": "Token %s" % token} url = urljoin(SEAFEVENTS_SERVER_URL, '/extract-file-details') resp = requests.post(url, json=params, headers=headers, timeout=30) return json.loads(resp.content)['details'] def generator_base64_code(length=4): possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz0123456789' ids = random.sample(possible, length) return ''.join(ids) def gen_unique_id(id_set, length=4): _id = generator_base64_code(length) while True: if _id not in id_set: return _id _id = generator_base64_code(length) def get_face_columns(): from seafevents.repo_metadata.constants import FACES_TABLE columns = [ FACES_TABLE.columns.vector.to_dict(), FACES_TABLE.columns.name.to_dict(), ] return columns def get_table_by_name(metadata_server_api, table_name): metadata = metadata_server_api.get_metadata() tables = metadata.get('tables', []) table = next((table for table in tables if table['name'] == table_name), None) return table def get_unmodifiable_columns(): from seafevents.repo_metadata.constants import METADATA_TABLE columns = [ METADATA_TABLE.columns.file_creator.to_dict(), METADATA_TABLE.columns.file_ctime.to_dict(), METADATA_TABLE.columns.file_modifier.to_dict(), METADATA_TABLE.columns.file_mtime.to_dict(), METADATA_TABLE.columns.parent_dir.to_dict(), METADATA_TABLE.columns.file_name.to_dict(), METADATA_TABLE.columns.is_dir.to_dict(), METADATA_TABLE.columns.file_type.to_dict(), METADATA_TABLE.columns.location.to_dict(), METADATA_TABLE.columns.obj_id.to_dict(), METADATA_TABLE.columns.size.to_dict(), METADATA_TABLE.columns.suffix.to_dict(), METADATA_TABLE.columns.file_details.to_dict(), ] return columns def init_metadata(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE, METADATA_TABLE_SYS_COLUMNS # delete base to prevent dirty data caused by last failure metadata_server_api.delete_base() metadata_server_api.create_base() # init sys column sys_columns = METADATA_TABLE_SYS_COLUMNS metadata_server_api.add_columns(METADATA_TABLE.id, sys_columns) def init_faces(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE, FACES_TABLE remove_faces_table(metadata_server_api) resp = metadata_server_api.create_table(FACES_TABLE.name) face_table_id = resp['id'] # add face vector column metadata_server_api.add_columns(METADATA_TABLE.id, [METADATA_TABLE.columns.face_vectors.to_dict()]) # init faces column face_columns = get_face_columns() metadata_server_api.add_columns(face_table_id, face_columns) # add face link column metadata_server_api.add_link_columns(FACES_TABLE.face_link_id, METADATA_TABLE.id, face_table_id, { "key": METADATA_TABLE.columns.face_links.key, "name": METADATA_TABLE.columns.face_links.name, "display_column_key": FACES_TABLE.columns.name.key }, { "key": FACES_TABLE.columns.photo_links.key, "name": FACES_TABLE.columns.photo_links.name, "display_column_key": METADATA_TABLE.columns.obj_id.key }) metadata_server_api.add_link_columns(FACES_TABLE.excluded_face_link_id, METADATA_TABLE.id, face_table_id, { "key": METADATA_TABLE.columns.excluded_face_links.key, "name": METADATA_TABLE.columns.excluded_face_links.name, "display_column_key": FACES_TABLE.columns.name.key }, { "key": FACES_TABLE.columns.excluded_photo_links.key, "name": FACES_TABLE.columns.excluded_photo_links.name, "display_column_key": METADATA_TABLE.columns.obj_id.key }) metadata_server_api.add_link_columns(FACES_TABLE.included_face_link_id, METADATA_TABLE.id, face_table_id, { "key": METADATA_TABLE.columns.included_face_links.key, "name": METADATA_TABLE.columns.included_face_links.name, "display_column_key": FACES_TABLE.columns.name.key }, { "key": FACES_TABLE.columns.included_photo_links.key, "name": FACES_TABLE.columns.included_photo_links.name, "display_column_key": METADATA_TABLE.columns.obj_id.key }) def remove_faces_table(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE, FACES_TABLE metadata = metadata_server_api.get_metadata() tables = metadata.get('tables', []) for table in tables: if table['name'] == FACES_TABLE.name: metadata_server_api.delete_table(table['id'], True) elif table['name'] == METADATA_TABLE.name: columns = table.get('columns', []) for column in columns: if column['key'] in [ METADATA_TABLE.columns.face_vectors.key, METADATA_TABLE.columns.face_links.key, METADATA_TABLE.columns.excluded_face_links.key, METADATA_TABLE.columns.included_face_links.key ]: metadata_server_api.delete_column(table['id'], column['key'], True) # tag def get_tag_columns(table_id): from seafevents.repo_metadata.constants import TAGS_TABLE columns = [ TAGS_TABLE.columns.name.to_dict(), TAGS_TABLE.columns.color.to_dict(), ] return columns def init_tag_file_links_column(metadata_server_api, tag_table_id): from seafevents.repo_metadata.constants import METADATA_TABLE, TAGS_TABLE file_link_id = TAGS_TABLE.file_link_id table_id = METADATA_TABLE.id other_table_id = tag_table_id table_column = { 'key': METADATA_TABLE.columns.tags.key, 'name': METADATA_TABLE.columns.tags.name, 'display_column_key': TAGS_TABLE.columns.name.name, } other_table_column = { 'key': TAGS_TABLE.columns.file_links.key, 'name': TAGS_TABLE.columns.file_links.name, 'display_column_key': TAGS_TABLE.columns.id.key, } metadata_server_api.add_link_columns(file_link_id, table_id, other_table_id, table_column, other_table_column) def init_tag_self_link_columns(metadata_server_api, tag_table_id): from seafevents.repo_metadata.constants import TAGS_TABLE link_id = TAGS_TABLE.self_link_id table_id = tag_table_id other_table_id = tag_table_id # as parent tags which is_linked_back is false table_column = { 'key': TAGS_TABLE.columns.parent_links.key, 'name': TAGS_TABLE.columns.parent_links.name, 'display_column_key': TAGS_TABLE.columns.id.key, } # as sub tags which is_linked_back is true other_table_column = { 'key': TAGS_TABLE.columns.sub_links.key, 'name': TAGS_TABLE.columns.sub_links.name, 'display_column_key': TAGS_TABLE.columns.id.key, } metadata_server_api.add_link_columns(link_id, table_id, other_table_id, table_column, other_table_column) def init_tags(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE, TAGS_TABLE remove_tags_table(metadata_server_api) resp = metadata_server_api.create_table(TAGS_TABLE.name) table_id = resp['id'] # init columns tag_columns = get_tag_columns(table_id) metadata_server_api.add_columns(table_id, tag_columns) # init link columns init_tag_file_links_column(metadata_server_api, table_id) init_tag_self_link_columns(metadata_server_api, table_id) def remove_tags_table(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE, TAGS_TABLE metadata = metadata_server_api.get_metadata() tables = metadata.get('tables', []) for table in tables: if table['name'] == TAGS_TABLE.name: metadata_server_api.delete_table(table['id'], True) elif table['name'] == METADATA_TABLE.name: columns = table.get('columns', []) for column in columns: if column['key'] in [METADATA_TABLE.columns.tags.key]: metadata_server_api.delete_column(table['id'], column['key'], True) # ocr def init_ocr(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE remove_ocr_column(metadata_server_api) # init ocr column columns = [ METADATA_TABLE.columns.ocr.to_dict(), ] metadata_server_api.add_columns(METADATA_TABLE.id, columns) def remove_ocr_column(metadata_server_api): from seafevents.repo_metadata.constants import METADATA_TABLE metadata = metadata_server_api.get_metadata() tables = metadata.get('tables', []) for table in tables: if table['name'] == METADATA_TABLE.name: columns = table.get('columns', []) for column in columns: if column['key'] == METADATA_TABLE.columns.ocr.key: metadata_server_api.delete_column(table['id'], METADATA_TABLE.columns.ocr.key, True) def get_file_download_token(repo_id, file_id, username): return seafile_api.get_fileserver_access_token(repo_id, file_id, 'download', username, use_onetime=True) def can_read_metadata(request, repo_id): permission = check_folder_permission(request, repo_id, '/') if permission: return True return False def get_column_valid_value(column, value): from seafevents.repo_metadata.constants import PropertyTypes if value and column['type'] == PropertyTypes.DATE: column_data = column.get('data', {}) format = column_data.get('format', 'YYYY-MM-DD') saved_format = '%Y-%m-%d' if 'HH:mm:ss' in format: saved_format = '%Y-%m-%d %H:%M:%S' elif 'HH:mm' in format: saved_format = '%Y-%m-%d %H:%M' datetime_obj = datetime.strptime(value, saved_format) return datetime_to_isoformat_timestr(datetime_obj) if column['type'] == PropertyTypes.SINGLE_SELECT and not value: return None return value def get_update_record(update={}, columns=[], unmodifiable_column_names=[]): if not update: return None update_record = {} for column_name, value in update.items(): if column_name not in unmodifiable_column_names: try: column = next(column for column in columns if column['name'] == column_name) valid_value = get_column_valid_value(column, value) update_record[column_name] = valid_value except Exception as e: pass return update_record