1 """Convenient validators and converters for data coming in from the web.
2
3 This module also imports everything from formencode.validators, so all
4 common validation routines are available here."""
5
6 import time
7 import re
8 from datetime import datetime
9 import warnings
10
11 try:
12 import json
13 except ImportError:
14 import simplejson as json
15
16 from formencode import ForEach
17 from formencode import validators
18 from formencode import national
19
20 from formencode.validators import *
21 from formencode.compound import *
22 from formencode.api import Invalid, NoDefault
23 from formencode.schema import Schema
24
25 from turbojson import jsonify
26
27 from turbogears import util
28 from turbogears.i18n import format
29
30
32
33
34 Validator.gettextargs['domain'] = 'FormEncode'
35
36
37
38
40 warnings.warn("Please use national.USStateProvince",
41 DeprecationWarning, 2)
42 return national.USStateProvince(*kw, **kwargs)
43
45 warnings.warn("Please use national.USPhoneNumber",
46 DeprecationWarning, 2)
47 return national.USPhoneNumber(*kw, **kwargs)
48
49 -def PostalCode(*kw, **kwargs):
50 warnings.warn("Please use national.USPostalCode",
51 DeprecationWarning, 2)
52 return national.USPostalCode(*kw, **kwargs)
53
55 warnings.warn("Please use national.InternationalPhoneNumber",
56 DeprecationWarning, 2)
57 return national.InternationalPhoneNumber(*kw, **kwargs)
58
59
62
63
64 -class Money(TgFancyValidator):
65 """Validate a monetary value with currency."""
66
67 messages = {
68 'badFormat': _('Invalid number format'),
69 'empty': _('Empty values not allowed'),
70 }
71
73 """Parse a string and return a float or integer."""
74 try:
75 return format.parse_decimal(value)
76 except ValueError:
77 raise Invalid(self.message('badFormat', state), value, state)
78
82
83
84 -class Number(TgFancyValidator):
85 """Validate a decimal number."""
86
87 decimals = None
88
97
114
115
117 """Convert between Python datetime objects and strings."""
118
119 format="%Y/%m/%d %H:%M"
120
121 messages = {
122 'badFormat': _('Invalid datetime format'),
123 'empty': _('Empty values not allowed'),
124 }
125
127 """Parse a string and return a datetime object."""
128 if value and isinstance(value, datetime):
129 return value
130 else:
131 try:
132 format = self.format
133 if callable(format):
134 format = format()
135 tpl = time.strptime(value, format)
136 except ValueError:
137 raise Invalid(self.message('badFormat', state), value, state)
138
139
140 return datetime(year=tpl.tm_year, month=tpl.tm_mon, day=tpl.tm_mday,
141 hour=tpl.tm_hour, minute=tpl.tm_min, second=tpl.tm_sec)
142
160
161
162
163
164
166
167 messages = {
168 'notEmpty': _("Filename must not be empty"),
169 }
170
172 try:
173 filename = value.filename
174 except AttributeError:
175 filename = None
176 if not filename and self.not_empty:
177 raise Invalid(self.message('notEmpty', state), value, state)
178 return value
179
180
181
182
183
184
185 import turbogears.i18n
186 _ = lambda s: turbogears.i18n.gettext(s, domain='TurboGears')
187
188
190 """A default validator for SelectionFields with multiple selection."""
191
192 if_missing = NoDefault
193 if_empty = []
194
200
201
203 """Modified Schema validator for TurboGears.
204
205 A schema validates a dictionary of values, applying different validators
206 (by key) to the different values.
207
208 This modified Schema allows fields that do not appear in the fields
209 parameter of your schema, but filters them out from the value dictionary.
210 You might want to set filter_extra_fields to True when you're building a
211 dynamic form with unpredictable keys and need these values.
212
213 """
214
215 filter_extra_fields = True
216 allow_extra_fields = True
217 if_key_missing = None
218
223
224
226 """A validator for JSON format."""
227
229 return jsonify.encode(value)
230
232 return json.loads(value)
233
234
235
236
238
239 sites = []
240 i = 0
241 while 1:
242 j = text.find(substr, i)
243 if j == -1:
244 break
245 sites.append(j)
246 i = j+1
247 return sites
248
249 _illegal_s = re.compile(r"((^|[^%])(%%)*%s)")
250
252 """strftime implementation supporting proleptic Gregorian dates before 1900.
253
254 @see: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/306860
255
256 """
257 if _illegal_s.search(fmt):
258 raise TypeError("This strftime implementation does not handle %s")
259 if dt.year > 1900:
260 return dt.strftime(fmt)
261
262 year = dt.year
263
264
265 delta = 2000 - year
266 off = 6*(delta // 100 + delta // 400)
267 year += off
268
269
270 year = year + ((2000 - year)//28)*28
271 timetuple = dt.timetuple()
272 s1 = time.strftime(fmt, (year,) + timetuple[1:])
273 sites1 = _findall(s1, str(year))
274
275 s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
276 sites2 = _findall(s2, str(year+28))
277
278 sites = []
279 for site in sites1:
280 if site in sites2:
281 sites.append(site)
282
283 s = s1
284 syear = "%4d" % (dt.year,)
285 for site in sites:
286 s = s[:site] + syear + s[site+4:]
287 return s
288