Added GasthausboxValidator.
[philipp/winterrodeln/wrpylib.git] / wrpylib / wrvalidators.py
index 2b43cab87897505f2f022b2b60d2e12718ed3f4b..fc432d13af9905c2b00be9ecac2c496224d4f7b2 100644 (file)
@@ -10,10 +10,61 @@ import datetime
 import re
 import xml.dom.minidom as minidom
 from xml.parsers.expat import ExpatError
+import collections
 import formencode
 import formencode.national
 
 
+class OrderedSchema(formencode.Schema):
+    def _convert_to_python(self, value, state):
+        pre_validators = self.pre_validators
+        chained_validators = self.chained_validators
+        for validator in pre_validators:
+            value = validator.to_python(value, state)
+        self.pre_validators = []
+        self.chained_validators = []
+        try:
+            result = formencode.Schema._convert_to_python(self, value, state)
+            ordered_result = collections.OrderedDict()
+            for key in value.iterkeys():
+                ordered_result[key] = result[key]
+            for validator in chained_validators:
+                ordered_result = validator.to_python(ordered_result, state)
+        finally:
+            self.pre_validators = pre_validators
+            self.chained_validators = chained_validators
+        return ordered_result
+
+    def _convert_from_python(self, value, state):
+        # store original pre- and chained validators
+        pre_validators = self.pre_validators
+        chained_validators = self.chained_validators[:]
+        # apply chained validators
+        chained = chained_validators[:]
+        chained.reverse()
+        for validator in chained:
+            value = validator.from_python(value, state)
+        # tempoarly remove pre- and chained validators
+        self.pre_validators = []
+        self.chained_validators = []
+        # apply original _convert_from_python method
+        try:
+            result = formencode.Schema._convert_from_python(self, value, state)
+            ordered_result = collections.OrderedDict()
+            for key in value.iterkeys():
+                ordered_result[key] = result[key]
+            # apply pre_validators
+            pre = pre_validators[:]
+            pre.reverse()
+            for validator in pre:
+                ordered_result = validator.from_python(ordered_result, state)
+        finally:
+            # resore original pre- and chained_validators
+            self.pre_validators = pre_validators
+            self.chained_validators = chained_validators
+        return ordered_result
+
+
 class NoneValidator(formencode.FancyValidator):
     """Takes a validator and makes it possible that empty strings are mapped to None."""
     def __init__(self, validator, python_none=None):
@@ -747,7 +798,7 @@ class SledRental(BoolUnicodeTupleValidator):
         BoolUnicodeTupleValidator.__init__(self, Loop(ValueCommentList()))
 
 
-class RodelbahnboxValidator(formencode.Schema):
+class RodelbahnboxDictValidator(OrderedSchema):
     """Takes the fields of the Rodelbahnbox as dict of strings and returns them as dict of appropriet types."""
     def __init__(self):
         self.add_field(u'Position', GeoNone()) # '47.583333 N 15.75 E'
@@ -773,3 +824,21 @@ class RodelbahnboxValidator(formencode.Schema):
         self.add_field(u'Bild', UnicodeNone())
         self.add_field(u'In Übersichtskarte', GermanBoolNone())
         self.add_field(u'Forumid', UnsignedNeinNone())
+
+
+class GasthausboxDictValidator(OrderedSchema):
+    """Takes the fields of the Gasthausbox as dict of strings and returns them as dict of appropriet types."""
+    def __init__(self):
+        self.add_field(u'Position', GeoNone()) # '47.583333 N 15.75 E'
+        self.add_field(u'Höhe', UnsignedNone())
+        self.add_field(u'Betreiber', UnicodeNone())
+        self.add_field(u'Sitzplätze', UnsignedNone())
+        self.add_field(u'Übernachtung', BoolUnicodeTupleValidator())
+        self.add_field(u'Rauchfrei', GermanTristateTuple())
+        self.add_field(u'Rodelverleih', BoolUnicodeTupleValidator())
+        self.add_field(u'Handyempfang', ValueCommentListNeinLoopNone())
+        self.add_field(u'Homepage', UrlNeinNone())
+        self.add_field(u'E-Mail', EmailCommentListNeinLoopNone(allow_masked_email=True))
+        self.add_field(u'Telefon', PhoneCommentListNeinLoopNone(comments_are_optional=True))
+        self.add_field(u'Bild', UnicodeNone())
+        self.add_field(u'Rodelbahnen', WikiPageListLoopNone())