-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature/metafeeds: Support for canteen meta feeds and index feed #2
Conversation
(added: testing meta feed rendering in retrievaltest)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thorough work 👍 Change in URL structure and split into two feeds are very welcome. Will require a bit of Flask-ification :)
stw_potsdam/feed.py
Outdated
builder.address = canteen.street | ||
builder.city = canteen.city | ||
|
||
if skip_meta is not True: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: if not skip_meta: ...
? Anyway, why parameterise? I'd prefer speaking names such as _create_meta_builder
or _create_menu_builder
. Latter could possibly be inlined, because it's just the constructor call for now.
stw_potsdam/feed.py
Outdated
|
||
for day in _active_days(menu): | ||
_process_day(builder, day) | ||
|
||
return builder.toXMLFeed() | ||
|
||
|
||
def render_meta(canteen, menu): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
render_meta
currently does not make use of (and should not require) a "menu" parameter.
stw_potsdam/feed.py
Outdated
(key, reverse("canteens/{}/meta".format(key))) for key in config | ||
) | ||
|
||
index_json = json.dumps(index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the world of Flask, this is probably
from flask import jsonify
return jsonify(index)
Which adds convenience, configurability, and sensitivity to production / debug mode.
Second, I believe the method should belong to views
. It is not related to feed building according to (Py)OpenMensa. It's possibly as simple as this two-line method:
# views.py
@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})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's right.
I additionally opened mswart/pyopenmensa#16, to discuss whether this should be a feature included in pyopenmensa or not.
stw_potsdam/reverse.py
Outdated
from flask import request | ||
|
||
|
||
def reverse(path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You were looking for flask.url_for
, weren't you?
I suggest to keep knowledge about the existence of Flask views (and their names, parameters, etc) fully to the views module. feed.render_meta
should receive the canteen and the menu URL (or possibly a function to retrieve menu URLs). Draft:
# views.py
from flask import url_for
def canteen_meta_feed_xml(canteen):
menu_url = url_for('canteen_menu_feed', canteen_name=canteen.key, _external=True)
xml = feed.render_meta(canteen, menu_url)
return _canteen_feed_xml(xml)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically, I was looking for flask.url_for, at least partially. I just was not sure how to 'override' this URL generation, which I want/need to use within my infrastructure, where the services are hidden behind a front-end proxy. (At least, I ran into that problem with my current implementation, before adding the BASE_URL environment variable). I will look into it. :)
At least, the urlparse.urljoin(request.url_root)
foo can be replaced by a much more flask-esque flask.url_for
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I'm unaware of your exact requirements but here is a proposal: use config variable SERVER_NAME
with the following patch:
# views.py
+import os
app = Flask(__name__)
+app.config['SERVER_NAME'] = os.environ.get('BASE_URL')
and use BASE_URL="spam.eggs:9090" make run
to execute (or similar). url_for
will then be aware of host + port when constructing absolute URLs. To my belief this should somewhat closely resemble what you have been attempting.
stw_potsdam/views.py
Outdated
|
||
|
||
def canteen_meta_feed_xml(canteen, menu): | ||
xml = feed.render_meta(canteen, menu) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"menu" parameter is obsolete. Also propagates into view and test methods.
tests/test_consistency.py
Outdated
assert expected == actual | ||
|
||
|
||
def test_index_consistency(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's moved inside the views module, this testcase is harder to implement. I think it's not required - it is testing more of the functionality of reverse
or then Flask's url_for
than anything else, I believe.
Thanks for your comments! :) |
Better? ;) |
stw_potsdam/feed.py
Outdated
return builder.toXMLFeed() | ||
|
||
|
||
def render_meta(canteen): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your current approach looks very neat, I'm that close to approving. Main culprit: tests do not pass due errors in argument passing. Second, some things appear half-finished to me in feed.py
:
- Remove unused import statement for
json
. (Yes, at some time I should really think about integrating basic automatic static analysis / linting) render_menu
no longer needs a canteen parameter.render_meta
still referencesreverse
function from ex-modulereverse
, which rightfully ceased to exist. It should take the canteen menu URL by parameter, populated viaurl_for
inside theviews
module.
I estimate a required fix time of two minutes 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoa, I see that I should not produce code when I'm in a hurry. I thought that all the tests passed (and I was surprised that everything worked out in the beginning), but it turns out that my test runner used the cached Docker image and not the current source code. 🤦♂️
Fixes should be up any minute.
removing debug prints that should never have been committed.
…w-potsdam-v2 into feature/metafeeds
Done so far. I just ran pycodestyle (former pep8) and pylint:
pylint (with disabled warnings
Since only the If you'd like, I could also give those a try, but I would need to know which one you would want to be addressed, and probably you're quicker just fixing them directly. 😉 |
Thanks for the info, yes, I'll postpone complaints of both tools. Those will be subject to later PRs. Are you generally interested in being a reviewer? I also noticed irregularities in the canteen API which require fixing (work in progress on my side). |
This PR adds support for meta feeds (as documented in doc.openmensa.org Feed v2.1 and for a feed/canteen index (undocumented on doc.openmensa.org as of yet).
This PR creates incompatible URLs to provide a consistent naming scheme (
/canteens/
for the canteen index,/canteens/<canteen>/meta
for canteen metadata and/canteens/<canteen>/menu
for the menu).For both the index feed and metadata feed, a "reverse url" module (
stw_potsdam/reverse.py
) had to be added, that either uses a base URL derived from an environment variable (BASE_URL
) or else from Flask's Request context.