zetikettes/backend/zetikettes/tikette/views.py
2025-08-07 12:09:27 +02:00

165 lines
3.9 KiB
Python

import json
import sys
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie
from google.auth.transport import requests
from google.oauth2 import id_token
from .planche import generate as stickersheet
from .models import Tikette, Tikategory, Tizer
def ok(payload=None):
return JsonResponse({"status": "ok", **(payload or {})})
def post_please(f):
def __f(request):
if request.method != "POST":
return JsonResponse(
{"status": "notok", "message": "this isn't the way"},
status=405,
headers={"Allow": "POST"},
)
return f(request)
return __f
def auth_only(f):
def __f(request):
# check that email is valid
# exp?
if "user_data" not in request.session:
raise PermissionDenied("Not logged in")
email = request.session["user_data"]["email"]
resp = Tizer.objects.filter(email=email)
if not resp:
raise PermissionDenied("User not found")
return f(request)
return __f
def quirk_bold_allergens(ingredients):
out = []
for ing in (x.strip() for x in ingredients.split(",")):
if ing.startswith("*"):
out.append(f'<tspan style="font-weight:bold">{ing[1:]}</tspan>')
else:
out.append(ing)
return ", ".join(out)
def handler403(request, exception):
return JsonResponse({"status": "notok", "message": "permission denied"}, status=403)
def handler404(request, exception):
return JsonResponse(
{"status": "notok", "message": "endpoint not found"}, status=404
)
@auth_only
@ensure_csrf_cookie
def get_list(request):
tikettes = [
{
"id": x.id,
"title": x.title,
"category": x.category.name,
"category_id": x.category.id,
"prototempalte": x.category.prototempalte.name,
"landscape": x.category.landscape,
"designation": x.designation,
"ingredients": x.ingredients,
"description": x.description,
"ab": x.ab,
"color": x.color,
"subs": {x.name: x.default for x in x.category.subs.all()},
}
for x in Tikette.objects.all()
]
return ok({"tikettes": tikettes})
@auth_only
def get_categories(request):
tikats = [
{
"id": x.id,
"name": x.name,
}
for x in Tikategory.objects.all()
]
return ok({"tikats": tikats})
@auth_only
@post_please
def generate(request):
payload = json.loads(request.body)
subs = dict(payload["subs"])
for key in ("designation", "ingredients", "description", "color", "AB"):
subs[key] = payload[key]
subs["ingredients"] = quirk_bold_allergens(subs["ingredients"])
pdfpath = stickersheet.generate(
template=payload["template"],
subs=subs,
out_dir=settings.TIKETTE_OUT_DIR,
landscape=payload["landscape"],
)
return ok({"file": pdfpath})
@auth_only
@post_please
def newtikette(request):
payload = json.loads(request.body)
tikette = Tikette(**payload)
tikette.save()
return ok()
@auth_only
@post_please
def deletetikette(request):
payload = json.loads(request.body)
Tikette.objects.get(id=payload["id"]).delete()
return ok()
@csrf_exempt
@post_please
def signin(request):
payload = json.loads(request.body)
token = payload["token"]
try:
user_data = id_token.verify_oauth2_token(
token, requests.Request(), settings.GOOGLE_OAUTH_CLIENT_ID
)
except ValueError:
raise
return JsonResponse({"status": "notok"}, status=403)
request.session["user_data"] = user_data
return ok(user_data)
def signout(request):
del request.session["user_data"]
return ok()