matemat/matemat/webserver/pagelets/modproduct.py

82 lines
3.2 KiB
Python

from typing import Any, Dict, Union
import os
import magic
from matemat.webserver import pagelet, RequestArguments, PageletResponse, RedirectResponse, TemplateResponse
from matemat.db import MatematDatabase
from matemat.primitives import Product
from matemat.exceptions import DatabaseConsistencyError, HttpException
from matemat.util.currency_format import parse_chf
@pagelet('/modproduct')
def modproduct(method: str,
path: str,
args: RequestArguments,
session_vars: Dict[str, Any],
headers: Dict[str, str],
config: Dict[str, str]) \
-> Union[str, bytes, PageletResponse]:
if 'authentication_level' not in session_vars or 'authenticated_user' not in session_vars:
return RedirectResponse('/login')
authlevel: int = session_vars['authentication_level']
auth_uid: int = session_vars['authenticated_user']
if authlevel < 2:
raise HttpException(403)
with MatematDatabase(config['DatabaseFile']) as db:
authuser = db.get_user(auth_uid)
if not authuser.is_admin:
raise HttpException(403)
if 'productid' not in args:
raise HttpException(400, '"productid" argument missing')
modproduct_id = int(str(args.productid))
product = db.get_product(modproduct_id)
if 'change' in args:
handle_change(args, product, db, config)
if str(args.change) == 'del':
return RedirectResponse('/admin')
return TemplateResponse('modproduct.html',
authuser=authuser, product=product, authlevel=authlevel,
setupname=config['InstanceName'])
def handle_change(args: RequestArguments, product: Product, db: MatematDatabase, config: Dict[str, str]) -> None:
change = str(args.change)
if change == 'del':
db.delete_product(product)
try:
abspath: str = os.path.join(os.path.abspath(config['UploadDir']), 'thumbnails/products/')
os.remove(os.path.join(abspath, f'{product.id}.png'))
except FileNotFoundError:
pass
elif change == 'update':
if 'name' not in args or 'pricemember' not in args or 'pricenonmember' not in args or 'stock' not in args:
return
name = str(args.name)
price_member = parse_chf(str(args.pricemember))
price_non_member = parse_chf(str(args.pricenonmember))
stock = int(str(args.stock))
try:
db.change_product(product,
name=name, price_member=price_member, price_non_member=price_non_member, stock=stock)
except DatabaseConsistencyError:
pass
if 'image' in args:
image = bytes(args.image)
filemagic: magic.FileMagic = magic.detect_from_content(image)
if filemagic.mime_type != 'image/png':
# TODO: Optionally convert to png
return
if len(image) > 0:
abspath: str = os.path.join(os.path.abspath(config['UploadDir']), 'thumbnails/products/')
os.makedirs(abspath, exist_ok=True)
with open(os.path.join(abspath, f'{product.id}.png'), 'wb') as f:
f.write(image)