From ab4ee6a00affdd6e9fc3ab2ae1135e06c04124cc Mon Sep 17 00:00:00 2001 From: Oskar Date: Mon, 30 Nov 2020 17:18:39 +0100 Subject: [PATCH] Add basic repo structure, dependencies and first endpoint --- .gitignore | 3 +++ README.md | 16 +++++++++++++++- config.ini | 2 ++ docs/SCHEMA.md | 13 +++++++++++++ ftracker/__init__.py | 1 + ftracker/__main__.py | 14 ++++++++++++++ ftracker/__version__.py | 11 +++++++++++ ftracker/config.py | 20 ++++++++++++++++++++ ftracker/core.py | 42 +++++++++++++++++++++++++++++++++++++++++ setup.py | 30 +++++++++++++++++++++++++++++ 10 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 config.ini create mode 100644 docs/SCHEMA.md create mode 100644 ftracker/__init__.py create mode 100644 ftracker/__main__.py create mode 100644 ftracker/__version__.py create mode 100644 ftracker/config.py create mode 100644 ftracker/core.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e075d71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +db.json +*.egg-info diff --git a/README.md b/README.md index a1e7bf0..8b9f79d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,20 @@ Small webapp to track who was in which room at which time to backtrace potential For Ideas and Progress see [Issues](https://git.fasttube.de/FaSTTUBe/ft-corona-tracker/issues). +## How to run + +(Dev setup, prod setup not finished yet) + +```bash +# clone, cd into repo +pip3 install -e . +python3 -m ftracker +``` + +Then, query the endpoint at . + +## License + Licensed under GNU GPL v3, see [LICENSE.md](https://git.fasttube.de/FaSTTUBe/ft-corona-tracker/src/branch/master/LICENSE.md) for details. -Copyright (C) 2020 Oskar/FaSTTUBe \ No newline at end of file +Copyright (C) 2020 Oskar/FaSTTUBe diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..8e061fa --- /dev/null +++ b/config.ini @@ -0,0 +1,2 @@ +[global] +db_file = db.json diff --git a/docs/SCHEMA.md b/docs/SCHEMA.md new file mode 100644 index 0000000..9274e17 --- /dev/null +++ b/docs/SCHEMA.md @@ -0,0 +1,13 @@ +Database Layout +=============== + +Default table +``` +[ + { + 'name': 'firstname-middlename-lastname', + 'arrival': 'UTC-ISO-TIMESTAMP', + 'departure': 'UTC-ISO-TIMESTAMP' + } +] +``` diff --git a/ftracker/__init__.py b/ftracker/__init__.py new file mode 100644 index 0000000..bb67a43 --- /dev/null +++ b/ftracker/__init__.py @@ -0,0 +1 @@ +from .core import * diff --git a/ftracker/__main__.py b/ftracker/__main__.py new file mode 100644 index 0000000..f7c0de1 --- /dev/null +++ b/ftracker/__main__.py @@ -0,0 +1,14 @@ +from .core import * + +# Start the flask server if run from terminal +if __name__ == "__main__": + + # Just allow everything to avoid the hassle when running locally. + @app.after_request + def add_headers(response): + response.headers['Access-Control-Allow-Origin'] = '*' + response.headers['Access-Control-Allow-Methods'] = '*' + response.headers['Access-Control-Allow-Headers'] = '*' + return response + + app.run() diff --git a/ftracker/__version__.py b/ftracker/__version__.py new file mode 100644 index 0000000..028ce52 --- /dev/null +++ b/ftracker/__version__.py @@ -0,0 +1,11 @@ +# _________ _________________________ ________ +# __/ ___/ __ __/´___/__ ____ __// / / // __ )____ +# / /_ _/´__` /\__ \ / /___/ / / / / // __ |/´_ \ +# _/ __/ / /_/ /___/ /_/ / _/ /__/ /_/ // /_/ // __/ +# /_/ ___\__,_//____/ /_/ __/_/ \____//_____/_\___/ + +# Corona time tracker + +VERSION = (0, 0, 1) + +__version__ = '.'.join(map(str, VERSION)) diff --git a/ftracker/config.py b/ftracker/config.py new file mode 100644 index 0000000..aa4099e --- /dev/null +++ b/ftracker/config.py @@ -0,0 +1,20 @@ +import sys, os +from configparser import ConfigParser + +def findConfigFile(): + if len(sys.argv) > 1: + return sys.argv[1] + elif os.path.isfile('config.ini'): + return 'config.ini' + elif os.path.isfile('/etc/ftracker/config.ini'): + return '/etc/ftracker/config.ini' + else: + return None + +configfile = findConfigFile() + +if configfile: + config = ConfigParser() + config.read(configfile) +else: + config = None diff --git a/ftracker/core.py b/ftracker/core.py new file mode 100644 index 0000000..678bf7e --- /dev/null +++ b/ftracker/core.py @@ -0,0 +1,42 @@ +import json +from datetime import datetime + +from .config import config +if not config: + print('No configuration file found.') + exit() + + +from tinydb import TinyDB +db = TinyDB(config.get('global','db_file', fallback='/tmp/ftracker-db.json'), indent=4) +# TODO: Load name list if needed + + +from flask import Flask, request +app = Flask(__name__) + + +@app.route('/') +def get_root(): + return "Error: No Endpoint selected. See docs/API.md for reference.", 404 + +@app.route('/arrival', methods=['POST']) +def post_time(): + + try: + payload = request.data.decode('UTF-8') + data = json.loads(payload) + except ValueError as e: + return 'Error: JSON decode error:\n' + str(e), 400 + + # TODO: JSON schema validation + # TODO: JSON content validation + + now = datetime.utcnow() + db.insert({ + 'name': data['name'], + 'arrival': now.isoformat(), + 'departure': None + }) + + return 'OK', 200 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..6be5e47 --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +import setuptools as st + +with open("README.md", "r") as f: + long_description = f.read() + +with open('LICENSE.md') as f: + license_text = f.read() + +st.setup( + name="ftracker", + version="0.1.0", + author="Oskar @ FaSTTUBe", + author_email="o.winkels@fasttube.de", + description="Small webapp to track who was in which room at which time to backtrace potential viral infections", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://git.fasttube.de/FaSTTUBe/ft-corona-tracker", + packages=st.find_packages(exclude=['tests', 'docs']), + install_requires=[ + "flask", + "tinydb", + ], + license=license_text, + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + "Operating System :: OS Independent", + ], + python_requires='>=3.6', +)