Meals
This commit is contained in:
parent
671db1b4eb
commit
ebab422869
3 changed files with 83 additions and 9 deletions
46
main.py
46
main.py
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
from meals.db import *
|
||||
45
meals/db.py
45
meals/db.py
|
|
@ -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]}')
|
||||
Loading…
Reference in a new issue