fix: opening timespec non-compliant to OpenMensa XML schema

This commit is contained in:
Kai Fabian
2024-01-03 21:14:06 +01:00
committed by f4lco
parent 1bee1c3242
commit 6e9e0732e9
2 changed files with 75 additions and 42 deletions
+14 -16
View File
@@ -1,7 +1,7 @@
import logging import logging
from datetime import datetime, date from datetime import datetime, date
from stw_potsdam.xml_types.canteen_xml import CanteenMeta, CanteenXML from stw_potsdam.xml_types.canteen_xml import CanteenMeta, CanteenXML
from stw_potsdam.xml_types.times_xml import TimesXML from stw_potsdam.xml_types.times_xml import CanteenOpenTimespec, TimesXML
from stw_potsdam.xml_types.meal_xml import MealXML from stw_potsdam.xml_types.meal_xml import MealXML
@@ -38,23 +38,21 @@ class SWPWebspeiseplanParser:
) )
canteen_meta = CanteenMeta(**meta) canteen_meta = CanteenMeta(**meta)
weekday_dict = { weekday_dict = {
"monday": f"{outlet['moZeit1']}, {outlet['moZeit2']}", # this approach only lists the first (valid) opening time,
"tuesday": f"{outlet['diZeit1']}, {outlet['diZeit2']}", # since OpenMensa does not support multiple time specs
"wednesday": f"{outlet['miZeit1']}, {outlet['miZeit2']}", # (yet).
"thursday": f"{outlet['doZeit1']}, {outlet['doZeit2']}", "monday": outlet['moZeit1'] or outlet['moZeit2'],
"friday": f"{outlet['frZeit1']}, {outlet['frZeit2']}", "tuesday": outlet['diZeit1'] or outlet['diZeit2'],
"saturday": f"{outlet['saZeit1']}, {outlet['saZeit2']}", "wednesday": outlet['miZeit1'] or outlet['miZeit2'],
"sunday": f"{outlet['soZeit1']}, {outlet['soZeit2']}", "thursday": outlet['doZeit1'] or outlet['doZeit2'],
"friday": outlet['frZeit1'] or outlet['frZeit2'],
"saturday": outlet['saZeit1'] or outlet['saZeit2'],
"sunday": outlet['soZeit1'] or outlet['soZeit2'],
} }
weekday_dict = { canteen_times = TimesXML({
k: v.replace("None, None", "") k: CanteenOpenTimespec(v) for k, v in weekday_dict.items()
.replace("None,", "") })
.replace(", None", "")
for k, v in weekday_dict.items()
}
canteen_times = TimesXML(weekday_dict)
canteen = CanteenXML(canteen_meta, canteen_times) canteen = CanteenXML(canteen_meta, canteen_times)
return canteen return canteen
+61 -26
View File
@@ -1,11 +1,60 @@
import re
from dataclasses import dataclass from dataclasses import dataclass
from xml.dom import minidom from xml.dom import minidom
class CanteenOpenTimespec(str):
"""Represents valid daily opening times in openMensaFeedv2."""
CLOSED = "geschlossen"
CLOSED_VALID_VALUES = {
CLOSED,
None,
False,
"",
}
PATTERN = (r'.*(?P<hour1>\d{1,2}):(?P<min1>\d{1,2})\s*'
r'-\s*(?P<hour2>\d{1,2}):(?P<min2>\d{1,2}).*')
MATCHER = re.compile(PATTERN)
def __new__(cls, spec):
"""Create CanteenOpenTimespec object.
Args:
spec (str | bool | None): time specification
"""
if spec in cls.CLOSED_VALID_VALUES:
return super().__new__(cls, cls.CLOSED)
match = cls.MATCHER.match(str(spec))
if not match:
raise ValueError(f'Invalid time specification: {spec!r} does'
f' not conform to regex {cls.PATTERN!r}')
# parse to int for format zerofill
int_spec = {k: int(v) for k, v in match.groupdict().items()}
clean_spec = (
f'{int_spec["hour1"]:02}:{int_spec["min1"]:02}-'
f'{int_spec["hour2"]:02}:{int_spec["min2"]:02}'
)
return super().__new__(cls, clean_spec)
@dataclass @dataclass
class TimesXML: class TimesXML:
"""Represents the times tag in openMensaFeedv2.""" """Represents the times tag in openMensaFeedv2."""
VALID_DAYS = (
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
)
monday: str monday: str
tuesday: str tuesday: str
wednesday: str wednesday: str
@@ -14,29 +63,24 @@ class TimesXML:
saturday: str saturday: str
sunday: str sunday: str
def __init__(self, weekday_dict: dict[str, str] = None): def __init__(self, weekday_dict: dict[str, CanteenOpenTimespec] = None):
"""Init TimesXML object. """Init TimesXML object.
Args: Args:
weekday_dict (dict[str, str]): _description_ weekday_dict (dict[str, str]): _description_
""" """
for key in weekday_dict: for key in weekday_dict:
if key in ( if key in self.VALID_DAYS:
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
):
setattr(self, key, weekday_dict[key]) setattr(self, key, weekday_dict[key])
else: else:
raise KeyError() raise KeyError()
def __create_node(self, doc: minidom.Document, tag: str, value: str): def __create_node(self,
doc: minidom.Document,
tag: str,
value: CanteenOpenTimespec):
elem = doc.createElement(tag) elem = doc.createElement(tag)
if value == "geschlossen": if value in CanteenOpenTimespec.CLOSED_VALID_VALUES:
elem.setAttribute("closed", "true") elem.setAttribute("closed", "true")
else: else:
elem.setAttribute("open", value) elem.setAttribute("open", value)
@@ -53,18 +97,9 @@ class TimesXML:
""" """
times = doc.createElement("times") times = doc.createElement("times")
times.setAttribute("type", "opening") times.setAttribute("type", "opening")
monday = self.__create_node(doc, "monday", self.monday)
times.appendChild(monday) for day in self.VALID_DAYS:
tuesday = self.__create_node(doc, "tuesday", self.tuesday) day_node = self.__create_node(doc, day, getattr(self, day))
times.appendChild(tuesday) times.appendChild(day_node)
wednesday = self.__create_node(doc, "wednesday", self.wednesday)
times.appendChild(wednesday)
thursday = self.__create_node(doc, "thursday", self.thursday)
times.appendChild(thursday)
friday = self.__create_node(doc, "friday", self.friday)
times.appendChild(friday)
saturday = self.__create_node(doc, "saturday", self.saturday)
times.appendChild(saturday)
sunday = self.__create_node(doc, "sunday", self.sunday)
times.appendChild(sunday)
return times return times