1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 """
58 This module defines classes for validating values stored in dbproperties
59 before they screw up the database or cause a CONSTRAINT error.
60 """
61
62
63 import re
64 from types import *
65 from string import *
66 from orm2.exceptions import *
67
69 """
70 The default validator: It doesn't check anything.
71 """
72 - def check(self, dbobj, dbproperty, value):
73 return True
74
76 """
77 For NOT NULL columns.
78 """
79 - def check(self, dbobj, dbproperty, value):
85
86
87 not_none_validator = not_null_validator
88
90 """
91 For columns which may not contain empty strings.
92 """
93 - def check(self, dbobj, dbproperty, value):
100
102 """
103 Check an argument value's length. None values will be ignored.
104 """
106 self.max_length = max_length
107
108 - def check(self, dbobj, dbproperty, value):
113
115 """
116 A generic validator for value ranges (fortunately Python doesn't care, it
117 can be used for numerals, dates, strings...)
118 """
119 - def __init__(self, lo, hi, include_bounds=False):
120 """
121 The formula goes::
122
123 lo < value < hi
124
125 if include_bounds is False (the default) or::
126
127 lo <= value <= hi
128
129 otherwise. If above formula is not valid, a RangeValidatorError will
130 be raised by check()
131 """
132 self.lo = lo
133 self.hi = hi
134 self.include_bounds = include_bounds
135
136 - def check(self, dbobj, dbproperty, value):
137 if not self.include_bounds:
138 if self.lo < value and value < self.hi:
139 return
140 else:
141 message = "Unmatched condition: %s < %s < %s (%s.%s)"
142 else:
143 if self.lo <= value and value <= self.hi:
144 return
145 else:
146 message = "Unmatched condition: %s <= %s <= %s (%s.%s)"
147
148 tpl = ( repr(self.lo), repr(self.hi), repr(value),
149 dbobj.__class__.__name__, dbproperty.attribute_name, )
150 raise RangeValidatorException(message % tpl, dbobj, dbproperty, value)
151
153 """
154 Regular expression validator. For strings and Unicode Objects
155 """
157 if type(re) in ( StringType, UnicodeType, ):
158 self.re = re.compile(re)
159 else:
160 self.re = re
161
162 - def check(self, dbobj, dbproperty, value):
163 match = self.re.match(value)
164
165 if match is None:
166 tpl = ( repr(value), self.re.pattern,
167 dbobj.__class__.__name__, dbproperty.attribute_name, )
168 msg = "%s does not match regular expression %s (%s.%s)" % tpl
169 raise ReValidatorException(msg, dbobj, dbproperty, self.re, value)
170
171
172
173
174
175
176 domain_name_re = re.compile("([0-9a-z]([0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,4}")
177 local_part_re = re.compile(r"[-a-z0-9_\.]+")
178 email_re = re.compile("[-a-z0-9_\.]+@([0-9a-z]([0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,4}")
179
181 """
182 Check if the value is a valid e-Mail Address using a regular expression.
183 Note that the re will not match un-encoded idna Domains, but it will work
184 on Unicode strings.
185 """
186
189
191 """
192 Check if the value is a valid fully qualified domain name. Note
193 that the rgex used will not match un-encoded idna Domains.
194 """
195
198
200 """
201 Like fqdn_validator above, but for idna Domains (Unicode)
202 """
203 - def check(self, dbobj, dbproperty, value):
204 if value is None:
205 return
206
207 if type(value) != UnicodeType:
208 raise TypeError("An idna fqdn must be represented as a " + \
209 "unicode string!")
210
211 value = value.encode("idna")
212 fqdn_validator.check(self, dbobj, dbproperty, value)
213
214
216 """
217 Like email_validator above, but for idna Domains (Unicode)
218 """
219
220 - def check(self, dbobj, dbproperty, value):
221 if value is None:
222 return
223
224 if type(value) != UnicodeType:
225 raise TypeError("An idna fqdn must be represented as a " + \
226 "unicode string!")
227
228 parts = split(value, "@")
229 if len(parts) == 2:
230 local_part, remote_part = parts
231
232 try:
233 local_part = local_part.encode("ascii")
234 except UnicodeDecodeError:
235 msg = "The local part of an e-mail address may not contain "+\
236 "non-ascii characters! (Even for an idna Domain!)"
237 raise ReValidatorException(msg, dbobj, dbproperty,
238 self.re, value)
239
240 remote_part = remote_part.encode("idna")
241
242 email_validator().check(dbobj, dbproperty,
243 local_part + "@" + remote_part)
244 else:
245 tpl = ( repr(value), self.re.pattern,
246 dbobj.__class__.__name__, dbproperty.attribute_name, )
247 msg = "%s does not match regular expression %s (%s.%s)" % tpl
248 raise ReValidatorException(msg, dbobj, dbproperty, self.re, value)
249
250
251
252
253
254
255
256