Skip to content

Commit

Permalink
hide relationships from package_show on search and read pages
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-iv committed Jul 18, 2024
1 parent 5eb4e01 commit 056ef39
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 60 deletions.
38 changes: 19 additions & 19 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ repos:
- id: debug-statements
stages: [push]

# ## Isort
# - repo: https://github.com/pycqa/isort
# rev: 5.12.0
# hooks:
# - id: isort
# name: isort
# stages: [pre-commit]
## Isort
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
name: isort
stages: [pre-commit]

# ## Black
# - repo: https://github.com/psf/black
# rev: 23.3.0
# hooks:
# - id: black
# stages: [pre-commit]
## Black
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
stages: [pre-commit]

# ## Ruff
# - repo: https://github.com/charliermarsh/ruff-pre-commit
# rev: v0.0.260
# hooks:
# - id: ruff
# stages: [pre-commit]
## Ruff
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.260
hooks:
- id: ruff
stages: [pre-commit]
14 changes: 14 additions & 0 deletions ckanext/relationship/config_declaration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 1
groups:
- annotation: ckanext-mbie-erms-shared
options:
- key: ckanext.relationship.views_without_relationships_in_package_show
type: list
default: search read
description: |
Adding relationships to the package show result can be time-consuming and
may decrease the performance of pages where this action is called multiple
times, such as the search page. Therefore, by default, relationships are
hidden from the package show for both the search page and the package read
page. To include relationships in the package_show action, you must add the
flag with_relationships=True to the data_dict.
16 changes: 15 additions & 1 deletion ckanext/relationship/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
from ckan import authz


def get_helpers():
helper_functions = [
relationship_get_entity_list,
relationship_get_current_relations_list,
relationship_get_selected_json,
relationship_get_choices_for_related_entity_field,
relationship_format_autocomplete,
]
return {f.__name__: f for f in helper_functions}


def relationship_get_entity_list(entity, entity_type, include_private=True):
"""Return ids list of specified entity (entity, entity_type)"""
context = {}
Expand Down Expand Up @@ -67,7 +78,10 @@ def relationship_get_current_relations_list(data, field) -> list[str]:
return current_relation_by_id + current_relation_by_name


def relationship_get_selected_json(selected_ids: list = []) -> str:
def relationship_get_selected_json(selected_ids: list | None = None) -> str:
if not selected_ids:
return json.dumps([])

selected_pkgs = []
for pkg_id in selected_ids:
try:
Expand Down
62 changes: 50 additions & 12 deletions ckanext/relationship/logic/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@
NotFound = logic.NotFound


def get_actions():
return {
"relationship_relation_create": relationship_relation_create,
"relationship_relation_delete": relationship_relation_delete,
"relationship_relations_list": relationship_relations_list,
"relationship_relations_ids_list": relationship_relations_ids_list,
"relationship_get_entity_list": relationship_get_entity_list,
"relationship_autocomplete": relationship_autocomplete,
"package_show": package_show,
}


@validate(schema.relation_create)
def relationship_relation_create(
context: Context,
Expand Down Expand Up @@ -155,7 +167,7 @@ def relationship_relations_ids_list(context: Context, data_dict: DataDict) -> li

rel_list = relationship_relations_list(context, data_dict)

return list(set([rel["object_id"] for rel in rel_list]))
return list({rel["object_id"] for rel in rel_list})


@validate(schema.get_entity_list)
Expand Down Expand Up @@ -219,10 +231,33 @@ def relationship_autocomplete(context: Context, data_dict: DataDict) -> DataDict
@tk.side_effect_free
def package_show(next_: Action, context: Context, data_dict: DataDict) -> DataDict:
result = next_(context, data_dict)
if "with_relationships" not in data_dict:
return result

pkg_id = result["id"]
pkg_type = result["type"]

views_without_relationships = tk.config[
"ckanext.relationship.views_without_relationships_in_package_show"
]

if (
tk.get_endpoint()[1] in views_without_relationships
and "with_relationships" not in data_dict
):
relations_info = utils.get_relations_info(pkg_type)
for (
related_entity,
related_entity_type,
relation_type,
) in relations_info:
field = utils.get_relation_field(
pkg_type,
related_entity,
related_entity_type,
relation_type,
)
result.pop(field["field_name"], None)
return result

relations_info = utils.get_relations_info(pkg_type)
for (
related_entity,
Expand All @@ -235,13 +270,16 @@ def package_show(next_: Action, context: Context, data_dict: DataDict) -> DataDi
related_entity_type,
relation_type,
)
result[field["field_name"]] = tk.get_action("relationship_relations_list")(
context,
{
"subject_id": pkg_id,
"object_entity": related_entity,
"object_type": related_entity_type,
"relation_type": relation_type,
},
)
result[field["field_name"]] = [
relation["object_id"]
for relation in tk.get_action("relationship_relations_list")(
context,
{
"subject_id": pkg_id,
"object_entity": related_entity,
"object_type": related_entity_type,
"relation_type": relation_type,
},
)
]
return result
12 changes: 12 additions & 0 deletions ckanext/relationship/logic/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
from ckan.plugins import toolkit as tk


def get_auth_functions():
auth_functions = [
relationship_relation_create,
relationship_relation_delete,
relationship_relations_list,
relationship_relations_ids_list,
relationship_get_entity_list,
relationship_relationship_autocomplete,
]
return {f.__name__: f for f in auth_functions}


def relationship_relation_create(context, data_dict):
return {"success": True}

Expand Down
6 changes: 6 additions & 0 deletions ckanext/relationship/logic/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
)


