From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on gnuweeb.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NO_DNS_FOR_FROM,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.6 Received: from localhost.localdomain (unknown [101.128.125.94]) by gnuweeb.org (Postfix) with ESMTPSA id 2A91E80605; Thu, 21 Jul 2022 23:30:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1658446222; bh=eRpPC0F3H/51fAyFHLsfeFN+MnUsQSHiL4lpWc9qU8M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P+8l7DHAUYAS7Iac78Gvb9A5toTUyaSgbC0+mctNMyt0rDbDA9jpgtvqspwY3ntFS AgeDjmuPiTYz1JLDcT/b12CffLw6IvBSe9J2seGKo0ujtSdDmHnbQBihh1+Tq1jqFj fu+pgXKIum03LdpnQZrgWK6qbB6U8gInU0heHZwN/igYTcuW7NGmt4EY2NAjT2y4zo TPR0zEOMI7AuTcEyNPqmY+nzk8g2YrQ12jHYuLrzYggWXYt+myPzn3YiBJ30AiWq5K y5lJn7XyuTSdc8gb93SjvCzfxiqofVdsCeB7nXRAFhWnbisYKy16eFgsy0tcyAGLVl jmPd1bhuc/CHg== From: Muhammad Rizki To: Ammar Faizi Cc: Muhammad Rizki , GNU/Weeb Mailing List Subject: [PATCH v3 13/17] daemon: Add @handle_flood decorator and remove some functions Date: Fri, 22 Jul 2022 06:29:34 +0700 Message-Id: <20220721232938.503-14-kiizuha@gnuweeb.org> X-Mailer: git-send-email 2.34.1.windows.1 In-Reply-To: <20220721232938.503-1-kiizuha@gnuweeb.org> References: <20220721232938.503-1-kiizuha@gnuweeb.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: From: Muhammad Rizki I decided to create @handle_flood decorator to make it easier to handle the Telegram floodwait. Remove __send_text_msg() and replace the call of the __send_text_msg() with send_text_email() in packages/client.py and it have handle_flood decorator support. Signed-off-by: Muhammad Rizki --- daemon/packages/client.py | 3 +++ daemon/packages/decorator.py | 38 +++++++++++++++++++++++++++++ daemon/scraper/bot.py | 47 ++++++------------------------------ 3 files changed, 49 insertions(+), 39 deletions(-) create mode 100644 daemon/packages/decorator.py diff --git a/daemon/packages/client.py b/daemon/packages/client.py index f73b913..45acac3 100644 --- a/daemon/packages/client.py +++ b/daemon/packages/client.py @@ -7,6 +7,7 @@ from pyrogram import Client from pyrogram.enums import ParseMode from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton from typing import Union, BinaryIO +from .decorator import handle_flood class DaemonClient(Client): @@ -16,6 +17,7 @@ class DaemonClient(Client): api_hash, **kwargs) + @handle_flood async def send_text_email( self, chat_id: Union[int, str], @@ -39,6 +41,7 @@ class DaemonClient(Client): ) + @handle_flood async def send_patch_email( self, chat_id: Union[int, str], diff --git a/daemon/packages/decorator.py b/daemon/packages/decorator.py new file mode 100644 index 0000000..7d7dc39 --- /dev/null +++ b/daemon/packages/decorator.py @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2022 Muhammad Rizki +# + +from pyrogram.errors.exceptions.flood_420 import FloodWait +from typing import Any, Callable +from functools import wraps +import re +import asyncio + +__all__ = ["handle_flood"] + + +def handle_flood(func: Callable[[Any], Any]) -> Callable[[Any], Any]: + @wraps(func) + async def callback(*args: Any) -> Any: + while True: + try: + return await func(*args) + except FloodWait as e: + # + # Aiee... we hit our limit. + # Let's slow down a bit. + # + _flood_exceptions(e) + print("[__handle_telegram_floodwait]: Woken up from flood wait...") + return callback + + +async def _flood_exceptions(e): + x = re.search(r"A wait of (\d+) seconds is required", str(e)) + if not x: + raise e + + n = int(x.group(1)) + print(f"[____handle_telegram_floodwait]: Sleeping for {n} seconds due to Telegram limit") + await asyncio.sleep(n) diff --git a/daemon/scraper/bot.py b/daemon/scraper/bot.py index 1abfa98..38c6e94 100644 --- a/daemon/scraper/bot.py +++ b/daemon/scraper/bot.py @@ -37,7 +37,7 @@ class Bot(): def __init__(self, client: DaemonClient, sched: AsyncIOScheduler, - scraper: Scraper, mutexes: BotMutexes, conn): + scraper: Scraper, mutexes: BotMutexes, conn): self.client = client self.sched = sched self.scraper = scraper @@ -88,7 +88,7 @@ class Bot(): for tg_chat_id in self.TG_CHAT_IDS: async with self.mutexes.send_to_tg: should_wait = await self.__send_to_tg(url, mail, - tg_chat_id) + tg_chat_id) if should_wait: await asyncio.sleep(1) @@ -105,7 +105,7 @@ class Bot(): return False email_id = self.__need_to_send_to_telegram(email_msg_id, - tg_chat_id) + tg_chat_id) if not email_id: # # Email has already been sent to Telegram. @@ -122,8 +122,9 @@ class Bot(): reply_to, text, url) else: text = "#ml\n" + text - m = await self.__send_text_msg(tg_chat_id, text, - reply_to, url) + m = await self.client.send_text_email( + tg_chat_id, text,reply_to, url + ) self.db.insert_telegram(email_id, m.chat.id, m.id) for d, f in files: @@ -161,40 +162,8 @@ class Bot(): print("[__send_patch_msg]") tmp, doc, caption, url = utils.prepare_send_patch(mail, text, url) - ret = await self.__handle_telegram_floodwait( - self.client.send_patch_email, - *[tg_chat_id, doc, caption, reply_to, url] + ret = await self.client.send_patch_email( + tg_chat_id, doc, caption, reply_to, url ) utils.clean_up_after_send_patch(tmp) return ret - - - async def __send_text_msg(self, *args): - return await self.__handle_telegram_floodwait( - self.client.send_text_email, - *args - ) - - - async def __handle_telegram_floodwait(self, callback, *args): - while True: - try: - return await callback(*args) - except pyrogram.errors.exceptions.flood_420.FloodWait as e: - # - # Aiee... we hit our limit. - # Let's slow down a bit. - # - await self.____handle_telegram_floodwait(e) - print("[__handle_telegram_floodwait]: Woken up from flood wait...") - - - async def ____handle_telegram_floodwait(self, e): - x = str(e) - x = re.search(r"A wait of (\d+) seconds is required", x) - if not x: - raise e - - n = int(x.group(1)) - print(f"[____handle_telegram_floodwait]: Sleeping for {n} seconds due to Telegram limit") - await asyncio.sleep(n) -- Muhammad Rizki