Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 import webapp2 | |
|
ojan
2014/07/22 02:01:25
Copyright
| |
| 2 from google.appengine.ext import ndb | |
| 3 import json | |
| 4 import calendar | |
| 5 import datetime | |
| 6 | |
| 7 | |
| 8 class DateTimeEncoder(json.JSONEncoder): | |
| 9 def default(self, obj): | |
| 10 # FIXME: This should be UTC. | |
| 11 if isinstance(obj, datetime.datetime): | |
| 12 return calendar.timegm(obj.timetuple()) | |
| 13 # Let the base class default method raise the TypeError | |
| 14 return json.JSONEncoder.default(self, obj) | |
| 15 | |
| 16 | |
| 17 class AlertBlob(ndb.Model): | |
| 18 date = ndb.DateTimeProperty(auto_now_add=True) | |
| 19 content = ndb.JsonProperty(indexed=False) | |
| 20 | |
| 21 | |
| 22 class IgnoreRule(ndb.Model): | |
| 23 date = ndb.DateTimeProperty(auto_now_add=True) | |
| 24 pattern = ndb.StringProperty(indexed=False) | |
|
ojan
2014/07/22 02:01:25
Will StringProperty be long enough?
| |
| 25 | |
| 26 def dict_with_key(self): | |
| 27 failure_dict = self.to_dict() | |
| 28 failure_dict['key'] = self.key.id() # Should this be urlsafe? | |
| 29 return failure_dict | |
| 30 | |
| 31 def matches(self, failure_dict): | |
| 32 pieces = self.pattern.split('=') | |
| 33 if len(pieces) != 2: | |
| 34 return False | |
| 35 key, value = pieces | |
| 36 if not key or not value: | |
| 37 return False | |
| 38 return value in failure_dict.get(key, '') | |
| 39 | |
| 40 | |
| 41 class IgnoreHandler(webapp2.RequestHandler): | |
| 42 def get(self): | |
| 43 query = IgnoreRule.query() | |
| 44 ignore_dicts = map(IgnoreRule.dict_with_key, query.fetch()) | |
| 45 self.response.headers.add_header("Access-Control-Allow-Origin", "*") | |
| 46 self.response.headers['Content-Type'] = 'application/json' | |
| 47 self.response.write(json.dumps(ignore_dicts, cls=DateTimeEncoder)) | |
| 48 | |
| 49 def post(self): | |
| 50 # FIXME: For whatever reason I can't get <form method='delete'> to work. | |
| 51 if self.request.get('action') == 'delete': | |
| 52 # FIXME: It's lame that this constructor is type-sensitive. | |
| 53 key = ndb.Key(IgnoreRule, int(self.request.get('key'))) | |
| 54 key.delete() | |
| 55 else: | |
| 56 ignore = IgnoreRule() | |
| 57 ignore.pattern = self.request.get('pattern') | |
| 58 ignore.put() | |
| 59 self.redirect('/') | |
| 60 | |
| 61 | |
| 62 class DataHandler(webapp2.RequestHandler): | |
| 63 def get(self): | |
| 64 query = AlertBlob.query().order(-AlertBlob.date) | |
| 65 entries = query.fetch(1) | |
| 66 response_json = {} | |
| 67 if entries: | |
| 68 response_json = entries[0].content | |
| 69 ignores = IgnoreRule.query().fetch() | |
| 70 | |
| 71 def add_ignores(alert): | |
| 72 alert['ignored_by'] = [ignore.key.id() for ignore in ignores if ignore.matches(alert)] | |
| 73 return alert | |
| 74 | |
| 75 response_json.update({ | |
| 76 'date': entries[0].date, | |
| 77 # FIXME: We should take an ignores param instead of always apply ing. | |
| 78 'alerts': map(add_ignores, response_json['alerts']), | |
| 79 'ignores': map(IgnoreRule.dict_with_key, ignores), | |
| 80 }) | |
| 81 | |
| 82 self.response.headers.add_header("Access-Control-Allow-Origin", "*") | |
| 83 self.response.headers['Content-Type'] = 'application/json' | |
| 84 self.response.write(json.dumps(response_json, cls=DateTimeEncoder, inden t=1)) | |
| 85 | |
| 86 def post(self): | |
| 87 alert = AlertBlob() | |
| 88 alert.content = json.loads(self.request.get('content')) | |
| 89 alert.put() | |
| 90 | |
| 91 | |
| 92 app = webapp2.WSGIApplication([ | |
| 93 ('/data', DataHandler), | |
| 94 ('/ignore', IgnoreHandler), | |
| 95 ], debug=True) | |
| OLD | NEW |