2 # -*- coding: iso-8859-15 -*-
5 """Contains functions that maintain/update the cache tables."""
6 from sqlalchemy import schema
7 from sqlalchemy.sql import select
9 from wrpylib import mwdb, wrmwdb, mwmarkup, wrmwmarkup
12 class UpdateCacheError(RuntimeError):
16 def update_wrsledruncache(connection):
17 """Updates the wrsledruncache table from the wiki. If convert errors occur, an UpdateCacheError exception
18 is raised. No other exception type should be raised under normal circumstances.
20 >>> from sqlalchemy.engine import create_engine
21 >>> engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=0')
22 >>> # see: https://sourceforge.net/tracker/?func=detail&aid=2837134&group_id=22307&atid=374932
23 >>> update_wrsledruncache(engine.connect())
25 metadata = schema.MetaData()
26 wrsledruncache = wrmwdb.wrsledruncache_table(metadata)
27 page = mwdb.page_table(metadata)
28 categorylinks = mwdb.categorylinks_table(metadata)
29 revision = mwdb.revision_table(metadata)
30 text = mwdb.text_table(metadata)
32 transaction = connection.begin()
35 q = select([page, categorylinks, revision, text], (page.c.page_latest==revision.c.rev_id) & (text.c.old_id==revision.c.rev_text_id) & (categorylinks.c.cl_from==page.c.page_id) & (categorylinks.c.cl_to==u'Rodelbahn'))
36 sledrun_pages = connection.execute(q)
38 # sql = u"select page_id, rev_id, old_id, page_title, old_text, 'In_Arbeit' in (select cl_to from categorylinks where cl_from=page_id) as under_construction from page, revision, text, categorylinks where page_latest=rev_id and old_id=rev_text_id and cl_from=page_id and cl_to='Rodelbahn' order by page_title"
40 # Delete all existing entries in wrsledruncache
41 # We rely on transactions MySQL InnoDB
42 connection.execute(wrsledruncache.delete())
44 # Refill wrsledruncache table
45 for sledrun_page in sledrun_pages:
47 start, end, sledrun = wrmwmarkup.rodelbahnbox_to_sledrun(sledrun_page.old_text)
48 sledrun.page_id = sledrun_page.page_id
49 sledrun.page_title = sledrun_page.page_title
50 sledrun.under_construction = connection.execute(select([categorylinks], (categorylinks.c.cl_from==sledrun_page.page_id) & (categorylinks.c.cl_to == u'In_Arbeit')).alias('x').count()).fetchone()[0] > 0 # It would be better to do this in the query above
51 connection.execute(wrsledruncache.insert(sledrun.__dict__))
52 except (RuntimeError, formencode.Invalid) as e:
53 transaction.rollback()
54 error_msg = u"Error at sled run '{0}': {1}".format(sledrun_page.page_title, unicode(e))
55 raise UpdateCacheError(error_msg, sledrun_page.page_title, e)
59 def update_wrinncache(connection):
60 """Updates the wrinncache table from the wiki. If convert errors occur, an UpdateCacheError exception
61 is raised. No other exception type should be raised under normal circumstances.
63 >>> from sqlalchemy.engine import create_engine
64 >>> engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=0')
65 >>> # see: https://sourceforge.net/tracker/?func=detail&aid=2837134&group_id=22307&atid=374932
66 >>> update_wrinncache(engine.connect())
68 metadata = schema.MetaData()
69 wrinncache = wrmwdb.wrinncache_table(metadata)
70 page = mwdb.page_table(metadata)
71 categorylinks = mwdb.categorylinks_table(metadata)
72 revision = mwdb.revision_table(metadata)
73 text = mwdb.text_table(metadata)
75 transaction = connection.begin()
78 q = select([page, categorylinks, revision, text], (page.c.page_latest==revision.c.rev_id) & (text.c.old_id==revision.c.rev_text_id) & (categorylinks.c.cl_from==page.c.page_id) & (categorylinks.c.cl_to==u'Gasthaus'))
79 inn_pages = connection.execute(q)
81 # Delete all existing entries in wrinncache
82 # We rely on transactions MySQL InnoDB
83 connection.execute(wrinncache.delete())
85 # Refill wrinncache table
86 for inn_page in inn_pages:
88 start, end, inn = wrmwmarkup.gasthausbox_to_inn(inn_page.old_text)
89 inn.page_id = inn_page.page_id
90 inn.page_title = inn_page.page_title
91 inn.under_construction = connection.execute(select([categorylinks], (categorylinks.c.cl_from==inn_page.page_id) & (categorylinks.c.cl_to == u'In_Arbeit')).alias('x').count()).fetchone()[0] > 0 # It would be better to do this in the query above
92 connection.execute(wrinncache.insert(inn.__dict__))
93 except (RuntimeError, formencode.Invalid) as e:
94 transaction.rollback()
95 error_msg = u"Error as inn '{0}': {1}".format(inn_page.page_title, unicode(e))
96 raise UpdateCacheError(error_msg, inn_page.page_title, e)
100 def update_wrreportcache(connection, page_id=None):
101 """Updates the wrreportcache table.
102 :param connection: sqlalchemy connection
103 :param page_id: Updates only the reportcache table for the sledrun described on the Winterrodeln wiki page
104 with the specified page_id. Use None for this parameter to update the whole table.
106 >>> from sqlalchemy.engine import create_engine
107 >>> engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=1')
108 >>> # see: https://sourceforge.net/tracker/?func=detail&aid=2837134&group_id=22307&atid=374932
109 >>> update_wrreportcache(engine.connect())
111 metadata = schema.MetaData()
112 wrreport = wrmwdb.wrreport_table(metadata)
113 wrreportcache = wrmwdb.wrreportcache_table(metadata)
114 transaction = connection.begin()
116 # Delete the datasets we are going to update
117 sql_del = wrreportcache.delete()
118 if not page_id is None: sql_del = sql_del.where(wrreportcache.c.page_id == page_id)
119 connection.execute(sql_del)
121 def insert_row(connection, rowlist):
122 if len(rowlist) == 0: return
124 row = dict(rowlist[0])
125 connection.execute(wrreportcache.insert(values=row))
127 # Select the rows to update
128 sql = 'select page_id, page_title, wrreport.id as report_id, date_report, `condition`, description, author_name, if(author_userid is null, null, author_username) as author_username from wrreport where {0}`condition` is not null and date_invalid > now() and delete_date is null order by page_id, date_report desc, date_entry desc'.format('' if page_id is None else 'page_id={0} and '.format(page_id))
129 cursor = connection.execute(sql)
133 if row.page_id != page_id:
134 insert_row(connection, rowlist)
135 page_id = row.page_id
138 insert_row(connection, rowlist)
142 def update_wrmapcache(connection):
143 """Updates the wrmappointcache and wrmappathcache tables from the wiki. If convert errors occur, an UpdateCacheError exception
144 is raised. No other exception type should be raised under normal circumstances.
146 >>> from sqlalchemy.engine import create_engine
147 >>> engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=0')
148 >>> # or: engine = create_engine('mysql://philipp@localhost:3306/philipp_winterrodeln_wiki?charset=utf8&use_unicode=0&passwd=XXXXX')
149 >>> # see: https://sourceforge.net/tracker/?func=detail&aid=2837134&group_id=22307&atid=374932
150 >>> connection = engine.connect()
151 >>> update_wrmapcache(connection)
153 metadata = schema.MetaData()
154 page = mwdb.page_table(metadata)
155 categorylinks = mwdb.categorylinks_table(metadata)
156 revision = mwdb.revision_table(metadata)
157 text = mwdb.text_table(metadata)
159 transaction = connection.begin()
162 q = select([page, categorylinks, revision, text], (page.c.page_latest==revision.c.rev_id) & (text.c.old_id==revision.c.rev_text_id) & (categorylinks.c.cl_from==page.c.page_id) & (categorylinks.c.cl_to==u'Rodelbahn'))
163 sledrun_pages = connection.execute(q)
165 # sql = u"select page_id, rev_id, old_id, page_title, old_text, 'In_Arbeit' in (select cl_to from categorylinks where cl_from=page_id) as under_construction from page, revision, text, categorylinks where page_latest=rev_id and old_id=rev_text_id and cl_from=page_id and cl_to='Rodelbahn' order by page_title"
167 # Delete all existing entries in wrmappointcache
168 # We rely on transactions MySQL InnoDB
169 connection.execute('delete from wrmappointcache')
170 connection.execute('delete from wrmappathcache')
172 # Refill wrmappointcache and wrmappathcache tables
173 for sledrun_page in sledrun_pages:
175 result = mwmarkup.parse_googlemap(sledrun_page.old_text)
176 if not result is None:
177 center, zoom, coords, paths = result
180 lon, lat, point_type, label = coord
181 point_types = {u'Gasthaus': u'hut', u'Haltestelle': u'busstop', u'Parkplatz': u'carpark', u'Achtung': u'warning'}
182 if not point_type is None:
183 if not point_types.has_key(point_type): raise RuntimeError(u'Unknown point type {0}'.format(point_type))
184 point_type = point_types[point_type]
185 sql = u'insert into wrmappointcache (page_id, type, point, label) values (%s, %s, POINT(%s, %s), %s)'
186 connection.execute(sql, (sledrun_page.page_id, point_type, lon, lat, label))
188 for path_type, coords in paths:
189 path_type = path_type.lower()
190 path_types = {u'6#ff014e9a': u'sledrun', u'6#ffe98401': u'walkup', u'6#ff7f7fff': u'alternative', u'3#ff000000': u'lift', u'3#ffe1e100': u'recommendedcarroute'}
191 if not path_types.has_key(path_type): raise RuntimeError(u'Unknown path type {0}'.format(path_type))
192 path_type = path_types[path_type]
193 path = u", ".join(["{0} {1}".format(lon, lat) for lon, lat, symbol, title in coords])
194 path = u'LineString({0})'.format(path)
195 if path_type == u'recommendedcarroute': continue
196 sql = u'insert into wrmappathcache (path, page_id, type) values (GeomFromText(%s), %s, %s)'
197 connection.execute(sql, (path, sledrun_page.page_id, path_type))
198 except RuntimeError as e:
199 error_msg = u"Error at sledrun '{0}': {1}".format(sledrun_page.page_title, unicode(e))
200 transaction.rollback()
201 raise UpdateCacheError(error_msg, sledrun_page.page_title, e)