main
 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3import re
 4from typing import Any
 5
 6from glom import glom
 7from loguru import logger
 8from pyrogram.enums import ParseMode
 9from pyrogram.errors import MediaCaptionTooLong, MessageTooLong
10from pyrogram.types import LinkPreviewOptions, Message
11
12
13def has_markdown_img(text: str) -> bool:
14    """Check if the text contains markdown img format.
15
16    ![alt](https://example.png)
17    """
18    pattern = r"!\[.*?\]\(.*?\)"
19    return bool(re.search(pattern, text))
20
21
22async def add_summary_url(url: str, message: Message) -> Message:
23    """Add telegraph url to caption.
24
25    First, we try to prepend the url to {time}  # 🕒2026-05-26 22:40:57
26    If failed, we try to add the url to {time}
27    If failed, we reply the url to the message.
28    """
29
30    def gen_captions() -> tuple[str, str]:
31        html = glom(message, "content.html", default="")
32        lines = html.split("\n")
33        time = ""
34        day = ""
35        for i, line in enumerate(lines):
36            if matched := re.match(r"^🕒(\d{4}-\d{2}-\d{2}) \d{2}:\d{2}:\d{2}", line):
37                lines[i] = f'<a href="{url}"><b>🤖AI导读</b></a> ' + line
38                time = matched.group(0)
39                day = matched.group(1)
40                break
41        prepend = "\n".join(lines)
42        added = html.replace(time, f'<a href="{url}"><b>🤖AI导读</b></a> 🕒{day}') if day else html
43        return prepend, added
44
45    prepend, added = gen_captions()
46    logger.trace(f"Add summary url {url} to {message.link}")
47    try:
48        message = await message.edit_caption(prepend, parse_mode=ParseMode.HTML)
49    except (MediaCaptionTooLong, MessageTooLong):
50        logger.warning("Caption is too long, use added caption")
51        message = await message.edit_caption(added, parse_mode=ParseMode.HTML)
52    except Exception as e:
53        logger.warning(f"Failed to add summary url {url} to caption: {e}")
54        link_preview = LinkPreviewOptions(is_disabled=False, show_above_text=True, url=url)
55        await message.reply_text(f'<a href="{url}"><b>🤖AI导读</b></a>', quote=True, parse_mode=ParseMode.HTML, link_preview_options=link_preview)
56    return message
57
58
59def trim(obj: Any) -> Any:
60    if isinstance(obj, dict):
61        return {k: trim(v) for k, v in obj.items() if v not in ["", None, {}]}
62    if isinstance(obj, list):
63        return [trim(item) for item in obj if item not in ["", None, {}]]
64    return obj