Send all Magnit price matches
This commit is contained in:
parent
75a63bb6fc
commit
43503dc778
1 changed files with 45 additions and 20 deletions
59
main.py
59
main.py
|
|
@ -416,15 +416,16 @@ def _normalize_magnit_product(entry) -> dict[str, str]:
|
|||
|
||||
raise ValueError("MAGNIT_PRODUCTS должен содержать строки или словари.")
|
||||
|
||||
def _pick_magnit_item(data: dict):
|
||||
def _pick_magnit_items(data: dict) -> list[dict]:
|
||||
items = data.get("items")
|
||||
if isinstance(items, list):
|
||||
return [item for item in items if isinstance(item, dict)]
|
||||
|
||||
best_match = data.get("best_match")
|
||||
if isinstance(best_match, dict):
|
||||
return best_match
|
||||
return [best_match]
|
||||
|
||||
items = data.get("items")
|
||||
if isinstance(items, list) and items:
|
||||
return items[0]
|
||||
return None
|
||||
return []
|
||||
|
||||
def _format_money(value) -> str | None:
|
||||
if value is None:
|
||||
|
|
@ -444,6 +445,26 @@ def _format_magnit_quantity(value) -> str:
|
|||
return "нет данных"
|
||||
return f"{value} шт."
|
||||
|
||||
async def _send_lines_in_chunks(message: Message, lines: list[str], limit: int = 4000) -> None:
|
||||
if not lines:
|
||||
await message.answer("Товары не найдены.")
|
||||
return
|
||||
|
||||
chunk: list[str] = []
|
||||
chunk_len = 0
|
||||
for line in lines:
|
||||
extra_len = len(line) + (1 if chunk else 0)
|
||||
if chunk and chunk_len + extra_len > limit:
|
||||
await message.answer("\n".join(chunk))
|
||||
chunk = [line]
|
||||
chunk_len = len(line)
|
||||
continue
|
||||
chunk.append(line)
|
||||
chunk_len += extra_len
|
||||
|
||||
if chunk:
|
||||
await message.answer("\n".join(chunk))
|
||||
|
||||
# --- Игровая логика (/penis) ---
|
||||
|
||||
def play_penis(user_id: int, user_name: str | None = None, now: datetime | None = None) -> tuple[bool, str]:
|
||||
|
|
@ -608,7 +629,7 @@ async def handle_prices_cmd(message: Message):
|
|||
await message.answer("Список MAGNIT_PRODUCTS пуст. Добавь товары в config.py.")
|
||||
return
|
||||
|
||||
async def fetch_product(product_cfg: dict[str, str]) -> str:
|
||||
async def fetch_product(product_cfg: dict[str, str]) -> list[str]:
|
||||
def fetch():
|
||||
return requests.get(
|
||||
f"{config.MAGNIT_API_BASE_URL.rstrip('/')}/price",
|
||||
|
|
@ -624,29 +645,33 @@ async def handle_prices_cmd(message: Message):
|
|||
resp = await asyncio.to_thread(fetch)
|
||||
if resp.status_code != 200:
|
||||
logger.warning("Magnit API returned %s for %s", resp.status_code, product_cfg["query"])
|
||||
return f"{label}, ошибка API ({resp.status_code}), -"
|
||||
return [f"{label}, ошибка API ({resp.status_code}), -"]
|
||||
|
||||
data = resp.json()
|
||||
if not isinstance(data, dict):
|
||||
return f"{label}, битый ответ API, -"
|
||||
return [f"{label}, битый ответ API, -"]
|
||||
|
||||
item = _pick_magnit_item(data)
|
||||
if not isinstance(item, dict):
|
||||
return f"{label}, товар не найден, -"
|
||||
items = _pick_magnit_items(data)
|
||||
if not items:
|
||||
return [f"{label}, товар не найден, -"]
|
||||
|
||||
lines = []
|
||||
for item in items:
|
||||
name = str(item.get("name") or label).strip() or label
|
||||
price = _format_magnit_price(item)
|
||||
quantity = _format_magnit_quantity(item.get("quantity"))
|
||||
return f"{name}, {price}, {quantity}"
|
||||
lines.append(f"{name}, {price}, {quantity}")
|
||||
return lines
|
||||
except requests.RequestException:
|
||||
logger.exception("Failed to fetch Magnit product: %s", product_cfg["query"])
|
||||
return f"{label}, ошибка запроса, -"
|
||||
return [f"{label}, ошибка запроса, -"]
|
||||
except ValueError:
|
||||
logger.exception("Magnit API returned invalid JSON for %s", product_cfg["query"])
|
||||
return f"{label}, битый JSON, -"
|
||||
return [f"{label}, битый JSON, -"]
|
||||
|
||||
lines = await asyncio.gather(*(fetch_product(product) for product in products))
|
||||
await message.answer("\n".join(lines)[:4000])
|
||||
result_groups = await asyncio.gather(*(fetch_product(product) for product in products))
|
||||
lines = [line for group in result_groups for line in group]
|
||||
await _send_lines_in_chunks(message, lines)
|
||||
|
||||
async def handle_fetch_cmd(message: Message):
|
||||
await handle_prices_cmd(message)
|
||||
|
|
|
|||
Loading…
Reference in a new issue