#!/usr/bin/env python3 import pickle import atexit import datetime from flask import Flask, jsonify, request, abort from flask_cors import CORS DB_FILE = "vacation.db" last_update = datetime.datetime.now() app = Flask(__name__) CORS(app) app.config["APPLICATION_ROOT"] = "/vacation/api" app.url_map.strict_slashes = False try: with open(DB_FILE, "rb") as infile: db = pickle.load(infile) except FileNotFoundError: db = {} @atexit.register def save_db(prefix=""): with open(prefix + DB_FILE, "wb") as outfile: pickle.dump(db, outfile) def backup_db(): save_db(f"backup-{datetime.datetime.now().isoformat()}-") @app.route("/") def health(): return jsonify({"status": "healthy"}) @app.route("/availability", methods=["GET", "POST"]) def status(): global last_update if request.method == "POST": body = request.get_json() if body is None: abort(400) name = body.get("name", None) availability = body.get("availability", None) if not isinstance(name, str) or not isinstance(availability, list): abort(400) transaction = [] for a in availability: month = a.get("month", None) day = a.get("day", None) status = a.get("status", None) if (month, day) not in db or status not in ("yes", "no", "maybe", "unknown"): abort(400) transaction.append((month, day, status)) last_update = datetime.datetime.now() for (month, day, status) in transaction: db[(month, day)][name] = status return jsonify({ "lastUpdated": last_update.isoformat(), "availability": [ { "month": month, "day": day, "availability": [{ "name": name, "status": status, } for (name, status) in avail.items()], } for (month, day), avail in db.items() ], }) if __name__ == "__main__": app.run("0.0.0.0", 5000, debug=True)