added RAG, Multiuser, TG bot
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user