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
from datetime import datetime, date
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
@@ -38,23 +38,21 @@ class SWPWebspeiseplanParser:
)
canteen_meta = CanteenMeta(**meta)
weekday_dict = {
"monday": f"{outlet['moZeit1']}, {outlet['moZeit2']}",
"tuesday": f"{outlet['diZeit1']}, {outlet['diZeit2']}",
"wednesday": f"{outlet['miZeit1']}, {outlet['miZeit2']}",
"thursday": f"{outlet['doZeit1']}, {outlet['doZeit2']}",
"friday": f"{outlet['frZeit1']}, {outlet['frZeit2']}",
"saturday": f"{outlet['saZeit1']}, {outlet['saZeit2']}",
"sunday": f"{outlet['soZeit1']}, {outlet['soZeit2']}",
# this approach only lists the first (valid) opening time,
# since OpenMensa does not support multiple time specs
# (yet).
"monday": outlet['moZeit1'] or outlet['moZeit2'],
"tuesday": outlet['diZeit1'] or outlet['diZeit2'],
"wednesday": outlet['miZeit1'] or outlet['miZeit2'],
"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 = {
k: v.replace("None, None", "")
.replace("None,", "")
.replace(", None", "")
for k, v in weekday_dict.items()
}
canteen_times = TimesXML(weekday_dict)
canteen_times = TimesXML({
k: CanteenOpenTimespec(v) for k, v in weekday_dict.items()
})
canteen = CanteenXML(canteen_meta, canteen_times)
return canteen
+61 -26
View File
@@ -1,11 +1,60 @@
import re
from dataclasses import dataclass
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
class TimesXML:
"""Represents the times tag in openMensaFeedv2."""
VALID_DAYS = (
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
)
monday: str
tuesday: str
wednesday: str
@@ -14,29 +63,24 @@ class TimesXML:
saturday: str
sunday: str
def __init__(self, weekday_dict: dict[str, str] = None):
def __init__(self, weekday_dict: dict[str, CanteenOpenTimespec] = None):
"""Init TimesXML object.
Args:
weekday_dict (dict[str, str]): _description_
"""
for key in weekday_dict:
if key in (
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
):
if key in self.VALID_DAYS:
setattr(self, key, weekday_dict[key])
else:
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)
if value == "geschlossen":
if value in CanteenOpenTimespec.CLOSED_VALID_VALUES:
elem.setAttribute("closed", "true")
else:
elem.setAttribute("open", value)
@@ -53,18 +97,9 @@ class TimesXML:
"""
times = doc.createElement("times")
times.setAttribute("type", "opening")
monday = self.__create_node(doc, "monday", self.monday)
times.appendChild(monday)
tuesday = self.__create_node(doc, "tuesday", self.tuesday)
times.appendChild(tuesday)
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)
for day in self.VALID_DAYS:
day_node = self.__create_node(doc, day, getattr(self, day))
times.appendChild(day_node)
return times