1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-10-16 05:37:27 +00:00
greed/duckbot.py
oleg20111511 55e14b10d5
Code refactor (#178)
Co-authored-by: Stefano Pigozzi <me@steffo.eu>
2022-05-20 02:55:12 +02:00

126 lines
5.1 KiB
Python

import logging
import sys, time
import traceback
import telegram.error
import nuconfig
log = logging.getLogger(__name__)
def factory(cfg: nuconfig.NuConfig):
"""Construct a DuckBot type based on the passed config."""
def catch_telegram_errors(func):
"""Decorator, can be applied to any function to retry in case of Telegram errors."""
def result_func(*args, **kwargs):
while True:
try:
return func(*args, **kwargs)
# Bot was blocked by the user
except telegram.error.Unauthorized:
log.debug(f"Unauthorized to call {func.__name__}(), skipping.")
return None
# Telegram API didn't answer in time
except telegram.error.TimedOut:
log.warning(f"Timed out while calling {func.__name__}(),"
f" retrying in {cfg['Telegram']['timed_out_pause']} secs...")
time.sleep(cfg["Telegram"]["timed_out_pause"])
continue
# Telegram is not reachable
except telegram.error.NetworkError as error:
log.error(f"Network error while calling {func.__name__}(),"
f" retrying in {cfg['Telegram']['error_pause']} secs...\n"
f"Full error: {error.message}")
time.sleep(cfg["Telegram"]["error_pause"])
continue
# Unknown error
except telegram.error.TelegramError as error:
if error.message.lower() in ["bad gateway", "invalid server response"]:
log.warning(f"Bad Gateway while calling {func.__name__}(),"
f" retrying in {cfg['Telegram']['error_pause']} secs...")
time.sleep(cfg["Telegram"]["error_pause"])
continue
elif error.message.lower() == "timed out":
log.warning(f"Timed out while calling {func.__name__}(),"
f" retrying in {cfg['Telegram']['timed_out_pause']} secs...")
time.sleep(cfg["Telegram"]["timed_out_pause"])
continue
else:
log.error(f"Telegram error while calling {func.__name__}(),"
f" retrying in {cfg['Telegram']['error_pause']} secs...\n"
f"Full error: {error.message}")
traceback.print_exception(*sys.exc_info())
time.sleep(cfg["Telegram"]["error_pause"])
continue
return result_func
class DuckBot:
def __init__(self, *args, **kwargs):
self.bot = telegram.Bot(token=cfg["Telegram"]["token"], *args, **kwargs)
@catch_telegram_errors
def send_message(self, *args, **kwargs):
# All messages are sent in HTML parse mode
return self.bot.send_message(parse_mode="HTML", *args, **kwargs)
@catch_telegram_errors
def send_photo(self, *args, **kwargs):
return self.bot.send_photo(parse_mode="HTML", *args, **kwargs)
@catch_telegram_errors
def edit_message_text(self, *args, **kwargs):
# All messages are sent in HTML parse mode
return self.bot.edit_message_text(parse_mode="HTML", *args, **kwargs)
@catch_telegram_errors
def edit_message_caption(self, *args, **kwargs):
# All messages are sent in HTML parse mode
return self.bot.edit_message_caption(parse_mode="HTML", *args, **kwargs)
@catch_telegram_errors
def edit_message_reply_markup(self, *args, **kwargs):
return self.bot.edit_message_reply_markup(*args, **kwargs)
@catch_telegram_errors
def get_updates(self, *args, **kwargs):
return self.bot.get_updates(*args, **kwargs)
@catch_telegram_errors
def get_me(self, *args, **kwargs):
return self.bot.get_me(*args, **kwargs)
@catch_telegram_errors
def answer_callback_query(self, *args, **kwargs):
return self.bot.answer_callback_query(*args, **kwargs)
@catch_telegram_errors
def answer_pre_checkout_query(self, *args, **kwargs):
return self.bot.answer_pre_checkout_query(*args, **kwargs)
@catch_telegram_errors
def send_invoice(self, *args, **kwargs):
return self.bot.send_invoice(*args, **kwargs)
@catch_telegram_errors
def get_file(self, *args, **kwargs):
return self.bot.get_file(*args, **kwargs)
@catch_telegram_errors
def send_chat_action(self, *args, **kwargs):
return self.bot.send_chat_action(*args, **kwargs)
@catch_telegram_errors
def delete_message(self, *args, **kwargs):
return self.bot.delete_message(*args, **kwargs)
@catch_telegram_errors
def send_document(self, *args, **kwargs):
return self.bot.send_document(*args, **kwargs)
# More methods can be added here
return DuckBot