38 import traceback |
38 import traceback |
39 import types |
39 import types |
40 import urllib |
40 import urllib |
41 import urlparse |
41 import urlparse |
42 import wsgiref.handlers |
42 import wsgiref.handlers |
|
43 |
|
44 try: |
|
45 from google.appengine.cron import groctimespecification |
|
46 from google.appengine.api import croninfo |
|
47 except ImportError: |
|
48 HAVE_CRON = False |
|
49 else: |
|
50 HAVE_CRON = True |
43 |
51 |
44 from google.appengine.api import datastore |
52 from google.appengine.api import datastore |
45 from google.appengine.api import datastore_admin |
53 from google.appengine.api import datastore_admin |
46 from google.appengine.api import datastore_types |
54 from google.appengine.api import datastore_types |
47 from google.appengine.api import datastore_errors |
55 from google.appengine.api import datastore_errors |
107 'datastore_batch_edit_path': base_path + DatastoreBatchEditHandler.PATH, |
115 'datastore_batch_edit_path': base_path + DatastoreBatchEditHandler.PATH, |
108 'interactive_path': base_path + InteractivePageHandler.PATH, |
116 'interactive_path': base_path + InteractivePageHandler.PATH, |
109 'interactive_execute_path': base_path + InteractiveExecuteHandler.PATH, |
117 'interactive_execute_path': base_path + InteractiveExecuteHandler.PATH, |
110 'memcache_path': base_path + MemcachePageHandler.PATH, |
118 'memcache_path': base_path + MemcachePageHandler.PATH, |
111 } |
119 } |
|
120 if HAVE_CRON: |
|
121 values['cron_path'] = base_path + CronPageHandler.PATH |
|
122 |
112 values.update(template_values) |
123 values.update(template_values) |
113 directory = os.path.dirname(__file__) |
124 directory = os.path.dirname(__file__) |
114 path = os.path.join(directory, os.path.join('templates', template_name)) |
125 path = os.path.join(directory, os.path.join('templates', template_name)) |
115 self.response.out.write(template.render(path, values, debug=_DEBUG)) |
126 self.response.out.write(template.render(path, values, debug=_DEBUG)) |
116 |
127 |
197 finally: |
208 finally: |
198 sys.stdout = save_stdout |
209 sys.stdout = save_stdout |
199 |
210 |
200 results = results_io.getvalue() |
211 results = results_io.getvalue() |
201 self.generate('interactive-output.html', {'output': results}) |
212 self.generate('interactive-output.html', {'output': results}) |
|
213 |
|
214 |
|
215 class CronPageHandler(BaseRequestHandler): |
|
216 """Shows information about configured cron jobs in this application.""" |
|
217 PATH = '/cron' |
|
218 |
|
219 def get(self, now=None): |
|
220 """Shows template displaying the configured cron jobs.""" |
|
221 if not now: |
|
222 now = datetime.datetime.now() |
|
223 values = {'request': self.request} |
|
224 cron_info = _ParseCronYaml() |
|
225 values['cronjobs'] = [] |
|
226 values['now'] = str(now) |
|
227 if cron_info: |
|
228 for entry in cron_info.cron: |
|
229 job = {} |
|
230 values['cronjobs'].append(job) |
|
231 if entry.description: |
|
232 job['description'] = entry.description |
|
233 else: |
|
234 job['description'] = '(no description)' |
|
235 if entry.timezone: |
|
236 job['timezone'] = entry.timezone |
|
237 job['url'] = entry.url |
|
238 job['schedule'] = entry.schedule |
|
239 schedule = groctimespecification.GrocTimeSpecification(entry.schedule) |
|
240 matches = schedule.GetMatches(now, 3) |
|
241 job['times'] = [] |
|
242 for match in matches: |
|
243 job['times'].append({'runtime': match.strftime("%Y-%m-%d %H:%M:%SZ"), |
|
244 'difference': str(match - now)}) |
|
245 self.generate('cron.html', values) |
202 |
246 |
203 |
247 |
204 class MemcachePageHandler(BaseRequestHandler): |
248 class MemcachePageHandler(BaseRequestHandler): |
205 """Shows stats about memcache and query form to get values.""" |
249 """Shows stats about memcache and query form to get values.""" |
206 PATH = '/memcache' |
250 PATH = '/memcache' |
1087 _NAMED_DATA_TYPES = {} |
1131 _NAMED_DATA_TYPES = {} |
1088 for data_type in _DATA_TYPES.values(): |
1132 for data_type in _DATA_TYPES.values(): |
1089 _NAMED_DATA_TYPES[data_type.name()] = data_type |
1133 _NAMED_DATA_TYPES[data_type.name()] = data_type |
1090 |
1134 |
1091 |
1135 |
|
1136 def _ParseCronYaml(): |
|
1137 """Load the cron.yaml file and parse it.""" |
|
1138 cronyaml_files = 'cron.yaml', 'cron.yml' |
|
1139 for cronyaml in cronyaml_files: |
|
1140 try: |
|
1141 fh = open(cronyaml, "r") |
|
1142 except IOError: |
|
1143 continue |
|
1144 try: |
|
1145 cron_info = croninfo.LoadSingleCron(fh) |
|
1146 return cron_info |
|
1147 finally: |
|
1148 fh.close() |
|
1149 return None |
|
1150 |
|
1151 |
1092 def main(): |
1152 def main(): |
1093 application = webapp.WSGIApplication([ |
1153 handlers = [ |
1094 ('.*' + DatastoreQueryHandler.PATH, DatastoreQueryHandler), |
1154 ('.*' + DatastoreQueryHandler.PATH, DatastoreQueryHandler), |
1095 ('.*' + DatastoreEditHandler.PATH, DatastoreEditHandler), |
1155 ('.*' + DatastoreEditHandler.PATH, DatastoreEditHandler), |
1096 ('.*' + DatastoreBatchEditHandler.PATH, DatastoreBatchEditHandler), |
1156 ('.*' + DatastoreBatchEditHandler.PATH, DatastoreBatchEditHandler), |
1097 ('.*' + InteractivePageHandler.PATH, InteractivePageHandler), |
1157 ('.*' + InteractivePageHandler.PATH, InteractivePageHandler), |
1098 ('.*' + InteractiveExecuteHandler.PATH, InteractiveExecuteHandler), |
1158 ('.*' + InteractiveExecuteHandler.PATH, InteractiveExecuteHandler), |
1099 ('.*' + MemcachePageHandler.PATH, MemcachePageHandler), |
1159 ('.*' + MemcachePageHandler.PATH, MemcachePageHandler), |
1100 ('.*' + ImageHandler.PATH, ImageHandler), |
1160 ('.*' + ImageHandler.PATH, ImageHandler), |
1101 ('.*', DefaultPageHandler), |
1161 ('.*', DefaultPageHandler), |
1102 ], debug=_DEBUG) |
1162 ] |
|
1163 if HAVE_CRON: |
|
1164 handlers.insert(0, ('.*' + CronPageHandler.PATH, CronPageHandler)) |
|
1165 application = webapp.WSGIApplication(handlers, debug=_DEBUG) |
1103 wsgiref.handlers.CGIHandler().run(application) |
1166 wsgiref.handlers.CGIHandler().run(application) |
1104 |
1167 |
1105 |
1168 |
1106 import django |
1169 import django |
1107 if django.VERSION[:2] < (0, 97): |
1170 if django.VERSION[:2] < (0, 97): |