Files
2026-05-21 08:21:49 +00:00

92 lines
4.6 KiB
ReStructuredText

Development
-----------
Because the parser may break on changes to the canteen website, it should be easy to fix. Refer to the following sections to jumpstart development.
Quickstart
~~~~~~~~~~
Use `uv <https://docs.astral.sh/uv/>`_ to setup the environment and start coding: ::
$ uv sync --extra dev # Create venv and install dependencies
$ make test # Check setup by running tests
$ make debug # Start app instance with debugger and pretty printing of JSON
$ make run # Start app without debugger
$ make lint # Enforce style guide / check for logic bugs
$ cd docs && make livehtml # View live-updating docs in the browser
The list of available canteens is available at the ``/canteens`` endpoint. The ``/canteens/<name>`` endpoint provides the XML feed for individual canteens, e.g., ``/canteens/griebnitzsee``.
Given the default configuration, http://127.0.0.1:5000/canteens/griebnitzsee will display the `OpenMensa` feed for the Griebnitzsee canteen.
Main Module Entry Points
~~~~~~~~~~~~~~~~~~~~~~~~
In the following the main workflow of this parser is explained.
Generating a new `OpenMensa` feed starts by reading the configured canteens. Some canteen data, such as ID, name, and location, are currently not scraped. Doing so would be very brittle and involve a multistep process. Refer to the :ref:`cache_hash` for deeper insight into the obstacles.
.. autofunction:: openmensa_parsers.config.read_canteen_config
.. autoclass:: openmensa_parsers.config.Canteen
Use the canteen data to select matching upstream outlets, download the required menu JSON, and render the OpenMensa XML.
Parser Providers
~~~~~~~~~~~~~~~~
The application is structured around parser providers. A provider owns the
source-specific work: fetching raw upstream data and converting it into the
shared OpenMensa XML structures. The ``Builder`` only asks a provider for
canteens, attaches feed metadata, and renders XML.
New cities or data sources should add a parser under ``openmensa_parsers.parsers``.
The parser should implement three methods:
``fetch()``
Download or load the raw source data.
``parse(config, raw_data)``
Convert raw data into a ``dict[str, CanteenXML]`` keyed by the configured
canteen key.
``create_feed(canteen, url)``
Return the feed metadata for one canteen. In most cases, subclass
``BaseOpenMensaParser`` and configure ``feed`` instead of overriding this
method.
Register the parser in ``openmensa_parsers.parsers.registry``. At runtime, select a
parser with ``OM_PARSER_ID``. The default is ``potsdam``.
Parser tests should keep network access separate from parsing. Store raw
fixtures in the test suite, pass them directly into ``parse()``, and reserve
live source checks for opt-in tests.
.. autoclass:: openmensa_parsers.webspeiseplan_api.WebspeiseplanAPI
.. autoclass:: openmensa_parsers.webspeiseplan_parser.WebspeiseplanParser
.. autoclass:: openmensa_parsers.parsers.base.BaseOpenMensaParser
.. autoclass:: openmensa_parsers.parsers.potsdam.PotsdamParser
The XML type modules contain the OpenMensa rendering objects:
.. autoclass:: openmensa_parsers.xml_types.builder.Builder
Tests
~~~~~
Unit tests are not a really good fit to the problem at hand. The parser is basically a converter, transforming loosely defined JSON input to well-specified XML output. The conversion is not very sophisticated, and the parser's correctness mainly depends on the stability of the JSON output of the canteen website. Two main questions are remaining.
First, if the parser logic has changed, has the change been intentionally, and is it meaningful? The `consistency` integration test covers that, it compares the results of one examplary API response to a canned XML feed.
Second, if the canteen API changed, or there is some variance in the response which has not been apparent at development time, which canteens are affected? The `retrieval` acceptance test iterates over all configured canteens, and tries to download and interpret the current API responses. No exception indicates a successful run.
Test execution works as follows: ::
make test # (1)
ENABLE_API_QUERY=1 make test # (2)
The first invocation runs tests whose outcome can solely be determined by the test suite, which makes them suitable for frequent execution and CI systems.
Setting the environment variable ``ENABLE_API_QUERY`` enables tests which require querying the canteen API. Because third-party services are queried, those are more suited to manual execution. Developers can quickly check if their change is applicable to today's menu.