[ini]
This commit is contained in:
commit
0898341511
10 changed files with 733 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/.geany
|
16
misc/conf.example.json
Normal file
16
misc/conf.example.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"log": {
|
||||||
|
"format": "human_readable",
|
||||||
|
"min_level": "info"
|
||||||
|
},
|
||||||
|
"backend": {
|
||||||
|
"scheme": "http",
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 4916,
|
||||||
|
"path": ""
|
||||||
|
},
|
||||||
|
"credentials": {
|
||||||
|
"name": "admin",
|
||||||
|
"password": "admin"
|
||||||
|
}
|
||||||
|
}
|
38
readme.md
Normal file
38
readme.md
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Mondvogel
|
||||||
|
|
||||||
|
## Beschreibung
|
||||||
|
|
||||||
|
- Kommandozeilen-Client für das [Espe](https://gitlab.die-linke.cloud/espe)
|
||||||
|
|
||||||
|
|
||||||
|
## Erstellung
|
||||||
|
|
||||||
|
### Voraussetzungen
|
||||||
|
|
||||||
|
- (keine)
|
||||||
|
|
||||||
|
|
||||||
|
### Anweisungen
|
||||||
|
|
||||||
|
- `tools/build <ziel-verzeichnis>` ausführen
|
||||||
|
|
||||||
|
|
||||||
|
## Benutzung
|
||||||
|
|
||||||
|
### Voraussetzungen
|
||||||
|
|
||||||
|
- Python 3 (Debian-Paket-Name: `python3`)
|
||||||
|
|
||||||
|
|
||||||
|
### Anweisungen
|
||||||
|
|
||||||
|
- Ausführung
|
||||||
|
- `python3 <ziel-verzeichnis>/main.py` ausführen
|
||||||
|
- durch Anfügen des Schalters `-h`/`--help` wird die Erläuterung zur Syntax angezeigt
|
||||||
|
- Konfiguration
|
||||||
|
- `misc/conf.example.json` kopieren nach (bspw.) `~/.mondvogel/conf.json` und die Werte anpassen um eine initiale Konfiguration zu erstellen
|
||||||
|
- das JSON-Schema der Konfiguration mit Hinweisen zu den verfügbaren Optionen lässt sich durch die Aktion `conf-schema` ausgeben
|
||||||
|
- die vervollständigte Konfiguration lässt sich durch die Aktion `conf-expose` anzeigen
|
||||||
|
- Installation
|
||||||
|
- als `root` `tools/install` ausführen
|
||||||
|
- dadurch sollte `mondvogel` als systemweiter Befehl verwendbar sein
|
118
source/backend.py
Normal file
118
source/backend.py
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
import typing as _typing
|
||||||
|
import json as _json
|
||||||
|
import requests as _requests
|
||||||
|
|
||||||
|
from helpers import *
|
||||||
|
from conf import *
|
||||||
|
from log import *
|
||||||
|
|
||||||
|
|
||||||
|
def backend_api_call_generic(
|
||||||
|
session_key,
|
||||||
|
http_method,
|
||||||
|
action_path,
|
||||||
|
data
|
||||||
|
):
|
||||||
|
log_info(
|
||||||
|
"backend_api_call",
|
||||||
|
{
|
||||||
|
"with_session_key": (not (session_key is None)),
|
||||||
|
"http_method": http_method,
|
||||||
|
"path": action_path,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
target = string_coin(
|
||||||
|
"{{scheme}}://{{host}}:{{port}}{{path_base}}{{path_action}}",
|
||||||
|
{
|
||||||
|
"scheme": conf_get()["api"]["scheme"],
|
||||||
|
"host": conf_get()["api"]["host"],
|
||||||
|
"port": ("%u" % conf_get()["api"]["port"]),
|
||||||
|
"path_base": conf_get()["api"]["path"],
|
||||||
|
"path_action": action_path,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (http_method == "GET"):
|
||||||
|
response_raw = _requests.get(
|
||||||
|
target,
|
||||||
|
headers = {
|
||||||
|
"X-Session-Key": session_key,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return _json.loads(response_raw.text)
|
||||||
|
elif (http_method == "POST"):
|
||||||
|
response_raw = _requests.post(
|
||||||
|
target,
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Session-Key": session_key,
|
||||||
|
},
|
||||||
|
json = data
|
||||||
|
)
|
||||||
|
return _json.loads(response_raw.text)
|
||||||
|
elif (http_method == "DELETE"):
|
||||||
|
response_raw = _requests.delete(
|
||||||
|
target,
|
||||||
|
headers = {
|
||||||
|
"X-Session-Key": session_key,
|
||||||
|
},
|
||||||
|
json = data
|
||||||
|
)
|
||||||
|
return _json.loads(response_raw.text)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("unhandled HTTP method: %s" % http_method)
|
||||||
|
|
||||||
|
|
||||||
|
def backend_api_call_session_begin(
|
||||||
|
) -> str:
|
||||||
|
return backend_api_call_generic(
|
||||||
|
None,
|
||||||
|
"POST",
|
||||||
|
"/session/begin",
|
||||||
|
{
|
||||||
|
"name": conf_get()["account"]["name"],
|
||||||
|
"password": conf_get()["account"]["password"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def backend_api_call_session_end(
|
||||||
|
session_key
|
||||||
|
):
|
||||||
|
return backend_api_call_generic(
|
||||||
|
session_key,
|
||||||
|
"DELETE",
|
||||||
|
"/session/end",
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def backend_api_call_member_list(
|
||||||
|
session_key : str
|
||||||
|
):
|
||||||
|
return backend_api_call_generic(
|
||||||
|
session_key,
|
||||||
|
"GET",
|
||||||
|
"/member/list",
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def backend_api_call_member_project(
|
||||||
|
session_key : str,
|
||||||
|
membership_number : _typing.Optional[str],
|
||||||
|
name_real_value : str,
|
||||||
|
email_address_private : _typing.Optional[str],
|
||||||
|
notification_target_url_template : _typing.Optional[str]
|
||||||
|
):
|
||||||
|
return backend_api_call_generic(
|
||||||
|
session_key,
|
||||||
|
"POST",
|
||||||
|
"/member/project",
|
||||||
|
{
|
||||||
|
"membership_number": membership_number,
|
||||||
|
"name_real_value": name_real_value,
|
||||||
|
"email_address_private": email_address_private,
|
||||||
|
"notification_target_url_template": notification_target_url_template,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
191
source/conf.py
Normal file
191
source/conf.py
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
import os as _os
|
||||||
|
import json as _json
|
||||||
|
|
||||||
|
from helpers import *
|
||||||
|
|
||||||
|
|
||||||
|
_conf_data = None
|
||||||
|
|
||||||
|
def conf_schema(
|
||||||
|
):
|
||||||
|
return {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"type": "number",
|
||||||
|
"enum": [
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"log": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"format": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"jsonl",
|
||||||
|
"human_readable",
|
||||||
|
],
|
||||||
|
"default": "human_readable",
|
||||||
|
"description": "Format der Log-Einträge"
|
||||||
|
},
|
||||||
|
"min_level": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"notice",
|
||||||
|
"warning",
|
||||||
|
"error",
|
||||||
|
],
|
||||||
|
"default": "notice",
|
||||||
|
"description": "Mindest-Level für Log-Einträge um aufgeführt zu werden"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"additionalProperties": False,
|
||||||
|
"required": [
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"scheme": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "https"
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 4916
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": False,
|
||||||
|
"required": [
|
||||||
|
"host"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"account": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"additionalProperties": False,
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"password",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def conf_refine(
|
||||||
|
data_raw
|
||||||
|
):
|
||||||
|
flaws = []
|
||||||
|
if (not ("version" in data_raw)):
|
||||||
|
flaws.append(
|
||||||
|
{
|
||||||
|
"incident": "mandatory_value_missing",
|
||||||
|
"details": {
|
||||||
|
"path": "version",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
data = None
|
||||||
|
else:
|
||||||
|
version = data_raw["version"]
|
||||||
|
if (version == 1):
|
||||||
|
# log
|
||||||
|
if True:
|
||||||
|
data_raw_log = data_raw.get("log", {})
|
||||||
|
data_log = {
|
||||||
|
"format": data_raw_log.get("format", "human_readable"),
|
||||||
|
"min_level": data_raw_log.get("min_level", "notice"),
|
||||||
|
}
|
||||||
|
# api
|
||||||
|
if True:
|
||||||
|
data_raw_api = data_raw.get("api", {})
|
||||||
|
data_api = {
|
||||||
|
"scheme": data_raw_api.get("scheme", "https"),
|
||||||
|
"host": data_raw_api["host"],
|
||||||
|
"port": data_raw_api.get("port", 4916),
|
||||||
|
"path": data_raw_api.get("path", ""),
|
||||||
|
}
|
||||||
|
# account
|
||||||
|
if True:
|
||||||
|
data_raw_account = data_raw.get("account", {})
|
||||||
|
data_account = {
|
||||||
|
"name": data_raw_account["name"],
|
||||||
|
"password": data_raw_account["password"],
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
"log": data_log,
|
||||||
|
"api": data_api,
|
||||||
|
"account": data_account,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
flaws.append(
|
||||||
|
{
|
||||||
|
"incident": "invalid_version",
|
||||||
|
"details": {
|
||||||
|
"value": version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
data = None
|
||||||
|
return {
|
||||||
|
"flaws": flaws,
|
||||||
|
"data": data,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def conf_load(
|
||||||
|
path : str
|
||||||
|
):
|
||||||
|
global _conf_data
|
||||||
|
if (not _os.path.exists(path)):
|
||||||
|
raise ValueError("configuration missing: %s" % path)
|
||||||
|
else:
|
||||||
|
data_raw = _json.loads(file_text_read(path))
|
||||||
|
refinement = conf_refine(data_raw)
|
||||||
|
if (len(refinement["flaws"]) > 0):
|
||||||
|
raise ValueError(
|
||||||
|
"configuration invalid:\n%s"
|
||||||
|
% convey(
|
||||||
|
refinement["flaws"],
|
||||||
|
[
|
||||||
|
lambda flaws: map(
|
||||||
|
lambda flaw: string_coin(
|
||||||
|
"- {{incident}} | {{details}}",
|
||||||
|
{
|
||||||
|
"incident": flaw["incident"],
|
||||||
|
"details": _json.dumps(flaw["details"]),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
flaws
|
||||||
|
),
|
||||||
|
"\n".join,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_conf_data = refinement["data"]
|
||||||
|
|
||||||
|
|
||||||
|
def conf_get(
|
||||||
|
):
|
||||||
|
global _conf_data
|
||||||
|
return _conf_data
|
||||||
|
|
63
source/helpers.py
Normal file
63
source/helpers.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import os as _os
|
||||||
|
import json as _json
|
||||||
|
import subprocess as _subprocess
|
||||||
|
import functools as _functools
|
||||||
|
|
||||||
|
|
||||||
|
def convey(
|
||||||
|
x,
|
||||||
|
fs
|
||||||
|
):
|
||||||
|
y = x
|
||||||
|
for f in fs:
|
||||||
|
y = f(y)
|
||||||
|
return y
|
||||||
|
|
||||||
|
|
||||||
|
def file_text_read(
|
||||||
|
path : str
|
||||||
|
) -> str:
|
||||||
|
handle = open(path, "r")
|
||||||
|
content = handle.read()
|
||||||
|
handle.close()
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def file_binary_read(
|
||||||
|
path : str
|
||||||
|
) -> str:
|
||||||
|
handle = open(path, "rb")
|
||||||
|
content = handle.read()
|
||||||
|
handle.close()
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def file_text_write(
|
||||||
|
path : str,
|
||||||
|
content : str
|
||||||
|
):
|
||||||
|
_os.makedirs(_os.path.dirname(path), exist_ok = True)
|
||||||
|
handle = open(path, "w" if _os.path.exists(path) else "a")
|
||||||
|
handle.write(content)
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
|
||||||
|
def file_binary_write(
|
||||||
|
path : str,
|
||||||
|
content
|
||||||
|
):
|
||||||
|
_os.makedirs(_os.path.dirname(path), exist_ok = True)
|
||||||
|
handle = open(path, ("w" if _os.path.exists(path) else "a") + "b")
|
||||||
|
handle.write(content)
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
|
||||||
|
def string_coin(
|
||||||
|
template : str,
|
||||||
|
arguments : dict[str,str]
|
||||||
|
) -> str:
|
||||||
|
result = template
|
||||||
|
for (key, value, ) in arguments.items():
|
||||||
|
result = result.replace("{{%s}}" % key, value)
|
||||||
|
return result
|
||||||
|
|
139
source/log.py
Normal file
139
source/log.py
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
import typing as _typing
|
||||||
|
import enum as _enum
|
||||||
|
import sys as _sys
|
||||||
|
import json as _json
|
||||||
|
import datetime as _datetime
|
||||||
|
|
||||||
|
from helpers import *
|
||||||
|
|
||||||
|
|
||||||
|
class enum_log_level(_enum.Enum):
|
||||||
|
DEBUG = 0
|
||||||
|
NOTICE = 1
|
||||||
|
INFO = 2
|
||||||
|
WARNING = 3
|
||||||
|
ERROR = 4
|
||||||
|
def __lt__(self, other):
|
||||||
|
return (self.value < other.value)
|
||||||
|
|
||||||
|
|
||||||
|
_log_outputs = []
|
||||||
|
|
||||||
|
|
||||||
|
def log_add_output(
|
||||||
|
output
|
||||||
|
):
|
||||||
|
_log_outputs.append(output)
|
||||||
|
|
||||||
|
|
||||||
|
def log_generic(
|
||||||
|
level,
|
||||||
|
report
|
||||||
|
):
|
||||||
|
def encode_level(level):
|
||||||
|
return {
|
||||||
|
enum_log_level.ERROR: "err",
|
||||||
|
enum_log_level.WARNING: "wrn",
|
||||||
|
enum_log_level.NOTICE: "ntc",
|
||||||
|
enum_log_level.INFO: "inf",
|
||||||
|
enum_log_level.DEBUG: "dbg",
|
||||||
|
}[level]
|
||||||
|
for output in _log_outputs:
|
||||||
|
if (level < output["min_level"]):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if (output["format"] == "jsonl"):
|
||||||
|
_sys.stderr.write(
|
||||||
|
_json.dumps(
|
||||||
|
{
|
||||||
|
"level": encode_level(level),
|
||||||
|
"timestamp": int(_datetime.datetime.now().timestamp()),
|
||||||
|
"incident": report["incident"],
|
||||||
|
"details": report["details"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
+
|
||||||
|
"\n"
|
||||||
|
)
|
||||||
|
elif (output["format"] == "human_readable"):
|
||||||
|
_sys.stderr.write(
|
||||||
|
string_coin(
|
||||||
|
"<{{time}}> [{{level}}] {{incident}} | {{details}}",
|
||||||
|
{
|
||||||
|
"time": _datetime.datetime.now().isoformat()[:19],
|
||||||
|
"level": encode_level(level),
|
||||||
|
"incident": report["incident"],
|
||||||
|
"details": _json.dumps(report["details"])[:127],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
+
|
||||||
|
"\n"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError("invalid log format: %s" % output["format"])
|
||||||
|
|
||||||
|
|
||||||
|
def log_error(
|
||||||
|
incident,
|
||||||
|
details = None
|
||||||
|
):
|
||||||
|
log_generic(
|
||||||
|
enum_log_level.ERROR,
|
||||||
|
{
|
||||||
|
"incident": incident,
|
||||||
|
"details": (details or {})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def log_warning(
|
||||||
|
incident,
|
||||||
|
details = None
|
||||||
|
):
|
||||||
|
log_generic(
|
||||||
|
enum_log_level.WARNING,
|
||||||
|
{
|
||||||
|
"incident": incident,
|
||||||
|
"details": (details or {})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def log_notice(
|
||||||
|
incident,
|
||||||
|
details = None
|
||||||
|
):
|
||||||
|
log_generic(
|
||||||
|
enum_log_level.NOTICE,
|
||||||
|
{
|
||||||
|
"incident": incident,
|
||||||
|
"details": (details or {})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def log_info(
|
||||||
|
incident,
|
||||||
|
details = None
|
||||||
|
):
|
||||||
|
log_generic(
|
||||||
|
enum_log_level.INFO,
|
||||||
|
{
|
||||||
|
"incident": incident,
|
||||||
|
"details": (details or {})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def log_debug(
|
||||||
|
incident,
|
||||||
|
details = None
|
||||||
|
):
|
||||||
|
log_generic(
|
||||||
|
enum_log_level.DEBUG,
|
||||||
|
{
|
||||||
|
"incident": incident,
|
||||||
|
"details": (details or {})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
134
source/main.py
Normal file
134
source/main.py
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import typing as _typing
|
||||||
|
import sys as _sys
|
||||||
|
import os as _os
|
||||||
|
import json as _json
|
||||||
|
import argparse as _argparse
|
||||||
|
|
||||||
|
from log import *
|
||||||
|
from conf import *
|
||||||
|
from backend import *
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
## args
|
||||||
|
argument_parser = _argparse.ArgumentParser(
|
||||||
|
prog = "mondvogel",
|
||||||
|
description = "CLI-Client-Programm für Espe",
|
||||||
|
formatter_class = _argparse.ArgumentDefaultsHelpFormatter
|
||||||
|
)
|
||||||
|
argument_parser.add_argument(
|
||||||
|
type = str,
|
||||||
|
dest = "action",
|
||||||
|
choices = [
|
||||||
|
"member-list",
|
||||||
|
"member-project",
|
||||||
|
],
|
||||||
|
metavar = "<action>",
|
||||||
|
help = "auszuführende Aktion; Optionen: 'conf-schema' : JSON-Schema der Konfiguration ausgeben | 'conf-expose' : vervollständigte Konfiguration ausgegeben | 'member-list' : Liste der Mitglieder ausgeben | 'member-project' : ein Mitglied anlegen und die ID des erzeugten Datensatzes ausgeben",
|
||||||
|
)
|
||||||
|
argument_parser.add_argument(
|
||||||
|
"-c",
|
||||||
|
"--conf-path",
|
||||||
|
type = str,
|
||||||
|
dest = "conf_path",
|
||||||
|
default = _os.path.join(_os.path.expanduser("~"), ".mondvogel", "conf.json"),
|
||||||
|
metavar = "<conf-path>",
|
||||||
|
help = "Pfad zur Konfigurations-Datei",
|
||||||
|
)
|
||||||
|
argument_parser.add_argument(
|
||||||
|
"-m",
|
||||||
|
"--membership-number",
|
||||||
|
type = str,
|
||||||
|
dest = "membership_number",
|
||||||
|
default = None,
|
||||||
|
metavar = "<membership-number>",
|
||||||
|
help = "Mitglieds-Nummer des Mitglieds",
|
||||||
|
)
|
||||||
|
argument_parser.add_argument(
|
||||||
|
"-n",
|
||||||
|
"--name",
|
||||||
|
type = str,
|
||||||
|
dest = "name",
|
||||||
|
default = None,
|
||||||
|
metavar = "<name>",
|
||||||
|
help = "Name des Mitglieds",
|
||||||
|
)
|
||||||
|
argument_parser.add_argument(
|
||||||
|
"-e",
|
||||||
|
"--email-address",
|
||||||
|
type = str,
|
||||||
|
dest = "email_address",
|
||||||
|
default = None,
|
||||||
|
metavar = "<email-address>",
|
||||||
|
help = "E-Mail-Adresse des Mitglieds",
|
||||||
|
)
|
||||||
|
args = argument_parser.parse_args()
|
||||||
|
|
||||||
|
## conf
|
||||||
|
conf_load(args.conf_path)
|
||||||
|
log_add_output(
|
||||||
|
{
|
||||||
|
"format": conf_get()["log"]["format"],
|
||||||
|
"min_level": (
|
||||||
|
{
|
||||||
|
"error": enum_log_level.ERROR,
|
||||||
|
"warning": enum_log_level.WARNING,
|
||||||
|
"notice": enum_log_level.NOTICE,
|
||||||
|
"info": enum_log_level.INFO,
|
||||||
|
"debug": enum_log_level.DEBUG,
|
||||||
|
}[conf_get()["log"]["min_level"]]
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
## exec
|
||||||
|
if (args.action == "conf-schema"):
|
||||||
|
_sys.stdout.write(_json.dumps(conf_schema(), indent = "\t") + "\n")
|
||||||
|
elif (args.action == "conf-expose"):
|
||||||
|
_sys.stdout.write(_json.dumps(conf_get(), indent = "\t") + "\n")
|
||||||
|
elif (args.action == "member-list"):
|
||||||
|
session_key = backend_api_call_session_begin()
|
||||||
|
data = backend_api_call_member_list(
|
||||||
|
session_key
|
||||||
|
)
|
||||||
|
backend_api_call_session_end(session_key)
|
||||||
|
_sys.stdout.write(_json.dumps(data, indent = "\t") + "\n")
|
||||||
|
elif (args.action == "member-project"):
|
||||||
|
if (
|
||||||
|
(args.membership_number is None)
|
||||||
|
or
|
||||||
|
(args.name is None)
|
||||||
|
or
|
||||||
|
(args.email_address is None)
|
||||||
|
):
|
||||||
|
log_error(
|
||||||
|
"mandatory_parameters_missing",
|
||||||
|
{
|
||||||
|
"parameters": [
|
||||||
|
"membership_number",
|
||||||
|
"name",
|
||||||
|
"email_address",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
session_key = backend_api_call_session_begin()
|
||||||
|
member_id = backend_api_call_member_project(
|
||||||
|
session_key,
|
||||||
|
args.membership_number,
|
||||||
|
args.name,
|
||||||
|
args.email_address,
|
||||||
|
None
|
||||||
|
)
|
||||||
|
backend_api_call_session_end(session_key)
|
||||||
|
_sys.stdout.write(_json.dumps(member_id, indent = "\t") + "\n")
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except ValueError as error:
|
||||||
|
_sys.stderr.write(str(error) + "\n")
|
||||||
|
_sys.exit(1)
|
17
tools/build
Executable file
17
tools/build
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
## args
|
||||||
|
|
||||||
|
if [ $# -ge 1 ] ; then dir_build=$1 && shift ; else dir_build="/tmp/mondvogel" ; fi
|
||||||
|
|
||||||
|
|
||||||
|
## vars
|
||||||
|
|
||||||
|
dir_source="source"
|
||||||
|
|
||||||
|
|
||||||
|
## exec
|
||||||
|
|
||||||
|
mkdir --parents ${dir_build}
|
||||||
|
cp --recursive --update ${dir_source}/*.py ${dir_build}/
|
||||||
|
echo "-- ${dir_build}"
|
16
tools/install
Executable file
16
tools/install
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
## args
|
||||||
|
|
||||||
|
if [ $# -ge 1 ] ; then dir_build=$1 && shift ; else dir_build="/tmp/mondvogel" ; fi
|
||||||
|
if [ $# -ge 1 ] ; then dir_target=$1 && shift ; else dir_target="/opt/mondvogel" ; fi
|
||||||
|
if [ $# -ge 1 ] ; then path_bin=$1 && shift ; else path_bin="/usr/local/bin/mondvogel" ; fi
|
||||||
|
|
||||||
|
|
||||||
|
## exec
|
||||||
|
|
||||||
|
mkdir --parents ${dir_target}
|
||||||
|
cp --recursive ${dir_build}/* ${dir_target}/
|
||||||
|
echo "cd ${dir_target} && python3 main.py \$@" > ${path_bin}
|
||||||
|
chmod +x ${path_bin}
|
||||||
|
echo "-- ${path_bin}"
|
Loading…
Add table
Reference in a new issue