Skip to content
Snippets Groups Projects
Commit f5b2810b authored by David Huss's avatar David Huss :speech_balloon:
Browse files

Cleanup ind Code & Readme

parent 8750596e
Branches
No related tags found
No related merge requests found
......@@ -89,14 +89,22 @@ chmod +x /etc/cron.daily/stechuhr_data_retention
## Configuration
### Application
Stechuhr-Server allows you to use _multiple_ configuration files, each overriding the previous one either in full or partly. In any case a default configuration is used, which might or might not fit your purpose (probably not).
To maintain control a helper script exists at `stechuhr_server/config.py` which allows you to create a new config, print the currently used ones, etc. If your system python has the `toml` dependency installed run it using `python3 stechuhr_server/config.py` and it will display the help. If you _don't_ have the toml dependency installed you can:
1. Install it
2. Use the python in env (see installation above): `path/to/env/bin/python stechuhr_server/config.py`
3. Use python poetry: `poetry run config`
### Config section: application
Application related settings. Here the database can be exposed via a GET request for debugging purposes. Make sure this is off in production, or make sure no such http requests can be made from the public internet.
### Database
### Config section: database.path
Set the path to change where the database file is stored. Make sure that the path is writeable by the service user
### ID verification
### Config section: database.id_patterns
in `config.toml` you can add a list of regex patterns that stechuhr (*both on server and on client!*) uses to verify the Card IDs. These two patterns for example allow upper/lowercase hex strings with lengths either between 6 and 16 characters OR exactly 24 characters:
......@@ -111,3 +119,7 @@ id_patterns = [
```
If in doubt consider [testing your regexes here](https://regexplained.com/)
### Config section: retention
You might not be allowed to keep the collected data around for later. Here you can specify the number of days you wanna keep the data around (in Germany this might be 28 days, but inform yourself). You will additionally need to [install the data retention script](#Data Retention)
\ No newline at end of file
......@@ -21,10 +21,10 @@ expose_visitor_data = false
expose_current_visitor_number = false
[database]
# sqlite db path, use ":memory:" for RAM db
# Path of the sqlite database file, use ":memory:" to use in RAM only database
path = "visitors.db"
# A list of possible regex patterns for the id (logical OR!)
# A list of possible regex patterns for the card ids (combined by logical OR!)
id_patterns = [
"^806[A-Z0-9]{9}04$",
"^FB6A1E60$",
......@@ -33,15 +33,15 @@ id_patterns = [
"^FB67D500$",
]
# minimum and maximum lengths for the received strings
# Minimum and maximum lengths for the received data fields
min_entrance_length = 1
max_entrance_length = 128
min_location_length = 1
max_location_length = 128
[retention]
# how old is data allowed to be (in days)
duration = 365
# Duration in days to keep data around (German law is 28 days)
duration = 28
"""
# Config for the logger, there should be no need to make
......@@ -149,6 +149,7 @@ def has_no_existing_config() -> bool:
"""
return len(get_existing_config_file_paths()) == 0
def merge(this: dict, that: dict) -> dict:
"""
Merge dict this in to dict that
......@@ -160,6 +161,7 @@ def merge(this: dict, that: dict) -> dict:
this[key] = value
return this
def initialize_config(logger=None) -> dict:
"""
Initialize a configuration. If none exists, create a default one
......@@ -208,8 +210,8 @@ def main():
Gets run only if config.py is called directly or via `poetry run config`
Entry point for the CLI application
"""
import sys
# List of available commands and their respective functions
commands = {
"default" : print_default,
"paths": print_paths,
......@@ -218,45 +220,82 @@ def main():
"test": test
}
# List of available options
availaible_options = [
["-h", "--help"]
]
# If no argument has been passed display the help and exit
if len(sys.argv) == 1:
print_help()
exit()
# Extract the command arguments
command_args = [c for c in sys.argv[1:] if not c.strip().startswith("-")]
# Extract the short_options
short_options = [c.lstrip("-") for c in sys.argv[1:] if c.strip().startswith("-") and not c.strip().startswith("--")]
# Flatten the short_options to e.g. so -1234 will result in ["1", "2", "3", "4"]
short_options = [item for sublist in short_options for item in sublist]
# Extract the long options
long_options = [c.lstrip("--") for c in sys.argv[1:] if c.strip().startswith("--")]
errored = False
# Short Options
for o in short_options:
if o not in [a[0].lstrip("-") for a in availaible_options]:
print("Error: the option \"-{}\" does not exist.".format(o), file=sys.stderr)
errored = True
# Long Options
for o in long_options:
if o not in [a[0].lstrip("--") for a in availaible_options]:
print("Error: the option \"--{}\" does not exist.".format(o), file=sys.stderr)
errored = True
# If any of the above errored, exit. This allows to display all errors at once
if errored:
print("\nCheck the available commands and options below:")
print()
print_help()
exit()
# Currently we only handle a single command
if len(command_args) == 1:
command = sys.argv[1]
# Short commands are allowed if they are not ambigous. E.g "te" will trigger "test"
if not any([c.startswith(command.strip().lower()) for c in commands.keys()]):
# No fitting command has been found, print helpt and exit
print_help()
exit()
elif len([c for c in commands.keys() if c.startswith(command.strip().lower())]) > 1:
# More than one fitting command has been found, display this message
print("Ambiguous Input: There are {} commands starting with \"{}\": {}".format(
len([c for c in commands.keys() if c.startswith(command.strip().lower())]),
command,
", ".join([c for c in commands.keys() if c.startswith(command.strip().lower())])
))
else:
# A command has been found:
choice = [c for c in commands.keys() if c.startswith(command.strip().lower())][0]
# If there is a -h or --help option, display the function's docstring
# otherwise execute the function
if "h" in short_options or "help" in long_options:
print("Help: config {}".format(commands[choice].__name__))
print(commands[choice].__doc__)
else:
commands[choice]()
else:
# If more than one command is given, display the help
print_help()
def test():
"""
Runs the config initialization as it would in production, prints out the
order in which the config files are read and spits out the final resulting
toml config
Reads all configs like it would in production, prints out the order in which the config files are read and spits out the final resulting toml config
"""
import pprint
config = initialize_config()
......@@ -265,11 +304,15 @@ def test():
def print_default():
"""
Print default config
Prints the default config.toml
"""
print(DEFAULT_CONFIG)
def print_paths():
"""
Prints the potential paths where a config could or should be. If environment variables are used to specify said path, this will be mentioned. If a file doesn't exist, it will be mentioned as well.
"""
paths = get_potential_config_file_paths()
if paths is not None:
for p in paths:
......@@ -286,6 +329,7 @@ def print_paths():
else:
print("There are no paths..")
def print_directories():
"""
Prints a list of directories where configs are searched for.
......@@ -301,9 +345,10 @@ def print_directories():
else:
print("There are no directories..")
def create_config():
"""
Interactivally create a config directory with a default config in it.
Interactivally create a config directory at a choice of different places with a default config in it.
"""
helptext = """Configs are read from the following directories (later overrides earlier):
1. DEFAULT_CONFIG (use config default to inspect)
......@@ -389,8 +434,10 @@ def create_config():
print("Default Config has been written to {}".format(config_path))
def print_help():
"""
Print the help
"""
helptext = """========= {} CONFIG =========
Helper tool for managing and installing a stechuhr-server config.
......@@ -408,9 +455,13 @@ Commands:
directories . . . Prints which config directories are read
paths . . . . . . Prints which config files are read
test . . . . . . Read in the configs and print the resulting combined toml
Options:
-h, --help . . . Display the help message of a command
""".format(APPLICATION_NAME.upper())
print(helptext)
if __name__ == "__main__":
main()
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment