import sqlalchemy as sa
import datetime
import formencode
+import wradmin.model.validators
log = logging.getLogger(__name__)
formencode.api.set_stdtranslation(domain="FormEncode", languages=["de"])
-class GermanDateTimeConverter(formencode.FancyValidator):
- def _to_python(self, value, state):
- "converts datetime strings like '2009-03-22 20:36'"
- self.assert_string(value, state)
- try: return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M')
- except ValueError, e: raise formencode.Invalid(str(e), value, state)
-
-
class RequireDateIfUserDefined(formencode.validators.FormValidator):
"requires that date_userdefined is not empty if date_invalid == 'userdefined'"
def _to_python(self, value_dict, state):
allow_extra_fields = True
filter_extra_fields = True
date_invalid = formencode.validators.OneOf(['no_change', 'tomorrow', 'one_week', 'two_weeks', 'one_week_more', 'end_of_saison', 'now', 'userdefined'], not_empty=True)
- date_userdefined = GermanDateTimeConverter
+ date_userdefined = wradmin.model.validators.DateTimeNoSecConverter
chained_validators = [RequireDateIfUserDefined()]
from wradmin.lib.base import BaseController, render
import wradmin.model as model
import sqlalchemy as sa
+import formencode
import re
from wradmin.lib.mediawiki import to_unsigned, to_date, to_geo, to_title, to_tristate, to_email, to_url, to_phone, conv, unicode_e
elif key == u'Telefon (Mobil)': inn.mobile_phone = conv(to_phone, value, u'Telefon (Mobil)')
elif key == u'Rauchfrei': (inn.nonsmoker_area, inn.smoker_area) = conv(to_tristate, value, u'Rauchfrei')
elif key == u'Aufnahmedatum': inn.creation_date = conv(to_date, value, u'Aufnahmedatum') # '2006-03-15'
- else: raise Exception(u"Unbekannte Eigenschaft der Gasthausbox: '%s' (mit Wert '%s')" % (key, value))
+ else: raise formencode.Invalid(u"Unbekannte Eigenschaft der Gasthausbox: '%s' (mit Wert '%s')" % (key, value), value, None)
inn.under_construction = None
return inn
inn = self._wikipage_to_wrinncache(inn)
inn.under_construction = c.execute(select([categorylinks], (categorylinks.c.cl_from==inn.page_id) & (categorylinks.c.cl_to == u'In_Arbeit')).alias('x').count()).fetchone()[0] > 0 # It would be better to do this in the query above
model.meta.Session.add(inn)
- except Exception, e: error_msg = u"Fehler bei Gasthaus '%s': " % inn.page_title + unicode_e(e)
+ except formencode.Invalid, e: error_msg = u"Fehler bei Gasthaus '%s': " % inn.page_title + unicode_e(e)
model.meta.Session.commit()
# Redirect to result page
elif key == u'Auskunft': sl.information = value
elif key == u'In Übersichtskarte': sl.show_in_overview = conv(to_bool, value, u'In Übersichtskarte')
elif key == u'Aufnahmedatum': sl.creation_date = conv(to_date, value, u'Aufnahmedatum') # '2006-03-15'
- else: raise Exception(u"Unbekannte Eigenschaft der Rodelbahnbox: '%s' (mit Wert '%s')" % (key, value))
+ else: raise formencode.Invalid(u"Unbekannte Eigenschaft der Rodelbahnbox: '%s' (mit Wert '%s')" % (key, value), value, None)
sl.under_construction = None
# Match Forumlink (e.g. {{Forumlink|68}})
sl = self._wikipage_to_wrsleddingcache(sl)
sl.under_construction = c.execute(select([categorylinks], (categorylinks.c.cl_from==sl.page_id) & (categorylinks.c.cl_to == u'In_Arbeit')).alias('x').count()).fetchone()[0] > 0 # It would be better to do this in the query above
model.meta.Session.add(sl)
- except Exception, e: error_msg = u"Fehler bei Rodelbahn '%s': " % sl.page_title + unicode_e(e)
+ except formencode.Invalid, e: error_msg = u"Fehler bei Rodelbahn '%s': " % sl.page_title + unicode_e(e)
model.meta.Session.commit()
# Redirect to result page
#from webhelpers.html.tags import checkbox, password
from routes import url_for
+import wradmin.model.validators
def wiki(page_title=None):
"Creates a link to the specified page in the www.winterrodeln.org wiki"
def bool(value):
"Takes a bool value and creates a German representation"
- if value is None: return None
- if value: return u'Ja'
- return u'Nein'
+ return wradmin.model.validators.GermanBool().from_python(value)
def tristate(yes, no):
"Takes a German representation of a tristate value"
- if yes is None or no is None: return None
- if yes == no: return u'Teilweise'
- if yes: return u'Ja'
- if no: return u'Nein'
+ return wradmin.model.validators.GermanTristate().from_python((yes, no))
from authkit.users import UsersReadOnly, md5
import datetime
-import re
import wradmin.model as model
+import wradmin.model.validators
+import formencode, formencode.national
import logging
log = logging.getLogger(__name__)
# -------------------
def to_bool(value):
- if not value: return None
- if value == u'Ja': return True
- if value == u'Nein': return False
- raise Exception(u"'%s' is not a valid boolean value, use one of 'Ja' or 'Nein'" % value)
+ return model.validators.GermanBool().to_python(value)
def to_unsigned(value):
- if value is None or value == u'': return None
- v = int(value)
- if v < 0: raise Exception('The value %v has to be positive.')
- return v
+ "Requires a positive number"
+ return formencode.validators.Int(min=0).to_python(value)
def to_date(value):
"Parses a date in the form 'yyy-mm-dd'"
- if value is None: return None
- return datetime.datetime.strptime(value, '%Y-%m-%d')
+ return model.validators.DateConverter().to_python(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(u'(\d+\.\d+) N (\d+\.\d+) E', value)
- if r is None: raise Exception(u"Coordinates '%s' have not a format like '47.076207 N 11.453553 E'" % value)
- return (float(r.groups()[0]), float(r.groups()[1]))
+ return model.validators.Geo().to_python(value)
def to_title(value):
u'Ja' -> (True, False)
u'Teilweise' -> (True, True)
u'Nein' -> (False, True)"""
- if value is None: return (None, None)
- elif value == u'Ja': return (True, False)
- elif value == u'Nein': return (False, True)
- elif value == u'Teilweise': return (True, True)
- raise Exception(u"The value has to be one of 'Ja', 'Nein' or 'Teilweise', not '%s'" % value)
+ return model.validators.GermanTristate().to_python(value)
def to_email(value):
- return value #!!!! TODO
+ return formencode.validators.Email().to_python(value)
def to_url(value):
- return value #!!!! TODO
+ return formencode.validators.URL().to_python(value)
def to_phone(value):
- return value #!!!! TODO
+ # return formencode.national.InternationalPhoneNumber(default_cc=43, messages={'phoneFormat': u"Telefonnummer muss das Format 0123/456789 oder +43/123/456789 haben"}).to_python(value)
+ return value # I should write my own PhoneNumber check.
def conv(fnct, value, fieldname):
"Like one of the to_xxx functions (e.g. to_bool), but adds the field name to the error message"
try: return fnct(value)
- except Exception, e: raise Exception(u"Conversion error in field '%s': %s" % (fieldname, unicode_e(e)))
+ except formencode.Invalid, e: raise formencode.Invalid(u"Conversion error in field '%s': %s" % (fieldname, unicode_e(e)), e.value, e.state)
def unicode_e(exception):
--- /dev/null
+# -*- coding: iso-8859-15 -*-
+
+import formencode
+import datetime
+import re
+
+
+class GermanBool(formencode.FancyValidator):
+ "Converts German bool values to the python bool type. 'Ja' and 'Nein' are supported."
+
+ def __init__(self, yes = [u'Ja'], no = [u'Nein'], **keywords):
+ "The yes and no arguments specify the valid possibilities. The first possibility is the default one."
+ formencode.FancyValidator.__init__(self, **keywords)
+ self.yes = yes
+ self.no = no
+
+ def _to_python(self, value, state):
+ self.assert_string(value, state)
+ if value in self.yes: return True
+ if value in self.no: return False
+ all = self.yes[:]
+ all.extend(self.no)
+ raise formencode.Invalid(u"'%s' is not a valid boolean value, use one of %s" % (value, all), value, state)
+
+ def from_python(self, value):
+ if value is None: return u''
+ if value: return self.yes[0]
+ return self.no[0]
+
+
+class GenericDateTimeConverter(formencode.FancyValidator):
+ """Converts generic date/time information to datetime classes with a user defined format.
+ '2009-03-22 20:36:15' would be specified as '%Y-%m-%d %H:%M:%S'."""
+
+ def __init__(self, date_time_format = '%Y-%m-%d %H:%M:%S', **keywords):
+ formencode.FancyValidator.__init__(self, **keywords)
+ self.date_time_format = date_time_format
+
+ def _to_python(self, value, state):
+ self.assert_string(value, state)
+ try: return datetime.datetime.strptime(value, self.date_time_format)
+ except ValueError, e: raise formencode.Invalid(str(e), value, state)
+
+ def _from_python(self, value, state):
+ if value is None: return u''
+ return value.strftime(self.date_time_format)
+
+
+class DateTimeNoSecConverter(GenericDateTimeConverter):
+ def __init__(self, **keywords):
+ GenericDateTimeConverter.__init__(self, '%Y-%m-%d %H:%M', **keywords)
+
+
+class DateConverter(GenericDateTimeConverter):
+ "Converts date information to date classes with the format '%Y-%m-%d'."
+
+ def __init__(self, **keywords):
+ GenericDateTimeConverter.__init__(self, '%Y-%m-%d', **keywords)
+
+ def _to_python(self, value, state):
+ GenericDateTimeConverter._to_python(self, value, state).date()
+
+
+class GermanTristate(formencode.FancyValidator):
+ """Does the following conversion:
+ None -> (None, None)
+ u'Ja' -> (True, False)
+ u'Teilweise' -> (True, True)
+ u'Nein' -> (False, True)"""
+
+ def __init__(self, yes_python = (True, False), no_python = (False, True), partly_python = (True, True), yes_text = [u'Ja'], no_text = [u'Nein'], partly_text = [u'Teilweise'], **keywords):
+ formencode.FancyValidator.__init__(self, if_empty = (None, None), **keywords)
+ self.yes_python = yes_python
+ self.no_python = no_python
+ self.partly_python = partly_python
+ self.yes_text = yes_text
+ self.no_text = no_text
+ self.partly_text = partly_text
+
+ def _to_python(self, value, state):
+ self.assert_string(value, state)
+ if value in self.yes_text: return self.yes_python
+ if value in self.no_text: return self.no_python
+ if value in self.partly_text: return self.partly_python
+ all = self.yes_text[:]
+ all.extend(self.no_text)
+ all.extend(self.partly_text)
+ raise formencode.Invalid(u"'%s' is not a valid value, use one of %s" % (value, all), value, state)
+
+ def _from_python(self, value, state):
+ if value == (None, None): return ''
+ if value == self.yes_python: return self.yes_text[0]
+ if value == self.no_python: return self.no_text[0]
+ if value == self.partly_python: return self.partly_text[0]
+ raise formencode.Invalid(u"Invalid representation of a tristate value: '%s'" % (value,), value, state)
+
+
+class Geo(formencode.FancyValidator):
+ "Formats to coordinates '47.076207 N 11.453553 E' to the (latitude, longitude) tuplet."
+
+ def __init__(self, **keywords):
+ formencode.FancyValidator.__init__(self, if_empty = (None, None), **keywords)
+
+ def _to_python(self, value, state):
+ r = re.match(u'(\d+\.\d+) N (\d+\.\d+) E', value)
+ if r is None: raise formencode.Invalid(u"Coordinates '%s' have not a format like '47.076207 N 11.453553 E'" % value, value, state)
+ return (float(r.groups()[0]), float(r.groups()[1]))
+
+ def _from_python(self, value, state):
+ if value == (None, None): return ''
+ latitude, longitude = value
+ return u'%.6f N %.6f E' % (latitude, longitude)
+import wradmin.model.validators
+import formencode
+
+def test_bool_validator():
+ v = wradmin.model.validators.GermanBool()
+ assert v.to_python(u'Ja') == True
+ assert v.to_python(u'Nein') == False
+ assert v.to_python(None) == None
+ assert v.to_python(u'') == None
+ try:
+ v.to_python(u'Wrong')
+ assert True, u"The value 'Wrong' must not be accepted by the validator."
+ except formencode.Invalid: pass
+
+ assert v.from_python(True) == u'Ja'
+ assert v.from_python(False) == u'Nein'
+ assert v.from_python(None) == u''
+
+
+def test_GermanTristate_validator():
+ v = wradmin.model.validators.GermanTristate()
+ assert v.to_python(u'Ja') == (True, False)
+ assert v.to_python(u'Nein') == (False, True)
+ assert v.to_python(u'Teilweise') == (True, True)
+ assert v.to_python(u'') == (None, None)
+ assert v.to_python(None) == (None, None)
+ try:
+ v.to_python(u'Wrong')
+ assert True, u"The value 'Wrong' must not be accepted by the validator."
+ except formencode.Invalid: pass
+
+ assert v.from_python((True, False)) == u'Ja'
+ assert v.from_python((False, True)) == u'Nein'
+ assert v.from_python((True, True)) == u'Teilweise'
+ assert v.from_python((None, None)) == u''
+
+
+def test_geo():
+ coord = u'47.076207 N 11.453553 E'
+ v = wradmin.model.validators.Geo()
+ (lat, lon) = v.to_python(coord)
+ assert lat == 47.076207
+ assert lon == 11.453553
+ assert v.to_python(u'') == (None, None)
+
+ assert v.from_python((lat, lon)) == coord
+ assert v.from_python((None, None)) == u''
+