annotate weather_server/server.py @ 8:d54155a199d8

Improve template; add stylesheet.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Sep 2019 20:32:48 -0400
parents 368f732f13d0
children 52ef21607b31
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
1 import hmac
5
368f732f13d0 Actually make the server runnable.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
2 import sys
4
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
3
1
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
4 import bson
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
5 import flask
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
6
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
7 from . import common
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
8 from . import locations
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
9 from . import types
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
10
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
11
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
12 def build_app(root_directory: str) -> flask.Flask:
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
13 locs = locations.Locations(root_directory)
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
14 app = flask.Flask(__name__)
8
d54155a199d8 Improve template; add stylesheet.
Paul Fisher <paul@pfish.zone>
parents: 5
diff changeset
15 app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
1
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
16
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
17 @app.route('/favicon.ico')
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
18 def favicon():
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
19 return flask.send_file('static/favicon.ico')
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
20
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
21 @app.route('/')
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
22 def home():
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
23 return 'Weather server'
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
24
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
25 @app.route('/_submit', methods=['POST'])
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
26 def submit():
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
27 req = flask.request
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
28 reader = bson.decode_file_iter(
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
29 req.stream, codec_options=common.BSON_OPTIONS)
3
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
30 try:
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
31 preamble = next(reader)
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
32 loc_name = preamble['location']
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
33 password = str(preamble['password'])
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
34 loc, logger = locs.get(loc_name)
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
35 if not hmac.compare_digest(password, loc.password):
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
36 flask.abort(400)
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
37 entries = [
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
38 types.Reading.from_now(
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
39 sample_time=item['sample_time'],
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
40 temp_c=item['temp_c'],
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
41 rh_pct=item['rh_pct'],
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
42 )
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
43 for item in reader
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
44 ]
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
45 except (KeyError, bson.InvalidBSON):
b42c4bfe57c7 server: Use a "preamble" object in the POST to auth.
Paul Fisher <paul@pfish.zone>
parents: 2
diff changeset
46 flask.abort(400)
2
cda47993a193 server: fix bugs and improve template.
Paul Fisher <paul@pfish.zone>
parents: 1
diff changeset
47 logger.write_rows(entries)
cda47993a193 server: fix bugs and improve template.
Paul Fisher <paul@pfish.zone>
parents: 1
diff changeset
48 return flask.jsonify({'status': 'OK'})
1
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
49
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
50 @app.route('/<location>')
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
51 def show(location):
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
52 try:
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
53 loc, logger = locs.get(location)
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
54 except KeyError:
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
55 flask.abort(404)
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
56 data = logger.data
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
57 if data:
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
58 last_reading = data[-1]
2
cda47993a193 server: fix bugs and improve template.
Paul Fisher <paul@pfish.zone>
parents: 1
diff changeset
59 tz = loc.timezone()
1
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
60 date = tz.normalize(last_reading.sample_time.astimezone(tz))
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
61 else:
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
62 last_reading = None
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
63 date = None
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
64 return flask.render_template(
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
65 'location.html',
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
66 location=loc,
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
67 last_reading=last_reading,
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
68 date=date)
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
69
f66df122f18d get the skeleton of a webserver up?
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
70 return app
4
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
71
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
72
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
73 def main(argv):
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
74 """Main function for a simple local demo."""
5
368f732f13d0 Actually make the server runnable.
Paul Fisher <paul@pfish.zone>
parents: 4
diff changeset
75 app = build_app(argv[0])
4
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
76 app.run(host='0.0.0.0')
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
77
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
78
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
79 if __name__ == '__main__':
e7c8dcc5fc15 Make the weather server pip-installable and locally runnable.
Paul Fisher <paul@pfish.zone>
parents: 3
diff changeset
80 main(sys.argv[1:])