Send all Magnit price matches

This commit is contained in:
q 2026-03-09 11:51:43 +03:00
parent 75a63bb6fc
commit 43503dc778

59
main.py
View file

@ -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)