Skip to content

Commit

Permalink
Merge pull request #45 from GenomicDataInfrastructure/refactor-with-u…
Browse files Browse the repository at this point in the history
…rl-labels

chore: `enhanced_package_show` and `enhanced_package_show`  endpoints
  • Loading branch information
hcvdwerf authored Apr 16, 2024
2 parents 7261973 + 075f73a commit 77e5fd7
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 49 deletions.
33 changes: 15 additions & 18 deletions ckanext/gdi_userportal/logic/action/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

from ckan.plugins import toolkit
from ckanext.gdi_userportal.logic.action.translation_utils import (
nested_replace,
collect_values_to_translate,
get_translations,
)
from ckanext.gdi_userportal.logic.action.translation_utils import replace_package, replace_search_facets
from typing import Dict

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -134,22 +134,19 @@ def scheming_package_show(context, data_dict):


@toolkit.side_effect_free
def get_with_url_labels(context, data_dict) -> Dict:
"""
A wrapper for an action function: calls the function and replaces all starting with http string values with
value-label object
"action_name" should be a valid name of an action function returning a dictionary
"""
try:
action_name = data_dict["action_name"]
except KeyError:
raise KeyError(f"'action_name' parameter should be provided")
del data_dict["action_name"]
result = toolkit.get_action(action_name)(context, data_dict)
values_to_translate = []
for key, value in result.items():
collect_values_to_translate(value, values_to_translate)
values_to_translate = list(set(values_to_translate))
def enhanced_package_search(context, data_dict) -> Dict:
result = toolkit.get_action("package_search")(context, data_dict)
values_to_translate = collect_values_to_translate(result)
translations = get_translations(values_to_translate)
result = nested_replace(result, translations)
result["results"] = [replace_package(package, translations) for package in result["results"]]
if "search_facets" in result.keys():
result["search_facets"] = replace_search_facets(result["search_facets"], translations)
return result


@toolkit.side_effect_free
def enhanced_package_show(context, data_dict) -> Dict:
result = toolkit.get_action("package_show")(context, data_dict)
values_to_translate = collect_values_to_translate(result)
translations = get_translations(values_to_translate)
return replace_package(result, translations)
95 changes: 66 additions & 29 deletions ckanext/gdi_userportal/logic/action/translation_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@
from ckan.plugins import toolkit
from typing import Any, List, Dict
from ckan.common import request, config
from dataclasses import dataclass


PACKAGE_REPLACE_FIELDS = ["access_rights", "conforms_to", "has_version", "language", "spatial", "theme"]
RESOURCE_REPLACE_FIELDS = ["format"]


@dataclass
class ValueLabel:
name: str
display_name: str
count: int = None


def get_translations(values_to_translate: List) -> Dict[str, str]:
Expand Down Expand Up @@ -37,32 +49,57 @@ def _get_language() -> str:
return language


def nested_replace(data: Any, replace_dict: Dict) -> Any:
"""
Walks over a json tree, replaces string values starting with 'http' with value-label objects
where 'value' is an original field value and `label` a replacement found in replacement_dict or None
"""
if isinstance(data, list):
return [nested_replace(item, replace_dict) for item in data]

if isinstance(data, dict):
return {key: nested_replace(value, replace_dict)
for key, value in data.items()}

if isinstance(data, str) and data.startswith("http"):
return {"value": data, "label": replace_dict.get(data, None)}
else:
return data


def collect_values_to_translate(data: Any, values_to_translate: List) -> List:
"""Walks over a json tree and returns a list of string values starting with 'http'"""
if isinstance(data, str) and data.startswith("http"):
values_to_translate.append(data)
elif isinstance(data, list):
for item in data:
collect_values_to_translate(item, values_to_translate)
elif isinstance(data, dict):
for key, value in data.items():
collect_values_to_translate(value, values_to_translate)
return values_to_translate
def _select_and_append_values(data_item: Dict, fields_list: List, target_list: List) -> List:
for key, value in data_item.items():
if key in fields_list:
if isinstance(value, list):
target_list.extend(value)
else:
target_list.append(value)
return target_list


def collect_values_to_translate(data: Any) -> List:
values_to_translate = []
if not isinstance(data, List):
data = [data]
for package in data:
values_to_translate = _select_and_append_values(package, PACKAGE_REPLACE_FIELDS, values_to_translate)
resources = package.get("resources", [])
for resource in resources:
values_to_translate = _select_and_append_values(resource, RESOURCE_REPLACE_FIELDS, values_to_translate)
return list(set(values_to_translate))


def replace_package(data, translation_dict):
data = _translate_fields(data, PACKAGE_REPLACE_FIELDS, translation_dict)
resources = data.get("resources", [])
data["resources"] = [_translate_fields(item, RESOURCE_REPLACE_FIELDS, translation_dict) for item in resources]
return data


def _translate_fields(data, fields_list, translation_dict):
for field in fields_list:
value = data.get(field)
if value:
if isinstance(value, List):
new_value = [ValueLabel(name=x, display_name=translation_dict.get(x, x)).__dict__ for x in value]
else:
new_value = ValueLabel(name=value, display_name=translation_dict.get(value, value)).__dict__
data[field] = new_value
return data


def _change_facet(facet, translation_dict):
name = facet["name"]
facet["display_name"] = translation_dict.get(name, name)
return facet


def replace_search_facets(data, translation_dict):
new_facets = {}
for key, facet in data.items():
title = facet["title"]
new_facets[key] = {"title": translation_dict.get(title, title)}
new_facets[key]["items"] = [_change_facet(item, translation_dict) for item in facet["items"]]
return data
6 changes: 4 additions & 2 deletions ckanext/gdi_userportal/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import ckan.plugins.toolkit as toolkit
from ckanext.gdi_userportal.logic.action.get import (
scheming_package_show,
get_with_url_labels,
enhanced_package_search,
enhanced_package_show,
)
from ckanext.gdi_userportal.logic.auth.get import config_option_show
import json
Expand Down Expand Up @@ -73,7 +74,8 @@ def get_auth_functions(self):
def get_actions(self):
return {
"scheming_package_show": scheming_package_show,
"with_url_labels": get_with_url_labels,
"enhanced_package_search": enhanced_package_search,
"enhanced_package_show": enhanced_package_show,
}

def read(self, entity):
Expand Down

0 comments on commit 77e5fd7

Please sign in to comment.