Skip to content

Commit

Permalink
Merge pull request #38 from NatLibFi/feature/simplye-263/default-library
Browse files Browse the repository at this point in the history
Improve consortium management
  • Loading branch information
attemoi authored Apr 8, 2024
2 parents 78d75de + 3d021b4 commit 700bfa8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 17 deletions.
7 changes: 7 additions & 0 deletions api/admin/controller/library_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from api.admin.problem_details import *
from api.circulation_manager import CirculationManager
from api.config import Configuration
from api.ekirjasto_consortium import EkirjastoConsortiumMonitor
from api.lanes import create_default_lanes
from core.configuration.library import LibrarySettings
from core.model import (
Expand All @@ -31,6 +32,7 @@
from core.model.announcements import SETTING_NAME as ANNOUNCEMENT_SETTING_NAME
from core.model.announcements import Announcement
from core.model.library import LibraryLogo
from core.scripts import RunMonitorScript
from core.util.problem_detail import ProblemDetail, ProblemError


Expand Down Expand Up @@ -159,6 +161,11 @@ def process_post(self) -> Response:
# Trigger a site configuration change
site_configuration_has_changed(self._db)

# Finland, update municipality list if consortium is defined
consortium = library.settings.kirkanta_consortium_slug
if consortium and consortium != "disabled":
RunMonitorScript(EkirjastoConsortiumMonitor, library=library).run()

if is_new:
# Now that the configuration settings are in place, create
# a default set of lanes.
Expand Down
26 changes: 16 additions & 10 deletions api/ekirjasto_consortium.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from core.metadata_layer import TimestampData
from core.model.library import Library
from core.monitor import Monitor
from core.util.cache import memoize


class KirkantaConsortium(BaseModel):
Expand Down Expand Up @@ -95,7 +96,11 @@ class EkirjastoConsortiumMonitor(Monitor):
_KIRKANTA_JUNK_CITIES: list[str] = ["Äävekaupunki"]

# Manually managed list of Kirkanta city names don't match with Koodistopalvelu
KIRKANTA_CITY_NAME_ALIASES: dict[str, str] = {"Pedersöre": "Pedersören kunta"}
_KIRKANTA_CITY_NAME_ALIASES: dict[str, str] = {"Pedersöre": "Pedersören kunta"}

def __init__(self, _db, collection=None, library: Library | None = None):
super().__init__(_db, collection)
self.library = library

def run_once(self, progress):
kirkanta_consortiums = self._fetch_kirkanta_consortiums()
Expand All @@ -114,8 +119,7 @@ def run_once(self, progress):
f"will be assigned to the default library."
)

libraries = self._db.query(Library).all()

libraries = [self.library] if self.library else self._db.query(Library).all()
for library in libraries:
self._synchronize_library(
library, kirkanta_consortiums, kirkanta_cities, koodisto_concept_codes
Expand All @@ -127,26 +131,26 @@ def run_once(self, progress):
f"The following Kirkanta city names were "
f"not found in Koodistopalvelu: {missing_cities}. "
f"Please add the missing city names manually to "
f"KIRKANTA_CITY_NAME_ALIASES."
f"_KIRKANTA_CITY_NAME_ALIASES."
)
return TimestampData(
achievements=f"Kirkanta synchronization done!",
)

def _fetch_kirkanta_cities(self) -> list[KirkantaCity]:
return self._get(
return EkirjastoConsortiumMonitor._get(
KirkantaCities, f"{self._KIRKANTA_API_URL}/city", {"limit": 9999}
).items

def _fetch_kirkanta_consortiums(self) -> list[KirkantaConsortium]:
return self._get(
return EkirjastoConsortiumMonitor._get(
KirkantaConsortiums,
f"{self._KIRKANTA_API_URL}/consortium",
{"status": "ACTIVE", "limit": 9999},
).items

def _fetch_koodisto_concept_codes(self, page: int = 1) -> list[KoodistoConceptCode]:
response: KoodistoConceptCodes = self._get(
response: KoodistoConceptCodes = EkirjastoConsortiumMonitor._get(
KoodistoConceptCodes,
f"{self._KOODISTO_API_URL}/classifications/{self._KOODISTO_CLASSIFICATION_ID}/conceptcodes",
{"pageSize": self._KOODISTO_MAX_ALLOWED_PAGESIZE, "page": page},
Expand Down Expand Up @@ -252,7 +256,7 @@ def _verify_all_kirkanta_cities_found_in_koodisto(
if missing_names:
logging.warning(
"The following Kirkanta city names are not found in Koodistopalvelu: %s. "
"Please add the missing city name manually to KIRKANTA_CITY_NAME_ALIASES.",
"Please add the missing city name manually to _KIRKANTA_CITY_NAME_ALIASES.",
str(missing_names),
)
return missing_names
Expand All @@ -270,7 +274,7 @@ def _to_koodisto_code(
if koodisto_city_name == kirkanta_city.name:
return code

alias: str | None = self.KIRKANTA_CITY_NAME_ALIASES.get(
alias: str | None = self._KIRKANTA_CITY_NAME_ALIASES.get(
kirkanta_city.name,
)
if alias and koodisto_city_name == alias:
Expand All @@ -280,7 +284,9 @@ def _to_koodisto_code(

R = TypeVar("R", bound=BaseModel)

def _get(self, response_type: type[R], url: str, params=None) -> R:
@memoize(ttls=3600)
@staticmethod
def _get(response_type: type[R], url: str, params=None) -> R:
"""Perform HTTP GET request and parse the response into a pydantic model of type R"""
try:
response = requests.get(url, params)
Expand Down
27 changes: 20 additions & 7 deletions core/configuration/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ class LibrarySettings(BaseSettings):
kirkanta_consortium_slug: str | None = FormField(
None,
form=LibraryConfFormItem(
label="Synchronize consortium data form Kirkanta",
description="If selected, the list of municipalities is updated automatically from Kirkanta. "
"Has no effect if configured for the default library.",
label="Consortium",
description="If selected, the municipalities are kept automatically "
"in sync with Kirkanta. Has no effect if set for the default library.",
category="Kirkanta Synchronization",
type=ConfigurationFormItemType.SELECT,
# The keys here should match the Kirkanta consortium slug
Expand Down Expand Up @@ -193,10 +193,9 @@ class LibrarySettings(BaseSettings):
form=LibraryConfFormItem(
label="The municipalities belonging to this consortium",
type=ConfigurationFormItemType.LIST,
format="municipality-code",
description="Each value should be a valid "
'<a href="https://koodistopalvelu.kanta.fi/codeserver/pages/classification-view-page.xhtml?classificationKey=362&versionKey=440" target="_blank">'
"municipality code</a>.",
"municipality code</a>. This list is populated automatically if the consortium is selected.",
category="Kirkanta Synchronization",
level=Level.ALL_ACCESS,
),
Expand Down Expand Up @@ -736,8 +735,22 @@ def validate_municipalities(
cls, value: list[str] | None, field: ModelField
) -> list[str] | None:
"""Verify that municipality IDs are valid."""
# TODO: implement validation
return value
if not value:
return value

for code in value:
if not code.isdigit():
raise SettingsValidationError(
problem_detail=UNKNOWN_LANGUAGE.detailed(
f'"{cls.get_form_field_label(field.name)}": "{code}" is not a valid language code.'
)
)

return cls._remove_duplicates(value)

@classmethod
def _remove_duplicates(cls, values: list[str]):
return list(set(values))

@validator(
"large_collection_languages",
Expand Down

0 comments on commit 700bfa8

Please sign in to comment.