diff --git a/stw_potsdam/canteen.py b/stw_potsdam/canteen.py index bd835ce..e630ac5 100644 --- a/stw_potsdam/canteen.py +++ b/stw_potsdam/canteen.py @@ -2,4 +2,4 @@ from collections import namedtuple -Canteen = namedtuple('Canteen', ('name', 'street', 'city', 'id', 'chash')) +Canteen = namedtuple('Canteen', ('key', 'name', 'street', 'city', 'id', 'chash')) diff --git a/stw_potsdam/config.py b/stw_potsdam/config.py index 9734469..192b12e 100644 --- a/stw_potsdam/config.py +++ b/stw_potsdam/config.py @@ -17,7 +17,8 @@ def _get_config(filename): def _parse_canteen(config, canteen_name): get = partial(config.get, canteen_name) - return Canteen(name=get('name'), + return Canteen(key=canteen_name, + name=get('name'), street=get('street'), city=get('city'), id=get('id'), diff --git a/stw_potsdam/feed.py b/stw_potsdam/feed.py index 38b4666..281dacc 100644 --- a/stw_potsdam/feed.py +++ b/stw_potsdam/feed.py @@ -2,6 +2,7 @@ from pyopenmensa.feed import LazyBuilder + PRICE_ROLE_MAPPING = { 'student': 'preis_s', 'other': 'preis_g', @@ -48,18 +49,22 @@ def _process_day(builder, day): roles=None) -def _create_builder(canteen): +def render_menu(menu): + builder = LazyBuilder() + + for day in _active_days(menu): + _process_day(builder, day) + + return builder.toXMLFeed() + + +def render_meta(canteen, menu_feed_url): builder = LazyBuilder() + builder.name = canteen.name builder.address = canteen.street builder.city = canteen.city - return builder - -def render(canteen, menu): - builder = _create_builder(canteen) - - for day in _active_days(menu): - _process_day(builder, day) + builder.define(name="full", priority="0", url=menu_feed_url, source=None, dayOfWeek="*", dayOfMonth="*", hour="8-18", minute="0", retry="30 1") return builder.toXMLFeed() diff --git a/stw_potsdam/views.py b/stw_potsdam/views.py index 7aaa87f..8f53e32 100644 --- a/stw_potsdam/views.py +++ b/stw_potsdam/views.py @@ -1,6 +1,9 @@ # -*- encoding: utf-8 -*- -from flask import Flask, make_response +import os +import urlparse + +from flask import Flask, jsonify, make_response, url_for from werkzeug.contrib.cache import SimpleCache import feed @@ -10,6 +13,16 @@ CACHE_TIMEOUT = 45 * 60 app = Flask(__name__) +app.url_map.strict_slashes = False + +if 'BASE_URL' in os.environ: + base_url = urlparse.urlparse(os.environ.get('BASE_URL')) + if base_url.scheme: + app.config['PREFERRED_URL_SCHEME'] = base_url.scheme + if base_url.netloc: + app.config['SERVER_NAME'] = base_url.netloc + if base_url.path: + app.config['APPLICATION_ROOT'] = base_url.path cache = SimpleCache() @@ -37,15 +50,37 @@ def get_menu(canteen, params): return menu -def canteen_feed_xml(canteen, menu): - xml = feed.render(canteen, menu) +def _canteen_feed_xml(xml): response = make_response(xml) response.mimetype = 'text/xml' return response -@app.route('/canteen/') -def canteen_feed(canteen_name): +def canteen_menu_feed_xml(menu): + xml = feed.render_menu(menu) + return _canteen_feed_xml(xml) + + +def canteen_meta_feed_xml(canteen): + menu_feed_url = url_for('canteen_menu_feed', canteen_name=canteen.key, _external=True) + xml = feed.render_meta(canteen, menu_feed_url) + return _canteen_feed_xml(xml) + + +@app.route('/canteens/') +@app.route('/canteens//meta') +def canteen_meta_feed(canteen_name): + config = read_canteen_config() + + if canteen_name not in config: + return canteen_not_found(config, canteen_name) + + canteen = config[canteen_name] + return canteen_meta_feed_xml(canteen) + + +@app.route('/canteens//menu') +def canteen_menu_feed(canteen_name): config = read_canteen_config() if canteen_name not in config: @@ -53,7 +88,15 @@ def canteen_feed(canteen_name): canteen = config[canteen_name] menu = get_menu_cached(canteen) - return canteen_feed_xml(canteen, menu) + return canteen_menu_feed_xml(menu) + + +@app.route('/') +@app.route('/canteens') +def canteen_index(): + config = read_canteen_config() + return jsonify({key: url_for('canteen_meta_feed', canteen_name=key, _external=True) for key in config}) + @app.route('/health_check') def health_check(): diff --git a/tests/resources/output.xml b/tests/resources/menu_output.xml similarity index 99% rename from tests/resources/output.xml rename to tests/resources/menu_output.xml index 865a23b..dfc19e7 100644 --- a/tests/resources/output.xml +++ b/tests/resources/menu_output.xml @@ -1,9 +1,6 @@ - Mensa Griebnitzsee -
August-Bebel-Straße 69, Haus 6
- 14482 Potsdam diff --git a/tests/resources/meta_output.xml b/tests/resources/meta_output.xml new file mode 100644 index 0000000..43c9b68 --- /dev/null +++ b/tests/resources/meta_output.xml @@ -0,0 +1,12 @@ + + + + Mensa Griebnitzsee +
August-Bebel-Straße 69, Haus 6
+ 14482 Potsdam + + + canteens/griebnitzsee/menu + +
+
diff --git a/tests/test_consistency.py b/tests/test_consistency.py index 2a3c47e..fad32d8 100644 --- a/tests/test_consistency.py +++ b/tests/test_consistency.py @@ -21,16 +21,32 @@ def _menu(): return json.load(f) -def _expected_feed(): - with io.open(_resource_path('output.xml'), encoding='utf-8') as f: +def _expected_meta_feed(): + with io.open(_resource_path('meta_output.xml'), encoding='utf-8') as f: return f.read() -def test_consistency(): +def _expected_menu_feed(): + with io.open(_resource_path('menu_output.xml'), encoding='utf-8') as f: + return f.read() + + +def test_meta_consistency(): + canteen = _canteen() + menu = _menu() + menu_feed_url = "canteens/{}/menu".format(canteen.key) + + actual = feed.render_meta(canteen, menu_feed_url) + + expected = _expected_meta_feed() + assert expected == actual + + +def test_menu_consistency(): canteen = _canteen() menu = _menu() - actual = feed.render(canteen, menu) + actual = feed.render_menu(menu) - expected = _expected_feed() + expected = _expected_menu_feed() assert expected == actual diff --git a/tests/test_retrieval.py b/tests/test_retrieval.py index 01c0e06..7c72524 100644 --- a/tests/test_retrieval.py +++ b/tests/test_retrieval.py @@ -27,4 +27,5 @@ def canteen(request): @requires_online_api def test_retrieval(canteen): menu = download_menu(MenuParams(canteen_id=canteen.id, chash=canteen.chash)) - feed.render(canteen, menu) + feed.render_meta(canteen, menu) + feed.render_menu(canteen, menu)