def get_validators():
return {
"relationship_related_entity": relationship_related_entity,
}


@scheming_validator
def relationship_related_entity(field, schema):
related_entity = field.get("related_entity")
Expand Down
1 change: 1 addition & 0 deletions ckanext/relationship/model/relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,4 @@ def _entity_name_by_id(entity_id):
)
if pkg:
return group.name
return None
51 changes: 30 additions & 21 deletions ckanext/relationship/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@

import ckanext.scheming.helpers as sch

from ckanext.relationship import utils
from ckanext.relationship import helpers, utils, views
from ckanext.relationship.logic import action, auth, validators


@tk.blanket.actions
@tk.blanket.auth_functions
@tk.blanket.validators
@tk.blanket.helpers
@tk.blanket.blueprints
class RelationshipPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IConfigurer)
plugins.implements(plugins.IActions)
plugins.implements(plugins.IAuthFunctions)
plugins.implements(plugins.IValidators)
plugins.implements(plugins.ITemplateHelpers)
plugins.implements(plugins.IBlueprint)
plugins.implements(plugins.IPackageController, inherit=True)

# IConfigurer
Expand All @@ -23,6 +24,26 @@ def update_config(self, config_):
tk.add_public_directory(config_, "public")
tk.add_resource("assets", "relationship")

# IActions
def get_actions(self):
return action.get_actions()

# IAuthFunctions
def get_auth_functions(self):
return auth.get_auth_functions()

# IValidators
def get_validators(self):
return validators.get_validators()

# ITemplateHelpers
def get_helpers(self):
return helpers.get_helpers()

# IBlueprint
def get_blueprint(self):
return views.get_blueprints()

# IPackageController
def after_dataset_create(self, context, pkg_dict):
context = context.copy()
Expand Down Expand Up @@ -93,21 +114,9 @@ def before_dataset_index(self, pkg_dict):

return pkg_dict

def after_dataset_show(self, context, pkg_dict):
pkg_type = pkg_dict["type"]
relations_info = utils.get_relations_info(pkg_type)
for (
related_entity,
related_entity_type,
relation_type,
) in relations_info:
field = utils.get_relation_field(
pkg_type,
related_entity,
related_entity_type,
relation_type,
)
pkg_dict.pop(field["field_name"], None)

if tk.check_ckan_version("2.10"):
tk.blanket.config_declarations(RelationshipPlugin)


def _update_relations(context, pkg_dict):
Expand Down
44 changes: 43 additions & 1 deletion ckanext/relationship/tests/logic/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def test_relation_delete_after_dataset_delete(self):
@pytest.mark.usefixtures("clean_db")
class TestRelationList:
@pytest.mark.parametrize(
"subject_factory, object_factory, object_entity, object_type",
("subject_factory", "object_factory", "object_entity", "object_type"),
[
(factories.Dataset, factories.Dataset, "package", "dataset"),
(factories.Dataset, factories.Organization, "organization", "organization"),
Expand Down Expand Up @@ -388,3 +388,45 @@ def test_relations_ids_list(self):

assert object1_id in result
assert object2_id in result


@pytest.mark.usefixtures("clean_db")
def test_keep_relation_after_dataset_patch():
subject_dataset = factories.Dataset(type="package_with_relationship")
object_dataset = factories.Dataset(type="package_with_relationship")

subject_id = subject_dataset["id"]
object_id = object_dataset["id"]
relation_type = "related_to"

tk.get_action("relationship_relation_create")(
{"ignore_auth": True},
{
"subject_id": subject_id,
"object_id": object_id,
"relation_type": relation_type,
},
)

tk.get_action("package_patch")(
{"ignore_auth": True},
{
"id": subject_id,
"title": "New title",
},
)

relation_straight = Relationship.by_object_id(
subject_id,
object_id,
relation_type,
)

relation_reverse = Relationship.by_object_id(
object_id,
subject_id,
relation_type,
)

assert relation_straight is not None
assert relation_reverse is not None
31 changes: 31 additions & 0 deletions ckanext/relationship/tests/package_with_relationship.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
scheming_version: 1
dataset_type: package_with_relationship
about_url: http://github.com/ckan/ckanext-relationship

dataset_fields:
- field_name: related_packages
validators: relationship_related_entity
current_entity: package
current_entity_type: package_with_relationship
related_entity: package
related_entity_type: package_with_relationship
relation_type: related_to

resource_fields:

- field_name: url
label: URL
preset: resource_url_upload

- field_name: name
label: Name
form_placeholder: eg. January 2011 Gold Prices

- field_name: description
label: Description
form_snippet: markdown.html
form_placeholder: Some useful notes about the data

- field_name: format
label: Format
preset: resource_format_autocomplete
1 change: 1 addition & 0 deletions ckanext/relationship/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ def entity_name_by_id(entity_id: str) -> str:
return entity.get("name")
except NotFound:
pass
return None
Loading

0 comments on commit 056ef39

Please sign in to comment.