#
[DEFAULT]
debug = true
-# Uncomment and replace with the address which should receive any error reports
-#email_to = you@yourdomain.com
+# address which should receive any error reports
+email_to = philipp.spitzer@winterrodeln.org
smtp_server = localhost
-error_email_from = paste@localhost
+error_email_from = philipp.spitzer@winterrodeln.org
+
+wikidbtype = mysql
+wikidbserver = localhost
+wikidbname = winterrodeln_wiki
+wikidbuser = philipp
+wikidbpassword =
[server:main]
use = egg:Paste#http
smtp_server = localhost
error_email_from = paste@localhost
+wikidbtype = mysql
+wikidbserver = localhost
+wikidbname = wiki
+wikidbuser = username
+wikidbpassword =
+
[server:main]
use = egg:Paste#http
host = 0.0.0.0
# CONFIGURATION OPTIONS HERE (note: all config options will override
# any Pylons config options)
+ config['pylons.strict_c'] = True
\ No newline at end of file
def make_map():
"""Create, configure and return the routes Mapper"""
map = Mapper(directory=config['pylons.paths']['controllers'],
- always_scan=config['debug'])
+ always_scan=config['debug'], explicit=True)
map.minimization = False
# The ErrorController route (handles 404/500 error pages); it should
# CUSTOM ROUTES HERE
- map.connect('/', controller='rodelbahn', action='index')
+ map.connect('/', controller='wrcontroller', action='index')
+ map.connect('/{action}', controller='wrcontroller')
+ map.connect('rodelbahnbox_update', '/wrcontroller/rodelbahnbox/update', controller='wrcontroller', action='rodelbahnbox', update=True)
map.connect('/{controller}/{action}')
map.connect('/{controller}/{action}/{id}')
+++ /dev/null
-import logging
-
-from pylons import request, response, session, tmpl_context as c
-from pylons.controllers.util import abort, redirect_to
-from pylons.templating import render_genshi as render
-
-from wradmin.lib.base import BaseController
-from wradmin.lib.wrdatabase import query_sledding_routes
-
-log = logging.getLogger(__name__)
-
-class RodelbahnController(BaseController):
-
- def index(self):
- return render('index.html')
-
- def rodelbahn(self, **kw):
- sledding_routes = query_sledding_routes()
- return render('rodelbahn.html', extra_vars={'page': 'rodelbahn', 'sledding_routes': sledding_routes})
-
--- /dev/null
+import logging
+
+from pylons import request, response, session, tmpl_context as c
+from pylons.controllers.util import abort, redirect_to
+from pylons.templating import render_genshi as render
+
+from wradmin.lib.base import BaseController
+from wradmin.lib.wrdatabase import query_sledding_routes
+from wradmin.lib.wrcachelists import update_rodelbahnbox
+
+log = logging.getLogger(__name__)
+
+class WrcontrollerController(BaseController):
+
+ def index(self):
+ return render('index.html')
+
+ def rodelbahnbox(self, update=False):
+ "update ... update the database from the Rodelbahnbox structures"
+ if update:
+ try: c.sledding_routes = update_rodelbahnbox()
+ except Exception, e:
+ c.update_error = e.message
+ c.update_performed = update
+ c.update_success = hasattr(c, 'sledding_routes')
+ return render('rodelbahnbox.html')
+
+ def forumlink(self, **kw):
+ c.sledding_routes = query_sledding_routes()
+ return render('forumlink.html')
--- /dev/null
+#!/usr/bin/python2.5
+# -*- coding: iso-8859-15 -*-
+#
+# This file was copied from http://www.winterrodeln.org/svn/servermediawiki/trunk/maintenance/wrcachelists.py
+# which containts the "more complete" code. In this file, only needed parts are included: For example,
+# the PostgreSQL support was dropped here.
+"Updates caching table for sledding runs."
+
+from wrdatabase import get_wiki_connection
+import re
+
+# Converter functions
+# -------------------
+
+def to_bool(value):
+ if not value: return None
+ if value == 'Ja': return True
+ if value == 'Nein': return False
+ raise Exception('%s is not a valid boolean value' % value)
+
+
+def to_geo(value):
+ """Formats to coordinates '47.076207 N 11.453553 E' to the (latitude, longitude) tuplet."""
+ if not value: return (None, None)
+ r = re.match('(\d+\.\d+) N (\d+\.\d+) E', value)
+ if r is None: raise Exception("Coordinates '%s' have not a format like '47.076207 N 11.453553 E'")
+ return (float(r.groups()[0]), float(r.groups()[1]))
+
+def to_title(value):
+ # Line 2237 of includes/Title.php says: $this->mTextform = str_replace( '_', ' ', $dbkey );
+ # No not check for None because a missing title is an error
+ return value.replace('_', ' ')
+
+
+# Sledding run
+# ------------
+
+def update_rodelbahnbox():
+ """Collects information from the Rodelbahnbox wiki structures.
+ It stores them in the database in case of success and returns a list of tuples (page_id, page_title) of successfully processed pages.
+ It raises an exception in case of errors and does not change the database."""
+
+ def process_row(row):
+ "It converts a database row to a dictionary and performs checks."
+ (page_id, rev_id, old_id, page_title, old_text, under_construction) = row
+ page_title = unicode(page_title, 'UTF-8')
+ old_text = unicode(old_text, 'UTF-8')
+ # Initialize property dict
+ property_keys = [
+ 'page_id',
+ 'page_title',
+ 'length',
+ 'walktime',
+ 'height_top',
+ 'height_bottom',
+ 'walkup_separate',
+ 'lift',
+ 'night_light',
+ 'sledge_rental',
+ 'public_transport',
+ 'image',
+ 'position_latitude',
+ 'position_longitude',
+ 'information',
+ 'show_in_overview',
+ 'creation_date']
+ properties = dict()
+ for property in property_keys:
+ properties[property] = None
+ # Match Rodelbahnbox
+ match = regexp.search(old_text)
+ if not match:
+ raise Exception("No 'Rodelbahnbox' found")
+ box = match.group(1)
+ # Process Rodelbahnbox
+ for property in box.split('|'):
+ property = property.strip()
+ if property == 'Rodelbahnbox': continue
+ key_value = property.split('=')
+ if len(key_value) != 2:
+ raise Exception("Property '%s' has unexpected format" % key_value)
+ key = key_value[0].strip()
+ value = key_value[1].strip()
+ if key == 'Rodelbahnnummer': pass
+ elif key == u'Länge' and value: properties['length'] = int(value)
+ elif key == u'Gehzeit' and value: properties['walktime'] = int(value)
+ elif key == u'Höhe oben' and value: properties['height_top'] = int(value)
+ elif key == u'Höhe unten' and value: properties['height_bottom'] = int(value)
+ elif key == u'Aufstieg getrennt': properties['walkup_separate'] = to_bool(value)
+ elif key == u'Lift': properties['lift'] = to_bool(value)
+ elif key == u'Beleuchtung': properties['night_light'] = to_bool(value)
+ elif key == u'Rodelverleih': properties['sledge_rental'] = to_bool(value)
+ elif key == u'Öffentliche Anreise': properties['public_transport'] = to_bool(value)
+ elif key == u'Bild': properties['image'] = value
+ elif key == u'Position': (properties['position_latitude'], properties['position_longitude']) = to_geo(value) # '47.583333 N 15.75 E'
+ elif key == u'Auskunft': properties['information'] = value
+ elif key == u'In Übersichtskarte': properties['show_in_overview'] = to_bool(value)
+ elif key == u'Aufnahmedatum': properties['creation_date'] = value # '2006-03-15'
+ properties['page_id'] = page_id
+ properties['page_title'] = to_title(page_title)
+ properties['under_construction'] = under_construction
+ del properties['creation_date'] # this is not saved in the database yet
+ return properties
+
+
+ # Load database modul
+ import MySQLdb
+ import re
+
+ conn = get_wiki_connection()
+ cuo = conn.cursor() # cursor for output (out of the database)
+ cui = conn.cursor() # cursor for input (into the database)
+
+ sql = "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, %(pagecontent)s, 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" % {'pagecontent': "text"}
+ cuo.execute(sql)
+
+ regexp = re.compile("\{\{(Rodelbahnbox[^\}]*)\}\}", re.DOTALL)
+ try:
+ sledding_list = [];
+ for row in cuo:
+ try:
+ properties = process_row(row)
+ except Exception, e:
+ raise Exception(e.message + '. Seite "%s" (page_id %d).' % (row[3], row[0]))
+ sledding_list.append(properties)
+
+ sql = 'delete from wrsleddingcache'
+ cui.execute(sql)
+
+ if len(sledding_list) > 0:
+ columns = sledding_list[0].keys()
+ sql = 'insert into wrsleddingcache (' + ', '.join(columns) + ') values '
+ sql = sql + '(' + ', '.join(['%s' for c in columns]) + ')'
+ for sledding in sledding_list:
+ cui.execute(sql, sledding.values())
+
+ conn.commit()
+ conn.close()
+ except:
+ conn.rollback()
+ conn.close()
+ raise
+ return sledding_list
\ No newline at end of file
import MySQLdb
+def get_wiki_connection():
+ "Returns a connection object to the wiki database."
+ return MySQLdb.connect(host="localhost", user="philipp", db="winterrodeln_wiki", use_unicode=True, charset='utf8')
def query_sledding_routes():
- conn = MySQLdb.connect(host="localhost", user="philipp", db="winterrodeln_wiki", use_unicode=True, charset='utf8')
+ conn = get_wiki_connection()
cu = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
sql = "select page_id, rev_id, old_id, cast(page_title as char) as page_title, 'In_Arbeit' in (select cl_to from categorylinks where cl_from=page_id) as under_construction, page_id in (select tl_from from templatelinks where tl_title='Forumlink' and tl_namespace='10') as forum_link_present 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"
cu.execute(sql)
sledding_routes = cu.fetchall()
return sledding_routes
-
}
#content {
- width: 720px;
- overflow: auto;
- margin-left: 10px;
+ margin: 10px;
padding-top: 0px;
padding-left: 10px;
padding-right: 10px;
+ padding-bottom: 15px;
min-height: 400px;
background-color: rgba(255, 255, 255, 0.5);
+ border-bottom-style: solid;
+ border-bottom-width: 3px;
+ border-bottom-color: #014E9A;
}
#mainmenu {
#mainmenu li {
display: inline;
+ margin:0px;
+ padding:0px;
+}
+
+#mainmenu a, .button {
+ color: white;
+ text-decoration: none;
background-image: url('btn_bg_blue.png');
height: 46px;
margin: 0px;
border-right-color: #003366;
}
-#mainmenu li:hover {
+#mainmenu a:hover, .button:hover {
+ text-decoration: underline;
background-image: url('btn_bg_orange.png');
border-left-color: #ffb507;
border-right-color: #9a5700;
}
-#mainmenu li:active {
+#mainmenu a:active, .button:active {
background-image: url('btn_bg_inv_orange.png');
border-left-color: #9a5700;
border-right-color: #ffb507;
}
-#mainmenu a {
- color: white;
- text-decoration: none;
-}
-
-#mainmenu a:hover {
- text-decoration: underline;
-}
table {
margin: 20px;
a {
color: #014E9A;
}
+
+#footer {
+ margin-top: 20px;
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+<xi:include href="master.html" />
+
+<head>
+ <title>Forum-Links zu Rodelbahnen</title>
+</head>
+
+<body>
+<h2>Forum-Links zu Rodelbahnen</h2>
+
+<p>Die folgende Tabelle zeigt "live" die der Kategorie <em>Rodelbahnen</em> zugeordneten Wiki-Seiten. Die Spalte <em>In Arbeit</em> gibt an, ob die Seite zusätzlich der Kategorie <em>In Arbeit</em> angehört und die Spalte <em>Forumlink</em> zeigt, ob die Seite mindestens einmal das Makro <tt>{{Forumlink ...}}</tt> enthält.</p>
+
+<table>
+ <tr><th>Name</th><th>In Arbeit</th><th>Forumlink</th></tr>
+ <tr py:for="sl in c.sledding_routes"><td>${sl['page_title']}</td><td>${sl['under_construction']}</td><td>${sl['forum_link_present']}</td></tr>
+</table>
+
+</body>
+</html>
<p>Willkommen auf den Administrationsseiten von Winterrodeln.</p>
<ul>
- <li><a href="">Forum-Links auf Rodelbahnen</a></li>
- <li><a href="">Rodelbahn-Infoboxen</a> überprüfen und Koordinaten aktualisieren</li>
+ <li><a href="${h.url_for(controller='wrcontroller', action='forumlink')}">Forum-Links auf Rodelbahnen</a></li>
+ <li><a href="${h.url_for(controller='wrcontroller', action='rodelbahnbox')}">Rodelbahn-Infoboxen</a> überprüfen und Koordinaten aktualisieren</li>
</ul>
<ul>
<head py:attrs="select('@*')">
<title py:with="title = list(select('title/text()'))">Winterrodeln<py:if test="title"> - ${title}</py:if></title>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
- <link rel="stylesheet" type="text/css" media="screen" href="/style.css" /> <!-- TODO: Don't use path -->
+ <link rel="stylesheet" type="text/css" media="screen" href="${h.url_for('/style.css')}" />
</head>
</py:match>
<py:match path="body" once="true">
<body py:attrs="select('@*')">
-<h1 id="header"><img src="/titlebanner.png" alt="Winterrodeln Administration"/></h1>
+<h1 id="header"><img src="${h.url_for('/titlebanner.png')}" alt="Winterrodeln Administration"/></h1>
<ul id="mainmenu">
- <li><a href="${h.url_for(controller='rodelbahn', action='index')}">Übersicht</a></li>
- <li><a href="${h.url_for(controller='rodelbahn', action='rodelbahn')}">Rodelbahnen</a></li>
+ <li><a href="${h.url_for(controller='wrcontroller', action='index')}">Übersicht</a></li>
+ <li><a href="${h.url_for(controller='wrcontroller', action='rodelbahnbox')}">Rodelbahnboxen</a></li>
+ <li><a href="${h.url_for(controller='wrcontroller', action='forumlink')}">Forum-Links</a></li>
</ul>
<div id="content">
${select('*|text()')}
</div>
-<hr />
-<div id="footer"><img src="/philipp_spitzer.png" alt="Philipp Spitzer"/></div>
+<div id="footer"><img src="${h.url_for('/philipp_spitzer.png')}" alt="Philipp Spitzer"/></div>
</body>
</py:match>
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-<xi:include href="master.html" />
-
-<head>
- <title>Rodelbahnen</title>
-</head>
-
-<body>
-<h2>Rodelbahnen</h2>
-
-<p>Die folgende Tabelle zeigt "live" die der Kategorie <em>Rodelbahnen</em> zugeordneten Wiki-Seiten. Die Spalte <em>In Arbeit</em> gibt an, ob die Seite zusätzlich der Kategorie <em>In Arbeit</em> angehört und die Spalte <em>Forumlink</em> zeigt, ob die Seite mindestens einmal das Makro <tt>{{Forumlink ...}}</tt> enthält.</p>
-
-<table>
- <colgroup><col/><col align="center"/><col align="center"/></colgroup>
- <tr><th>Name</th><th>In Arbeit</th><th>Forumlink</th></tr>
- <tr py:for="sl in sledding_routes"><td>${sl['page_title']}</td><td>${sl['under_construction']}</td><td>${sl['forum_link_present']}</td></tr>
-</table>
-
-</body>
-</html>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+<xi:include href="master.html" />
+
+<head>
+ <title>Rodelbahnboxen aktualisieren</title>
+</head>
+
+<body>
+<h2>Rodelbahnboxen aktualisieren</h2>
+
+<py:if test="c.update_performed">
+<py:if test="c.update_success">
+<p>Das Update der Rodelbahnboxen wurde erfolgreich durchgeführt. Folgende Informationen wurden aktualisiert:</p>
+
+<table>
+ <tr>
+ <th>Seite</th>
+ <th>Länge</th>
+ <th>Gehzeit</th>
+ <th>Höhe unten</th>
+ <th>Höhe oben</th>
+ <th>Information</th>
+ <th>Licht</th>
+ <th>Verleih</th>
+ <th>Lift</th>
+ <th>Öff. Anreise</th>
+ <th>Aufst. getr.</th>
+ <th>Position</th>
+ <th>Bild</th>
+ <th>In Übersicht</th>
+ <th>In Arbeit</th>
+ <th>Seiten-ID</th>
+ </tr>
+ <tr py:for="sl in c.sledding_routes">
+ <td>${sl['page_title']}</td>
+ <td>${sl['length']}</td>
+ <td>${sl['walktime']}</td>
+ <td>${sl['height_bottom']}</td>
+ <td>${sl['height_top']}</td>
+ <td>${sl['information']}</td>
+ <td>${sl['night_light']}</td>
+ <td>${sl['sledge_rental']}</td>
+ <td>${sl['lift']}</td>
+ <td>${sl['public_transport']}</td>
+ <td>${sl['walkup_separate']}</td>
+ <td>${sl['position_latitude']}, ${sl['position_longitude']}</td>
+ <td>${sl['image']}</td>
+ <td>${sl['show_in_overview']}</td>
+ <td>${sl['under_construction']}</td>
+ <td>${sl['page_id']}</td>
+ </tr>
+</table>
+
+</py:if>
+<py:if test="not c.update_success">
+<p>Beim Update der Rodelbahnboxen ist ein Fehler aufgetreten:</p>
+<p>${c.update_error}</p>
+</py:if>
+</py:if>
+
+<py:if test="not c.update_performed">
+<p>Die in den Rodelbahnboxen eingetragenen Informationen können mit folgendem Button ausgelesen und in eine Datenbanktabelle (<tt>wrsleddingcache</tt>) eingetragen werden. Diese Tabelle wird im Folgenden u.A. benutzt, um die Positionen der Rodelbahnen auf der Landkarte zu zeichnen. Auch die Daten der neuen Übersichtslisten im Wiki kommen aus dieser Tabelle.</p>
+
+<p>Nun ist es nicht unwahrscheinlich, dass Benutzer Fehler machen beim Ausfühllen der Rodelbahnbox. In dem Fall wird die Seite mit dem Fehler angezeigt und die Datenbanktabelle wird nicht geändert. Es kann dann das Wiki korrigiert werden und anschließend das Auslesen neu gestartet werden.</p>
+</py:if>
+
+<a href="${h.url_for('rodelbahnbox_update')}" class="button">Rodelbahnboxen auslesen und DB aktualisieren</a>
+
+</body>
+</html>