autoformat
This commit is contained in:
parent
83388b2925
commit
8a4616fb13
7 changed files with 25 additions and 15 deletions
|
|
@ -34,5 +34,3 @@ async def parse_ingredient(
|
||||||
parsed_one = ingredients_mod.parse_ingredient_from_nlp(line)
|
parsed_one = ingredients_mod.parse_ingredient_from_nlp(line)
|
||||||
matched_one = await ingredients_mod.match_existing_products(conn, [parsed_one])
|
matched_one = await ingredients_mod.match_existing_products(conn, [parsed_one])
|
||||||
return matched_one[0]
|
return matched_one[0]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
20
api/meals.py
20
api/meals.py
|
|
@ -244,7 +244,9 @@ async def create_meal_scoped(
|
||||||
valid_ids = set(users.keys())
|
valid_ids = set(users.keys())
|
||||||
invalid = sorted(member_ids - valid_ids)
|
invalid = sorted(member_ids - valid_ids)
|
||||||
if invalid:
|
if invalid:
|
||||||
return error_response(request, 400, f"Invalid member id(s): {', '.join(map(str, invalid))}")
|
return error_response(
|
||||||
|
request, 400, f"Invalid member id(s): {', '.join(map(str, invalid))}"
|
||||||
|
)
|
||||||
|
|
||||||
# Validate recipes (existence and household scope) via recipes repository
|
# Validate recipes (existence and household scope) via recipes repository
|
||||||
if domain_meal.recipes:
|
if domain_meal.recipes:
|
||||||
|
|
@ -263,7 +265,11 @@ async def create_meal_scoped(
|
||||||
if not recipe:
|
if not recipe:
|
||||||
invalid_recipes.append(rid)
|
invalid_recipes.append(rid)
|
||||||
if invalid_recipes:
|
if invalid_recipes:
|
||||||
return error_response(request, 400, f"Invalid recipe id(s): {', '.join(map(str, sorted(set(invalid_recipes))))}")
|
return error_response(
|
||||||
|
request,
|
||||||
|
400,
|
||||||
|
f"Invalid recipe id(s): {', '.join(map(str, sorted(set(invalid_recipes))))}",
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
await meals.insert_meal_scoped(conn, domain_meal, hid)
|
await meals.insert_meal_scoped(conn, domain_meal, hid)
|
||||||
except aiosqlite.IntegrityError:
|
except aiosqlite.IntegrityError:
|
||||||
|
|
@ -338,7 +344,9 @@ async def update_meal_scoped(
|
||||||
valid_ids = set(users.keys())
|
valid_ids = set(users.keys())
|
||||||
invalid = sorted(member_ids - valid_ids)
|
invalid = sorted(member_ids - valid_ids)
|
||||||
if invalid:
|
if invalid:
|
||||||
return error_response(request, 400, f"Invalid member id(s): {', '.join(map(str, invalid))}")
|
return error_response(
|
||||||
|
request, 400, f"Invalid member id(s): {', '.join(map(str, invalid))}"
|
||||||
|
)
|
||||||
|
|
||||||
if domain_meal.recipes:
|
if domain_meal.recipes:
|
||||||
from recipes.repository import find_recipe_by_id_scoped, find_recipe_by_id
|
from recipes.repository import find_recipe_by_id_scoped, find_recipe_by_id
|
||||||
|
|
@ -355,7 +363,11 @@ async def update_meal_scoped(
|
||||||
if not recipe:
|
if not recipe:
|
||||||
invalid_recipes.append(rid)
|
invalid_recipes.append(rid)
|
||||||
if invalid_recipes:
|
if invalid_recipes:
|
||||||
return error_response(request, 400, f"Invalid recipe id(s): {', '.join(map(str, sorted(set(invalid_recipes))))}")
|
return error_response(
|
||||||
|
request,
|
||||||
|
400,
|
||||||
|
f"Invalid recipe id(s): {', '.join(map(str, sorted(set(invalid_recipes))))}",
|
||||||
|
)
|
||||||
await meals.update_meal(conn, domain_meal)
|
await meals.update_meal(conn, domain_meal)
|
||||||
# Return updated state
|
# Return updated state
|
||||||
updated = await meals.find_meal_by_id_scoped(conn, meal_id, hid)
|
updated = await meals.find_meal_by_id_scoped(conn, meal_id, hid)
|
||||||
|
|
|
||||||
1
main.py
1
main.py
|
|
@ -141,6 +141,7 @@ def create_app() -> FastAPI:
|
||||||
app.include_router(recipes_router.router, prefix="/api/v1", tags=["recipes"]) # canonical
|
app.include_router(recipes_router.router, prefix="/api/v1", tags=["recipes"]) # canonical
|
||||||
app.include_router(recipes_router.public, prefix="/api/v1", tags=["recipes"]) # public utils
|
app.include_router(recipes_router.public, prefix="/api/v1", tags=["recipes"]) # public utils
|
||||||
from api import ingredients as ingredients_router
|
from api import ingredients as ingredients_router
|
||||||
|
|
||||||
app.include_router(ingredients_router.router, prefix="/api/v1", tags=["ingredients"]) # scoped
|
app.include_router(ingredients_router.router, prefix="/api/v1", tags=["ingredients"]) # scoped
|
||||||
app.include_router(meals_router.router, prefix="/api/v1", tags=["meals"]) # canonical
|
app.include_router(meals_router.router, prefix="/api/v1", tags=["meals"]) # canonical
|
||||||
app.include_router(shopping_router.router, prefix="/api/v1", tags=["shopping"]) # canonical
|
app.include_router(shopping_router.router, prefix="/api/v1", tags=["shopping"]) # canonical
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,7 @@ def _fallback_urls(url: str) -> Iterable[str]:
|
||||||
q = dict(parse_qsl(parsed.query, keep_blank_values=True))
|
q = dict(parse_qsl(parsed.query, keep_blank_values=True))
|
||||||
if q.get("output") != "amp":
|
if q.get("output") != "amp":
|
||||||
q["output"] = "amp"
|
q["output"] = "amp"
|
||||||
amp_url = urlunparse(
|
amp_url = urlunparse(parsed._replace(query=urlencode(q, doseq=True)))
|
||||||
parsed._replace(query=urlencode(q, doseq=True))
|
|
||||||
)
|
|
||||||
if amp_url != url:
|
if amp_url != url:
|
||||||
yield amp_url
|
yield amp_url
|
||||||
|
|
||||||
|
|
@ -79,9 +77,7 @@ async def scrape_recipe_ldata(url: str) -> Optional[dict]:
|
||||||
# Some CDNs prefer a referer; provide same-origin referer as a harmless hint.
|
# Some CDNs prefer a referer; provide same-origin referer as a harmless hint.
|
||||||
headers = dict(DEFAULT_HEADERS)
|
headers = dict(DEFAULT_HEADERS)
|
||||||
headers.setdefault("Referer", candidate)
|
headers.setdefault("Referer", candidate)
|
||||||
response = await client.get(
|
response = await client.get(candidate, headers=headers, follow_redirects=True)
|
||||||
candidate, headers=headers, follow_redirects=True
|
|
||||||
)
|
|
||||||
if response.status_code in BLOCK_STATUSES:
|
if response.status_code in BLOCK_STATUSES:
|
||||||
# Try next fallback
|
# Try next fallback
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,7 @@ async def request_meal_scoped(
|
||||||
INSERT INTO ShoppingListItem (ingredient_id, person_id, meal_id, created_date, household_id)
|
INSERT INTO ShoppingListItem (ingredient_id, person_id, meal_id, created_date, household_id)
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(None, person_id, meal.id, item.created_date.isoformat(), household_id),
|
(None, person_id, meal.id, item.created_date.isoformat(), household_id),
|
||||||
) as cursor:
|
) as cursor:
|
||||||
item.id = cursor.lastrowid
|
item.id = cursor.lastrowid
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from db import connect, create
|
||||||
|
|
||||||
SAMPLE_URL = "https://www.allrecipes.com/recipe/262696/cheese-omelette/"
|
SAMPLE_URL = "https://www.allrecipes.com/recipe/262696/cheese-omelette/"
|
||||||
with open("tests/sample_files/recipes/cheese-omelette.html", "r", encoding="utf-8") as f:
|
with open("tests/sample_files/recipes/cheese-omelette.html", "r", encoding="utf-8") as f:
|
||||||
SAMPLE_HTML = f.read()
|
SAMPLE_HTML = f.read()
|
||||||
|
|
||||||
|
|
||||||
class TestRecipesParseFromUrlIntegrationV2(unittest.IsolatedAsyncioTestCase):
|
class TestRecipesParseFromUrlIntegrationV2(unittest.IsolatedAsyncioTestCase):
|
||||||
|
|
@ -58,7 +58,9 @@ class TestRecipesParseFromUrlIntegrationV2(unittest.IsolatedAsyncioTestCase):
|
||||||
|
|
||||||
async def get(self, url, headers=None, follow_redirects=False):
|
async def get(self, url, headers=None, follow_redirects=False):
|
||||||
# Allow the scraper to call the base URL or an AMP fallback
|
# Allow the scraper to call the base URL or an AMP fallback
|
||||||
assert url == SAMPLE_URL or (url.startswith(SAMPLE_URL) and ("output=amp" in url or url.endswith("/amp")))
|
assert url == SAMPLE_URL or (
|
||||||
|
url.startswith(SAMPLE_URL) and ("output=amp" in url or url.endswith("/amp"))
|
||||||
|
)
|
||||||
return DummyResp(200, SAMPLE_HTML)
|
return DummyResp(200, SAMPLE_HTML)
|
||||||
|
|
||||||
orig_client = scraping.httpx.AsyncClient
|
orig_client = scraping.httpx.AsyncClient
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ class TestRecipesParseFromUrlV2(unittest.IsolatedAsyncioTestCase):
|
||||||
|
|
||||||
# Success case
|
# Success case
|
||||||
import recipes as recipes_pkg
|
import recipes as recipes_pkg
|
||||||
|
|
||||||
orig = recipes_pkg._scrape_recipe_ldata
|
orig = recipes_pkg._scrape_recipe_ldata
|
||||||
recipes_pkg._scrape_recipe_ldata = fake_scrape
|
recipes_pkg._scrape_recipe_ldata = fake_scrape
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue