Better unit matching, search for recipes

This commit is contained in:
jableader 2024-01-13 22:37:39 +11:00
parent 3be9bf4786
commit 8a89726e29
4 changed files with 45 additions and 20 deletions

16
main.py
View file

@ -65,11 +65,21 @@ async def load_full_recipe(conn: sqlite3.Connection, id: int) -> recipes.Recipe:
return r
@app.get("/recipes/")
async def get_recipes(conn: sqlite3.Connection = Depends(get_db)) -> List[recipes.Recipe]:
async def get_recipes(q: str | None = None, conn: sqlite3.Connection = Depends(get_db)) -> List[recipes.Recipe]:
result = []
async for recipe in recipes.get_all(conn):
result.append(recipe)
if q:
async for recipe in recipes.find_recipes_by_name(conn, q):
result.append(recipe)
else:
async for recipe in recipes.get_all(conn):
result.append(recipe)
for recipe in result:
recipe.ingredients = []
async for ingredient in recipes.find_ingredients_by_recipe_id(conn, recipe.id):
ingredient.product = await products.find_product_by_id(conn, ingredient.product_id)
recipe.ingredients.append(ingredient)
return result
@app.get("/recipes/{recipe_id}")

View file

@ -1,5 +1,5 @@
from products import Product, find_product_by_tag
from recipes.db import Recipe, Ingredient, insert_recipe, insert_ingredient, find_recipe_by_id, find_ingredients_by_recipe_id, get_all
from recipes.db import Recipe, Ingredient, insert_recipe, insert_ingredient, find_recipe_by_id, find_ingredients_by_recipe_id, get_all, find_recipes_by_name
from recipes.scraping import scrape_recipe
from ingredient_parser import parse_multiple_ingredients
@ -17,17 +17,21 @@ def parse_ingredient_from_nlp(ingredients: List[str]) -> Ingredient:
for ingredient in parse_multiple_ingredients(ingredients):
name = ingredient.name.text if ingredient.name else ''
quantity, unit = 1, units.ITEMS.name
if ingredient.amount:
amount = ingredient.amount[0]
quantity = amount.quantity if amount.quantity else 1
real_unit = units.get_unit(unit)
if real_unit:
unit = real_unit.name
elif not name:
name = unit
quantity, unit = None, None
for amount in ingredient.amount:
if quantity is None and amount.quantity:
quantity = amount.quantity
if unit is None and amount.unit:
real_unit = units.get_unit(amount.unit)
if real_unit:
unit = real_unit.name
if quantity is None:
quantity = 1
if unit is None:
unit = units.ITEMS.name
results.append(Ingredient(id=0,
line=ingredient.sentence,
name=name,
@ -52,6 +56,9 @@ async def _get_recipe_from_ldata(conn, url: str, ldata: dict) -> dict:
ingredients = await match_existing_products(conn, ingredients)
name = ldata['name'] if 'name' in ldata else url
images = ldata['image'] if 'image' in ldata else []
if isinstance(images, str):
images = [images]
return Recipe(
id=0,
name=name,

View file

@ -61,13 +61,13 @@ async def insert_ingredient(conn, ingredient: Ingredient):
async def insert_recipe(conn, recipe: Recipe):
async with conn.execute('''
INSERT INTO Recipe (name, link, raw_data, image_urls)
VALUES (?, ?, ?)
VALUES (?, ?, ?, ?)
''', (recipe.name, recipe.link, recipe.raw_data, json.dumps(recipe.image_urls))) as cursor:
recipe.id = cursor.lastrowid
def row_to_recipe(row) -> Recipe:
d = {k:v for k,v in zip(Recipe.KEYS, row)}
d['img_urls'] = json.loads(d['img_urls'])
d['image_urls'] = json.loads(d['image_urls'])
return Recipe(**d)
async def find_recipe_by_id(conn, recipe_id: int) -> Recipe:
@ -87,6 +87,14 @@ async def find_ingredients_by_recipe_id(conn, recipe_id: int) -> List[Ingredient
async for row in cursor:
yield Ingredient(**{k:v for k,v in zip(Ingredient.KEYS, row)})
async def find_recipes_by_name(conn, name: str) -> List[Recipe]:
async with conn.execute(f'''
SELECT {','.join(Recipe.KEYS)} FROM Recipe
WHERE name LIKE ?
''', (f'%{name}%',)) as cursor:
async for row in cursor:
yield row_to_recipe(row)
async def get_all(conn) -> List[Recipe]:
async with conn.execute(f'''
SELECT {','.join(Recipe.KEYS)} FROM Recipe

View file

@ -21,11 +21,11 @@ LITRE = Unit("Litre", ["litre", "liter", "l"], "volume", 1)
GRAM = Unit("Gram", ["gram", "g"], "weight", 1)
# Add conversion factors for common cooking measurements
CUP = Unit("Cup", ["cup", "c"], "volume", 240)
TABLESPOON = Unit("Tablespoon", ["tablespoon", "tablespoons", "tbsp"], "volume", 15)
TEASPOON = Unit("Teaspoon", ["teaspoon", "teaspoons", "tsp"], "volume", 5)
CUP = Unit("Cup", ["cup", "cups", "c"], "volume", 240)
TABLESPOON = Unit("Tablespoon", ["tablespoon", "tablespoons", "tbsp", "tbsps"], "volume", 15)
TEASPOON = Unit("Teaspoon", ["teaspoon", "teaspoons", "tsp", "tsps"], "volume", 5)
OUNCE = Unit("Ounce", ["ounce", "ounces", "oz"], "weight", 28.3495)
POUND = Unit("Pound", ["pound", "pounds", "lb"], "weight", 453.592)
POUND = Unit("Pound", ["pound", "pounds", "lb", "lbs"], "weight", 453.592)
FLUID_OUNCE = Unit("Fluid Ounce", ["fluid ounce", "fl oz"], "volume", 29.5735)
PINT = Unit("Pint", ["pint", "pt"], "volume", 473.176)
QUART = Unit("Quart", ["quart", "qt"], "volume", 946.353)