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