view weather_server/server.py @ 2:cda47993a193

server: fix bugs and improve template.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Sep 2019 01:18:18 -0400
parents f66df122f18d
children b42c4bfe57c7
line wrap: on
line source

import bson
import flask

from . import common
from . import locations
from . import types


def build_app(root_directory: str) -> flask.Flask:
    locs = locations.Locations(root_directory)
    app = flask.Flask(__name__)

    @app.route('/favicon.ico')
    def favicon():
        return flask.send_file('static/favicon.ico')

    @app.route('/')
    def home():
        return 'Weather server'

    @app.route('/_submit', methods=['POST'])
    def submit():
        req = flask.request
        target = req.args.get('location')
        if not target:
            flask.abort(404)
        try:
            target_loc, logger = locs.get(target)
        except KeyError:
            flask.abort(404)

        password = req.args.get('password')
        if password != target_loc.password:
            flask.abort(401)

        reader = bson.decode_file_iter(
            req.stream, codec_options=common.BSON_OPTIONS)
        entries = [
            types.Reading.from_now(
                sample_time=item['sample_time'],
                temp_c=item['temp_c'],
                rh_pct=item['rh_pct'],
            )
            for item in reader
        ]
        logger.write_rows(entries)
        return flask.jsonify({'status': 'OK'})

    @app.route('/<location>')
    def show(location):
        try:
            loc, logger = locs.get(location)
        except KeyError:
            flask.abort(404)
        data = logger.data
        if data:
            last_reading = data[-1]
            tz = loc.timezone()
            date = tz.normalize(last_reading.sample_time.astimezone(tz))
        else:
            last_reading = None
            date = None
        return flask.render_template(
            'location.html',
            location=loc,
            last_reading=last_reading,
            date=date)

    return app