equal
deleted
inserted
replaced
21 application. Supports loading the records from yaml. |
21 application. Supports loading the records from yaml. |
22 """ |
22 """ |
23 |
23 |
24 |
24 |
25 |
25 |
|
26 import logging |
|
27 import sys |
|
28 import traceback |
|
29 |
|
30 try: |
|
31 import pytz |
|
32 except ImportError: |
|
33 pytz = None |
|
34 |
26 from google.appengine.cron import groc |
35 from google.appengine.cron import groc |
27 from google.appengine.api import validation |
36 from google.appengine.api import validation |
28 from google.appengine.api import yaml_builder |
37 from google.appengine.api import yaml_builder |
29 from google.appengine.api import yaml_listener |
38 from google.appengine.api import yaml_listener |
30 from google.appengine.api import yaml_object |
39 from google.appengine.api import yaml_object |
31 |
40 |
32 _URL_REGEX = r'^/.*$' |
41 _URL_REGEX = r'^/.*$' |
33 |
|
34 |
|
35 _TIMEZONE_REGEX = r'^.{0,100}$' |
42 _TIMEZONE_REGEX = r'^.{0,100}$' |
36 |
|
37 _DESCRIPTION_REGEX = r'^.{0,499}$' |
43 _DESCRIPTION_REGEX = r'^.{0,499}$' |
38 |
44 |
39 |
45 |
40 class GrocValidator(validation.Validator): |
46 class GrocValidator(validation.Validator): |
41 """Checks that a schedule is in valid groc format.""" |
47 """Checks that a schedule is in valid groc format.""" |
53 raise validation.ValidationError('schedule \'%s\' failed to parse: %s'%( |
59 raise validation.ValidationError('schedule \'%s\' failed to parse: %s'%( |
54 value, e.args[0])) |
60 value, e.args[0])) |
55 return value |
61 return value |
56 |
62 |
57 |
63 |
|
64 class TimezoneValidator(validation.Validator): |
|
65 """Checks that a timezone can be correctly parsed and is known.""" |
|
66 |
|
67 def Validate(self, value): |
|
68 """Validates a timezone.""" |
|
69 if value is None: |
|
70 return |
|
71 if not isinstance(value, basestring): |
|
72 raise TypeError('timezone must be a string, not \'%r\'' % type(value)) |
|
73 if pytz is None: |
|
74 return value |
|
75 try: |
|
76 pytz.timezone(value) |
|
77 except pytz.UnknownTimeZoneError: |
|
78 raise validation.ValidationError('timezone \'%s\' is unknown' % value) |
|
79 except IOError: |
|
80 return value |
|
81 except: |
|
82 e, v, t = sys.exc_info() |
|
83 logging.warning("pytz raised an unexpected error: %s.\n" % (v) + |
|
84 "Traceback:\n" + "\n".join(traceback.format_tb(t))) |
|
85 raise |
|
86 return value |
|
87 |
|
88 |
58 CRON = 'cron' |
89 CRON = 'cron' |
59 |
90 |
60 URL = 'url' |
91 URL = 'url' |
61 SCHEDULE = 'schedule' |
92 SCHEDULE = 'schedule' |
62 TIMEZONE = 'timezone' |
93 TIMEZONE = 'timezone' |
71 class CronEntry(validation.Validated): |
102 class CronEntry(validation.Validated): |
72 """A cron entry describes a single cron job.""" |
103 """A cron entry describes a single cron job.""" |
73 ATTRIBUTES = { |
104 ATTRIBUTES = { |
74 URL: _URL_REGEX, |
105 URL: _URL_REGEX, |
75 SCHEDULE: GrocValidator(), |
106 SCHEDULE: GrocValidator(), |
76 TIMEZONE: validation.Optional(_TIMEZONE_REGEX), |
107 TIMEZONE: TimezoneValidator(), |
77 DESCRIPTION: validation.Optional(_DESCRIPTION_REGEX) |
108 DESCRIPTION: validation.Optional(_DESCRIPTION_REGEX) |
78 } |
109 } |
79 |
110 |
80 |
111 |
81 class CronInfoExternal(validation.Validated): |
112 class CronInfoExternal(validation.Validated): |