from __future__ import annotations import logging import re from aiogram import Bot from aiogram.types import BufferedInputFile from bot.ha_client import HaClient from bot.tg_util import send_text, split_telegram_message logger = logging.getLogger(__name__) IMAGE_MD_RE = re.compile(r"!\[([^\]]*)\]\(([^)]+)\)") TG_CAPTION_MAX = 1024 def parse_notice_content(content: str) -> tuple[str, list[str]]: image_paths: list[str] = [] def _replace(match: re.Match[str]) -> str: image_paths.append(match.group(2).strip()) return "" text = IMAGE_MD_RE.sub(_replace, content) text = _plain_markdown(text) return text, image_paths def _plain_markdown(text: str) -> str: text = re.sub(r"```[^\n]*\n(.*?)```", r"\1", text, flags=re.DOTALL) text = re.sub(r"\*\*([^*]+)\*\*", r"\1", text) text = re.sub(r"\*([^*]+)\*", r"\1", text) text = re.sub(r"__([^_]+)__", r"\1", text) text = re.sub(r"`([^`]+)`", r"\1", text) text = re.sub(r"\n{3,}", "\n\n", text) return text.strip() async def send_notice_content( bot: Bot, chat_id: int, content: str, client: HaClient, *, ha_api_base: str, ) -> None: caption, image_paths = parse_notice_content(content) if not image_paths: await send_text(bot, chat_id, caption or content) return caption_chunks = split_telegram_message(caption, TG_CAPTION_MAX) if caption else [] first_caption = caption_chunks[0] if caption_chunks else None for index, image_path in enumerate(image_paths): try: image_bytes = await client.download_media(image_path, ha_api_base=ha_api_base) except Exception: logger.exception("Failed to download image %s for chat_id=%s", image_path, chat_id) fallback = f"{caption}\n\n(не удалось загрузить: {image_path})".strip() await send_text(bot, chat_id, fallback or image_path) return cap = first_caption if index == 0 else None await bot.send_photo( chat_id, BufferedInputFile(image_bytes, filename="image.png"), caption=cap or None, ) if len(caption_chunks) > 1: for extra in caption_chunks[1:]: await send_text(bot, chat_id, extra) elif caption and not first_caption and len(caption) > TG_CAPTION_MAX: await send_text(bot, chat_id, caption)