| OLD | NEW |
| 1 # coding: utf-8 | 1 # coding: utf-8 |
| 2 # Copyright 2014 The LUCI Authors. All rights reserved. | 2 # Copyright 2014 The LUCI Authors. All rights reserved. |
| 3 # Use of this source code is governed by the Apache v2.0 license that can be | 3 # Use of this source code is governed by the Apache v2.0 license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Tasks definition. | 6 """Tasks definition. |
| 7 | 7 |
| 8 Each user request creates a new TaskRequest. The TaskRequest instance saves the | 8 Each user request creates a new TaskRequest. The TaskRequest instance saves the |
| 9 metadata of the request, e.g. who requested it, when why, etc. It links to the | 9 metadata of the request, e.g. who requested it, when why, etc. It links to the |
| 10 actual data of the request in a TaskProperties. The TaskProperties represents | 10 actual data of the request in a TaskProperties. The TaskProperties represents |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 # The world started on 2010-01-01 at 00:00:00 UTC. The rationale is that using | 87 # The world started on 2010-01-01 at 00:00:00 UTC. The rationale is that using |
| 88 # EPOCH (1970) means that 40 years worth of keys are wasted. | 88 # EPOCH (1970) means that 40 years worth of keys are wasted. |
| 89 # | 89 # |
| 90 # Note: This creates a 'naive' object instead of a formal UTC object. Note that | 90 # Note: This creates a 'naive' object instead of a formal UTC object. Note that |
| 91 # datetime.datetime.utcnow() also return naive objects. That's python. | 91 # datetime.datetime.utcnow() also return naive objects. That's python. |
| 92 _BEGINING_OF_THE_WORLD = datetime.datetime(2010, 1, 1, 0, 0, 0, 0) | 92 _BEGINING_OF_THE_WORLD = datetime.datetime(2010, 1, 1, 0, 0, 0, 0) |
| 93 | 93 |
| 94 | 94 |
| 95 # Used for isolated files. | 95 # Used for isolated files. |
| 96 _HASH_CHARS = frozenset('0123456789abcdef') | 96 _HASH_CHARS = frozenset('0123456789abcdef') |
| 97 _NAMESPACE_RE = re.compile(r'^[a-z0-9A-Z\-._]+$') | 97 NAMESPACE_RE = re.compile(r'^[a-z0-9A-Z\-._]+$') |
| 98 | 98 |
| 99 | 99 |
| 100 ### Properties validators must come before the models. | 100 ### Properties validators must come before the models. |
| 101 | 101 |
| 102 | 102 |
| 103 def _validate_isolated(prop, value): | 103 def _validate_isolated(prop, value): |
| 104 if value: | 104 if value: |
| 105 if not _HASH_CHARS.issuperset(value) or len(value) != 40: | 105 if not _HASH_CHARS.issuperset(value) or len(value) != 40: |
| 106 raise datastore_errors.BadValueError( | 106 raise datastore_errors.BadValueError( |
| 107 '%s must be lowercase hex of length 40, not %s' % (prop._name, value)) | 107 '%s must be lowercase hex of length 40, not %s' % (prop._name, value)) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 118 if parsed.netloc.endswith('appspot.com'): | 118 if parsed.netloc.endswith('appspot.com'): |
| 119 if parsed.scheme != 'https': | 119 if parsed.scheme != 'https': |
| 120 raise datastore_errors.BadValueError( | 120 raise datastore_errors.BadValueError( |
| 121 '%s must be https://, not %s' % (prop._name, value)) | 121 '%s must be https://, not %s' % (prop._name, value)) |
| 122 elif parsed.scheme not in ('http', 'https'): | 122 elif parsed.scheme not in ('http', 'https'): |
| 123 raise datastore_errors.BadValueError( | 123 raise datastore_errors.BadValueError( |
| 124 '%s must be https:// or http://, not %s' % (prop._name, value)) | 124 '%s must be https:// or http://, not %s' % (prop._name, value)) |
| 125 | 125 |
| 126 | 126 |
| 127 def _validate_namespace(prop, value): | 127 def _validate_namespace(prop, value): |
| 128 if not _NAMESPACE_RE.match(value): | 128 if not NAMESPACE_RE.match(value): |
| 129 raise datastore_errors.BadValueError('malformed %s' % prop._name) | 129 raise datastore_errors.BadValueError('malformed %s' % prop._name) |
| 130 | 130 |
| 131 | 131 |
| 132 def _validate_dict_of_strings(prop, value): | 132 def _validate_dict_of_strings(prop, value): |
| 133 """Validates TaskProperties.env.""" | 133 """Validates TaskProperties.env.""" |
| 134 if not all( | 134 if not all( |
| 135 isinstance(k, unicode) and isinstance(v, unicode) | 135 isinstance(k, unicode) and isinstance(v, unicode) |
| 136 for k, v in value.iteritems()): | 136 for k, v in value.iteritems()): |
| 137 # pylint: disable=W0212 | 137 # pylint: disable=W0212 |
| 138 raise TypeError('%s must be a dict of strings' % prop._name) | 138 raise TypeError('%s must be a dict of strings' % prop._name) |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 _put_request(request) | 723 _put_request(request) |
| 724 return request | 724 return request |
| 725 | 725 |
| 726 | 726 |
| 727 def validate_priority(priority): | 727 def validate_priority(priority): |
| 728 """Throws ValueError if priority is not a valid value.""" | 728 """Throws ValueError if priority is not a valid value.""" |
| 729 if 0 > priority or MAXIMUM_PRIORITY < priority: | 729 if 0 > priority or MAXIMUM_PRIORITY < priority: |
| 730 raise datastore_errors.BadValueError( | 730 raise datastore_errors.BadValueError( |
| 731 'priority (%d) must be between 0 and %d (inclusive)' % | 731 'priority (%d) must be between 0 and %d (inclusive)' % |
| 732 (priority, MAXIMUM_PRIORITY)) | 732 (priority, MAXIMUM_PRIORITY)) |
| OLD | NEW |