Desynth page and improved item info api. Added string substitution to utils.
This commit is contained in:
@@ -15,6 +15,7 @@ from .database import get_session
|
||||
|
||||
# Map craft names -> table names in Postgres
|
||||
ALLOWED_CRAFTS = {
|
||||
"desynthesis": "recipes_desynthesis",
|
||||
"woodworking": "recipes_woodworking",
|
||||
"smithing": "recipes_smithing",
|
||||
"alchemy": "recipes_alchemy",
|
||||
@@ -33,6 +34,17 @@ class RecipeUsageSummary(BaseModel):
|
||||
name: str
|
||||
level: int
|
||||
|
||||
class DesynthRecipe(BaseModel):
|
||||
id: int
|
||||
craft: str
|
||||
cap: Optional[int] | None = None
|
||||
item: str
|
||||
crystal: str
|
||||
ingredients: str # raw text, quantity assumed 1 each
|
||||
hq1: Optional[str] | None = None
|
||||
hq2: Optional[str] | None = None
|
||||
hq3: Optional[str] | None = None
|
||||
|
||||
class ItemRecipeUsage(BaseModel):
|
||||
crafted: list[RecipeUsageSummary] = []
|
||||
ingredient: list[RecipeUsageSummary] = []
|
||||
@@ -60,6 +72,29 @@ def _craft_table(craft: str) -> str:
|
||||
return ALLOWED_CRAFTS[craft_lower]
|
||||
|
||||
|
||||
@router.get("/recipes/desynthesis", response_model=List[DesynthRecipe])
|
||||
async def list_desynth_recipes(session: AsyncSession = Depends(get_session)):
|
||||
q = text("SELECT * FROM recipes_desynthesis ORDER BY item")
|
||||
result = await session.execute(q)
|
||||
rows = result.fetchall()
|
||||
out: list[DesynthRecipe] = []
|
||||
for r in rows:
|
||||
out.append(
|
||||
DesynthRecipe(
|
||||
id=r.id,
|
||||
craft=r.craft,
|
||||
cap=r.cap,
|
||||
item=r.item,
|
||||
crystal=r.crystal,
|
||||
ingredients=r.ingredients,
|
||||
hq1=r.hq1,
|
||||
hq2=r.hq2,
|
||||
hq3=r.hq3,
|
||||
)
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
@router.get("/recipes/{craft}", response_model=List[RecipeDetail])
|
||||
async def list_recipes(
|
||||
craft: str = Path(..., description="Craft name, e.g. woodworking"),
|
||||
@@ -134,10 +169,15 @@ async def item_recipe_usage(item_name: str, session: AsyncSession = Depends(get_
|
||||
)
|
||||
|
||||
# As ingredient (simple text match in JSON/array column)
|
||||
# Match exact ingredient name by looking for the item quoted in the JSON text.
|
||||
# Using the surrounding double quotes prevents partial matches, e.g. "Chestnut" will not
|
||||
# match the ingredient string "Chestnut Lumber".
|
||||
quoted = f'"{item_name}"'
|
||||
q2 = text(
|
||||
f"SELECT id, name, level FROM {table} WHERE ingredients::text ILIKE :pat LIMIT 50"
|
||||
f"SELECT id, name, level FROM {table} "
|
||||
f"WHERE ingredients::text ILIKE :pat LIMIT 50"
|
||||
)
|
||||
res2 = await session.execute(q2, {"pat": f"%{item_name}%"})
|
||||
res2 = await session.execute(q2, {"pat": f"%{quoted}%"})
|
||||
for r in res2.fetchall():
|
||||
if not any(c.id == r.id and c.craft == craft for c in crafted) and not any(
|
||||
i.id == r.id and i.craft == craft for i in ingredient
|
||||
|
||||
Reference in New Issue
Block a user