]> ToastFreeware Gitweb - philipp/winterrodeln/wrpylib.git/blobdiff - wrpylib/wrvalidators.py
Parse cachet.
[philipp/winterrodeln/wrpylib.git] / wrpylib / wrvalidators.py
index 48bc6b3cdabfe1fdab36e854153218ee8506987a..3b0ae5f84156d130f0ba4aa916a44ebf85e7c9c4 100644 (file)
@@ -12,9 +12,10 @@ import urllib.parse
 import re
 from collections import OrderedDict, namedtuple
 from email.errors import HeaderParseError
-from typing import Tuple, Optional, List, Any, Callable, Union, TypeVar, Dict
+from typing import Tuple, Optional, List, Callable, Union, TypeVar, Dict, NamedTuple
 
 import mwparserfromhell  # https://github.com/earwig/mwparserfromhell
+from mwparserfromhell.nodes import Template
 
 from wrpylib.mwmarkup import format_template_table
 
@@ -384,7 +385,7 @@ def wikipage_from_str(value: str) -> str:
     '[[Birgitzer Alm]]' => '[[Birgitzer Alm]]'
     """
     if re.match(r'\[\[[^\[\]]+]]$', value) is None:
-        raise ValueError('No valid wiki page name "{}"'.format(value))
+        raise ValueError(f'No valid wiki page name "{value}"')
     return value
 
 
@@ -417,7 +418,7 @@ def email_from_str(value: str) -> str:
     try:
         email.headerregistry.Address(addr_spec=value)
     except HeaderParseError as e:
-        raise ValueError('Invalid email address: {}'.format(value), e)
+        raise ValueError(f'Invalid email address: {value}', e)
     return value
 
 
@@ -438,11 +439,11 @@ def masked_email_from_str(value: str, mask='(at)', masked_only=False) -> Tuple[s
 def masked_email_to_str(value: Tuple[str, bool], mask='(at)') -> str:
     """Value is a tuple. The first entry is the email address, the second one is a boolean telling whether the
     email address should be masked."""
-    email, do_masking = value
-    email = email_to_str(email)
+    email_, do_masking = value
+    email_ = email_to_str(email_)
     if do_masking:
-        email = email.replace('@', mask)
-    return email
+        email_ = email_.replace('@', mask)
+    return email_
 
 
 def emails_from_str(value: str) -> Optional[List[Tuple[str, str]]]:
@@ -511,30 +512,30 @@ opt_phone_comment_opt_enum_converter = FromToConverter(lambda value: opt_phone_c
 # longitude/latitude converter
 # ----------------------------
 
-LonLat = namedtuple('LonLat', ['lon', 'lat'])
-
-
-lonlat_none = LonLat(None, None)
+class LonLat(NamedTuple):
+    lon: float
+    lat: float
 
 
 def lonlat_from_str(value: str) -> LonLat:
     """Converts a Winterrodeln geo string like '47.076207 N 11.453553 E' (being '<latitude> N <longitude> E'
     to the LonLat(lon, lat) named  tuple."""
     r = re.match(r'(\d+\.\d+) N (\d+\.\d+) E', value)
-    if r is None: raise ValueError("Coordinates '{}' have not a format like '47.076207 N 11.453553 E'".format(value))
+    if r is None:
+        raise ValueError(f"Coordinates '{value}' have not a format like '47.076207 N 11.453553 E'")
     return LonLat(float(r.groups()[1]), float(r.groups()[0]))
 
 
 def lonlat_to_str(value: LonLat) -> str:
-    return '{:.6f} N {:.6f} E'.format(value.lat, value.lon)
+    return f'{value.lat:.6f} N {value.lon:.6f} E'
 
 
-def opt_lonlat_from_str(value: str) -> LonLat:
-    return opt_from_str(value, lonlat_from_str, lonlat_none)
+def opt_lonlat_from_str(value: str) -> Optional[LonLat]:
+    return opt_from_str(value, lonlat_from_str, None)
 
 
-def opt_lonlat_to_str(value: LonLat) -> str:
-    return opt_to_str(value, lonlat_to_str, lonlat_none)
+def opt_lonlat_to_str(value: Optional[LonLat]) -> str:
+    return opt_to_str(value, lonlat_to_str, None)
 
 
 opt_lonlat_converter = FromToConverter(opt_lonlat_from_str, opt_lonlat_to_str)
@@ -683,9 +684,9 @@ CACHET_REGEXP = [r'(Tiroler Naturrodelbahn-Gütesiegel) ([12]\d{3}) (leicht|mitt
 
 def single_cachet_german_from_str(value: str) -> Tuple[str, str, str]:
     for pattern in CACHET_REGEXP:
-        match = re.match(pattern, value)
-        if match:
-            return match.groups()
+        match_ = re.match(pattern, value)
+        if match_:
+            return match_.groups()
     raise ValueError(f"'{value}' is no valid cachet")
 
 
@@ -693,7 +694,7 @@ def single_cachet_german_to_str(value: Tuple[str, str, str]) -> str:
     return ' '.join(value)
 
 
-def cachet_german_from_str(value):
+def cachet_german_from_str(value) -> Optional[List[Tuple[str, str, str]]]:
     """Converts a "Gütesiegel":
     '' => None
     'Nein' => []
@@ -763,7 +764,7 @@ class ValueErrorList(ValueError):
     pass
 
 
-def wikibox_from_template(template, converter_dict):
+def wikibox_from_template(template: Template, converter_dict: dict) -> dict:
     """Returns an ordered dict."""
     result = OrderedDict()
     exceptions_dict = OrderedDict()
@@ -771,42 +772,43 @@ def wikibox_from_template(template, converter_dict):
     for key, converter in converter_dict.items():
         try:
             if not template.has(key):
-                raise ValueError('Missing parameter "{}"'.format(key))
+                raise ValueError(f'Missing parameter "{key}"')
             result[key] = converter.from_str(str(template.get(key).value.strip()))
         except ValueError as e:
             exceptions_dict[key] = e
     # check if keys are superfluous
     superfluous_keys = {str(p.name.strip()) for p in template.params} - set(converter_dict.keys())
     for key in superfluous_keys:
-        exceptions_dict[key] = ValueError('Superfluous parameter: "{}"'.format(key))
+        exceptions_dict[key] = ValueError(f'Superfluous parameter: "{key}"')
     if len(exceptions_dict) > 0:
-        raise ValueErrorList('{} error(s) occurred when parsing template parameters.'.format(len(exceptions_dict)), exceptions_dict)
+        raise ValueErrorList(f'{len(exceptions_dict)} error(s) occurred when parsing template parameters.',
+                             exceptions_dict)
     return result
 
 
-def wikibox_to_template(value, name, converter_dict):
-    template = mwparserfromhell.nodes.template.Template(name)
+def wikibox_to_template(value: dict, name: str, converter_dict: dict) -> Template:
+    template = Template(name)
     for key, converter in converter_dict.items():
         template.add(key, converter.to_str(value[key]))
     return template
 
 
-def template_from_str(value, name):
+def template_from_str(value: str, name: str) -> Template:
     wikicode = mwparserfromhell.parse(value)
     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))
