4 from google
.appengine
._internal
.django
.core
.exceptions
import ValidationError
5 from google
.appengine
._internal
.django
.utils
.translation
import ugettext_lazy
as _
6 from google
.appengine
._internal
.django
.utils
.encoding
import smart_unicode
8 # These values, if given to validate(), will trigger the self.required check.
9 EMPTY_VALUES
= (None, '', [], (), {})
12 from google
.appengine
._internal
.django
.conf
import settings
13 URL_VALIDATOR_USER_AGENT
= settings
.URL_VALIDATOR_USER_AGENT
15 # It's OK if Django settings aren't configured.
16 URL_VALIDATOR_USER_AGENT
= 'Django (http://www.djangoproject.com/)'
18 class RegexValidator(object):
20 message
= _(u
'Enter a valid value.')
23 def __init__(self
, regex
=None, message
=None, code
=None):
26 if message
is not None:
27 self
.message
= message
31 if isinstance(self
.regex
, basestring
):
32 self
.regex
= re
.compile(regex
)
34 def __call__(self
, value
):
36 Validates that the input matches the regular expression.
38 if not self
.regex
.search(smart_unicode(value
)):
39 raise ValidationError(self
.message
, code
=self
.code
)
41 class URLValidator(RegexValidator
):
43 r
'^https?://' # http:// or https://
44 r
'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' #domain...
45 r
'localhost|' #localhost...
46 r
'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
47 r
'(?::\d+)?' # optional port
48 r
'(?:/?|[/?]\S+)$', re
.IGNORECASE
)
50 def __init__(self
, verify_exists
=False, validator_user_agent
=URL_VALIDATOR_USER_AGENT
):
51 super(URLValidator
, self
).__init
__()
52 self
.verify_exists
= verify_exists
53 self
.user_agent
= validator_user_agent
55 def __call__(self
, value
):
57 super(URLValidator
, self
).__call
__(value
)
58 except ValidationError
, e
:
59 # Trivial case failed. Try for possible IDN domain
61 value
= smart_unicode(value
)
62 scheme
, netloc
, path
, query
, fragment
= urlparse
.urlsplit(value
)
64 netloc
= netloc
.encode('idna') # IDN -> ACE
65 except UnicodeError: # invalid domain part
67 url
= urlparse
.urlunsplit((scheme
, netloc
, path
, query
, fragment
))
68 super(URLValidator
, self
).__call
__(url
)
74 if self
.verify_exists
:
77 "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
78 "Accept-Language": "en-us,en;q=0.5",
79 "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
80 "Connection": "close",
81 "User-Agent": self
.user_agent
,
84 req
= urllib2
.Request(url
, None, headers
)
85 u
= urllib2
.urlopen(req
)
87 raise ValidationError(_(u
'Enter a valid URL.'), code
='invalid')
88 except: # urllib2.URLError, httplib.InvalidURL, etc.
89 raise ValidationError(_(u
'This URL appears to be a broken link.'), code
='invalid_link')
92 def validate_integer(value
):
95 except (ValueError, TypeError), e
:
96 raise ValidationError('')
98 class EmailValidator(RegexValidator
):
100 def __call__(self
, value
):
102 super(EmailValidator
, self
).__call
__(value
)
103 except ValidationError
, e
:
104 # Trivial case failed. Try for possible IDN domain-part
105 if value
and u
'@' in value
:
106 parts
= value
.split(u
'@')
107 domain_part
= parts
[-1]
109 parts
[-1] = parts
[-1].encode('idna')
112 super(EmailValidator
, self
).__call
__(u
'@'.join(parts
))
116 email_re
= re
.compile(
117 r
"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
118 r
'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
119 r
')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re
.IGNORECASE
) # domain
120 validate_email
= EmailValidator(email_re
, _(u
'Enter a valid e-mail address.'), 'invalid')
122 slug_re
= re
.compile(r
'^[-\w]+$')
123 validate_slug
= RegexValidator(slug_re
, _(u
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
125 ipv4_re
= re
.compile(r
'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
126 validate_ipv4_address
= RegexValidator(ipv4_re
, _(u
'Enter a valid IPv4 address.'), 'invalid')
128 comma_separated_int_list_re
= re
.compile('^[\d,]+$')
129 validate_comma_separated_integer_list
= RegexValidator(comma_separated_int_list_re
, _(u
'Enter only digits separated by commas.'), 'invalid')
132 class BaseValidator(object):
133 compare
= lambda self
, a
, b
: a
is not b
134 clean
= lambda self
, x
: x
135 message
= _(u
'Ensure this value is %(limit_value)s (it is %(show_value)s).')
138 def __init__(self
, limit_value
):
139 self
.limit_value
= limit_value
141 def __call__(self
, value
):
142 cleaned
= self
.clean(value
)
143 params
= {'limit_value': self
.limit_value
, 'show_value': cleaned
}
144 if self
.compare(cleaned
, self
.limit_value
):
145 raise ValidationError(
146 self
.message
% params
,
151 class MaxValueValidator(BaseValidator
):
152 compare
= lambda self
, a
, b
: a
> b
153 message
= _(u
'Ensure this value is less than or equal to %(limit_value)s.')
156 class MinValueValidator(BaseValidator
):
157 compare
= lambda self
, a
, b
: a
< b
158 message
= _(u
'Ensure this value is greater than or equal to %(limit_value)s.')
161 class MinLengthValidator(BaseValidator
):
162 compare
= lambda self
, a
, b
: a
< b
163 clean
= lambda self
, x
: len(x
)
164 message
= _(u
'Ensure this value has at least %(limit_value)d characters (it has %(show_value)d).')
167 class MaxLengthValidator(BaseValidator
):
168 compare
= lambda self
, a
, b
: a
> b
169 clean
= lambda self
, x
: len(x
)
170 message
= _(u
'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).')