From ea87e3aab90b44c692c400893507bacb74f11fae Mon Sep 17 00:00:00 2001 From: Marian Steinbach Date: Mon, 5 Mar 2018 22:28:37 +0100 Subject: [PATCH] Add feed endpoint --- service/README.md | 28 ++++++++++++++++++++++++ service/api/feeds.py | 45 ++++++++++++++++++++++++++++++++++++++ service/api/main.py | 13 +++++++++++ service/requirements.txt | 1 + service/tests/test_main.py | 7 ++++++ 5 files changed, 94 insertions(+) create mode 100644 service/api/feeds.py diff --git a/service/README.md b/service/README.md index 53db6bc..4e90d97 100644 --- a/service/README.md +++ b/service/README.md @@ -12,6 +12,34 @@ Kalender zurück. ## API +### `GET /feed/` - Beiträge eines RSS- oder Atom Feed ausgeben + +Request URL Parameter: + +- `url`: URL des Feed +- `num`: Anzahl der Einträge, die zurück gegeben werden sollen (default: 1) + +Ausgabe: + +```json +{ + "meta": { + "title": "Die Grünen Rösrath", + "link": "http://gruene-roesrath.de", + "description": "", + "published": null + }, + "items": [ + { + "title": "Informationsveranstaltung zur Start-/Landebahnsanierung am Flughafen", + "summary": "Die Flughafen Köln/Bonn GmbH informiert am 1. März über die anstehende Sanierung der großen Start-...", + "link": "http://gruene-roesrath.de/startseite/news-detailansicht/article/informationsveranstaltung_zur_start_landebahnsanierung_am_flughafen/", + "published": "2018-02-19T20:15:00" + } + ] +} +``` + ### `GET /events/` - Die nächsten Termine eines iCal Kalenders ausgeben Request URL Parameter: diff --git a/service/api/feeds.py b/service/api/feeds.py new file mode 100644 index 0000000..4a6c4e0 --- /dev/null +++ b/service/api/feeds.py @@ -0,0 +1,45 @@ +import feedparser +from datetime import datetime + +class Client(object): + + def __init__(self, url): + self.url = url + self.__load() + + def __load(self): + self.feed = feedparser.parse(self.url) + + def metadata(self): + """ + Returns meta information from the feed + """ + return { + "title": self.feed["feed"].get("title"), + "link": self.feed["feed"].get("link"), + "description": self.feed["feed"].get("description"), + "published": self.feed["feed"].get("published"), + } + + def __entry_details(self, entry): + """ + Returns only a few entry details we care about + """ + return { + "title": entry["title"], + "summary": entry["summary"], + "link": entry["link"], + "published": datetime( + entry["published_parsed"][0], entry["published_parsed"][1], entry["published_parsed"][2], + entry["published_parsed"][3], entry["published_parsed"][4], entry["published_parsed"][5] + ) + } + + def recent_items(self, num=3): + """ + Returns the num most recent entries from the feed + """ + out = [] + for n in range(0, num): + out.append(self.__entry_details(self.feed.entries[n])) + return out diff --git a/service/api/main.py b/service/api/main.py index 9f83eea..bce3980 100644 --- a/service/api/main.py +++ b/service/api/main.py @@ -2,6 +2,7 @@ from . import events from . import jsonhandler +from . import feeds from datetime import datetime from falcon import media from falcon_cors import CORS @@ -31,6 +32,17 @@ class EventsResource(object): maxage = 60 * 60 # 1 hour resp.cache_control = ["max_age=%d" % maxage] +class FeedResource(object): + + def on_get(self, req, resp): + feed_url = req.get_param("url", required=True) + num = int(req.get_param("num", required=False, default="1")) + c = feeds.Client(feed_url) + resp.media = { + "meta": c.metadata(), + "items": c.recent_items(num=num) + } + class ParticleSensorResource(object): def on_get(self, req, resp, sensor_id): @@ -61,4 +73,5 @@ app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers app.add_route('/events/', EventsResource()) +app.add_route('/feed/', FeedResource()) app.add_route('/luftdaten.info/v1/sensor/{sensor_id}/', ParticleSensorResource()) diff --git a/service/requirements.txt b/service/requirements.txt index 423b056..389fe02 100644 --- a/service/requirements.txt +++ b/service/requirements.txt @@ -3,6 +3,7 @@ certifi==2018.1.18 chardet==3.0.4 falcon==1.4.1 falcon-cors==1.1.7 +feedparser==5.2.1 funcsigs==1.0.2 gunicorn==19.7.1 icalendar==4.0.0 diff --git a/service/tests/test_main.py b/service/tests/test_main.py index d82174e..6912224 100644 --- a/service/tests/test_main.py +++ b/service/tests/test_main.py @@ -21,3 +21,10 @@ def test_get_events(client): "ical_url": "http://www.webcal.fi/cal.php?id=75&rid=ics&wrn=0&wp=12&wf=55" }) assert response.status == falcon.HTTP_OK + +def test_get_feed(client): + response = client.simulate_get('/feed/', params={ + "url": "http://www.feedforall.com/sample.xml", + "num": "1" + }) + assert response.status == falcon.HTTP_OK