]> ToastFreeware Gitweb - philipp/winterrodeln/wrfeed.git/blob - wrfeed/berichte.py
29425cf3df2953e8831d5a2cea80eefb497d2955
[philipp/winterrodeln/wrfeed.git] / wrfeed / berichte.py
1 """Creates an Atom-Feed for single or multiple winterrodeln sled reports.
2
3 Format:
4     http://www.winterrodeln.org/feed/berichte/alle
5     http://www.winterrodeln.org/feed/berichte/bahn/kemater_alm
6     http://www.winterrodeln.org/feed/berichte/bahnen/5+280+251
7     http://www.winterrodeln.org/feed/berichte/region/osttirol
8 See:
9     http://www.atompub.org/
10     http://effbot.org/zone/element.htm
11     http://www.winterrodeln.org/trac/wiki/UrlSchema
12 """
13 import datetime
14 from xml.etree.ElementTree import Element, SubElement, tostring
15 from flask import url_for
16 from sqlalchemy import func, desc
17
18
19 class CreateFeedError(RuntimeError):
20     pass
21
22
23 class RegionNotFoundError(CreateFeedError):
24     pass
25
26
27 def create_feed(db, limit, page_title=None, page_ids=None, region_name=None):
28     """If a page_title is given, only the reports for the given sledrun are shown.
29     If a list of page_ids is given, only the reports for the selected pages are shown.
30     If a region name (lower case) is given, the reports just for this region are shown.
31     Otherwise, all reports are shown."""
32
33     wrreport = db.metadata.tables['wrreport']
34     wrsledruncache = db.metadata.tables['wrsledruncache']
35     wrregion = db.metadata.tables['wrregion']
36     wrregioncache = db.metadata.tables['wrregioncache']
37
38     sql = db.select([
39             wrreport,
40             wrsledruncache.c.position_longitude.label('lon'),
41             wrsledruncache.c.position_latitude.label('lat')
42         ]). \
43         select_from(wrreport.outerjoin(wrsledruncache, wrreport.c.page_id == wrsledruncache.c.page_id)). \
44         where(wrreport.c.date_invalid > func.now()). \
45         where(wrreport.c.delete_date.is_(None)). \
46         order_by(desc(wrreport.c.id)). \
47         limit(limit)
48
49     if page_title is not None:
50         # page_title is given
51         page_title = page_title.replace('_', ' ')
52         sql = sql.where(func.lcase(wrreport.c.page_title) == func.lcase(page_title))
53     elif page_ids is not None:
54         # a list of page_ids is given
55         sql = sql.where(wrreport.c.page_id.in_(page_ids))
56     elif region_name is not None:
57         # a name of a region is given
58         # (1) find out whether the region exists
59         sub_sql = db.select([wrregion]).where(wrregion.c.name == func.lcase(region_name))
60         sub_result = db.session.connection().execute(sub_sql)
61         if sub_result.rowcount == 0:
62             # no region with such a name
63             raise RegionNotFoundError(region_name)
64         assert sub_result.rowcount == 1
65         sub_row = sub_result.fetchone()
66         region_id = sub_row.id
67         # (2) now we have the id of the region
68         sql = sql.where(wrreport.c.page_id.in_(db.select([wrregioncache.c.page_id]).where(region_id == wrregioncache.c.region_id)))
69     else:
70         # user wants to have all reports
71         pass
72     result = db.session.connection().execute(sql)
73
74     feed = Element("feed", xmlns="http://www.w3.org/2005/Atom", attrib={'xmlns:georss': 'http://www.georss.org/georss', 'xmlns:wr': 'http://www.winterrodeln.org/schema/wrreport'})
75     feed_title = SubElement(feed, "title")
76     feed_title.text = "Winterrodeln Rodelbahnberichte"
77     feed_id = SubElement(feed, "id")
78     if not page_title is None:
79         feed_id.text = url_for('bahn', bahn=page_title, _external=True)
80     elif not page_ids is None:
81         feed_id.text = url_for('bahnen', bahnen="+".join(map(str, page_ids)), _external=True)
82     elif not region_name is None:
83         feed_id.text = url_for('region', region=region_name, _external=True)
84     else:
85         feed_id.text = url_for('alle', _external=True)
86     feed_updated = SubElement(feed, "updated")
87     feed.append(Element("link", rel="self", href=feed_id.text))
88
89     last_updated = None
90     for row in result:
91         page_title_url = row.page_title.replace(' ', '_')
92         entry = SubElement(feed, "entry")
93         entry_title = SubElement(entry, "title")
94         entry_title.text = row.page_title
95         entry.append(Element("link", rel="alternate", href="http://www.winterrodeln.org/wiki/{0}".format(page_title_url), type="text/html", hreflang="de"))
96         entry_id = SubElement(entry, "id")
97         entry_id.text = "http://www.winterrodeln.org/wiki/{0}#{1}".format(page_title_url, row.id)
98         entry_updated = SubElement(entry, "updated")
99         entry_updated.text = row.date_entry.isoformat() + "+01:00"
100         if last_updated is None: last_updated = row.date_entry
101         # entry_summary = SubElement(entry, "summary")
102         # entry_summary.text = str(condition)
103         entry_content = SubElement(entry, "content")
104         entry_content.attrib["type"] = "xhtml"
105         entry_content_div = SubElement(entry_content, "div")
106         entry_content_div.attrib["xmlns"] = "http://www.w3.org/1999/xhtml"
107         entry_content_ul = SubElement(entry_content_div, "ul")
108         if not row.date_report is None:
109             entry_content_date = SubElement(entry_content_ul, "li")
110             entry_content_date.text = "Bericht für " + row.date_report.isoformat()
111         if not row.condition is None:
112             entry_content_condition = SubElement(entry_content_ul, "li")
113             entry_content_condition.text = "Schneelage: " + {1: 'Sehr gut', 2: 'Gut', 3: 'Mittelmäßig', 4: 'Schlecht', 5: 'Geht nicht'}[row.condition]
114         entry_content_description = SubElement(entry_content_ul, "li")
115         entry_content_description.text = row.description
116         entry_author = SubElement(entry, "author")
117         entry_author_name = SubElement(entry_author, "name")
118         if row.author_name is None or len(row.author_name.strip()) == 0:
119             entry_author_name.text = "Anonymous user"
120         else:
121             entry_author_name.text = row.author_name
122         if not row.lon is None and not row.lat is None:
123             entry_geo = SubElement(entry, "georss:point")
124             entry_geo.text = "{lat} {lon}".format(lat=row.lat, lon=row.lon)
125         entry_wrreport = SubElement(entry, "wr:report")
126         entry_wrreport.attrib['report_id'] = str(row.id)
127         entry_wrreport.attrib['page_id'] = str(row.page_id)
128         entry_wrreport.attrib['page_title'] = row.page_title
129         entry_wrreport.attrib['date_report'] = str(row.date_report)
130         entry_wrreport.attrib['date_entry'] = str(row.date_entry)
131         entry_wrreport.attrib['condition'] = "0" if row.condition is None else str(row.condition)
132         entry_wrreport.attrib['author_name'] = row.author_name
133         entry_wrreport.attrib['author_username'] = "" if row.author_userid is None else row.author_username
134         entry_wrreport.text = row.description
135
136     if last_updated is None:
137         last_updated = datetime.datetime.now()
138     feed_updated.text = last_updated.isoformat() + "+01:00"
139
140     return b'<?xml version="1.0" encoding="utf-8"?>\n' + tostring(feed)