#!/usr/bin/python3.4
-# -*- coding: iso-8859-15 -*-
# $Id$
# $HeadURL$
"""
import re
from collections import OrderedDict, namedtuple
-import mwparserfromhell
+import mwparserfromhell # https://github.com/earwig/mwparserfromhell
-from wrpylib.mwmarkup import template_to_table
+from wrpylib.mwmarkup import format_template_table
# FromToConverter type
return value
-# dict converter
-# --------------
+# dictkey converter
+# -----------------
def dictkey_from_str(value, key_str_dict):
"""Returns the key of an entry in the key_str_dict if the value of the entry corresponds to the given value."""
def value_comment_from_str(value, value_from_str, comment_from_str, comment_optional=False):
"""Makes it possible to have a mandatory comment in parenthesis at the end of the string."""
- open_brackets = 0
comment = ''
- comment_end_pos = None
- for i, char in enumerate(value[::-1]):
- if char == ')':
- open_brackets += 1
- if open_brackets == 1:
- comment_end_pos = i
- if len(value[-1-comment_end_pos:].rstrip()) > 1:
- raise ValueError('invalid characters after comment')
- elif char == '(':
- open_brackets -= 1
- if open_brackets == 0:
- comment = value[-i:-1-comment_end_pos]
- value = value[:-i-1].rstrip()
- break
+ if value.endswith(')'):
+ open_brackets = 0
+ for i, char in enumerate(value[::-1]):
+ if char == ')':
+ open_brackets += 1
+ elif char == '(':
+ open_brackets -= 1
+ if open_brackets == 0:
+ comment = value[-i:-1]
+ value = value[:-i-1]
+ if len(value) > 1 and value[-1] != ' ':
+ raise ValueError('there has to be a space before the opening bracket of the comment')
+ value = value[:-1]
+ break
+ else:
+ if open_brackets > 0:
+ raise ValueError('bracket mismatch')
+ if not comment_optional:
+ raise ValueError('mandatory comment not found')
else:
- if open_brackets > 0:
- raise ValueError('bracket mismatch')
if not comment_optional:
- raise ValueError('mandatory comment not found')
+ raise ValueError('mandatory comment not found in "{}"'.format(value))
return value_from_str(value), comment_from_str(comment)
# -------------------------------
def opt_tristate_german_comment_from_str(value):
- """Ja, Nein or Vielleicht, optionally with comment in parenthesis."""
+ """Ja, Nein or Teilweise, optionally with comment in parenthesis."""
return value_comment_from_str(value, opt_tristate_german_from_str, opt_str_from_str, True)
# ---------------------
def webauskunft_from_str(value):
+ """Converts a URL or 'Nein' to a tuple
+ 'http://www.example.com/' -> (True, 'http://www.example.com/')
+ 'Nein' -> (False, None)
+ '' -> (None, None)
+
+ :param value: URL or 'Nein'
+ :return: tuple
+ """
return opt_no_german_from_str(value, url_from_str)
def wikipage_from_str(value):
"""Validates wiki page name like '[[Birgitzer Alm]]'.
- The page is not checked for existance.
+ The page is not checked for existence.
An empty string is an error.
'[[Birgitzer Alm]]' => '[[Birgitzer Alm]]'
"""
- if not value.startswith('[[') or not value.endswith(']]'):
+ if re.match(r'\[\[[^\[\]]+\]\]$', value) is None:
raise ValueError('No valid wiki page name "{}"'.format(value))
return value
return opt_no_german_to_str(value, lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, masked_email_to_str, opt_str_to_str, True)), False, [], None)
-emails_converter = FromToConverter(emails_from_str, email_to_str)
+emails_converter = FromToConverter(emails_from_str, emails_to_str)
# phone converter
def opt_phone_comment_enum_from_str(value, comment_optional=False):
- return opt_no_german_from_str(value, lambda val: enum_from_str(val, lambda v: value_comment_from_str(v, phone_number_from_str, req_str_from_str, comment_optional)), False, [], None)
+ return opt_no_german_from_str(value, lambda val: enum_from_str(val, lambda v: value_comment_from_str(v, phone_number_from_str, opt_str_from_str if comment_optional else req_str_from_str, comment_optional)), False, [], None)
def opt_phone_comment_enum_to_str(value, comment_optional=False):
- return opt_no_german_to_str(value, lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, phone_number_to_str, str_to_str, comment_optional)), False, [], None)
+ return opt_no_german_to_str(value, lambda val: enum_to_str(val, lambda v: value_comment_to_str(v, phone_number_to_str, opt_str_to_str if comment_optional else str_to_str, comment_optional)), False, [], None)
opt_phone_comment_enum_converter = FromToConverter(opt_phone_comment_enum_from_str, opt_phone_comment_enum_to_str)
# avalanches converter
# --------------------
-AVALANCHES_GERMAN = OrderedDict([(1, 'kaum'), (2, 'selten'), (3, 'gelegentlich'), (4, 'häufig')])
+AVALANCHES_GERMAN = OrderedDict([(1, 'kaum'), (2, 'selten'), (3, 'gelegentlich'), (4, 'häufig')])
def avalanches_german_from_str(value):
'' <=> None
'Nein' <=> []
'Sessellift <=> [('Sessellift', None)]
- 'Gondel (nur bis zur Hälfte)' <=> [('Gondel', 'nur bis zur Hälfte')]
+ 'Gondel (nur bis zur Hälfte)' <=> [('Gondel', 'nur bis zur Hälfte')]
'Sessellift; Taxi' <=> [('Sessellift', None), ('Taxi', None)]
'Sessellift (Wochenende); Taxi (6 Euro)' <=> [('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')]
"""
# public transport converter
# --------------------------
-PUBLIC_TRANSPORT_GERMAN = OrderedDict([(1, 'Sehr gut'), (2, 'Gut'), (3, 'Mittelmäßig'), (4, 'Schlecht'), (5, 'Nein'), (6, 'Ja')])
+PUBLIC_TRANSPORT_GERMAN = OrderedDict([(1, 'Sehr gut'), (2, 'Gut'), (3, 'Mittelmäßig'), (4, 'Schlecht'), (5, 'Nein'), (6, 'Ja')])
def public_transport_german_from_str(value):
# cachet converter
# ----------------
-CACHET_REGEXP = [r'(Tiroler Naturrodelbahn-Gütesiegel) ([12]\d{3}) (leicht|mittel|schwer)$']
+CACHET_REGEXP = [r'(Tiroler Naturrodelbahn-Gütesiegel) ([12]\d{3}) (leicht|mittel|schwer)$']
def single_cachet_german_from_str(value):
def cachet_german_from_str(value):
- """Converts a "Gütesiegel":
+ """Converts a "Gütesiegel":
'' => None
'Nein' => []
- 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel' => [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]"""
+ 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel' => [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]"""
return opt_no_german_from_str(value, lambda val: enum_from_str(val, single_cachet_german_from_str), False, [], None)
pass
-def wikibox_from_template(template, name, converter_dict):
- if template.name.strip() != name:
- raise ValueError('Box name has to be "{}"'.format(name))
+def wikibox_from_template(template, converter_dict):
+ """Returns an ordered dict."""
result = OrderedDict()
exceptions_dict = OrderedDict()
# check values
def template_from_str(value, name):
wikicode = mwparserfromhell.parse(value)
- template_list = wikicode.filter_templates(name)
- if len(name) == 0:
+ template_list = wikicode.filter_templates(recursive=False, matches=lambda t: t.name.strip() == name)
+ if len(template_list) == 0:
raise ValueError('No "{}" template was found'.format(name))
if len(template_list) > 1:
raise ValueError('{} "{}" templates were found'.format(len(template_list), name))
def wikibox_from_str(value, name, converter_dict):
template = template_from_str(value, name)
- return wikibox_from_template(template, name, converter_dict)
+ return wikibox_from_template(template, converter_dict)
def wikibox_to_str(value, name, converter_dict):
RODELBAHNBOX_DICT = OrderedDict([
('Position', opt_lonlat_converter), # '47.583333 N 15.75 E'
('Position oben', opt_lonlat_converter), # '47.583333 N 15.75 E'
- ('Höhe oben', opt_uint_converter), # '2000'
+ ('Höhe oben', opt_uint_converter), # '2000'
('Position unten', opt_lonlat_converter), # '47.583333 N 15.75 E'
- ('Höhe unten', opt_uint_converter), # '1200'
- ('Länge', opt_uint_converter), # 3500
+ ('Höhe unten', opt_uint_converter), # '1200'
+ ('Länge', opt_uint_converter), # 3500
('Schwierigkeit', opt_difficulty_german_converter), # 'mittel'
('Lawinen', opt_avalanches_german_converter), # 'kaum'
('Betreiber', opt_str_converter), # 'Max Mustermann'
- ('Öffentliche Anreise', opt_public_transport_german_converter), # 'Mittelmäßig'
- ('Aufstieg möglich', opt_bool_german_converter), # 'Ja'
+ ('Öffentliche Anreise', opt_public_transport_german_converter), # 'Mittelmäßig'
+ ('Aufstieg möglich', opt_bool_german_converter), # 'Ja'
('Aufstieg getrennt', opt_tristate_german_comment_converter), # 'Ja'
('Gehzeit', opt_uint_converter), # 90
('Aufstiegshilfe', lift_german_converter), # 'Gondel (unterer Teil)'
('Beleuchtungsanlage', opt_tristate_german_comment_converter),
('Beleuchtungstage', nightlightdays_converter), # '3 (Montag, Mittwoch, Freitag)'
('Rodelverleih', opt_str_opt_comment_enum_converter), # 'Talstation Serlesbahnan'
- ('Gütesiegel', cachet_german_converter), # 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'
- ('Webauskunft', webauskunft_converter), # 'http://www.nösslachhütte.at/page9.php'
+ ('Gütesiegel', cachet_german_converter), # 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'
+ ('Webauskunft', webauskunft_converter), # 'http://www.nösslachhütte.at/page9.php'
('Telefonauskunft', opt_phone_comment_enum_converter), # '+43-664-5487520 (Mitterer Alm)'
('Bild', opt_str_converter),
- ('In Übersichtskarte', opt_bool_german_converter),
+ ('In Übersichtskarte', opt_bool_german_converter),
('Forumid', opt_uint_converter)
])
def rodelbahnbox_from_template(template):
- return wikibox_from_template(template, RODELBAHNBOX_TEMPLATE_NAME, RODELBAHNBOX_DICT)
+ """Returns an ordered dict."""
+ return wikibox_from_template(template, RODELBAHNBOX_DICT)
def rodelbahnbox_to_template(value):
def rodelbahnbox_from_str(value):
+ """Returns an ordered dict."""
return wikibox_from_str(value, RODELBAHNBOX_TEMPLATE_NAME, RODELBAHNBOX_DICT)
def rodelbahnbox_to_str(value):
template = rodelbahnbox_to_template(value)
- template_to_table(template, 20)
+ format_template_table(template, 20)
return str(template)
GASTHAUSBOX_DICT = OrderedDict([
('Position', opt_lonlat_converter), # '47.583333 N 15.75 E'
- ('Höhe', opt_uint_converter),
+ ('Höhe', opt_uint_converter),
('Betreiber', opt_str_converter),
- ('Sitzplätze', opt_uint_converter),
- ('Übernachtung', opt_no_or_str_converter),
+ ('Sitzplätze', opt_uint_converter),
+ ('Übernachtung', opt_no_or_str_converter),
('Rauchfrei', opt_tristate_german_converter),
('Rodelverleih', opt_no_or_str_converter),
('Handyempfang', opt_str_opt_comment_enum_converter),
('Rodelbahnen', opt_wikipage_enum_converter)])
+def gasthausbox_from_template(template):
+ """Returns an ordered dict."""
+ return wikibox_from_template(template, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
+
+
+def gasthausbox_to_template(value):
+ return wikibox_to_template(value, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
+
+
+def gasthausbox_from_str(value):
+ """Returns an ordered dict."""
+ return wikibox_from_str(value, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
+
+
+def gasthausbox_to_str(value):
+ template = gasthausbox_to_template(value)
+ format_template_table(template, 17)
+ return str(template)
+
+
# Helper function to make page title pretty
# -----------------------------------------