treewide: fix a bunch of lints

This commit is contained in:
2026-02-03 23:24:37 +09:00
parent e84b43e2a0
commit cf945143ba
23 changed files with 122 additions and 140 deletions
+9 -11
View File
@@ -1,8 +1,8 @@
from typing import Any
from pathlib import Path
import tomllib
import os import os
import sys import sys
import tomllib
from pathlib import Path
from typing import Any
DEFAULT_CONFIG_PATH = Path("/etc/dibbler/dibbler.toml") DEFAULT_CONFIG_PATH = Path("/etc/dibbler/dibbler.toml")
@@ -19,11 +19,11 @@ def default_config_path_submissive_and_readable() -> bool:
and DEFAULT_CONFIG_PATH.stat().st_gid == os.getgid() and DEFAULT_CONFIG_PATH.stat().st_gid == os.getgid()
), ),
(DEFAULT_CONFIG_PATH.stat().st_mode & 0o004), (DEFAULT_CONFIG_PATH.stat().st_mode & 0o004),
] ],
) )
config: dict[str, dict[str, Any]] = dict() config: dict[str, dict[str, Any]] = {}
def load_config(config_path: Path | None = None): def load_config(config_path: Path | None = None):
@@ -49,7 +49,7 @@ def config_db_string() -> str:
path = Path(config["database"]["sqlite"]["path"]) path = Path(config["database"]["sqlite"]["path"])
return f"sqlite:///{path.absolute()}" return f"sqlite:///{path.absolute()}"
elif db_type == "postgresql": if db_type == "postgresql":
host = config["database"]["postgresql"]["host"] host = config["database"]["postgresql"]["host"]
port = config["database"]["postgresql"].get("port", 5432) port = config["database"]["postgresql"].get("port", 5432)
username = config["database"]["postgresql"].get("username", "dibbler") username = config["database"]["postgresql"].get("username", "dibbler")
@@ -65,8 +65,6 @@ def config_db_string() -> str:
if host.startswith("/"): if host.startswith("/"):
return f"postgresql+psycopg2://{username}:{password}@/{dbname}?host={host}" return f"postgresql+psycopg2://{username}:{password}@/{dbname}?host={host}"
else: return f"postgresql+psycopg2://{username}:{password}@{host}:{port}/{dbname}"
return f"postgresql+psycopg2://{username}:{password}@{host}:{port}/{dbname}" print(f"Error: unknown database type '{db_type}'")
else: exit(1)
print(f"Error: unknown database type '{db_type}'")
exit(1)
+9 -9
View File
@@ -2,7 +2,8 @@ import os
import pwd import pwd
import signal import signal
import subprocess import subprocess
from typing import Any, Callable, Literal from collections.abc import Callable
from typing import Any, Literal
from sqlalchemy import and_, not_, or_ from sqlalchemy import and_, not_, or_
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -24,18 +25,17 @@ def search_user(
) )
if exact_match: if exact_match:
return exact_match return exact_match
user_list = ( return (
sql_session.query(User) sql_session.query(User)
.filter( .filter(
or_( or_(
User.name.ilike(f"%{string}%"), User.name.ilike(f"%{string}%"),
User.card.ilike(f"%{string}%"), User.card.ilike(f"%{string}%"),
User.rfid.ilike(f"%{string}%"), User.rfid.ilike(f"%{string}%"),
) ),
) )
.all() .all()
) )
return user_list
def search_product( def search_product(
@@ -60,7 +60,7 @@ def search_product(
Product.name == string, Product.name == string,
not_(Product.hidden), not_(Product.hidden),
), ),
) ),
) )
.first() .first()
) )
@@ -73,7 +73,7 @@ def search_product(
or_( or_(
Product.bar_code.ilike(f"%{string}%"), Product.bar_code.ilike(f"%{string}%"),
Product.name.ilike(f"%{string}%"), Product.name.ilike(f"%{string}%"),
) ),
) )
.all() .all()
) )
@@ -87,7 +87,7 @@ def search_product(
Product.name.ilike(f"%{string}%"), Product.name.ilike(f"%{string}%"),
not_(Product.hidden), not_(Product.hidden),
), ),
) ),
) )
.all() .all()
) )
@@ -121,7 +121,7 @@ def guess_data_type(string: str) -> Literal["card", "rfid", "bar_code", "usernam
def argmax( def argmax(
d, d,
all: bool = False, all_: bool = False,
value: Callable[[Any], Any] | None = None, value: Callable[[Any], Any] | None = None,
): ):
maxarg = None maxarg = None
@@ -133,7 +133,7 @@ def argmax(
for key in list(d.keys()): for key in list(d.keys()):
if maxarg is None or d[key] > d[maxarg]: if maxarg is None or d[key] > d[maxarg]:
maxarg = key maxarg = key
if all: if all_:
return [k for k in list(d.keys()) if d[k] == d[maxarg]] return [k for k in list(d.keys()) if d[k] == d[maxarg]]
return maxarg return maxarg
-2
View File
@@ -1,5 +1,3 @@
import os
import datetime
# import barcode # import barcode
# from brother_ql.brother_ql_create import create_label # from brother_ql.brother_ql_create import create_label
+16 -15
View File
@@ -3,11 +3,12 @@
import datetime import datetime
from collections import defaultdict from collections import defaultdict
from pathlib import Path
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .helpers import *
from ..models import Transaction from ..models import Transaction
from .helpers import *
def getUser(sql_session: Session): def getUser(sql_session: Session):
@@ -176,7 +177,7 @@ def addLineToDatabase(database, inputLine):
if abs(inputLine.price) > 90000: if abs(inputLine.price) > 90000:
return database return database
# fyller inn for varer # fyller inn for varer
if (not inputLine.product == "") and ( if (inputLine.product != "") and (
(inputLine.inputProduct == "") or (inputLine.inputProduct == inputLine.product) (inputLine.inputProduct == "") or (inputLine.inputProduct == inputLine.product)
): ):
database.varePersonAntall[inputLine.product][inputLine.user] = ( database.varePersonAntall[inputLine.product][inputLine.user] = (
@@ -190,7 +191,7 @@ def addLineToDatabase(database, inputLine):
database.vareUkedagAntall[inputLine.product][inputLine.weekday] += 1 database.vareUkedagAntall[inputLine.product][inputLine.weekday] += 1
# fyller inn for personer # fyller inn for personer
if (inputLine.inputUser == "") or (inputLine.inputUser == inputLine.user): if (inputLine.inputUser == "") or (inputLine.inputUser == inputLine.user):
if not inputLine.product == "": if inputLine.product != "":
database.personVareAntall[inputLine.user][inputLine.product] = ( database.personVareAntall[inputLine.user][inputLine.product] = (
database.personVareAntall[inputLine.user].setdefault(inputLine.product, 0) + 1 database.personVareAntall[inputLine.user].setdefault(inputLine.product, 0) + 1
) )
@@ -214,7 +215,7 @@ def addLineToDatabase(database, inputLine):
database.personNegTransactions[inputLine.user] = ( database.personNegTransactions[inputLine.user] = (
database.personNegTransactions.setdefault(inputLine.user, 0) + inputLine.price database.personNegTransactions.setdefault(inputLine.user, 0) + inputLine.price
) )
elif not (inputLine.inputType == 1): elif inputLine.inputType != 1:
database.globalVareAntall[inputLine.product] = ( database.globalVareAntall[inputLine.product] = (
database.globalVareAntall.setdefault(inputLine.product, 0) + 1 database.globalVareAntall.setdefault(inputLine.product, 0) + 1
) )
@@ -225,7 +226,7 @@ def addLineToDatabase(database, inputLine):
# fyller inn for global statistikk # fyller inn for global statistikk
if (inputLine.inputType == 3) or (inputLine.inputType == 4): if (inputLine.inputType == 3) or (inputLine.inputType == 4):
database.pengebeholdning[inputLine.dateNum] += inputLine.price database.pengebeholdning[inputLine.dateNum] += inputLine.price
if not (inputLine.product == ""): if inputLine.product != "":
database.globalPersonAntall[inputLine.user] = ( database.globalPersonAntall[inputLine.user] = (
database.globalPersonAntall.setdefault(inputLine.user, 0) + 1 database.globalPersonAntall.setdefault(inputLine.user, 0) + 1
) )
@@ -273,7 +274,7 @@ def buildDatabaseFromDb(inputType, inputProduct, inputUser, sql_session: Session
inputLine.price = 0 inputLine.price = 0
print("saving as default.dibblerlog...", end=" ") print("saving as default.dibblerlog...", end=" ")
f = open("default.dibblerlog", "w") f = Path.open("default.dibblerlog", "w")
line_format = "%s|%s|%s|%s|%s|%s\n" line_format = "%s|%s|%s|%s|%s|%s\n"
transaction_list = sql_session.query(Transaction).all() transaction_list = sql_session.query(Transaction).all()
for transaction in transaction_list: for transaction in transaction_list:
@@ -290,7 +291,7 @@ def buildDatabaseFromDb(inputType, inputProduct, inputUser, sql_session: Session
transaction.description, transaction.description,
) )
f.write(line.encode("utf8")) f.write(line.encode("utf8"))
f.close f.close()
# bygg database.pengebeholdning # bygg database.pengebeholdning
if (inputType == 3) or (inputType == 4): if (inputType == 3) or (inputType == 4):
for i in range(inputLine.numberOfDays + 1): for i in range(inputLine.numberOfDays + 1):
@@ -310,7 +311,7 @@ def buildDatabaseFromFile(inputFile, 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)? ")
f = open(inputFile) f = Path.open(inputFile)
try: try:
fileLines = f.readlines() fileLines = f.readlines()
finally: finally:
@@ -328,7 +329,7 @@ def buildDatabaseFromFile(inputFile, inputType, inputProduct, inputUser):
database.globalUkedagForbruk = [0] * 7 database.globalUkedagForbruk = [0] * 7
database.pengebeholdning = [0] * (inputLine.numberOfDays + 1) database.pengebeholdning = [0] * (inputLine.numberOfDays + 1)
for linje in fileLines: for linje in fileLines:
if not (linje[0] == "#") and not (linje == "\n"): if linje[0] != "#" and linje != "\n":
# henter dateNum, products, user, price # henter dateNum, products, user, price
restDel = linje.partition("|") restDel = linje.partition("|")
restDel = restDel[2].partition(" ") restDel = restDel[2].partition(" ")
@@ -406,7 +407,7 @@ def printWeekdays(week, days):
def printBalance(database, user): def printBalance(database, user):
forbruk = 0 forbruk = 0
if user in database.personVareVerdi: if user in database.personVareVerdi:
forbruk = sum([i for i in list(database.personVareVerdi[user].values())]) forbruk = sum(list(database.personVareVerdi[user].values()))
print("totalt kjøpt for: ", forbruk, end=" ") print("totalt kjøpt for: ", forbruk, end=" ")
if user in database.personNegTransactions: if user in database.personNegTransactions:
print("kr, totalt lagt til: ", -database.personNegTransactions[user], end=" ") print("kr, totalt lagt til: ", -database.personNegTransactions[user], end=" ")
@@ -453,9 +454,9 @@ def printGlobal(database, dateLine, n):
"Det er solgt varer til en verdi av: ", "Det er solgt varer til en verdi av: ",
sum(database.globalDatoForbruk), sum(database.globalDatoForbruk),
"kr, det er lagt til", "kr, det er lagt til",
-sum([i for i in list(database.personNegTransactions.values())]), -sum(list(database.personNegTransactions.values())),
"og tatt fra", "og tatt fra",
sum([i for i in list(database.personPosTransactions.values())]), sum(list(database.personPosTransactions.values())),
end=" ", end=" ",
) )
print( print(
@@ -470,12 +471,12 @@ def alt4menuTextOnly(database, dateLine, sql_session: Session):
n = 10 n = 10
while 1: while 1:
print( print(
"\n1: user-statistics, 2: product-statistics, 3:global-statistics, n: adjust amount of data shown q:quit" "\n1: user-statistics, 2: product-statistics, 3:global-statistics, n: adjust amount of data shown q:quit",
) )
inp = input("") inp = input("")
if inp == "q": if inp == "q":
break break
elif inp == "1": if inp == "1":
try: try:
printUser(database, dateLine, getUser(sql_session), n) printUser(database, dateLine, getUser(sql_session), n)
except: except:
@@ -505,5 +506,5 @@ def statisticsTextOnly(sql_session: Session):
database, dateLine = buildDatabaseFromDb(inputType, product, user, sql_session) database, dateLine = buildDatabaseFromDb(inputType, product, user, sql_session)
elif inp == "0" or inp == "": elif inp == "0" or inp == "":
database, dateLine = buildDatabaseFromFile("default.dibblerlog", inputType, product, user) database, dateLine = buildDatabaseFromFile("default.dibblerlog", inputType, product, user)
if not inp == "q": if inp != "q":
alt4menuTextOnly(database, dateLine, sql_session) alt4menuTextOnly(database, dateLine, sql_session)
+1 -1
View File
@@ -4,7 +4,7 @@ from pathlib import Path
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from dibbler.conf import load_config, config_db_string from dibbler.conf import config_db_string, load_config
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
+9 -9
View File
@@ -26,28 +26,28 @@ __all__ = [
from .addstock import AddStockMenu from .addstock import AddStockMenu
from .buymenu import BuyMenu from .buymenu import BuyMenu
from .editing import ( from .editing import (
AddUserMenu,
EditUserMenu,
AddProductMenu, AddProductMenu,
EditProductMenu, AddUserMenu,
AdjustStockMenu, AdjustStockMenu,
CleanupStockMenu, CleanupStockMenu,
EditProductMenu,
EditUserMenu,
) )
from .faq import FAQMenu from .faq import FAQMenu
from .helpermenus import Menu from .helpermenus import Menu
from .mainmenu import MainMenu from .mainmenu import MainMenu
from .miscmenus import ( from .miscmenus import (
ProductSearchMenu,
TransferMenu,
AdjustCreditMenu, AdjustCreditMenu,
UserListMenu,
ShowUserMenu,
ProductListMenu, ProductListMenu,
ProductSearchMenu,
ShowUserMenu,
TransferMenu,
UserListMenu,
) )
from .printermenu import PrintLabelMenu from .printermenu import PrintLabelMenu
from .stats import ( from .stats import (
ProductPopularityMenu,
ProductRevenueMenu,
BalanceMenu, BalanceMenu,
LoggedStatisticsMenu, LoggedStatisticsMenu,
ProductPopularityMenu,
ProductRevenueMenu,
) )
+2 -2
View File
@@ -139,10 +139,10 @@ much money you're due in credits for the purchase when prompted.\n"""
old_price = product.price old_price = product.price
old_hidden = product.hidden old_hidden = product.hidden
product.price = int( product.price = int(
ceil(float(value) / (max(product.stock, 0) + self.products[product][0])) ceil(float(value) / (max(product.stock, 0) + self.products[product][0])),
) )
product.stock = max( product.stock = max(
self.products[product][0], product.stock + self.products[product][0] self.products[product][0], product.stock + self.products[product][0],
) )
product.hidden = False product.hidden = False
print( print(
+10 -12
View File
@@ -64,7 +64,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['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.")
@@ -74,8 +74,7 @@ When finished, write an empty line to confirm the purchase.\n"""
if timeout: if timeout:
print("THIS PURCHASE WILL AUTOMATICALLY BE PERFORMED IN 3 MINUTES!") print("THIS PURCHASE WILL AUTOMATICALLY BE PERFORMED IN 3 MINUTES!")
return self.confirm(prompt=">", default=True, timeout=180) return self.confirm(prompt=">", default=True, timeout=180)
else: return self.confirm(prompt=">", default=True)
return self.confirm(prompt=">", default=True)
def add_thing_to_purchase( def add_thing_to_purchase(
self, self,
@@ -145,7 +144,7 @@ When finished, write an empty line to confirm the purchase.\n"""
True, True,
True, True,
): "Enter more products or users, or an empty line to confirm", ): "Enter more products or users, or an empty line to confirm",
}[(len(self.purchase.transactions) > 0, len(self.purchase.entries) > 0)] }[(len(self.purchase.transactions) > 0, len(self.purchase.entries) > 0)],
) )
# Read in a 'thing' (product or user): # Read in a 'thing' (product or user):
@@ -163,16 +162,15 @@ When finished, write an empty line to confirm the purchase.\n"""
if thing is None: if thing is None:
if not self.complete_input(): if not self.complete_input():
if self.confirm( if self.confirm(
"Not enough information entered. Abort purchase?", default=True "Not enough information entered. Abort purchase?", default=True,
): ):
return False return False
continue continue
break break
else: # once we get something in the
# once we get something in the # purchase, we want to protect the
# purchase, we want to protect the # user from accidentally killing it
# user from accidentally killing it self.exit_confirm_msg = "Abort purchase?"
self.exit_confirm_msg = "Abort purchase?"
# Add the thing to our purchase object: # Add the thing to our purchase object:
if not self.add_thing_to_purchase(thing, amount=num): if not self.add_thing_to_purchase(thing, amount=num):
@@ -221,7 +219,7 @@ When finished, write an empty line to confirm the purchase.\n"""
string += "(empty)" string += "(empty)"
else: else:
string += ", ".join( string += ", ".join(
[t.user.name + ("*" if not self.credit_check(t.user) else "") for t in transactions] [t.user.name + ("*" if not self.credit_check(t.user) else "") for t in transactions],
) )
string += "\n products: " string += "\n products: "
if len(entries) == 0: if len(entries) == 0:
@@ -229,7 +227,7 @@ When finished, write an empty line to confirm the purchase.\n"""
else: else:
string += "\n " string += "\n "
string += "\n ".join( string += "\n ".join(
[f"{e.amount:d}x {e.product.name} ({e.product.price:d} kr)" for e in entries] [f"{e.amount:d}x {e.product.name} ({e.product.price:d} kr)" for e in entries],
) )
if len(transactions) > 1: if len(transactions) > 1:
string += f"\n price per person: {self.purchase.price_per_transaction():d} kr" string += f"\n price per person: {self.purchase.price_per_transaction():d} kr"
+2 -2
View File
@@ -1,8 +1,8 @@
import sqlalchemy import sqlalchemy
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from dibbler.models import User, Product from dibbler.models import Product, User
from .helpermenus import Menu, Selector from .helpermenus import Menu, Selector
__all__ = [ __all__ = [
-1
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .helpermenus import Menu, MessageMenu from .helpermenus import Menu, MessageMenu
+33 -36
View File
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
import re import re
import sys import sys
from collections.abc import Callable, Iterable
from select import select from select import select
from typing import Any, Callable, Iterable, Literal, Self from typing import Any, Literal, Self
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -24,7 +24,7 @@ class ExitMenuException(Exception):
pass pass
class Menu(object): class Menu:
name: str name: str
sql_session: Session sql_session: Session
items: list[Self | tuple | str] items: list[Self | tuple | str]
@@ -111,10 +111,9 @@ class Menu(object):
def item_name(self, i: int) -> str: def item_name(self, i: int) -> str:
if self.item_is_submenu(i): if self.item_is_submenu(i):
return self.items[i].name return self.items[i].name
elif isinstance(self.items[i], tuple): if isinstance(self.items[i], tuple):
return self.items[i][1] return self.items[i][1]
else: return self.items[i]
return self.items[i]
def item_value(self, i: int): def item_value(self, i: int):
if isinstance(self.items[i], tuple): if isinstance(self.items[i], tuple):
@@ -189,7 +188,7 @@ class Menu(object):
): ):
if length_range[0] and length_range[1]: if length_range[0] and length_range[1]:
print( print(
f"Value must have length in range [{length_range[0]:d}, {length_range[1]:d}]" f"Value must have length in range [{length_range[0]:d}, {length_range[1]:d}]",
) )
elif length_range[0]: elif length_range[0]:
print(f"Value must have length at least {length_range[0]:d}") print(f"Value must have length at least {length_range[0]:d}")
@@ -231,7 +230,7 @@ class Menu(object):
else: else:
if result.isdigit(): if result.isdigit():
choice = int(result) choice = int(result)
if choice == 0 and 10 <= number_of_choices: if choice == 0 and number_of_choices >= 10:
return 10 return 10
if 0 < choice <= number_of_choices: if 0 < choice <= number_of_choices:
return choice return choice
@@ -342,29 +341,28 @@ class Menu(object):
search_lst = search_str.split(" ") search_lst = search_str.split(" ")
if search_str == "" and empty_input_permitted: if search_str == "" and empty_input_permitted:
return None return None
else: result = self.search_for_thing(
result = self.search_for_thing( search_str,
search_str, permitted_things,
permitted_things, add_nonexisting,
add_nonexisting, find_hidden_products,
find_hidden_products, )
) num = 1
num = 1
if (result is None) and (len(search_lst) > 1): if (result is None) and (len(search_lst) > 1):
print('Interpreting input as "<number> <product>"') print('Interpreting input as "<number> <product>"')
try: try:
num = int(search_lst[0]) num = int(search_lst[0])
result = self.search_for_thing( result = self.search_for_thing(
" ".join(search_lst[1:]), " ".join(search_lst[1:]),
permitted_things, permitted_things,
add_nonexisting, add_nonexisting,
find_hidden_products, find_hidden_products,
) )
# Her kan det legges inn en except ValueError, # Her kan det legges inn en except ValueError,
# men da blir det fort mye plaging av brukeren # men da blir det fort mye plaging av brukeren
except Exception as e: except Exception as e:
print(e) print(e)
return result, num return result, num
def search_for_thing( def search_for_thing(
@@ -544,7 +542,7 @@ class Menu(object):
of money PVVVV owes the user. This value decreases with the of money PVVVV owes the user. This value decreases with the
appropriate amount when you register a purchase, and you may increase appropriate amount when you register a purchase, and you may increase
it by putting money in the box and using the "Adjust credit" menu. it by putting money in the box and using the "Adjust credit" menu.
""" """,
) )
def local_help(self): def local_help(self):
@@ -627,17 +625,16 @@ class ConfirmMenu(Menu):
options = {True: "[y]/n", False: "y/[n]", None: "y/n"}[self.default] options = {True: "[y]/n", False: "y/[n]", None: "y/n"}[self.default]
while True: while True:
result = self.input_str( result = self.input_str(
f"{self.prompt} ({options})", end_prompt=": ", timeout=self.timeout f"{self.prompt} ({options})", end_prompt=": ", timeout=self.timeout,
) )
result = result.lower().strip() result = result.lower().strip()
if result in ["y", "yes"]: if result in ["y", "yes"]:
return True return True
elif result in ["n", "no"]: if result in ["n", "no"]:
return False return False
elif self.default is not None and result == "": if self.default is not None and result == "":
return self.default return self.default
else: print("Please answer yes or no")
print("Please answer yes or no")
class Selector(Menu): class Selector(Menu):
+3 -4
View File
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import os import os
import random import random
import sys import sys
@@ -48,18 +47,18 @@ class MainMenu(Menu):
restart() restart()
pass pass
return True return True
elif result == "c": if result == "c":
os.system( os.system(
'echo -e "\033[' 'echo -e "\033['
+ str(random.randint(40, 49)) + str(random.randint(40, 49))
+ ";" + ";"
+ str(random.randint(30, 37)) + str(random.randint(30, 37))
+ ';5m"' + ';5m"',
) )
os.system("clear") os.system("clear")
self.show_context() self.show_context()
return True return True
elif result == "cs": if result == "cs":
os.system('echo -e "\033[0m"') os.system('echo -e "\033[0m"')
os.system("clear") os.system("clear")
self.show_context() self.show_context()
+9 -15
View File
@@ -2,8 +2,8 @@ import sqlalchemy
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from dibbler.conf import config from dibbler.conf import config
from dibbler.models import Transaction, Product, User
from dibbler.lib.helpers import less from dibbler.lib.helpers import less
from dibbler.models import Product, Transaction, User
from .helpermenus import Menu, Selector from .helpermenus import Menu, Selector
@@ -90,10 +90,7 @@ class ShowUserMenu(Menu):
if t.purchase: if t.purchase:
products = [] products = []
for entry in t.purchase.entries: for entry in t.purchase.entries:
if abs(entry.amount) != 1: amount = f"{abs(entry.amount)}x " if abs(entry.amount) != 1 else ""
amount = f"{abs(entry.amount)}x "
else:
amount = ""
product = f"{amount}{entry.product.name}" product = f"{amount}{entry.product.name}"
products.append(product) products.append(product)
string += "purchase (" string += "purchase ("
@@ -215,14 +212,11 @@ class ProductSearchMenu(Menu):
self.print_header() self.print_header()
self.set_context("Enter (part of) product name or bar code") self.set_context("Enter (part of) product name or bar code")
product = self.input_product() product = self.input_product()
print( print(", ".join([
"Result: %s, price: %d kr, bar code: %s, stock: %d, hidden: %s" f"Result: {product.name}",
% ( f"price: {product.price} kr",
product.name, f"bar code: {product.bar_code}",
product.price, f"stock: {product.stock}",
product.bar_code, f"hidden: {'Y' if product.hidden else 'N'}",
product.stock, ]))
("Y" if product.hidden else "N"),
)
)
# self.pause() # self.pause()
-4
View File
@@ -1,11 +1,7 @@
import re
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from dibbler.conf import config
from dibbler.models import Product, User
# from dibbler.lib.printer_helpers import print_bar_code, print_name_label # from dibbler.lib.printer_helpers import print_bar_code, print_name_label
from .helpermenus import Menu from .helpermenus import Menu
+1 -1
View File
@@ -2,8 +2,8 @@ from sqlalchemy import desc, func
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from dibbler.lib.helpers import less from dibbler.lib.helpers import less
from dibbler.models import PurchaseEntry, Product, User
from dibbler.lib.statistikkHelpers import statisticsTextOnly from dibbler.lib.statistikkHelpers import statisticsTextOnly
from dibbler.models import Product, PurchaseEntry, User
from .helpermenus import Menu from .helpermenus import Menu
+2 -2
View File
@@ -18,7 +18,7 @@ class Base(DeclarativeBase):
"ck": "ck_%(table_name)s_`%(constraint_name)s`", "ck": "ck_%(table_name)s_`%(constraint_name)s`",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s", "pk": "pk_%(table_name)s",
} },
) )
@declared_attr.directive @declared_attr.directive
@@ -38,7 +38,7 @@ class Base(DeclarativeBase):
isinstance(v, InstrumentedList), isinstance(v, InstrumentedList),
isinstance(v, InstrumentedSet), isinstance(v, InstrumentedSet),
isinstance(v, InstrumentedDict), isinstance(v, InstrumentedDict),
] ],
) )
) )
return f"<{self.__class__.__name__}({columns})>" return f"<{self.__class__.__name__}({columns})>"
+1
View File
@@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from sqlalchemy import ( from sqlalchemy import (
+1 -2
View File
@@ -43,8 +43,7 @@ class Purchase(Base):
def price_per_transaction(self, round_up: bool = True) -> int: def price_per_transaction(self, round_up: bool = True) -> int:
if round_up: if round_up:
return int(math.ceil(float(self.price) / len(self.transactions))) return int(math.ceil(float(self.price) / len(self.transactions)))
else: return int(math.floor(float(self.price) / len(self.transactions)))
return int(math.floor(float(self.price) / len(self.transactions)))
def set_price(self, round_up: bool = True) -> None: def set_price(self, round_up: bool = True) -> None:
self.price = 0 self.price = 0
+4 -3
View File
@@ -1,9 +1,10 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from sqlalchemy import ( from sqlalchemy import (
Integer,
ForeignKey, ForeignKey,
Integer,
) )
from sqlalchemy.orm import ( from sqlalchemy.orm import (
Mapped, Mapped,
@@ -27,8 +28,8 @@ class PurchaseEntry(Base):
product_id: Mapped[int] = mapped_column(ForeignKey("products.product_id")) product_id: Mapped[int] = mapped_column(ForeignKey("products.product_id"))
purchase_id: Mapped[int] = mapped_column(ForeignKey("purchases.id")) purchase_id: Mapped[int] = mapped_column(ForeignKey("purchases.id"))
product: Mapped[Product] = relationship(back_populates='purchases', lazy="joined") product: Mapped[Product] = relationship(back_populates="purchases", lazy="joined")
purchase: Mapped[Purchase] = relationship(back_populates='entries', lazy="joined") purchase: Mapped[Purchase] = relationship(back_populates="entries", lazy="joined")
def __init__(self, purchase, product, amount): def __init__(self, purchase, product, amount):
self.product = product self.product = product
+3 -3
View File
@@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING
from sqlalchemy import ( from sqlalchemy import (
DateTime, DateTime,
@@ -18,8 +18,8 @@ from sqlalchemy.orm import (
from .Base import Base from .Base import Base
if TYPE_CHECKING: if TYPE_CHECKING:
from .User import User
from .Purchase import Purchase from .Purchase import Purchase
from .User import User
class Transaction(Base): class Transaction(Base):
@@ -36,7 +36,7 @@ class Transaction(Base):
purchase_id: Mapped[int | None] = mapped_column(ForeignKey("purchases.id")) purchase_id: Mapped[int | None] = mapped_column(ForeignKey("purchases.id"))
user: Mapped[User] = relationship(lazy="joined") user: Mapped[User] = relationship(lazy="joined")
purchase: Mapped[Purchase] = relationship(back_populates='transactions', lazy="joined") purchase: Mapped[Purchase] = relationship(back_populates="transactions", lazy="joined")
def __init__( def __init__(
self, self,
+3 -2
View File
@@ -1,9 +1,10 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from sqlalchemy import ( from sqlalchemy import (
Integer,
ForeignKey, ForeignKey,
Integer,
) )
from sqlalchemy.orm import ( from sqlalchemy.orm import (
Mapped, Mapped,
@@ -14,8 +15,8 @@ from sqlalchemy.orm import (
from .Base import Base from .Base import Base
if TYPE_CHECKING: if TYPE_CHECKING:
from .User import User
from .Product import Product from .Product import Product
from .User import User
class UserProducts(Base): class UserProducts(Base):
+3 -2
View File
@@ -1,5 +1,4 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*-
import random import random
import sys import sys
@@ -91,7 +90,9 @@ def main(sql_session: Session):
exit_confirm_msg="Really quit Dibbler?", exit_confirm_msg="Really quit Dibbler?",
) )
if not config["general"]["quit_allowed"]: if not config["general"]["quit_allowed"]:
main_menu.exit_disallowed_msg = "You can check out any time you like, but you can never leave." main_menu.exit_disallowed_msg = (
"You can check out any time you like, but you can never leave."
)
while True: while True:
# noinspection PyBroadException # noinspection PyBroadException
try: try:
+1 -2
View File
@@ -1,5 +1,4 @@
import json import json
from pathlib import Path from pathlib import Path
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -21,7 +20,7 @@ def main(sql_session: Session):
product_items = [] product_items = []
user_items = [] user_items = []
with open(JSON_FILE) as f: with Path.open(JSON_FILE) as f:
json_obj = json.load(f) json_obj = json.load(f)
for product in json_obj["products"]: for product in json_obj["products"]: