Mercurial > templog
annotate web/templog.py @ 237:abc837a7e60f
gevent seems to work
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 06 May 2015 19:40:37 +0800 |
parents | 88dfac30d065 |
children | 509a1be16456 |
rev | line source |
---|---|
27 | 1 #!/usr/bin/env python2.7 |
2 | |
28 | 3 import binascii |
146
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
4 import json |
28 | 5 import hmac |
29 | 6 import zlib |
69 | 7 from datetime import datetime, timedelta |
31
5e75e08d20ac
- Various fixes for web server, kind of works
Matt Johnston <matt@ucc.asn.au>
parents:
30
diff
changeset
|
8 import time |
69 | 9 import urllib |
10 import sys | |
182 | 11 import os |
185 | 12 import traceback |
13 import fcntl | |
28 | 14 |
27 | 15 import bottle |
31
5e75e08d20ac
- Various fixes for web server, kind of works
Matt Johnston <matt@ucc.asn.au>
parents:
30
diff
changeset
|
16 from bottle import route, request, response |
27 | 17 |
28 | 18 import config |
19 import log | |
185 | 20 import secure |
191 | 21 import atomicfile |
28 | 22 |
69 | 23 DATE_FORMAT = '%Y%m%d-%H.%M' |
24 ZOOM_SCALE = 2.0 | |
25 | |
237 | 26 class TemplogBottle(bottle.Bottle): |
27 def run(*args, **argm): | |
28 argm['server'] = 'gevent' | |
29 super(TemplogBottle, self).run(*args, **argm) | |
30 print "ran custom bottle" | |
31 | |
32 bottle.default_app.push(TemplogBottle()) | |
33 | |
34 secure.setup_csrf() | |
35 | |
27 | 36 @route('/update', method='post') |
37 def update(): | |
146
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
38 js_enc = request.forms.data |
28 | 39 mac = request.forms.hmac |
40 | |
146
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
41 if hmac.new(config.HMAC_KEY, js_enc).hexdigest() != mac: |
85 | 42 raise bottle.HTTPError(code = 403, output = "Bad key") |
28 | 43 |
146
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
44 js = zlib.decompress(binascii.a2b_base64(js_enc)) |
28 | 45 |
146
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
46 params = json.loads(js) |
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
47 |
3b4277aaed3c
update web to handle new style params
Matt Johnston <matt@ucc.asn.au>
parents:
103
diff
changeset
|
48 log.parse(params) |
28 | 49 |
50 return "OK" | |
27 | 51 |
52 @route('/graph.png') | |
53 def graph(): | |
69 | 54 length_minutes = int(request.query.length) |
55 end = datetime.strptime(request.query.end, DATE_FORMAT) | |
56 start = end - timedelta(minutes=length_minutes) | |
30
13fcf497f8b7
parse the arguments for start/length
Matt Johnston <matt@ucc.asn.au>
parents:
29
diff
changeset
|
57 |
13fcf497f8b7
parse the arguments for start/length
Matt Johnston <matt@ucc.asn.au>
parents:
29
diff
changeset
|
58 response.set_header('Content-Type', 'image/png') |
69 | 59 start_epoch = time.mktime(start.timetuple()) |
60 return log.graph_png(start_epoch, length_minutes * 60) | |
27 | 61 |
188 | 62 @route('/set/update', method='post') |
194 | 63 def set_update(): |
188 | 64 post_json = json.loads(request.forms.data) |
65 | |
66 csrf_blob = post_json['csrf_blob'] | |
67 | |
194 | 68 if not secure.check_csrf_blob(csrf_blob): |
69 bottle.response.status = 403 | |
70 return "Bad csrf" | |
71 | |
72 ret = log.update_params(post_json['params']) | |
73 if not ret is True: | |
74 bottle.response.status = 403 | |
75 return ret | |
76 | |
77 return "Good" | |
188 | 78 |
182 | 79 @route('/set') |
80 def set(): | |
211
59379b2bd056
key fingerprints are case- and whitespace-insensitive.
Matt Johnston <matt@ucc.asn.au>
parents:
202
diff
changeset
|
81 allowed = ["false", "true"][secure.check_user_hash(config.ALLOWED_USERS)] |
202
6dd157a12035
Add url link, improve atomicfile
Matt Johnston <matt@ucc.asn.au>
parents:
194
diff
changeset
|
82 response.set_header('Cache-Control', 'no-cache') |
185 | 83 return bottle.template('set', |
84 inline_data = log.get_params(), | |
189 | 85 csrf_blob = secure.get_csrf_blob(), |
86 allowed = allowed) | |
182 | 87 |
27 | 88 @route('/') |
89 def top(): | |
69 | 90 |
91 minutes = int(request.query.get('length', 26*60)) | |
92 | |
93 if 'end' in request.query: | |
94 end = datetime.strptime(request.query.end, DATE_FORMAT) | |
95 else: | |
96 end = datetime.now() | |
97 | |
98 if 'zoom' in request.query: | |
99 orig_start = end - timedelta(minutes=minutes) | |
100 orig_end = end | |
101 xpos = int(request.query.x) | |
77 | 102 xpos -= config.GRAPH_LEFT_MARGIN * config.ZOOM |
69 | 103 |
77 | 104 if xpos >= 0 and xpos < config.GRAPH_WIDTH * config.ZOOM: |
69 | 105 click_time = orig_start \ |
77 | 106 + timedelta(minutes=(float(xpos) / (config.GRAPH_WIDTH * config.ZOOM)) * minutes) |
69 | 107 minutes = int(minutes / ZOOM_SCALE) |
108 | |
109 end = click_time + timedelta(minutes=minutes/2) | |
110 else: | |
111 # zoom out | |
112 minutes = int(minutes*ZOOM_SCALE) | |
113 end += timedelta(minutes=minutes/2) | |
114 | |
115 if end > datetime.now(): | |
116 end = datetime.now() | |
117 | |
118 request.query.replace('length', minutes) | |
119 request.query.replace('end', end.strftime(DATE_FORMAT)) | |
120 | |
121 urlparams = urllib.urlencode(request.query) | |
122 return bottle.template('top', urlparams=urlparams, | |
123 end = end.strftime(DATE_FORMAT), | |
124 length = minutes) | |
27 | 125 |
103 | 126 @route('/debug') |
127 def debuglog(): | |
128 response.set_header('Content-Type', 'text/plain') | |
129 return log.tail_debug_log() | |
37
8da0fdadc8d7
- Getting there, update has problems
Matt Johnston <matt@ucc.asn.au>
parents:
31
diff
changeset
|
130 |
182 | 131 @route('/env') |
132 def env(): | |
133 response.set_header('Content-Type', 'text/plain') | |
189 | 134 #return '\n'.join(traceback.format_stack()) |
135 return '\n'.join(("%s %s" % k) for k in request.environ.items()) | |
182 | 136 #return str(request.environ) |
137 #yield "\n" | |
138 #var_lookup = environ['mod_ssl.var_lookup'] | |
139 #return var_lookup("SSL_SERVER_I_DN_O") | |
140 | |
141 @bottle.get('/<filename:re:.*\.js>') | |
142 def javascripts(filename): | |
185 | 143 response.set_header('Cache-Control', "public, max-age=1296000") |
182 | 144 return bottle.static_file(filename, root='static') |
145 | |
27 | 146 def main(): |
61 | 147 #bottle.debug(True) |
148 #bottle.run(reloader=True) | |
149 bottle.run(server='cgi', reloader=True) | |
40 | 150 #bottle.run(port=9999, reloader=True) |
27 | 151 |
152 if __name__ == '__main__': | |
153 main() | |
154 |