Skip to content

Commit

Permalink
GeoNode#10995 Faceting: thesauri
Browse files Browse the repository at this point in the history
  • Loading branch information
etj committed May 2, 2023
1 parent 50b69bb commit 5723dce
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
10 changes: 10 additions & 0 deletions geonode/facets/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ def ready(self):

urlpatterns += urls.urlpatterns

init_thesaurus_providers()


def init_thesaurus_providers():
# should be called at startup and whenever records in Thesaurus or ThesaurusLabel change
from geonode.facets.providers.thesaurus import create_thesaurus_providers

for provider in create_thesaurus_providers():
register_facet_provider(provider)


def register_facet_provider(provider: FacetProvider):
logging.info(f"Registering {provider}")
Expand Down
95 changes: 95 additions & 0 deletions geonode/facets/providers/thesaurus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import logging

from django.db.models import Count

from geonode.base.models import Thesaurus, ResourceBase
from geonode.facets.models import FacetProvider, DEFAULT_FACET_TOPICS_LIMIT

logger = logging.getLogger(__name__)


class ThesaurusFacetProvider(FacetProvider):
"""
Implements faceting for a given Thesaurus
"""

def __init__(self, identifier, title, order, labels: dict):
self._name = identifier
self.label = title
self.order = order
self.labels = labels

@property
def name(self) -> str:
return self._name

def get_info(self, lang="en") -> dict:
return {
"name": self._name,
"key": "tkeyword",
"label": self.labels.get(lang, self.label),
"type": "thesaurus",
"hierarchical": False,
"order": self.order,
}

def get_facet_items(self, queryset=None, lang="en", page: int = 0, limit: int = DEFAULT_FACET_TOPICS_LIMIT) -> dict:
logging.debug("Retrieving facets for %s", self._name)

if not queryset:
queryset = ResourceBase.objects

q = (
queryset.filter(tkeywords__thesaurus__identifier=self._name, tkeywords__keyword__lang=lang)
.values("tkeywords", "tkeywords__keyword__label")
.annotate(count=Count("tkeywords"))
.order_by("-count")
)

cnt = q.count()
start = page * limit
end = start + limit

ret = {
"total": cnt,
"start": start,
"page": page,
"limit": limit,
}

logging.debug("Found %d facets for %s", cnt, self._name)
logging.debug(" ---> %s\n\n", q.query)
logging.debug(" ---> %r\n\n", q.all())

topics = [
{"key": r["tkeywords"], "label": r["tkeywords__keyword__label"], "count": r["count"]}
for r in q[start:end].all()
]

ret["items"] = topics

return ret


def create_thesaurus_providers() -> list:
# this query return the list of thesaurus X the list of localized titles
q = (
Thesaurus.objects.filter(facet=True)
.values("identifier", "title", "order", "rel_thesaurus__label", "rel_thesaurus__lang")
.order_by("order")
)

# coalesce the localized labels
ret = {}
for r in q.all():
identifier = r["identifier"]
t = ret.get(identifier, None)
if not t:
t = {k: r[k] for k in ("identifier", "title", "order")}
t["labels"] = {}
if r["rel_thesaurus__lang"] and r["rel_thesaurus__label"]:
t["labels"][r["rel_thesaurus__lang"]] = r["rel_thesaurus__label"]
ret[identifier] = t

logging.info("Creating providers for %r", ret)
return [ThesaurusFacetProvider(t["identifier"], t["title"], t["order"], t["labels"]) for t in ret.values()]

0 comments on commit 5723dce

Please sign in to comment.