Files
lapp/items.py
T
2026-01-03 16:35:29 +01:00

220 lines
7.7 KiB
Python

from flask import Blueprint, render_template, redirect, url_for, request
from flask_login import login_required, current_user
from models import db
from models import Item
from sqlalchemy import desc, text
import os
from log import Log
items_bp = Blueprint("items", __name__)
ICONPATH = "static/categories/" #without starting / and with ending /
# home screen for items
@items_bp.route("/items/<listid>")
@login_required
def items(listid):
return render_template("items_show.html", user=current_user,
items=Item.query.filter_by(listofitems_id=listid, is_suggestion=False).order_by(text("is_checked, category, label")).all(),
button_top_url1 = url_for("items.items_append", listid=listid),
button_top_txt1 = "add",
button_top_url2 = url_for("items.items_clean", listid=listid),
button_top_txt2 = "clean")
# webservice for updating checked state of one item
@items_bp.route("/item_update/<itemid>/<itemchecked>")
@login_required
def item_update(itemid, itemchecked):
i = Item.query.get(itemid)
i.is_checked = True if itemchecked == 'true' else False
db.session.commit()
return '', 204
def interpret_and_add_item(listid, newlabel):
# could be
# appeltjes
# appel goudr
#. appel zilver 4
#. appel zilver 4kratten
unit = ''
quantity = ''
if ' ' in newlabel:
# could be:
# paard 5
# paard 5 poten
# 3 paarden
# 3kilo schaap
# 3 kilo schaap
# take the last word
words = newlabel.split(' ')
# -1- if there is a digit in the last word
if any(char.isdigit() for char in words[-1]):
# ... paard 5
# ... paard 5poten
for char in words[-1]:
if char.isdigit():
quantity += char
else:
unit += char
newlabel = ' '.join(words[0:-1])
elif len(words)>2 and any(char.isdigit() for char in words[-2]):
# ... paard 5 poten
# ... paard 4keer poten
for char in words[-2]:
if char.isdigit():
quantity += char
else:
unit += char
unit = words[-1] if unit=='' else unit+' '+words[-1]
newlabel = ' '.join(words[0:-2])
elif any(char.isdigit() for char in words[0]):
# 5 paarden
# 5koppig paarden
for char in words[0]:
if char.isdigit():
quantity += char
else:
unit += char
newlabel = ' '.join(words[1:])
if unit=='':
if len(words)>2 and len(words[1])<=4:
unit = words[1]
newlabel = ' '.join(words[2:])
if unit == '':
unit = 'x'
if quantity == '':
quantity = 1
newlabel=newlabel.title()
# check if the item exists already
item = Item.query.filter_by(listofitems_id=listid, label=newlabel, unit=unit).first()
if item:
if item.is_checked:
item.quantity += int(quantity)
if item.is_suggestion:
item.quantity = quantity
item.is_suggestion = False
item.is_checked = False
else:
# create a new one
item=Item(listofitems_id=listid, label=newlabel)
if unit:
item.unit = unit
if quantity:
item.quantity = int(quantity)
db.session.add(item)
db.session.commit()
return item
# user adds items to list
@items_bp.route("/items_append/<listid>", methods=["GET", "POST"])
@login_required
def items_append(listid):
if request.method == "POST":
# a new item has been added
newlabel = request.form["newItem"]
interpret_and_add_item(listid, newlabel)
# read icons
icon_names = []
icon_list = os.listdir(ICONPATH)
for i in icon_list:
if not i.startswith('.'):
icon_names.append(os.path.splitext(i)[0])
return render_template("items_append.html", user=current_user,
listid=listid,
items=Item.query.filter_by(listofitems_id=listid).order_by(Item.label).all(),
icons = icon_names,
iconpath = '/'+ICONPATH,
logo_url=url_for("items.items", listid=listid))
# user adds items to list
@items_bp.route("/items_multiappend/<listid>", methods=["GET", "POST"])
@login_required
def items_multiappend(listid):
if request.method == "POST":
# a new item has been added
newitems = request.form["newItems"]
for line in newitems.splitlines():
line = line.strip()
if len(line)>2:
interpret_and_add_item(listid, line.strip())
return redirect(url_for("items.items_append", listid=listid))
# webservice for deleting one item
@items_bp.route("/item_delete/<itemid>")
@login_required
def item_delete(itemid):
i = Item.query.get(itemid)
listid = i.listofitems_id
db.session.delete(i)
db.session.commit()
Log.info(f'User {current_user.id} deleted item {itemid}')
# return render_template("items_append.html", user=current_user,
# items=Item.query.filter_by(listofitems_id=listid).order_by(Item.label).all(),
# iconpath = '/'+ICONPATH,
# logo_url=url_for("items.items", listid=listid))
return redirect(url_for("items.items_append", listid=listid))
# webservice for cleaning all checked items to suggestion
@items_bp.route("/items_clean/<listid>")
@login_required
def items_clean(listid):
for i in Item.query.filter_by(listofitems_id=listid, is_checked=True, is_suggestion=False).all():
i.is_suggestion = True
db.session.commit()
return redirect(url_for("items.items", listid=listid))
# webservice for adding one item
@items_bp.route("/item_addone/<itemid>")
@login_required
def item_addone(itemid):
i = Item.query.get(itemid)
listid = i.listofitems_id
# if it is checked or not on the list yet, set quantity to one
if i.is_suggestion or i.is_checked:
i.quantity = 1
# and make sure its on the list
i.is_suggestion = False
i.is_checked = False
else:
# else add one to the quantity, to a minimum of 2
i.quantity += 1 if i.quantity else 2
# if no unit given, make it 'x'
if not i.unit:
i.unit = 'x'
db.session.commit()
return render_template("items_append.html", user=current_user,
items=Item.query.filter_by(listofitems_id=listid).order_by(Item.label).all(),
logo_url=url_for("items.items", listid=listid))
# webservice for adding one item with a quantity/unit
@items_bp.route("/item_addquantity/<itemid>/<quantity>")
@login_required
def item_addquantity(itemid, quantity):
i = Item.query.get(itemid)
listid = i.listofitems_id
# always add the item to the active todo
if i.is_suggestion or i.is_checked:
# and make sure its on the list
i.is_suggestion = False
i.is_checked = False
else:
i.quantity += int(quantity)
db.session.commit()
return render_template("items_append.html", user=current_user,
items=Item.query.filter_by(listofitems_id=listid).order_by(Item.label).all(),
logo_url=url_for("items.items", listid=listid))
# webservice for updating category of one item
@items_bp.route("/item_update_category/<itemid>/<category>")
@login_required
def item_upitem_update_categorydate(itemid, category):
i = Item.query.get(itemid)
i.category = category
db.session.commit()
return '', 204