diff --git a/dogconfig/dogproject/settings.py b/dogconfig/dogproject/settings.py index 0b4630a..1c012db 100644 --- a/dogconfig/dogproject/settings.py +++ b/dogconfig/dogproject/settings.py @@ -63,7 +63,8 @@ INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] - +DTR_ENABLED = True +VERIFY_SSL = False # Application definition INSTALLED_APPS = [ @@ -86,11 +87,10 @@ # local 'dogapi', 'dogui' - ] -DTR_ENABLED = False - +if DTR_ENABLED: + INSTALLED_APPS += ['dogdtr'] REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ @@ -100,14 +100,10 @@ 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', } -VERIFY_SSL = False - - - SPECTACULAR_SETTINGS = { 'TITLE': 'Digital Object Gate', 'DESCRIPTION': 'DOG API resolving referenced resources in the metadata', - 'VERSION': '1.0.3', + 'VERSION': VERSION, 'SERVE_INCLUDE_SCHEMA': False, # OTHER SETTINGS } @@ -143,6 +139,9 @@ }, ] +if DTR_ENABLED: + TEMPLATES[0]['DIRS'] += [join(BASE_DIR, './../dogdtr/dogdtr/templates')] + DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/dogconfig/dogproject/urls.py b/dogconfig/dogproject/urls.py index 74dd770..02eabe5 100644 --- a/dogconfig/dogproject/urls.py +++ b/dogconfig/dogproject/urls.py @@ -7,7 +7,7 @@ from dogapi.views_api import (fetch, identify, sniff, is_pid, get_all_repositories, get_repositories_status) -from dogdtr.views_api import expand_datatype +from dogdtr.views_api import expand_datatype_view from dogdtr.views_ui import dtr from dogui.views_ui import about, contact, home @@ -24,13 +24,13 @@ path('api/v1/ispid/', is_pid, name='is pid'), path('__debug__/', include('debug_toolbar.urls')), - path('api/v1/expanddatatype/', expand_datatype, name='expand data type'), + path('api/v1/expanddatatype/', expand_datatype_view, name='expand data type'), path('api/v1/allregrepo/', get_all_repositories, name='get all repositories'), path('api/v1/repostatus/', get_repositories_status, name='get repositories status'), # UI path('', home, name='main'), - path('about', about, name='about'), - path('contact', contact, name='contact'), - path('dtr', dtr, name='contact') + path('about/', about, name='about'), + path('contact/', contact, name='contact'), + path('dtr/', dtr, name='dtr'), ] diff --git a/dogui/dogui/templates/UI/_.html b/dogconfig/templates/UI/_.html similarity index 100% rename from dogui/dogui/templates/UI/_.html rename to dogconfig/templates/UI/_.html diff --git a/dogui/dogui/templates/UI/_about.html b/dogconfig/templates/UI/_about.html similarity index 100% rename from dogui/dogui/templates/UI/_about.html rename to dogconfig/templates/UI/_about.html diff --git a/dogui/dogui/templates/UI/_contact.html b/dogconfig/templates/UI/_contact.html similarity index 100% rename from dogui/dogui/templates/UI/_contact.html rename to dogconfig/templates/UI/_contact.html diff --git a/dogui/dogui/templates/UI/_navbar.html b/dogconfig/templates/UI/_navbar.html similarity index 100% rename from dogui/dogui/templates/UI/_navbar.html rename to dogconfig/templates/UI/_navbar.html diff --git a/dogdtr/dogdtr/dtr.py b/dogdtr/dogdtr/dtr.py index 1814f08..27ee245 100644 --- a/dogdtr/dogdtr/dtr.py +++ b/dogdtr/dogdtr/dtr.py @@ -1,8 +1,12 @@ - import json +import urllib from requests import RequestException from requests import get +from typing import List, Tuple, Union + + +from .utils import MIMEType class DataTypeNotFoundException(Exception): @@ -10,11 +14,14 @@ def __init__(self, message): self.message = message -def expand_datatype(data_type: str) -> dict: +def expand_datatype(data_type: Union[str, List[str]]) -> List[dict]: """ Wrapper for DTR datatype taxonomy discovery """ - return get_dtr_taxonomy_by_type(data_type) + if isinstance(data_type, str): + return [get_dtr_taxonomy_by_type(data_type)] + elif isinstance(data_type, list): + return [get_dtr_taxonomy_by_type(dt) for dt in data_type] def get_dtr_taxonomy_by_type(data_type: str) -> dict: @@ -24,61 +31,50 @@ def get_dtr_taxonomy_by_type(data_type: str) -> dict: :param data_type: str, MIME type, e.g. 'text/xml' :return: dict, a dictionary representation of the type's taxonomy """ - dtr_type_search_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/search?query={data_type}&name={data_type}" + dtr_taxonomy_search_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/search?query={data_type}&name={data_type}" + data_type = urllib.parse.quote(data_type, safe='') try: - url, dtr_taxonomy_search_response, header = get(dtr_type_search_endpoint) + dtr_taxonomy_search_response = get(dtr_taxonomy_search_endpoint) except RequestException as error: - raise DataTypeNotFoundException(f"DataType <{data_type}> doesn't exist in the DTR taxonomy") from error + raise DataTypeNotFoundException(f"Failed to reach DTR to query for taxonomy") from error + except ValueError as error: + raise DataTypeNotFoundException(f"Failed to unpack DTR response. Most probably {data_type} is not registered") from error - dtr_taxonomy_json = json.loads(dtr_taxonomy_search_response) - print("get_dtr_taxonomy_by_type: TAXONOMY") - print(dtr_taxonomy_json) try: - dtr_type_id = dtr_taxonomy_json[0]["id"] - except (IndexError, KeyError) as error: - raise DataTypeNotFoundException(f"DataType <{data_type}> doesn't exist in the DTR taxonomy") from error - parents = dtr_taxonomy_json[0]["parents"] - if parents: - for parent_id, parent_name in parents.items(): - dtr_type_id = get_taxonomy_root_node_by_id(parent_id) - return get_taxonomy_subtree_from_root_id(dtr_type_id) + dtr_taxonomy_search_json = dtr_taxonomy_search_response.json() + type_taxonomy_id = dtr_taxonomy_search_json[0]["id"] + except IndexError as error: + raise DataTypeNotFoundException(f"Failed to resolve {data_type} taxonomy. Most probably it doesn't exist.") -def get_taxonomy_root_node_by_id(data_type_id: str) -> str: - """ - Returns an ID of the root type of the taxonomy for the given data_type_id + root_taxonomy_id = retrieve_root(type_taxonomy_id) + taxonomy_tree = retrieve_taxonomy_tree(root_taxonomy_id) + return taxonomy_tree - :param data_type_id: str, DTR MIME type PID, e.g. 21.T11969/f33c32fa8246e2ca6d5c - :return: dict, a dictionary representation of the type's taxonomy - """ - dtr_taxonomy_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{data_type_id}" - url, dtr_taxonomy_node_response, header = get(dtr_taxonomy_endpoint) - dtr_taxonomy_json = json.loads(dtr_taxonomy_node_response) - try: - dtr_type_id = dtr_taxonomy_json["id"] - except (IndexError, KeyError) as error: - raise DataTypeNotFoundException(f"DataType with id <{data_type_id}> doesn't exist in the DTR taxonomy") from error - parents = dtr_taxonomy_json["parents"] - # Assumption of single parent - taxonomy_root_id = dtr_type_id - if parents: - for parent_id, parent_name in parents.items(): - taxonomy_root_id = get_taxonomy_root_node_by_id(parent_id) - return taxonomy_root_id - - -def get_taxonomy_subtree_from_root_id(root_id: str) -> dict: - """ - Get a subtree from the root ID +def retrieve_root(taxonomy_id: str) -> Tuple[str, str]: + dtr_taxonomy_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{taxonomy_id}" + taxonomy_response = get(dtr_taxonomy_endpoint) + taxonomy_json = taxonomy_response.json() - :param root_id: str, the root node ID - :return: dict, MIME type taxonomy - """ - dtr_taxonomy_subtree_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{root_id}/subtree" - url, dtr_taxonomy_subtree_response, header = get(dtr_taxonomy_subtree_endpoint) - dtr_taxonomy_subtree_json = json.loads(dtr_taxonomy_subtree_response) - return dtr_taxonomy_subtree_json + # Recurse until no parent under "parents" key + for parent_id, parent_name in taxonomy_json["parents"].items(): + return retrieve_root(parent_id) + taxonomy_id = taxonomy_json["id"] + return taxonomy_id + + +def retrieve_taxonomy_tree(taxonomy_id: str): + dtr_taxonomy_endpoint = f"http://typeapi.lab.pidconsortium.net/v1/taxonomy/{taxonomy_id}" + dtr_taxonomy_response = get(dtr_taxonomy_endpoint) + dtr_taxonomy_json = dtr_taxonomy_response.json() + + taxonomy_name = dtr_taxonomy_json["name"] + + children = [] + for child_id, child_name in dtr_taxonomy_json["children"].items(): + children.append(retrieve_taxonomy_tree(child_id)) + return {taxonomy_name: {"id": taxonomy_id, "children": children}} """ diff --git a/dogdtr/dogdtr/forms.py b/dogdtr/dogdtr/forms.py index af54942..1d31eb6 100644 --- a/dogdtr/dogdtr/forms.py +++ b/dogdtr/dogdtr/forms.py @@ -34,9 +34,10 @@ class MIMETypeForm(forms.Form): """ Input form for inserting MIMEtype """ - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields["mimetype"].label = "" mimetype_field: MIMETypeField = MIMETypeField(required=True, widget=forms.TextInput(attrs={'required': 'True'})) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["mimetype_field"].label = "" diff --git a/dogdtr/dogdtr/templates/UI/_dtr.html b/dogdtr/dogdtr/templates/UI/_dtr.html index da825e0..066db53 100644 --- a/dogdtr/dogdtr/templates/UI/_dtr.html +++ b/dogdtr/dogdtr/templates/UI/_dtr.html @@ -1,4 +1,18 @@ {% extends 'UI/_.html' %} {% block content %} -