main
 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4import asyncio
 5from pathlib import Path
 6
 7from loguru import logger
 8from pyrogram.errors import FloodWait, MessageNotModified
 9from pyrogram.types import Message
10
11from config import TEXT_LENGTH, cache
12from messages.utils import delete_message, smart_split
13
14
15async def modify_progress(
16    message: Message | None = None,
17    text: str = "",
18    *,
19    detail_progress: bool = False,
20    del_status: bool = False,
21    ttl: float = 3,
22    del_delay: float = 0,
23    force_update: bool = False,
24    **kwargs,
25):
26    """Modify the progress message.
27
28    Telegram rate limit:
29        - 1 message per second for a single chat
30        - 20 messages per minute for a single group
31        - 30 messages per second for multiple chats
32
33    Args:
34        message (Message): The progress message object.
35        text (str): The new text to update.
36        detail_progress(bool): Whether to show the detail progress.
37        del_status (bool): Whether the progress is done.
38        ttl (float): Time to live for the cache.
39        del_delay (float): Delay seconds to delete the message.
40        force_update (bool): Force update the message.
41    """
42    if message is None:
43        message = kwargs.get("progress")
44    if not isinstance(message, Message):
45        return
46    if del_status:
47        logger.info("Deleting progress message")
48        await asyncio.sleep(del_delay)
49        await delete_message(message)
50        return
51    try:
52        if not text:
53            return
54        text = str(text)
55        if text == message.text:
56            return
57        if cache.get("modify_progress"):  # DO NOT update too frequently
58            detail_progress = False
59        if force_update:
60            detail_progress = True
61        if not detail_progress:
62            return
63        if len(text) > TEXT_LENGTH:
64            text = text[: 10 * TEXT_LENGTH]  # trim the very long texts
65            text = (await smart_split(text))[0]
66        logger.trace(f"Progress: {text!r}")
67        await message.edit_text(text)
68        cache.set("modify_progress", "1", ttl=ttl)
69    except FloodWait as e:
70        logger.warning(e)
71        await asyncio.sleep(e.value)  # type: ignore
72    except MessageNotModified:
73        pass
74    except Exception as e:
75        logger.warning(f"modify_progress: {e}")
76
77
78async def telegram_uploading(current: int, total: int, *args):
79    """Show video uploading progress."""
80    msg = f"上传中: {current / 1024 / 1024:.1f} / {total / 1024 / 1024:.1f} MB ({current / total:.2%})"
81    if len(args) != 3:
82        return
83    message = args[0]
84    path = args[1]
85    detail_progress = args[2]
86    if not Path(path).is_file():
87        logger.error(f"File not found: {path}")
88        return
89    ext = Path(path).suffix.lstrip(".")
90    msg = f"{ext.upper()} {msg}\n💾{Path(path).name}"
91    await modify_progress(message=message, text=msg, detail_progress=detail_progress)