Better unit matching, search for recipes
This commit is contained in:
parent
3be9bf4786
commit
8a89726e29
4 changed files with 45 additions and 20 deletions
16
main.py
16
main.py
|
|
@ -65,10 +65,20 @@ 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,16 +17,20 @@ 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
|
||||
quantity, unit = None, None
|
||||
for amount in ingredient.amount:
|
||||
if quantity is None and amount.quantity:
|
||||
quantity = amount.quantity
|
||||
|
||||
real_unit = units.get_unit(unit)
|
||||
if real_unit:
|
||||
unit = real_unit.name
|
||||
elif not name:
|
||||
name = unit
|
||||
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,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
8
units.py
8
units.py
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue