]> ToastFreeware Gitweb - philipp/winterrodeln/wradmin.git/commitdiff
wrsleddingcache table update works now from GUI
authorphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Sun, 8 Mar 2009 11:53:33 +0000 (11:53 +0000)
committerphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Sun, 8 Mar 2009 11:53:33 +0000 (11:53 +0000)
git-svn-id: http://www.winterrodeln.org/svn/servermediawiki/trunk/wradmin@412 7aebc617-e5e2-0310-91dc-80fb5f6d2477

14 files changed:
wradmin/development.ini
wradmin/wradmin/config/deployment.ini_tmpl
wradmin/wradmin/config/environment.py
wradmin/wradmin/config/routing.py
wradmin/wradmin/controllers/rodelbahn.py [deleted file]
wradmin/wradmin/controllers/wrcontroller.py [new file with mode: 0644]
wradmin/wradmin/lib/wrcachelists.py [new file with mode: 0644]
wradmin/wradmin/lib/wrdatabase.py
wradmin/wradmin/public/style.css
wradmin/wradmin/templates/forumlink.html [new file with mode: 0644]
wradmin/wradmin/templates/index.html
wradmin/wradmin/templates/master.html
wradmin/wradmin/templates/rodelbahn.html [deleted file]
wradmin/wradmin/templates/rodelbahnbox.html [new file with mode: 0644]

index 963dd8293dd8ee872e6272856a6a05b2fa1066e4..d08a8c9354b0c7a4a29cb7fa723b3ab12cf40608 100644 (file)
@@ -5,10 +5,16 @@
 #
 [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
index ce762c3652276c4e2d0edaed3d331b64a4953313..eb7a512248cbb624043a11081cb82a216096ae69 100644 (file)
@@ -9,6 +9,12 @@ email_to = you@yourdomain.com
 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
index e18a9fa650988a4932aff9380afd404866a99cb1..01f34b93eabc63f84bf21d41af62f162e8af7852 100644 (file)
@@ -32,3 +32,4 @@ def load_environment(global_conf, app_conf):
 
     # CONFIGURATION OPTIONS HERE (note: all config options will override
     # any Pylons config options)
+    config['pylons.strict_c'] = True
\ No newline at end of file
index 4d5e73855613a2bb835ffd6824bd6caf8cc58417..f8a9f6f2d63fb4fa7ce50574ea8f965720e9a5cc 100644 (file)
@@ -10,7 +10,7 @@ from routes import Mapper
 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
@@ -20,7 +20,9 @@ def make_map():
 
     # 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}')
 
diff --git a/wradmin/wradmin/controllers/rodelbahn.py b/wradmin/wradmin/controllers/rodelbahn.py
deleted file mode 100644 (file)
index 9ca8889..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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})
-
diff --git a/wradmin/wradmin/controllers/wrcontroller.py b/wradmin/wradmin/controllers/wrcontroller.py
new file mode 100644 (file)
index 0000000..5b0ab4a
--- /dev/null
@@ -0,0 +1,30 @@
+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')
diff --git a/wradmin/wradmin/lib/wrcachelists.py b/wradmin/wradmin/lib/wrcachelists.py
new file mode 100644 (file)
index 0000000..6075a65
--- /dev/null
@@ -0,0 +1,143 @@
+#!/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
index f455a2557aac993bf44153104947a1935a14f847..d27629b567de9950b97611433101eabd48f11d47 100644 (file)
@@ -3,12 +3,14 @@
 
 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
-
index a6a8e5486a063275805b1d1d1750d08de293eb01..6d5a5906854b184d3366030ae6d7c7b90a8ccd40 100644 (file)
@@ -15,14 +15,16 @@ h2 {
 }
 
 #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 {
@@ -31,6 +33,13 @@ h2 {
 
 #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;
@@ -46,26 +55,19 @@ h2 {
        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;
@@ -100,3 +102,7 @@ td + td {
 a {
        color: #014E9A;
 }
+
+#footer {
+       margin-top: 20px;
+}
\ No newline at end of file
diff --git a/wradmin/wradmin/templates/forumlink.html b/wradmin/wradmin/templates/forumlink.html
new file mode 100644 (file)
index 0000000..007de06
--- /dev/null
@@ -0,0 +1,24 @@
+<?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>
index e1c082b63f980e0f858246169909ea2a341dd95a..5dd8f8b238dd3a4d1c50fe1983da182752748152 100644 (file)
@@ -16,8 +16,8 @@
 <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>
index 0af5b279fb94927c78f62bb24dfbc5e0bbe5fa13..6510d1eeec75d4a926fd11530820c1b34245ad59 100644 (file)
 <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>
diff --git a/wradmin/wradmin/templates/rodelbahn.html b/wradmin/wradmin/templates/rodelbahn.html
deleted file mode 100644 (file)
index 6a4d26c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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>
diff --git a/wradmin/wradmin/templates/rodelbahnbox.html b/wradmin/wradmin/templates/rodelbahnbox.html
new file mode 100644 (file)
index 0000000..68eb06d
--- /dev/null
@@ -0,0 +1,75 @@
+<?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>