From 43503dc778cb81c381c48d913665ccefcd16e363 Mon Sep 17 00:00:00 2001 From: q Date: Mon, 9 Mar 2026 11:51:43 +0300 Subject: [PATCH] Send all Magnit price matches --- main.py | 65 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/main.py b/main.py index 80f08a2..737ed36 100644 --- a/main.py +++ b/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}, товар не найден, -"] - 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 = [] + 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")) + 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)