Replace configparser with tomllib
This commit is contained in:
@@ -20,9 +20,9 @@ Installer python, og lag og aktiver et venv. Installer så avhengighetene med `p
|
|||||||
Deretter kan du kjøre programmet med
|
Deretter kan du kjøre programmet med
|
||||||
|
|
||||||
```console
|
```console
|
||||||
python -m dibbler -c example-config.ini create-db
|
python -m dibbler -c example-config.toml create-db
|
||||||
python -m dibbler -c example-config.ini seed-data
|
python -m dibbler -c example-config.toml seed-data
|
||||||
python -m dibbler -c example-config.ini loop
|
python -m dibbler -c example-config.toml loop
|
||||||
```
|
```
|
||||||
|
|
||||||
## Nix
|
## Nix
|
||||||
@@ -46,7 +46,7 @@ Du kan også bygge pakken manuelt, eller kjøre den direkte:
|
|||||||
```console
|
```console
|
||||||
nix build .#dibbler
|
nix build .#dibbler
|
||||||
|
|
||||||
nix run .# -- --config example-config.ini create-db
|
nix run .# -- --config example-config.toml create-db
|
||||||
nix run .# -- --config example-config.ini seed-data
|
nix run .# -- --config example-config.toml seed-data
|
||||||
nix run .# -- --config example-config.ini loop
|
nix run .# -- --config example-config.toml loop
|
||||||
```
|
```
|
||||||
|
|||||||
+18
-7
@@ -1,13 +1,10 @@
|
|||||||
# This module is supposed to act as a singleton and be filled
|
from typing import Any
|
||||||
# with config variables by cli.py
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import tomllib
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
import configparser
|
DEFAULT_CONFIG_PATH = Path('/etc/dibbler/dibbler.toml')
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
|
|
||||||
DEFAULT_CONFIG_PATH = Path('/etc/dibbler/dibbler.conf')
|
|
||||||
|
|
||||||
def default_config_path_submissive_and_readable() -> bool:
|
def default_config_path_submissive_and_readable() -> bool:
|
||||||
return DEFAULT_CONFIG_PATH.is_file() and any(
|
return DEFAULT_CONFIG_PATH.is_file() and any(
|
||||||
@@ -23,3 +20,17 @@ def default_config_path_submissive_and_readable() -> bool:
|
|||||||
(DEFAULT_CONFIG_PATH.stat().st_mode & 0o004),
|
(DEFAULT_CONFIG_PATH.stat().st_mode & 0o004),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
config: dict[str, dict[str, Any]] = dict()
|
||||||
|
|
||||||
|
def load_config(config_path: Path | None = None):
|
||||||
|
global config
|
||||||
|
if config_path is not None:
|
||||||
|
with Path(config_path).open("rb") as file:
|
||||||
|
config = tomllib.load(file)
|
||||||
|
elif default_config_path_submissive_and_readable():
|
||||||
|
with DEFAULT_CONFIG_PATH.open("rb") as file:
|
||||||
|
config = tomllib.load(file)
|
||||||
|
else:
|
||||||
|
print("Could not read config file, it was neither provided nor readable in default location", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|||||||
+4
-18
@@ -1,19 +1,5 @@
|
|||||||
from pathlib import Path
|
from sqlalchemy.engine.base import Engine
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
engine: Engine = None
|
||||||
from sqlalchemy.orm import sessionmaker
|
session: Session = None
|
||||||
|
|
||||||
from dibbler.conf import config
|
|
||||||
|
|
||||||
database_url: str | None = None
|
|
||||||
|
|
||||||
if (url := config.get("database", "url")) is not None:
|
|
||||||
database_url = url
|
|
||||||
elif (url_file := config.get("database", "url_file")) is not None:
|
|
||||||
with Path(url_file).open() as file:
|
|
||||||
database_url = file.read().strip()
|
|
||||||
|
|
||||||
assert database_url is not None, "Database URL must be specified in config"
|
|
||||||
|
|
||||||
engine = create_engine(database_url)
|
|
||||||
Session = sessionmaker(bind=engine)
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ from collections import defaultdict
|
|||||||
|
|
||||||
from .helpers import *
|
from .helpers import *
|
||||||
from ..models import Transaction
|
from ..models import Transaction
|
||||||
from ..db import Session
|
from ..db import session as create_session
|
||||||
|
|
||||||
|
|
||||||
def getUser():
|
def getUser():
|
||||||
while 1:
|
while 1:
|
||||||
string = input("user? ")
|
string = input("user? ")
|
||||||
session = Session()
|
session = create_session()
|
||||||
user = search_user(string, session)
|
user = search_user(string, session)
|
||||||
session.close()
|
session.close()
|
||||||
if not isinstance(user, list):
|
if not isinstance(user, list):
|
||||||
@@ -40,7 +40,7 @@ def getUser():
|
|||||||
def getProduct():
|
def getProduct():
|
||||||
while 1:
|
while 1:
|
||||||
string = input("product? ")
|
string = input("product? ")
|
||||||
session = Session()
|
session = create_session()
|
||||||
product = search_product(string, session)
|
product = search_product(string, session)
|
||||||
session.close()
|
session.close()
|
||||||
if not isinstance(product, list):
|
if not isinstance(product, list):
|
||||||
@@ -242,7 +242,7 @@ def buildDatabaseFromDb(inputType, inputProduct, inputUser):
|
|||||||
sdate = input("enter start date (yyyy-mm-dd)? ")
|
sdate = input("enter start date (yyyy-mm-dd)? ")
|
||||||
edate = input("enter end date (yyyy-mm-dd)? ")
|
edate = input("enter end date (yyyy-mm-dd)? ")
|
||||||
print("building database...")
|
print("building database...")
|
||||||
session = Session()
|
session = create_session()
|
||||||
transaction_list = session.query(Transaction).all()
|
transaction_list = session.query(Transaction).all()
|
||||||
inputLine = InputLine(inputUser, inputProduct, inputType)
|
inputLine = InputLine(inputUser, inputProduct, inputType)
|
||||||
startDate = getDateDb(transaction_list[0].time, sdate)
|
startDate = getDateDb(transaction_list[0].time, sdate)
|
||||||
|
|||||||
+13
-9
@@ -1,8 +1,11 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from dibbler.conf import DEFAULT_CONFIG_PATH, config, default_config_path_submissive_and_readable
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
from dibbler.conf import load_config
|
||||||
|
from dibbler.db import engine, session
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
@@ -12,7 +15,7 @@ parser.add_argument(
|
|||||||
help="Path to the config file",
|
help="Path to the config file",
|
||||||
type=Path,
|
type=Path,
|
||||||
metavar="FILE",
|
metavar="FILE",
|
||||||
default="config.ini",
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(
|
subparsers = parser.add_subparsers(
|
||||||
@@ -29,12 +32,13 @@ subparsers.add_parser("seed-data", help="Fill with mock data")
|
|||||||
def main():
|
def main():
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.config is not None:
|
load_config(args.config)
|
||||||
config.read(args.config)
|
|
||||||
elif default_config_path_submissive_and_readable():
|
from dibbler.conf import config
|
||||||
config.read(DEFAULT_CONFIG_PATH)
|
|
||||||
else:
|
global engine, session
|
||||||
print("Could not read config file, it was neither provided nor readable in default location", file=sys.stderr)
|
engine = create_engine(config['database']['url'])
|
||||||
|
session = sessionmaker(bind=engine)
|
||||||
|
|
||||||
if args.subcommand == "loop":
|
if args.subcommand == "loop":
|
||||||
import dibbler.subcommands.loop as loop
|
import dibbler.subcommands.loop as loop
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
|||||||
"""
|
"""
|
||||||
assert isinstance(user, User)
|
assert isinstance(user, User)
|
||||||
|
|
||||||
return user.credit > config.getint("limits", "low_credit_warning_limit")
|
return user.credit > config["limits"]["low_credit_warning_limit"]
|
||||||
|
|
||||||
def low_credit_warning(self, user, timeout=False):
|
def low_credit_warning(self, user, timeout=False):
|
||||||
assert isinstance(user, User)
|
assert isinstance(user, User)
|
||||||
@@ -58,7 +58,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
|||||||
print("***********************************************************************")
|
print("***********************************************************************")
|
||||||
print("")
|
print("")
|
||||||
print(
|
print(
|
||||||
f"USER {user.name} HAS LOWER CREDIT THAN {config.getint('limits', 'low_credit_warning_limit'):d}."
|
f"USER {user.name} HAS LOWER CREDIT THAN {config['limits']['low_credit_warning_limit']:d}."
|
||||||
)
|
)
|
||||||
print("THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH.")
|
print("THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH.")
|
||||||
print("CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS.")
|
print("CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS.")
|
||||||
@@ -178,9 +178,9 @@ When finished, write an empty line to confirm the purchase.\n"""
|
|||||||
for t in self.purchase.transactions:
|
for t in self.purchase.transactions:
|
||||||
if not t.user.is_anonymous():
|
if not t.user.is_anonymous():
|
||||||
print(f"User {t.user.name}'s credit is now {t.user.credit:d} kr")
|
print(f"User {t.user.name}'s credit is now {t.user.credit:d} kr")
|
||||||
if t.user.credit < config.getint("limits", "low_credit_warning_limit"):
|
if t.user.credit < config["limits"]["low_credit_warning_limit"]:
|
||||||
print(
|
print(
|
||||||
f"USER {t.user.name} HAS LOWER CREDIT THAN {config.getint('limits', 'low_credit_warning_limit'):d},",
|
f"USER {t.user.name} HAS LOWER CREDIT THAN {config['limits']['low_credit_warning_limit']:d},",
|
||||||
"AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.",
|
"AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
from select import select
|
from select import select
|
||||||
|
|
||||||
from dibbler.db import Session
|
from dibbler.db import session as create_session
|
||||||
from dibbler.models import User
|
from dibbler.models import User
|
||||||
from dibbler.lib.helpers import (
|
from dibbler.lib.helpers import (
|
||||||
search_user,
|
search_user,
|
||||||
@@ -485,7 +485,7 @@ class Menu(object):
|
|||||||
self.set_context(None)
|
self.set_context(None)
|
||||||
try:
|
try:
|
||||||
if self.uses_db and not self.session:
|
if self.uses_db and not self.session:
|
||||||
self.session = Session()
|
self.session = create_session()
|
||||||
return self._execute(**kwargs)
|
return self._execute(**kwargs)
|
||||||
except ExitMenu:
|
except ExitMenu:
|
||||||
self.at_exit()
|
self.at_exit()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import os
|
|||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from dibbler.db import Session
|
from dibbler.db import session as create_session
|
||||||
|
|
||||||
from .buymenu import BuyMenu
|
from .buymenu import BuyMenu
|
||||||
from .faq import FAQMenu
|
from .faq import FAQMenu
|
||||||
@@ -28,7 +28,7 @@ class MainMenu(Menu):
|
|||||||
else:
|
else:
|
||||||
num = 1
|
num = 1
|
||||||
item_name = in_str
|
item_name = in_str
|
||||||
buy_menu = BuyMenu(Session())
|
buy_menu = BuyMenu(create_session())
|
||||||
thing = buy_menu.search_for_thing(item_name, find_hidden_products=False)
|
thing = buy_menu.search_for_thing(item_name, find_hidden_products=False)
|
||||||
if thing:
|
if thing:
|
||||||
buy_menu.execute(initial_contents=[(thing, num)])
|
buy_menu.execute(initial_contents=[(thing, num)])
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class ShowUserMenu(Menu):
|
|||||||
(
|
(
|
||||||
"transactions",
|
"transactions",
|
||||||
"Recent transactions (List of last "
|
"Recent transactions (List of last "
|
||||||
+ str(config.getint("limits", "user_recent_transaction_limit"))
|
+ str(config["limits"]["user_recent_transaction_limit"])
|
||||||
+ ")",
|
+ ")",
|
||||||
),
|
),
|
||||||
("products", f"Which products {user.name} has bought, and how many"),
|
("products", f"Which products {user.name} has bought, and how many"),
|
||||||
@@ -65,7 +65,7 @@ class ShowUserMenu(Menu):
|
|||||||
)
|
)
|
||||||
what = selector.execute()
|
what = selector.execute()
|
||||||
if what == "transactions":
|
if what == "transactions":
|
||||||
self.print_transactions(user, config.getint("limits", "user_recent_transaction_limit"))
|
self.print_transactions(user, config["limits"]["user_recent_transaction_limit"])
|
||||||
elif what == "products":
|
elif what == "products":
|
||||||
self.print_purchased_products(user)
|
self.print_purchased_products(user)
|
||||||
elif what == "transactions-all":
|
elif what == "transactions-all":
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ Put it up somewhere in the vicinity.
|
|||||||
thing.bar_code,
|
thing.bar_code,
|
||||||
thing.name,
|
thing.name,
|
||||||
barcode_type=bar_type,
|
barcode_type=bar_type,
|
||||||
rotate=config.getboolean("printer", "rotate"),
|
rotate=config["printer"]["rotate"],
|
||||||
printer_type="QL-700",
|
printer_type="QL-700",
|
||||||
label_type=config.get("printer", "label_type"),
|
label_type=config.get("printer", "label_type"),
|
||||||
)
|
)
|
||||||
elif isinstance(thing, User):
|
elif isinstance(thing, User):
|
||||||
print_name_label(
|
print_name_label(
|
||||||
text=thing.name,
|
text=thing.name,
|
||||||
label_type=config.get("printer", "label_type"),
|
label_type=config["printer"]["label_type"],
|
||||||
rotate=config.getboolean("printer", "rotate"),
|
rotate=config["printer"]["rotate"],
|
||||||
printer_type="QL-700",
|
printer_type="QL-700",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ random.seed()
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not config.getboolean("general", "stop_allowed"):
|
if not config["general"]["stop_allowed"]:
|
||||||
signal.signal(signal.SIGQUIT, signal.SIG_IGN)
|
signal.signal(signal.SIGQUIT, signal.SIG_IGN)
|
||||||
|
|
||||||
if not config.getboolean("general", "stop_allowed"):
|
if not config["general"]["stop_allowed"]:
|
||||||
signal.signal(signal.SIGTSTP, signal.SIG_IGN)
|
signal.signal(signal.SIGTSTP, signal.SIG_IGN)
|
||||||
|
|
||||||
main = MainMenu(
|
main = MainMenu(
|
||||||
@@ -56,7 +56,7 @@ def main():
|
|||||||
exit_msg="happy happy joy joy",
|
exit_msg="happy happy joy joy",
|
||||||
exit_confirm_msg="Really quit Dibbler?",
|
exit_confirm_msg="Really quit Dibbler?",
|
||||||
)
|
)
|
||||||
if not config.getboolean("general", "quit_allowed"):
|
if not config["general"]["quit_allowed"]:
|
||||||
main.exit_disallowed_msg = "You can check out any time you like, but you can never leave."
|
main.exit_disallowed_msg = "You can check out any time you like, but you can never leave."
|
||||||
while True:
|
while True:
|
||||||
# noinspection PyBroadException
|
# noinspection PyBroadException
|
||||||
@@ -68,7 +68,7 @@ def main():
|
|||||||
except:
|
except:
|
||||||
print("Something went wrong.")
|
print("Something went wrong.")
|
||||||
print(f"{sys.exc_info()[0]}: {sys.exc_info()[1]}")
|
print(f"{sys.exc_info()[0]}: {sys.exc_info()[1]}")
|
||||||
if config.getboolean("general", "show_tracebacks"):
|
if config["general"]["show_tracebacks"]:
|
||||||
traceback.print_tb(sys.exc_info()[2])
|
traceback.print_tb(sys.exc_info()[2])
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
from dibbler.db import Session
|
from dibbler.db import session as create_session
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ def clear_db(session):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
session = Session()
|
session = create_session()
|
||||||
clear_db(session)
|
clear_db(session)
|
||||||
product_items = []
|
product_items = []
|
||||||
user_items = []
|
user_items = []
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
from dibbler.db import Session
|
from dibbler.db import session as create_session
|
||||||
from dibbler.models import User
|
from dibbler.models import User
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# Start an SQL session
|
# Start an SQL session
|
||||||
session = Session()
|
session = create_session()
|
||||||
# Let's find all users with a negative credit
|
# Let's find all users with a negative credit
|
||||||
slabbedasker = session.query(User).filter(User.credit < 0).all()
|
slabbedasker = session.query(User).filter(User.credit < 0).all()
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
{ config, pkgs, lib, ... }: let
|
{ config, pkgs, lib, ... }: let
|
||||||
cfg = config.services.dibbler;
|
cfg = config.services.dibbler;
|
||||||
|
|
||||||
format = pkgs.formats.ini { };
|
format = pkgs.formats.toml { };
|
||||||
in {
|
in {
|
||||||
options.services.dibbler = {
|
options.services.dibbler = {
|
||||||
enable = lib.mkEnableOption "dibbler, the little kiosk computer";
|
enable = lib.mkEnableOption "dibbler, the little kiosk computer";
|
||||||
@@ -58,7 +58,7 @@ in {
|
|||||||
|
|
||||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
{
|
{
|
||||||
services.dibbler.settings = lib.pipe ../example-config.ini [
|
services.dibbler.settings = lib.pipe ../example-config.toml [
|
||||||
builtins.readFile
|
builtins.readFile
|
||||||
builtins.fromTOML
|
builtins.fromTOML
|
||||||
(lib.mapAttrsRecursive (_: lib.mkDefault))
|
(lib.mapAttrsRecursive (_: lib.mkDefault))
|
||||||
@@ -67,7 +67,7 @@ in {
|
|||||||
{
|
{
|
||||||
environment.systemPackages = [ cfg.package ];
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
environment.etc."dibbler/dibbler.conf".source = format.generate "dibbler.conf" cfg.settings;
|
environment.etc."dibbler/dibbler.toml".source = format.generate "dibbler.toml" cfg.settings;
|
||||||
|
|
||||||
users = {
|
users = {
|
||||||
users.dibbler = {
|
users.dibbler = {
|
||||||
@@ -97,7 +97,7 @@ in {
|
|||||||
};
|
};
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${lib.getExe cfg.package} --config /etc/dibbler/dibbler.conf create-db";
|
ExecStart = "${lib.getExe cfg.package} --config /etc/dibbler/dibbler.toml create-db";
|
||||||
ExecStartPost = "${lib.getExe' pkgs.coreutils "touch"} /var/lib/dibbler/.db-setup-done";
|
ExecStartPost = "${lib.getExe' pkgs.coreutils "touch"} /var/lib/dibbler/.db-setup-done";
|
||||||
StateDirectory = "dibbler";
|
StateDirectory = "dibbler";
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ in {
|
|||||||
];
|
];
|
||||||
|
|
||||||
dibblerArgs = lib.cli.toCommandLineShellGNU { } {
|
dibblerArgs = lib.cli.toCommandLineShellGNU { } {
|
||||||
config = "/etc/dibbler/dibbler.conf";
|
config = "/etc/dibbler/dibbler.toml";
|
||||||
};
|
};
|
||||||
|
|
||||||
in "${lib.getExe cfg.screenPackage} ${screenArgs} ${lib.getExe cfg.package} ${dibblerArgs} loop";
|
in "${lib.getExe cfg.screenPackage} ${screenArgs} ${lib.getExe cfg.package} ${dibblerArgs} loop";
|
||||||
|
|||||||
Reference in New Issue
Block a user