X-Git-Url: https://git.toastfreeware.priv.at/philipp/winterrodeln/wrpylib.git/blobdiff_plain/bc75d77de7226fefdce6130eb5694e087d8dcda0..89ce18f172baf648a6aec45910419a12d26e99ef:/wrpylib/wrvalidators.py diff --git a/wrpylib/wrvalidators.py b/wrpylib/wrvalidators.py index cbfac19..d721da0 100644 --- a/wrpylib/wrvalidators.py +++ b/wrpylib/wrvalidators.py @@ -1,15 +1,17 @@ -#!/usr/bin/python2.6 +#!/usr/bin/python2.7 # -*- coding: iso-8859-15 -*- +# $Id$ +# $HeadURL$ """This file contains "validators" that convert between string and python (database) representation of properties used in the "Rodelbahnbox" and "Gasthausbox". The "to_python" method has to get a unicode argument. """ -import formencode -import formencode.national import datetime import re import xml.dom.minidom as minidom from xml.parsers.expat import ExpatError +import formencode +import formencode.national class NoneValidator(formencode.FancyValidator): @@ -124,7 +126,7 @@ class Loop(formencode.FancyValidator): def from_python(self, value): # we don't call self.validator.to_python(self.validator.from_python(value)) - # here because our to_python implementation basically leaves the input untouches + # here because our to_python implementation basically leaves the input untouched # and so should from_python do. return self.validator.from_python(self.validator.to_python(value)) @@ -147,7 +149,8 @@ class DictValidator(formencode.FancyValidator): def from_python(self, value): for k, v in self.dict.iteritems(): - if type(v) == type(value) and v == value: return k + if v == value: + return k raise formencode.Invalid('Invalid value', value, None) @@ -183,10 +186,14 @@ class GermanTristateFloat(GermanTristateTuple): class ValueComment(formencode.FancyValidator): - """Converts value with a potentially optional comment to a python tuple: - u'' <=> (None, None) - u'value' <=> (u'value', None) - u'value (comment)' <=> (u'value', u'comment')""" + """Converts value with a potentially optional comment to a python tuple. If a comment is present, the + closing bracket has to be the rightmost character. + u'' <=> (None, None) + u'value' <=> (u'value', None) + u'value (comment)' <=> (u'value', u'comment') + u'[[link (linkcomment)]]' <=> (u'[[link (linkcomment)]]', None) + u'[[link (linkcomment)]] (comment)' <=> (u'[[link (linkcomment)]]', comment) + """ def __init__(self, value_validator=UnicodeNone(), comment_validator=UnicodeNone(), comment_is_optional=True): self.value_validator = value_validator self.comment_validator = comment_validator @@ -198,16 +205,16 @@ class ValueComment(formencode.FancyValidator): v = value c = value else: - left = value.find('(') right = value.rfind(')') - if left < 0 and right < 0: + if right+1 != len(value): if not self.comment_is_optional: raise formencode.Invalid(u'Mandatory comment not present', value, None) v = value c = u'' - elif left >= 0 and right >= 0 and left < right: + else: + left = value.rfind('(') + if left < 0: raise formencode.Invalid(u'Invalid format', value, None) v = value[:left].strip() c = value[left+1:right].strip() - else: raise formencode.Invalid(u'Invalid format', value, None) return self.value_validator.to_python(v), self.comment_validator.to_python(c) def from_python(self, value): @@ -592,6 +599,38 @@ class PhoneCommentListNeinLoopNone(NoneValidator): NoneValidator.__init__(self, NeinValidator(Loop(ValueCommentList(PhoneNumber(default_cc=43), comments_are_optional=comments_are_optional)))) +class MaskedEmail(formencode.FancyValidator): + """A masked email address as defined here is an email address that has the `@` character replacted by the text `(at)`. + So instead of `abd.def@example.com` it would be `abc.def(at)example.com`. + This validator takes either a normal or a masked email address in it's to_python method and returns the normal email address as well + as a bool indicating whether the email address was masked. + u'' <=> (None, None) + u'abc.def@example.com' <=> (u'abc.def@example.com', False) + u'abc.def(at)example.com' <=> (u'abc.def@example.com', True) + + """ + def __init__(self, *args, **kw): + if not kw.has_key('strip'): kw['strip'] = True + if not kw.has_key('not_empty'): kw['not_empty'] = False + if not kw.has_key('if_empty'): kw['if_empty'] = (None, None) + self.at = '(at)' + formencode.FancyValidator.__init__(self, *args, **kw) + + def _to_python(self, value, state): + email = value.replace(self.at, '@') + masked = value != email + val_email = formencode.validators.Email() + return val_email.to_python(email), masked + + def _from_python(self, value, state): + email, masked = value + if email is None: return u'' + val_email = formencode.validators.Email() + email = val_email.from_python(email) + if masked: email = email.replace('@', self.at) + return email + + class EmailCommentListNeinLoopNone(NoneValidator): """Converts a semicolon-separated list of email addresses with optional comments to itself. The special value of u'Nein' indicates that there are no email addresses. @@ -600,9 +639,12 @@ class EmailCommentListNeinLoopNone(NoneValidator): u'Nein' <=> u'Nein' u'first@example.com' <=> u'first@example.com' u'first@example.com (Nur Winter); second@example.com' <=> u'first@example.com (Nur Winter); second@example.com' + + If the parameter allow_masked_email is true, the following gives no error: + u'abc.def(at)example.com (comment)' <=> u'abc.def(at)example.com (comment)' """ - def __init__(self): - NoneValidator.__init__(self, NeinValidator(Loop(ValueCommentList(formencode.validators.Email())))) + def __init__(self, allow_masked_email=False): + NoneValidator.__init__(self, NeinValidator(Loop(ValueCommentList(MaskedEmail() if allow_masked_email else formencode.validators.Email())))) class WikiPage(formencode.FancyValidator):