+        raise ValueError(f'No "{name}" template was found')
     if len(template_list) > 1:
-        raise ValueError('{} "{}" templates were found'.format(len(template_list), name))
+        raise ValueError(f'{len(template_list)} "{name}" templates were found')
     return template_list[0]
 
 
-def wikibox_from_str(value, name, converter_dict):
+def wikibox_from_str(value: str, name: str, converter_dict: dict) -> dict:
     template = template_from_str(value, name)
     return wikibox_from_template(template, converter_dict)
 
 
-def wikibox_to_str(value, name, converter_dict):
+def wikibox_to_str(value: dict, name: str, converter_dict: dict) -> str:
     return str(wikibox_to_template(value, name, converter_dict))
 
 
@@ -825,7 +827,7 @@ RODELBAHNBOX_DICT = OrderedDict([
     ('Länge', opt_uint_converter),  # 3500
     ('Schwierigkeit', opt_difficulty_german_converter),  # 'mittel'
     ('Lawinen', opt_avalanches_german_converter),  # 'kaum'
-    ('Betreiber', opt_str_converter),  # 'Max Mustermann'
+    ('Betreiber', opt_no_or_str_converter),  # 'Max Mustermann'
     ('Ö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'
@@ -843,21 +845,21 @@ RODELBAHNBOX_DICT = OrderedDict([
 ])
 
 
-def rodelbahnbox_from_template(template):
+def rodelbahnbox_from_template(template: Template) -> dict:
     """Returns an ordered dict."""
     return wikibox_from_template(template, RODELBAHNBOX_DICT)
 
 
-def rodelbahnbox_to_template(value):
+def rodelbahnbox_to_template(value: dict) -> Template:
     return wikibox_to_template(value, RODELBAHNBOX_TEMPLATE_NAME, RODELBAHNBOX_DICT)
 
 
-def rodelbahnbox_from_str(value):
+def rodelbahnbox_from_str(value: str) -> Dict:
     """Returns an ordered dict."""
     return wikibox_from_str(value, RODELBAHNBOX_TEMPLATE_NAME, RODELBAHNBOX_DICT)
 
 
-def rodelbahnbox_to_str(value):
+def rodelbahnbox_to_str(value: Dict) -> str:
     template = rodelbahnbox_to_template(value)
     format_template_table(template, 20)
     return str(template)
@@ -870,7 +872,7 @@ GASTHAUSBOX_TEMPLATE_NAME = 'Gasthausbox'
 
 
 GASTHAUSBOX_DICT = OrderedDict([
-    ('Position', opt_lonlat_converter), # '47.583333 N 15.75 E'
+    ('Position', opt_lonlat_converter),  # '47.583333 N 15.75 E'
     ('Höhe', opt_uint_converter),
     ('Betreiber', opt_str_converter),
     ('Sitzplätze', opt_uint_converter),
@@ -885,21 +887,21 @@ GASTHAUSBOX_DICT = OrderedDict([
     ('Rodelbahnen', opt_wikipage_enum_converter)])
 
 
-def gasthausbox_from_template(template):
+def gasthausbox_from_template(template: Template) -> dict:
     """Returns an ordered dict."""
     return wikibox_from_template(template, GASTHAUSBOX_DICT)
 
 
-def gasthausbox_to_template(value):
+def gasthausbox_to_template(value: dict) -> Template:
     return wikibox_to_template(value, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
 
 
-def gasthausbox_from_str(value):
+def gasthausbox_from_str(value: str) -> dict:
     """Returns an ordered dict."""
     return wikibox_from_str(value, GASTHAUSBOX_TEMPLATE_NAME, GASTHAUSBOX_DICT)
 
 
-def gasthausbox_to_str(value):
+def gasthausbox_to_str(value: dict) -> str:
     template = gasthausbox_to_template(value)
     format_template_table(template, 17)
     return str(template)
@@ -908,7 +910,7 @@ def gasthausbox_to_str(value):
 # Helper function to make page title pretty
 # -----------------------------------------
 
-def sledrun_page_title_to_pretty_url(page_title):
+def sledrun_page_title_to_pretty_url(page_title: str) -> str:
     """Converts a page_title from the page_title column of wrsledruncache to name_url.
     name_url is not used by MediaWiki but by new applications like wrweb."""
     return page_title.lower().replace(' ', '-').replace('_', '-').replace('(', '').replace(')', '')