Converted encoding to UTF-8.
[philipp/winterrodeln/wrpylib.git] / wrpylib / wrvalidators.py
index 61a961d01980288609583495398bd05651437bce..127b5132fb50f111d72b2276c7f1075f2cd152fe 100644 (file)
@@ -1,5 +1,4 @@
 #!/usr/bin/python3.4
-# -*- coding: iso-8859-15 -*-
 # $Id$
 # $HeadURL$
 """
@@ -16,9 +15,9 @@ import urllib.parse
 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
@@ -86,8 +85,8 @@ def choice_from_str(value, choices):
     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."""
@@ -126,27 +125,29 @@ def enum_to_str(value, to_str, separator='; '):
 
 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)
 
 
@@ -514,7 +515,7 @@ opt_difficulty_german_converter = FromToConverter(opt_difficulty_german_from_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):
@@ -557,7 +558,7 @@ def lift_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')]
     """
@@ -574,7 +575,7 @@ lift_german_converter = FromToConverter(lift_german_from_str, lift_german_to_str
 # 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):
@@ -599,7 +600,7 @@ opt_public_transport_german_converter = FromToConverter(opt_public_transport_ger
 # 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):
@@ -615,10 +616,10 @@ def single_cachet_german_to_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)
 
 
@@ -668,9 +669,8 @@ class ValueErrorList(ValueError):
     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
@@ -699,8 +699,8 @@ def wikibox_to_template(value, name, converter_dict):
 
 def template_from_str(value, name):
     wikicode = mwparserfromhell.parse(value)
-    template_list = wikicode.filter_templates(name)
-    if len(name) == 0:
+    template_list = [template for template in wikicode.filter_templates(name) if template.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))
@@ -709,7 +709,7 @@ def template_from_str(value, 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):
@@ -725,32 +725,33 @@ RODELBAHNBOX_TEMPLATE_NAME = 'Rodelbahnbox'
 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):
@@ -758,12 +759,13 @@ 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)
 
 
@@ -775,10 +777,10 @@ GASTHAUSBOX_TEMPLATE_NAME = 'Gasthausbox'
 
 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),
@@ -790,6 +792,7 @@ GASTHAUSBOX_DICT = OrderedDict([
 
 
 def gasthausbox_from_template(template):
+    """Returns an ordered dict."""
     return wikibox_from_template(template, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
 
 
@@ -798,12 +801,13 @@ def gasthausbox_to_template(value):
 
 
 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)
-    template_to_table(template, 17)
+    format_template_table(template, 17)
     return str(template)