Files
OpenMensa-Parsers/openmensa_parsers/parsers/base.py
T
2026-05-21 08:21:49 +00:00

62 lines
1.8 KiB
Python

"""Shared parser contract for city-specific OpenMensa parsers."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Protocol
from openmensa_parsers.config import Canteen
from openmensa_parsers.xml_types.canteen_xml import CanteenXML
from openmensa_parsers.xml_types.feed_xml import FeedXML, ScheduleXML
@dataclass(frozen=True)
class FeedDefinition:
"""Default feed metadata used when publishing a parser result."""
source: str
name: str = "full"
priority: int = 0
schedule: dict[str, Any] = field(
default_factory=lambda: {"hour": "8-14", "retry": "30 1"}
)
class OpenMensaParser(Protocol):
"""Contract implemented by each city/source parser."""
id: str
feed: FeedDefinition
def fetch(self) -> Any:
"""Download or load source-specific raw data."""
def parse(
self,
config: dict[str, Canteen],
raw_data: Any,
) -> dict[str, CanteenXML]:
"""Convert raw source data into OpenMensa canteen structures."""
def create_feed(self, canteen: Canteen, url: str) -> FeedXML:
"""Build the OpenMensa feed metadata for one configured canteen."""
class BaseOpenMensaParser: # pylint: disable=too-few-public-methods
"""Base helper for parsers that use the standard OpenMensa feed block."""
id = "base"
feed: FeedDefinition
def create_feed(self, _canteen: Canteen, url: str) -> FeedXML:
"""Create a standard feed tag for a configured canteen."""
schedule_data = dict(self.feed.schedule)
schedule = ScheduleXML(**schedule_data)
return FeedXML(
name=self.feed.name,
priority=self.feed.priority,
source=self.feed.source,
url=url,
schedule=schedule,
)