This commit is contained in:
jableader 2024-01-13 18:42:23 +11:00
parent 671db1b4eb
commit ebab422869
3 changed files with 83 additions and 9 deletions

46
main.py
View file

@ -1,5 +1,6 @@
import sqlite3
import product, recipe, db
import product, recipe, db, meals
import datetime
from pydantic import BaseModel
from typing import List, Annotated
@ -51,19 +52,26 @@ class ProductUrl(BaseModel):
async def create_product(url: ProductUrl, conn: sqlite3.Connection = Depends(get_db)) -> product.Product:
return await product.get_or_create(conn, url.url, url.tags)
@app.get("/recipes/{recipe_id}")
async def get_recipe(recipe_id: int, conn: sqlite3.Connection = Depends(get_db)) -> recipe.Recipe:
r = await recipe.find_recipe_by_id(conn, recipe_id)
async def load_full_recipe(conn: sqlite3.Connection, id: int) -> recipe.Recipe:
r = await recipe.find_recipe_by_id(conn, id)
if not r:
return JSONResponse(status_code=404, content={'message': 'Recipe not found'})
return None
r.ingredients = []
async for ingredient in recipe.find_ingredients_by_recipe_id(conn, recipe_id):
async for ingredient in recipe.find_ingredients_by_recipe_id(conn, id):
ingredient.product = await product.find_product_by_id(conn, ingredient.product_id)
r.ingredients.append(ingredient)
return r
@app.get("/recipes/{recipe_id}")
async def get_recipe(recipe_id: int, conn: sqlite3.Connection = Depends(get_db)) -> recipe.Recipe:
r = await load_full_recipe(conn, recipe_id)
if not r:
return JSONResponse(status_code=404, content={'message': 'Recipe not found'})
return r
@app.post('/recipes/')
async def create_recipe(item: recipe.Recipe, conn: sqlite3.Connection = Depends(get_db)) -> recipe.Recipe:
if not item.ingredients:
@ -80,4 +88,28 @@ async def create_recipe(item: recipe.Recipe, conn: sqlite3.Connection = Depends(
await recipe.insert_ingredient(conn, ingredient)
await conn.commit()
return item
return item
@app.get("/meals/")
async def get_meals(start: datetime.datetime, end: datetime.datetime, conn: sqlite3.Connection = Depends(get_db)) -> List[meals.Meal]:
result = []
async for meal in meals.find_meals_by_date_range(conn, start, end):
meal.recipe = await load_full_recipe(conn, meal.recipe_id)
result.append(meal)
return result
@app.post("/meals/")
async def create_meal(meal: meals.Meal, conn: sqlite3.Connection = Depends(get_db)) -> meals.Meal:
if not meal.chef:
return JSONResponse(status_code=400, content={'message': 'Meal must have at least one chef'})
if not meal.cleanup:
return JSONResponse(status_code=400, content={'message': 'Meal must have at least one cleanup person'})
if not meal.consumers:
return JSONResponse(status_code=400, content={'message': 'Meal must have at least one consumer'})
await meals.insert_meal(conn, meal)
await conn.commit()
return meal

View file

@ -0,0 +1 @@
from meals.db import *

View file

@ -37,12 +37,27 @@ async def create(conn):
FOREIGN KEY(recipe_id) REFERENCES Recipe(id)
);''')
async def insert_meal_participant(conn, meal_id: int, person_id: int, role: str):
await conn.execute('''
INSERT INTO MealParticipant (meal_id, person_id, role)
VALUES (?, ?, ?)
''', (meal_id, person_id, role))
async def insert_meal(conn, meal: Meal):
async with conn.execute('''
INSERT INTO Meal (date)
VALUES (?)
''', (meal.date,)) as cursor:
return cursor.lastrowid
meal.id = cursor.lastrowid
for person in meal.chef:
await insert_meal_participant(conn, meal.id, person.id, 'chef')
for person in meal.cleanup:
await insert_meal_participant(conn, meal.id, person.id, 'cleanup')
for person in meal.consumers:
await insert_meal_participant(conn, meal.id, person.id, 'consumer')
async def find_meal_by_id(conn, meal_id: int) -> Meal:
async with conn.execute(f'''
@ -60,4 +75,30 @@ async def find_meal_by_date(conn, date: datetime) -> Meal:
LIMIT 1
''', (date,)) as cursor:
async for row in cursor:
return Meal(**{k:v for k,v in zip(Meal.KEYS, row)})
return Meal(**{k:v for k,v in zip(Meal.KEYS, row)})
async def find_meals_by_date_range(conn, start: datetime, end: datetime) -> List[Meal]:
async with conn.execute(f'''
SELECT {','.join(Meal.KEYS)} FROM Meal
WHERE date >= ? AND date <= ?
''', (start, end)) as cursor:
result = []
async for row in cursor:
result.append(Meal(**{k:v for k,v in zip(Meal.KEYS, row)}))
return result
async def load_participants(conn, meal: Meal) -> None:
async with conn.execute(f'''
SELECT person_id, role FROM MealParticipant
WHERE meal_id = ?
''', (meal.id,)) as cursor:
async for row in cursor:
person = await Person.find_person_by_id(conn, row[0])
if row[1] == 'chef':
meal.chef.append(person)
elif row[1] == 'cleanup':
meal.cleanup.append(person)
elif row[1] == 'consumer':
meal.consumers.append(person)
else:
raise Exception(f'Unknown role: {row[1]}')