Skip to content

Commit

Permalink
refactor(xmlupload): change serialisation of date value (#1277)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nora-Olivia-Ammann authored Nov 15, 2024
1 parent cd2f940 commit 2b31398
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
from collections.abc import Sequence
from dataclasses import dataclass
from typing import Any
from typing import TypeAlias
from typing import Union

from dsp_tools.utils.date_util import Date
from dsp_tools.utils.date_util import DayMonthYearEra
from dsp_tools.utils.date_util import SingleDate
from dsp_tools.utils.date_util import StartEnd

ValueTypes: TypeAlias = Union[str, Date]


@dataclass(frozen=True)
Expand All @@ -21,7 +30,7 @@ def serialise(self) -> dict[str, Any]:
class SerialiseValue(ABC):
"""A value to be serialised."""

value: str
value: ValueTypes
permissions: str | None
comment: str | None

Expand All @@ -39,6 +48,8 @@ def _get_optionals(self) -> dict[str, str]:
class SerialiseColor(SerialiseValue):
"""A ColorValue to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:ColorValue",
Expand All @@ -48,9 +59,39 @@ def serialise(self) -> dict[str, Any]:
return serialised


class SerialiseDate(SerialiseValue):
"""A DateValue to be serialised."""

value: Date

def serialise(self) -> dict[str, Any]:
serialised = {"knora-api:dateValueHasCalendar": self.value.calendar.value} if self.value.calendar else {}
serialised["@type"] = "knora-api:DateValue"
serialised.update(self._get_one_date_dict(self.value.start, StartEnd.START))
if self.value.end:
serialised.update(self._get_one_date_dict(self.value.end, StartEnd.END))
serialised.update(self._get_optionals())
return serialised

def _get_one_date_dict(self, date: SingleDate, start_end: StartEnd) -> dict[str, Any]:
def get_prop(precision: DayMonthYearEra) -> str:
return f"knora-api:dateValueHas{start_end.value}{precision.value}"

date_dict: dict[str, Any] = {get_prop(DayMonthYearEra.YEAR): date.year} if date.year else {}
if date.month:
date_dict[get_prop(DayMonthYearEra.MONTH)] = date.month
if date.day:
date_dict[get_prop(DayMonthYearEra.DAY)] = date.day
if date.era:
date_dict[get_prop(DayMonthYearEra.ERA)] = date.era.value
return date_dict


class SerialiseDecimal(SerialiseValue):
"""A DecimalValue to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:DecimalValue",
Expand All @@ -66,6 +107,8 @@ def serialise(self) -> dict[str, Any]:
class SerialiseGeometry(SerialiseValue):
"""A GeomValue to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:GeomValue",
Expand All @@ -78,6 +121,8 @@ def serialise(self) -> dict[str, Any]:
class SerialiseGeoname(SerialiseValue):
"""A GeonameValue to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:GeonameValue",
Expand All @@ -90,6 +135,8 @@ def serialise(self) -> dict[str, Any]:
class SerialiseSimpletext(SerialiseValue):
"""A Simpletext to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:TextValue",
Expand All @@ -102,6 +149,8 @@ def serialise(self) -> dict[str, Any]:
class SerialiseRichtext(SerialiseValue):
"""A Richtext to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:TextValue",
Expand All @@ -117,6 +166,8 @@ def serialise(self) -> dict[str, Any]:
class SerialiseTime(SerialiseValue):
"""A TimeValue to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:TimeValue",
Expand All @@ -132,6 +183,8 @@ def serialise(self) -> dict[str, Any]:
class SerialiseURI(SerialiseValue):
"""A UriValue to be serialised."""

value: str

def serialise(self) -> dict[str, Any]:
serialised = {
"@type": "knora-api:UriValue",
Expand Down
39 changes: 15 additions & 24 deletions src/dsp_tools/commands/xmlupload/resource_create_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from dsp_tools.commands.xmlupload.models.serialise.serialise_rdf_value import BooleanValueRDF
from dsp_tools.commands.xmlupload.models.serialise.serialise_rdf_value import IntValueRDF
from dsp_tools.commands.xmlupload.models.serialise.serialise_value import SerialiseColor
from dsp_tools.commands.xmlupload.models.serialise.serialise_value import SerialiseDate
from dsp_tools.commands.xmlupload.models.serialise.serialise_value import SerialiseDecimal
from dsp_tools.commands.xmlupload.models.serialise.serialise_value import SerialiseGeometry
from dsp_tools.commands.xmlupload.models.serialise.serialise_value import SerialiseGeoname
Expand Down Expand Up @@ -183,6 +184,12 @@ def make_values(p: XMLProperty) -> list[dict[str, Any]]:
iri_resolver=self.iri_resolver,
)
properties_serialised.update(transformed_prop.serialise())
case "date":
transformed_prop = _transform_into_date_prop(
prop=prop,
permissions_lookup=self.permissions_lookup,
)
properties_serialised.update(transformed_prop.serialise())
# serialised with rdflib
case "integer":
int_prop_name = self._get_absolute_prop_iri(prop.name, namespaces)
Expand Down Expand Up @@ -213,8 +220,6 @@ def _get_absolute_prop_iri(self, prefixed_prop: str, namespaces: dict[str, Names

def _make_value(self, value: XMLValue, value_type: str) -> dict[str, Any]:
match value_type:
case "date":
res = _make_date_value(value)
case "interval":
res = _make_interval_value(value)
case "resptr":
Expand Down Expand Up @@ -285,30 +290,16 @@ def _to_boolean(s: str | int | bool) -> bool:
raise BaseError(f"Could not parse boolean value: {s}")


def _make_date_value(value: XMLValue) -> dict[str, Any]:
def _transform_into_date_prop(prop: XMLProperty, permissions_lookup: dict[str, Permissions]) -> SerialiseProperty:
vals = [_transform_into_date_value(v, permissions_lookup) for v in prop.values]
return SerialiseProperty(property_name=prop.name, values=vals)


def _transform_into_date_value(value: XMLValue, permissions_lookup: dict[str, Permissions]) -> SerialiseDate:
string_value = _assert_is_string(value.value)
date = parse_date_string(string_value)
res: dict[str, Any] = {
"@type": "knora-api:DateValue",
"knora-api:dateValueHasStartYear": date.start.year,
}
if month := date.start.month:
res["knora-api:dateValueHasStartMonth"] = month
if day := date.start.day:
res["knora-api:dateValueHasStartDay"] = day
if era := date.start.era:
res["knora-api:dateValueHasStartEra"] = era.value
if calendar := date.calendar:
res["knora-api:dateValueHasCalendar"] = calendar.value
if date.end:
res["knora-api:dateValueHasEndYear"] = date.end.year
if month := date.end.month:
res["knora-api:dateValueHasEndMonth"] = month
if day := date.end.day:
res["knora-api:dateValueHasEndDay"] = day
if era := date.end.era:
res["knora-api:dateValueHasEndEra"] = era.value
return res
permission_str = _get_permission_str(value.permissions, permissions_lookup)
return SerialiseDate(value=date, permissions=permission_str, comment=value.comment)


def _transform_into_decimal_prop(prop: XMLProperty, permissions_lookup: dict[str, Permissions]) -> SerialiseProperty:
Expand Down
12 changes: 12 additions & 0 deletions src/dsp_tools/utils/date_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ def from_string(s: str) -> Era:
raise BaseError(f"Invalid era type: {s}")


class DayMonthYearEra(Enum):
DAY = "Day"
MONTH = "Month"
YEAR = "Year"
ERA = "Era"


class StartEnd(Enum):
START = "Start"
END = "End"


@dataclass(frozen=True)
class SingleDate:
"""Information about a single date."""
Expand Down

0 comments on commit 2b31398

Please sign in to comment.