appier 1.31.4__py2.py3-none-any.whl → 1.32.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- appier/__init__.py +333 -52
- appier/amqp.py +29 -30
- appier/api.py +214 -212
- appier/asgi.py +54 -55
- appier/async_neo.py +46 -35
- appier/async_old.py +55 -42
- appier/asynchronous.py +7 -13
- appier/base.py +1762 -1429
- appier/bus.py +51 -52
- appier/cache.py +99 -84
- appier/common.py +9 -11
- appier/component.py +17 -19
- appier/compress.py +25 -28
- appier/config.py +96 -73
- appier/controller.py +9 -15
- appier/crypt.py +25 -21
- appier/data.py +73 -57
- appier/defines.py +191 -226
- appier/exceptions.py +103 -63
- appier/execution.py +94 -88
- appier/export.py +90 -88
- appier/extra.py +6 -13
- appier/extra_neo.py +8 -11
- appier/extra_old.py +18 -16
- appier/geo.py +57 -47
- appier/git.py +101 -90
- appier/graph.py +23 -24
- appier/http.py +520 -398
- appier/legacy.py +373 -180
- appier/log.py +90 -97
- appier/meta.py +42 -42
- appier/mock.py +32 -34
- appier/model.py +793 -681
- appier/model_a.py +208 -183
- appier/mongo.py +183 -107
- appier/observer.py +39 -31
- appier/part.py +23 -24
- appier/preferences.py +44 -47
- appier/queuing.py +78 -96
- appier/redisdb.py +40 -35
- appier/request.py +227 -175
- appier/scheduler.py +13 -18
- appier/serialize.py +37 -31
- appier/session.py +161 -147
- appier/settings.py +2 -11
- appier/smtp.py +53 -49
- appier/storage.py +39 -33
- appier/structures.py +50 -45
- appier/test/__init__.py +2 -11
- appier/test/base.py +111 -108
- appier/test/cache.py +28 -35
- appier/test/config.py +10 -19
- appier/test/crypt.py +3 -12
- appier/test/data.py +3 -12
- appier/test/exceptions.py +8 -17
- appier/test/export.py +16 -33
- appier/test/graph.py +27 -60
- appier/test/http.py +42 -54
- appier/test/legacy.py +20 -30
- appier/test/log.py +14 -35
- appier/test/mock.py +27 -123
- appier/test/model.py +79 -91
- appier/test/part.py +5 -14
- appier/test/preferences.py +5 -13
- appier/test/queuing.py +29 -37
- appier/test/request.py +61 -73
- appier/test/serialize.py +12 -23
- appier/test/session.py +10 -19
- appier/test/smtp.py +8 -14
- appier/test/structures.py +20 -24
- appier/test/typesf.py +14 -28
- appier/test/util.py +480 -438
- appier/typesf.py +251 -171
- appier/util.py +578 -407
- appier/validation.py +280 -143
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/METADATA +6 -1
- appier-1.32.0.dist-info/RECORD +86 -0
- appier-1.31.4.dist-info/RECORD +0 -86
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/LICENSE +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/WHEEL +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/top_level.txt +0 -0
appier/validation.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Hive Appier Framework
|
|
5
|
-
# Copyright (c) 2008-
|
|
5
|
+
# Copyright (c) 2008-2024 Hive Solutions Lda.
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Hive Appier Framework.
|
|
8
8
|
#
|
|
@@ -22,16 +22,7 @@
|
|
|
22
22
|
__author__ = "João Magalhães <joamag@hive.pt>"
|
|
23
23
|
""" The author(s) of the module """
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
""" The version of the module """
|
|
27
|
-
|
|
28
|
-
__revision__ = "$LastChangedRevision$"
|
|
29
|
-
""" The revision number of the module """
|
|
30
|
-
|
|
31
|
-
__date__ = "$LastChangedDate$"
|
|
32
|
-
""" The last change date of the module """
|
|
33
|
-
|
|
34
|
-
__copyright__ = "Copyright (c) 2008-2022 Hive Solutions Lda."
|
|
25
|
+
__copyright__ = "Copyright (c) 2008-2024 Hive Solutions Lda."
|
|
35
26
|
""" The copyright for the module """
|
|
36
27
|
|
|
37
28
|
__license__ = "Apache License, Version 2.0"
|
|
@@ -55,7 +46,9 @@ EMAIL_REGEX_VALUE = "^[\w\d\._%+-]+@[\w\d\.\-]+$"
|
|
|
55
46
|
""" The email regex value used to validate
|
|
56
47
|
if the provided value is in fact an email """
|
|
57
48
|
|
|
58
|
-
URL_REGEX_VALUE =
|
|
49
|
+
URL_REGEX_VALUE = (
|
|
50
|
+
"^\w+\:\/\/([^@]+\:[^@]+@)?[^\:\/\?#]+(\:\d+)?(\/[^\?#]+)*\/?(\?[^#]*)?(#.*)?$"
|
|
51
|
+
)
|
|
59
52
|
""" The URL regex value used to validate
|
|
60
53
|
if the provided value is in fact an URL/URI """
|
|
61
54
|
|
|
@@ -72,7 +65,8 @@ URL_REGEX = re.compile(URL_REGEX_VALUE)
|
|
|
72
65
|
""" The URL regex used to validate
|
|
73
66
|
if the provided value is in fact an URL/URI """
|
|
74
67
|
|
|
75
|
-
|
|
68
|
+
|
|
69
|
+
def validate(method=None, methods=[], object=None, ctx=None, build=True):
|
|
76
70
|
# retrieves the base request object that is going to be used in
|
|
77
71
|
# the construction of the object
|
|
78
72
|
request = common.base().get_request()
|
|
@@ -99,16 +93,21 @@ def validate(method = None, methods = [], object = None, ctx = None, build = Tru
|
|
|
99
93
|
# uses all the values referencing data in the request to try
|
|
100
94
|
# to populate the object this way it may be constructed using
|
|
101
95
|
# any of theses strategies (easier for the developer)
|
|
102
|
-
for name, value in data_j.items():
|
|
103
|
-
|
|
104
|
-
for name, value in request.
|
|
105
|
-
|
|
96
|
+
for name, value in data_j.items():
|
|
97
|
+
object[name] = value
|
|
98
|
+
for name, value in request.files_s.items():
|
|
99
|
+
object[name] = value
|
|
100
|
+
for name, value in request.post_s.items():
|
|
101
|
+
object[name] = value
|
|
102
|
+
for name, value in request.params_s.items():
|
|
103
|
+
object[name] = value
|
|
106
104
|
|
|
107
105
|
# iterates over the complete set of methods registered for validation
|
|
108
106
|
# and runs them expecting exceptions to be raised from them, each adding
|
|
109
107
|
# new errors to the current errors stack
|
|
110
108
|
for method in methods:
|
|
111
|
-
try:
|
|
109
|
+
try:
|
|
110
|
+
method(object, ctx=ctx)
|
|
112
111
|
except exceptions.ValidationMultipleError as error:
|
|
113
112
|
errors.extend(error.errors)
|
|
114
113
|
except exceptions.ValidationInternalError as error:
|
|
@@ -118,7 +117,8 @@ def validate(method = None, methods = [], object = None, ctx = None, build = Tru
|
|
|
118
117
|
# field name of the object and the validation errors associated with it
|
|
119
118
|
errors_map = dict()
|
|
120
119
|
for name, message in errors:
|
|
121
|
-
if not name in errors_map:
|
|
120
|
+
if not name in errors_map:
|
|
121
|
+
errors_map[name] = []
|
|
122
122
|
_errors = errors_map[name]
|
|
123
123
|
_errors.append(message)
|
|
124
124
|
|
|
@@ -126,294 +126,413 @@ def validate(method = None, methods = [], object = None, ctx = None, build = Tru
|
|
|
126
126
|
# model name with the sequence of errors and the validated object (state)
|
|
127
127
|
return errors_map, object
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
|
|
130
|
+
def validate_b(method=None, methods=[], object=None, ctx=None, build=True):
|
|
130
131
|
errors_map, object = validate(
|
|
131
|
-
method =
|
|
132
|
-
methods = methods,
|
|
133
|
-
object = object,
|
|
134
|
-
ctx = ctx,
|
|
135
|
-
build = build
|
|
132
|
+
method=method, methods=methods, object=object, ctx=ctx, build=build
|
|
136
133
|
)
|
|
137
134
|
result = False if errors_map else True
|
|
138
135
|
return result
|
|
139
136
|
|
|
140
|
-
|
|
137
|
+
|
|
138
|
+
def validate_e(method=None, methods=[], object=None, ctx=None, build=True):
|
|
141
139
|
errors_map, object = validate(
|
|
142
|
-
method =
|
|
143
|
-
methods = methods,
|
|
144
|
-
object = object,
|
|
145
|
-
ctx = ctx,
|
|
146
|
-
build = build
|
|
140
|
+
method=method, methods=methods, object=object, ctx=ctx, build=build
|
|
147
141
|
)
|
|
148
|
-
if not errors_map:
|
|
142
|
+
if not errors_map:
|
|
143
|
+
return
|
|
149
144
|
raise exceptions.ValidationError(errors_map, object)
|
|
150
145
|
|
|
146
|
+
|
|
151
147
|
def safe(comparision):
|
|
152
|
-
try:
|
|
153
|
-
|
|
148
|
+
try:
|
|
149
|
+
return comparision()
|
|
150
|
+
except TypeError:
|
|
151
|
+
return False
|
|
152
|
+
|
|
154
153
|
|
|
155
|
-
def eq(name, value_c, message
|
|
154
|
+
def eq(name, value_c, message="must be equal to %s", locale=True):
|
|
156
155
|
def validation(object, ctx):
|
|
157
156
|
value = object.get(name, None)
|
|
158
|
-
if value == None:
|
|
159
|
-
|
|
157
|
+
if value == None:
|
|
158
|
+
return True
|
|
159
|
+
if value == value_c:
|
|
160
|
+
return True
|
|
160
161
|
message_l = _to_locale(message) if locale else message
|
|
161
162
|
raise exceptions.ValidationInternalError(name, message_l % str(value_c))
|
|
163
|
+
|
|
162
164
|
return validation
|
|
163
165
|
|
|
164
|
-
|
|
166
|
+
|
|
167
|
+
def gt(name, value_c, message="must be greater than %s", locale=True):
|
|
165
168
|
def validation(object, ctx):
|
|
166
169
|
value = object.get(name, None)
|
|
167
|
-
if value == None:
|
|
168
|
-
|
|
170
|
+
if value == None:
|
|
171
|
+
return True
|
|
172
|
+
if safe(lambda: value > value_c):
|
|
173
|
+
return True
|
|
169
174
|
message_l = _to_locale(message) if locale else message
|
|
170
175
|
raise exceptions.ValidationInternalError(name, message_l % str(value_c))
|
|
176
|
+
|
|
171
177
|
return validation
|
|
172
178
|
|
|
173
|
-
|
|
179
|
+
|
|
180
|
+
def gte(name, value_c, message="must be greater than or equal to %s", locale=True):
|
|
174
181
|
def validation(object, ctx):
|
|
175
182
|
value = object.get(name, None)
|
|
176
|
-
if value == None:
|
|
177
|
-
|
|
183
|
+
if value == None:
|
|
184
|
+
return True
|
|
185
|
+
if safe(lambda: value >= value_c):
|
|
186
|
+
return True
|
|
178
187
|
message_l = _to_locale(message) if locale else message
|
|
179
188
|
raise exceptions.ValidationInternalError(name, message_l % str(value_c))
|
|
189
|
+
|
|
180
190
|
return validation
|
|
181
191
|
|
|
182
|
-
|
|
192
|
+
|
|
193
|
+
def lt(name, value_c, message="must be less than %s", locale=True):
|
|
183
194
|
def validation(object, ctx):
|
|
184
195
|
value = object.get(name, None)
|
|
185
|
-
if value == None:
|
|
186
|
-
|
|
196
|
+
if value == None:
|
|
197
|
+
return True
|
|
198
|
+
if safe(lambda: value < value_c):
|
|
199
|
+
return True
|
|
187
200
|
message_l = _to_locale(message) if locale else message
|
|
188
201
|
raise exceptions.ValidationInternalError(name, message_l % str(value_c))
|
|
202
|
+
|
|
189
203
|
return validation
|
|
190
204
|
|
|
191
|
-
|
|
205
|
+
|
|
206
|
+
def lte(name, value_c, message="must be less than or equal to %s", locale=True):
|
|
192
207
|
def validation(object, ctx):
|
|
193
208
|
value = object.get(name, None)
|
|
194
|
-
if value == None:
|
|
195
|
-
|
|
209
|
+
if value == None:
|
|
210
|
+
return True
|
|
211
|
+
if safe(lambda: value <= value_c):
|
|
212
|
+
return True
|
|
196
213
|
message_l = _to_locale(message) if locale else message
|
|
197
214
|
raise exceptions.ValidationInternalError(name, message_l % str(value_c))
|
|
215
|
+
|
|
198
216
|
return validation
|
|
199
217
|
|
|
200
|
-
|
|
218
|
+
|
|
219
|
+
def not_null(name, message="value is not set", locale=True):
|
|
201
220
|
def validation(object, ctx):
|
|
202
221
|
value = object.get(name, None)
|
|
203
|
-
if not value == None:
|
|
222
|
+
if not value == None:
|
|
223
|
+
return True
|
|
204
224
|
message_l = _to_locale(message) if locale else message
|
|
205
225
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
226
|
+
|
|
206
227
|
return validation
|
|
207
228
|
|
|
208
|
-
|
|
229
|
+
|
|
230
|
+
def not_empty(name, message="value is empty", locale=True):
|
|
209
231
|
def validation(object, ctx):
|
|
210
232
|
value = object.get(name, None)
|
|
211
|
-
if value == None:
|
|
212
|
-
|
|
233
|
+
if value == None:
|
|
234
|
+
return True
|
|
235
|
+
if len(value):
|
|
236
|
+
return True
|
|
213
237
|
message_l = _to_locale(message) if locale else message
|
|
214
238
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
239
|
+
|
|
215
240
|
return validation
|
|
216
241
|
|
|
217
|
-
|
|
242
|
+
|
|
243
|
+
def not_false(name, message="value is false", locale=True):
|
|
218
244
|
def validation(object, ctx):
|
|
219
245
|
value = object.get(name, None)
|
|
220
|
-
if value == None:
|
|
221
|
-
|
|
246
|
+
if value == None:
|
|
247
|
+
return True
|
|
248
|
+
if not value == False:
|
|
249
|
+
return True
|
|
222
250
|
message_l = _to_locale(message) if locale else message
|
|
223
251
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
252
|
+
|
|
224
253
|
return validation
|
|
225
254
|
|
|
226
|
-
|
|
255
|
+
|
|
256
|
+
def is_in(name, values, message="value is not in set", locale=True):
|
|
227
257
|
def validation(object, ctx):
|
|
228
258
|
value = object.get(name, None)
|
|
229
|
-
if value == None:
|
|
230
|
-
|
|
259
|
+
if value == None:
|
|
260
|
+
return True
|
|
261
|
+
if value in values:
|
|
262
|
+
return True
|
|
231
263
|
message_l = _to_locale(message) if locale else message
|
|
232
264
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
265
|
+
|
|
233
266
|
return validation
|
|
234
267
|
|
|
235
|
-
|
|
268
|
+
|
|
269
|
+
def is_upper(name, message="value contains lower cased characters", locale=True):
|
|
236
270
|
def validation(object, ctx):
|
|
237
271
|
value = object.get(name, None)
|
|
238
|
-
if value == None:
|
|
239
|
-
|
|
240
|
-
if value ==
|
|
272
|
+
if value == None:
|
|
273
|
+
return True
|
|
274
|
+
if value == "":
|
|
275
|
+
return True
|
|
276
|
+
if value == value.upper():
|
|
277
|
+
return True
|
|
241
278
|
message_l = _to_locale(message) if locale else message
|
|
242
279
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
280
|
+
|
|
243
281
|
return validation
|
|
244
282
|
|
|
245
|
-
|
|
283
|
+
|
|
284
|
+
def is_lower(name, message="value contains upper cased characters", locale=True):
|
|
246
285
|
def validation(object, ctx):
|
|
247
286
|
value = object.get(name, None)
|
|
248
|
-
if value == None:
|
|
249
|
-
|
|
250
|
-
if value ==
|
|
287
|
+
if value == None:
|
|
288
|
+
return True
|
|
289
|
+
if value == "":
|
|
290
|
+
return True
|
|
291
|
+
if value == value.lower():
|
|
292
|
+
return True
|
|
251
293
|
message_l = _to_locale(message) if locale else message
|
|
252
294
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
295
|
+
|
|
253
296
|
return validation
|
|
254
297
|
|
|
255
|
-
|
|
298
|
+
|
|
299
|
+
def is_simple(name, message="value contains invalid characters", locale=True):
|
|
256
300
|
def validation(object, ctx):
|
|
257
301
|
value = object.get(name, None)
|
|
258
|
-
if value == None:
|
|
259
|
-
|
|
260
|
-
if
|
|
302
|
+
if value == None:
|
|
303
|
+
return True
|
|
304
|
+
if value == "":
|
|
305
|
+
return True
|
|
306
|
+
if SIMPLE_REGEX.match(value):
|
|
307
|
+
return True
|
|
261
308
|
message_l = _to_locale(message) if locale else message
|
|
262
309
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
310
|
+
|
|
263
311
|
return validation
|
|
264
312
|
|
|
265
|
-
|
|
313
|
+
|
|
314
|
+
def is_email(name, message="value is not a valid email", locale=True):
|
|
266
315
|
def validation(object, ctx):
|
|
267
316
|
value = object.get(name, None)
|
|
268
|
-
if value == None:
|
|
269
|
-
|
|
270
|
-
if
|
|
317
|
+
if value == None:
|
|
318
|
+
return True
|
|
319
|
+
if value == "":
|
|
320
|
+
return True
|
|
321
|
+
if EMAIL_REGEX.match(value):
|
|
322
|
+
return True
|
|
271
323
|
message_l = _to_locale(message) if locale else message
|
|
272
324
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
325
|
+
|
|
273
326
|
return validation
|
|
274
327
|
|
|
275
|
-
|
|
328
|
+
|
|
329
|
+
def is_url(name, message="value is not a valid URL", locale=True):
|
|
276
330
|
def validation(object, ctx):
|
|
277
331
|
value = object.get(name, None)
|
|
278
|
-
if value == None:
|
|
279
|
-
|
|
280
|
-
if
|
|
332
|
+
if value == None:
|
|
333
|
+
return True
|
|
334
|
+
if value == "":
|
|
335
|
+
return True
|
|
336
|
+
if URL_REGEX.match(value):
|
|
337
|
+
return True
|
|
281
338
|
message_l = _to_locale(message) if locale else message
|
|
282
339
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
340
|
+
|
|
283
341
|
return validation
|
|
284
342
|
|
|
285
|
-
|
|
343
|
+
|
|
344
|
+
def is_regex(name, regex, message="value has incorrect format", locale=True):
|
|
286
345
|
def validation(object, ctx):
|
|
287
346
|
value = object.get(name, None)
|
|
288
|
-
if value == None:
|
|
289
|
-
|
|
347
|
+
if value == None:
|
|
348
|
+
return True
|
|
349
|
+
if value == "":
|
|
350
|
+
return True
|
|
290
351
|
match = re.match(regex, value)
|
|
291
|
-
if match:
|
|
352
|
+
if match:
|
|
353
|
+
return True
|
|
292
354
|
message_l = _to_locale(message) if locale else message
|
|
293
355
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
356
|
+
|
|
294
357
|
return validation
|
|
295
358
|
|
|
296
|
-
|
|
359
|
+
|
|
360
|
+
def field_eq(name, field, message="must be equal to %s", locale=True):
|
|
297
361
|
def validation(object, ctx):
|
|
298
362
|
name_v = object.get(name, None)
|
|
299
363
|
field_v = object.get(field, None)
|
|
300
|
-
if name_v == None:
|
|
301
|
-
|
|
302
|
-
if
|
|
364
|
+
if name_v == None:
|
|
365
|
+
return True
|
|
366
|
+
if field_v == None:
|
|
367
|
+
return True
|
|
368
|
+
if name_v == field_v:
|
|
369
|
+
return True
|
|
303
370
|
message_l = _to_locale(message) if locale else message
|
|
304
371
|
raise exceptions.ValidationInternalError(name, message_l % field)
|
|
372
|
+
|
|
305
373
|
return validation
|
|
306
374
|
|
|
307
|
-
|
|
375
|
+
|
|
376
|
+
def field_gt(name, field, message="must be greater than %s", locale=True):
|
|
308
377
|
def validation(object, ctx):
|
|
309
378
|
name_v = object.get(name, None)
|
|
310
379
|
field_v = object.get(field, None)
|
|
311
|
-
if name_v == None:
|
|
312
|
-
|
|
313
|
-
if
|
|
380
|
+
if name_v == None:
|
|
381
|
+
return True
|
|
382
|
+
if field_v == None:
|
|
383
|
+
return True
|
|
384
|
+
if safe(lambda: name_v > field_v):
|
|
385
|
+
return True
|
|
314
386
|
message_l = _to_locale(message) if locale else message
|
|
315
387
|
raise exceptions.ValidationInternalError(name, message_l % field)
|
|
388
|
+
|
|
316
389
|
return validation
|
|
317
390
|
|
|
318
|
-
|
|
391
|
+
|
|
392
|
+
def field_gte(name, field, message="must be greater or equal than %s", locale=True):
|
|
319
393
|
def validation(object, ctx):
|
|
320
394
|
name_v = object.get(name, None)
|
|
321
395
|
field_v = object.get(field, None)
|
|
322
|
-
if name_v == None:
|
|
323
|
-
|
|
324
|
-
if
|
|
396
|
+
if name_v == None:
|
|
397
|
+
return True
|
|
398
|
+
if field_v == None:
|
|
399
|
+
return True
|
|
400
|
+
if safe(lambda: name_v >= field_v):
|
|
401
|
+
return True
|
|
325
402
|
message_l = _to_locale(message) if locale else message
|
|
326
403
|
raise exceptions.ValidationInternalError(name, message_l % field)
|
|
404
|
+
|
|
327
405
|
return validation
|
|
328
406
|
|
|
329
|
-
|
|
407
|
+
|
|
408
|
+
def field_lt(name, field, message="must be less than %s", locale=True):
|
|
330
409
|
def validation(object, ctx):
|
|
331
410
|
name_v = object.get(name, None)
|
|
332
411
|
field_v = object.get(field, None)
|
|
333
|
-
if name_v == None:
|
|
334
|
-
|
|
335
|
-
if
|
|
412
|
+
if name_v == None:
|
|
413
|
+
return True
|
|
414
|
+
if field_v == None:
|
|
415
|
+
return True
|
|
416
|
+
if safe(lambda: name_v < field_v):
|
|
417
|
+
return True
|
|
336
418
|
message_l = _to_locale(message) if locale else message
|
|
337
419
|
raise exceptions.ValidationInternalError(name, message_l % field)
|
|
420
|
+
|
|
338
421
|
return validation
|
|
339
422
|
|
|
340
|
-
|
|
423
|
+
|
|
424
|
+
def field_lte(name, field, message="must be less or equal than %s", locale=True):
|
|
341
425
|
def validation(object, ctx):
|
|
342
426
|
name_v = object.get(name, None)
|
|
343
427
|
field_v = object.get(field, None)
|
|
344
|
-
if name_v == None:
|
|
345
|
-
|
|
346
|
-
if
|
|
428
|
+
if name_v == None:
|
|
429
|
+
return True
|
|
430
|
+
if field_v == None:
|
|
431
|
+
return True
|
|
432
|
+
if safe(lambda: name_v <= field_v):
|
|
433
|
+
return True
|
|
347
434
|
message_l = _to_locale(message) if locale else message
|
|
348
435
|
raise exceptions.ValidationInternalError(name, message_l % field)
|
|
436
|
+
|
|
349
437
|
return validation
|
|
350
438
|
|
|
351
|
-
|
|
439
|
+
|
|
440
|
+
def string_gt(name, size, message="must be larger than %d characters", locale=True):
|
|
352
441
|
def validation(object, ctx):
|
|
353
442
|
value = object.get(name, None)
|
|
354
|
-
if value == None:
|
|
355
|
-
|
|
356
|
-
if
|
|
443
|
+
if value == None:
|
|
444
|
+
return True
|
|
445
|
+
if value == "":
|
|
446
|
+
return True
|
|
447
|
+
if len(value) > size:
|
|
448
|
+
return True
|
|
357
449
|
message_l = _to_locale(message) if locale else message
|
|
358
450
|
raise exceptions.ValidationInternalError(name, message_l % size)
|
|
451
|
+
|
|
359
452
|
return validation
|
|
360
453
|
|
|
361
|
-
|
|
454
|
+
|
|
455
|
+
def string_lt(name, size, message="must be smaller than %d characters", locale=True):
|
|
362
456
|
def validation(object, ctx):
|
|
363
457
|
value = object.get(name, None)
|
|
364
|
-
if value == None:
|
|
365
|
-
|
|
366
|
-
if
|
|
458
|
+
if value == None:
|
|
459
|
+
return True
|
|
460
|
+
if value == "":
|
|
461
|
+
return True
|
|
462
|
+
if len(value) < size:
|
|
463
|
+
return True
|
|
367
464
|
message_l = _to_locale(message) if locale else message
|
|
368
465
|
raise exceptions.ValidationInternalError(name, message_l % size)
|
|
466
|
+
|
|
369
467
|
return validation
|
|
370
468
|
|
|
371
|
-
|
|
469
|
+
|
|
470
|
+
def string_eq(name, size, message="must be exactly %d characters", locale=True):
|
|
372
471
|
def validation(object, ctx):
|
|
373
472
|
value = object.get(name, None)
|
|
374
|
-
if value == None:
|
|
375
|
-
|
|
376
|
-
if
|
|
473
|
+
if value == None:
|
|
474
|
+
return True
|
|
475
|
+
if value == "":
|
|
476
|
+
return True
|
|
477
|
+
if len(value) == size:
|
|
478
|
+
return True
|
|
377
479
|
message_l = _to_locale(message) if locale else message
|
|
378
480
|
raise exceptions.ValidationInternalError(name, message_l % size)
|
|
481
|
+
|
|
379
482
|
return validation
|
|
380
483
|
|
|
381
|
-
|
|
484
|
+
|
|
485
|
+
def equals(first_name, second_name, message="value is not equal to %s", locale=True):
|
|
382
486
|
def validation(object, ctx):
|
|
383
487
|
first_value = object.get(first_name, None)
|
|
384
488
|
second_value = object.get(second_name, None)
|
|
385
|
-
if first_value == None:
|
|
386
|
-
|
|
387
|
-
if
|
|
489
|
+
if first_value == None:
|
|
490
|
+
return True
|
|
491
|
+
if second_value == None:
|
|
492
|
+
return True
|
|
493
|
+
if first_value == second_value:
|
|
494
|
+
return True
|
|
388
495
|
message_l = _to_locale(message) if locale else message
|
|
389
496
|
raise exceptions.ValidationInternalError(first_name, message_l % second_name)
|
|
497
|
+
|
|
390
498
|
return validation
|
|
391
499
|
|
|
392
|
-
|
|
500
|
+
|
|
501
|
+
def not_past(name, message="date is in the past", locale=True):
|
|
393
502
|
def validation(object, ctx):
|
|
394
503
|
value = object.get(name, None)
|
|
395
|
-
if value == None:
|
|
396
|
-
|
|
504
|
+
if value == None:
|
|
505
|
+
return True
|
|
506
|
+
if value >= datetime.datetime.utcnow():
|
|
507
|
+
return True
|
|
397
508
|
message_l = _to_locale(message) if locale else message
|
|
398
509
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
510
|
+
|
|
399
511
|
return validation
|
|
400
512
|
|
|
401
|
-
|
|
513
|
+
|
|
514
|
+
def not_duplicate(name, collection, message="value is duplicate", locale=True):
|
|
402
515
|
def validation(object, ctx):
|
|
403
516
|
_id = object.get("_id", None)
|
|
404
517
|
value = object.get(name, None)
|
|
405
|
-
if value == None:
|
|
406
|
-
|
|
518
|
+
if value == None:
|
|
519
|
+
return True
|
|
520
|
+
if value == "":
|
|
521
|
+
return True
|
|
407
522
|
adapter = common.base().get_adapter()
|
|
408
523
|
_collection = adapter.collection(collection)
|
|
409
|
-
item = _collection.find_one({name
|
|
410
|
-
if not item:
|
|
411
|
-
|
|
524
|
+
item = _collection.find_one({name: value})
|
|
525
|
+
if not item:
|
|
526
|
+
return True
|
|
527
|
+
if str(item["_id"]) == str(_id):
|
|
528
|
+
return True
|
|
412
529
|
message_l = _to_locale(message) if locale else message
|
|
413
530
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
531
|
+
|
|
414
532
|
return validation
|
|
415
533
|
|
|
416
|
-
|
|
534
|
+
|
|
535
|
+
def all_different(name, name_ref=None, message="has duplicates", locale=True):
|
|
417
536
|
def validation(object, ctx):
|
|
418
537
|
# uses the currently provided context to retrieve
|
|
419
538
|
# the definition of the name to be validation and
|
|
@@ -430,30 +549,39 @@ def all_different(name, name_ref = None, message = "has duplicates", locale = Tr
|
|
|
430
549
|
# that is going to be used for all different matching in
|
|
431
550
|
# case any of them does not exist returns valid
|
|
432
551
|
value = object.get(name, None)
|
|
433
|
-
if value == None:
|
|
434
|
-
|
|
552
|
+
if value == None:
|
|
553
|
+
return True
|
|
554
|
+
if len(value) == 0:
|
|
555
|
+
return True
|
|
435
556
|
|
|
436
557
|
# verifies if the sequence is in fact a proxy object and
|
|
437
558
|
# contains the ids attribute in case that's the case the
|
|
438
559
|
# ids attributes is retrieved as the sequence instead
|
|
439
|
-
if hasattr(value, "ids"):
|
|
560
|
+
if hasattr(value, "ids"):
|
|
561
|
+
values = value.ids
|
|
440
562
|
|
|
441
563
|
# otherwise this is a normal sequence and the it must be
|
|
442
564
|
# iterates to check if the reference name should be retrieve
|
|
443
565
|
# or if the concrete values should be used instead
|
|
444
|
-
else:
|
|
445
|
-
|
|
566
|
+
else:
|
|
567
|
+
values = [
|
|
568
|
+
getattr(_value, _name_ref) if hasattr(_value, _name_ref) else _value
|
|
569
|
+
for _value in value
|
|
570
|
+
]
|
|
446
571
|
|
|
447
572
|
# creates a set structure from the the sequence of values
|
|
448
573
|
# and in case the size of the sequence and the set are the
|
|
449
574
|
# same the sequence is considered to not contain duplicates
|
|
450
575
|
values_set = set(values)
|
|
451
|
-
if len(value) == len(values_set):
|
|
576
|
+
if len(value) == len(values_set):
|
|
577
|
+
return True
|
|
452
578
|
message_l = _to_locale(message) if locale else message
|
|
453
579
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
580
|
+
|
|
454
581
|
return validation
|
|
455
582
|
|
|
456
|
-
|
|
583
|
+
|
|
584
|
+
def no_self(name, name_ref=None, message="contains self", locale=True):
|
|
457
585
|
def validation(object, ctx):
|
|
458
586
|
# uses the currently provided context to retrieve
|
|
459
587
|
# the definition of the name to be validation and
|
|
@@ -471,28 +599,37 @@ def no_self(name, name_ref = None, message = "contains self", locale = True):
|
|
|
471
599
|
# case any of them does not exist returns valid
|
|
472
600
|
_id = object.get(_name_ref, None)
|
|
473
601
|
value = object.get(name, None)
|
|
474
|
-
if _id == None:
|
|
475
|
-
|
|
602
|
+
if _id == None:
|
|
603
|
+
return True
|
|
604
|
+
if value == None:
|
|
605
|
+
return True
|
|
476
606
|
|
|
477
607
|
# verifies if the sequence is in fact a proxy object and
|
|
478
608
|
# contains the ids attribute in case that's the case the
|
|
479
609
|
# ids attributes is retrieved as the sequence instead
|
|
480
|
-
if hasattr(value, "ids"):
|
|
610
|
+
if hasattr(value, "ids"):
|
|
611
|
+
values = value.ids
|
|
481
612
|
|
|
482
613
|
# otherwise this is a normal sequence and the it must be
|
|
483
614
|
# iterates to check if the reference name should be retrieve
|
|
484
615
|
# or if the concrete values should be used instead
|
|
485
|
-
else:
|
|
486
|
-
|
|
616
|
+
else:
|
|
617
|
+
values = [
|
|
618
|
+
getattr(_value, _name_ref) if hasattr(_value, _name_ref) else _value
|
|
619
|
+
for _value in value
|
|
620
|
+
]
|
|
487
621
|
|
|
488
622
|
# verifies if the current identifier value exists in the
|
|
489
623
|
# sequence and if that's the case raises the validation
|
|
490
624
|
# exception indicating the validation problem
|
|
491
625
|
exists = _id in values
|
|
492
|
-
if not exists:
|
|
626
|
+
if not exists:
|
|
627
|
+
return True
|
|
493
628
|
message_l = _to_locale(message) if locale else message
|
|
494
629
|
raise exceptions.ValidationInternalError(name, message_l)
|
|
630
|
+
|
|
495
631
|
return validation
|
|
496
632
|
|
|
633
|
+
|
|
497
634
|
def _to_locale(value):
|
|
498
635
|
return common.base().to_locale(value)
|