Система переработана для учёта длительной работы без прерывани

This commit is contained in:
2025-08-08 10:34:26 +07:00
parent bea6859b15
commit 11fd0bf28d

View File

@@ -277,64 +277,81 @@ class MainBot(AnyBots):
def __init__(self, DataBase, stop_event, task_start = True): def __init__(self, DataBase, stop_event, task_start = True):
super().__init__(DataBase) super().__init__(DataBase)
self.stop_event = stop_event self.stop_event = stop_event
self.ready_once = asyncio.Event()
self.task_start = task_start self.task_start = task_start
async def on_ready(self): async def on_ready(self):
await super().on_ready() await super().on_ready()
if self.task_start: if not self.ready_once.is_set():
self.CheckDataBases.cancel() self.loops = [self.CheckDataBases, self.MakeBackups, self.SendingDeferredMessages, self.watchdog]
self.MakeBackups.cancel()
self.SendingDeferredMessages.cancel() if self.task_start:
for loop in self.loops:
loop.start()
self.MakeBackups.start() else:
self.CheckDataBases.start() pass
self.SendingDeferredMessages.start()
else: self.ready_once.set()
self.SendingDeferredMessages.start()
async def BotOff(self): async def BotOff(self):
if self.task_start: if self.task_start and self.ready_once.is_set():
self.CheckDataBases.cancel() for loop in self.loops:
self.MakeBackups.cancel() loop.cancel()
self.SendingDeferredMessages.cancel()
self.stop_event.set() self.stop_event.set()
async def on_disconnect(self): # async def on_disconnect(self):
if self.stop_event.is_set(): # if self.stop_event.is_set():
pass # pass
else: # else:
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: Соединение с дискордом разорвано") # print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: Соединение с дискордом разорвано")
await self.BotOff() # await self.BotOff()
@staticmethod
def catch_exceptions(func):
import functools, traceback
@functools.wraps(func)
async def wrapper(*args, **kwargs):
try:
return await func(*args, **kwargs)
except Exception:
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: [ERROR] {func.__name__}:\n{traceback.format_exc()}")
return wrapper
@tasks.loop(seconds=30)
@catch_exceptions.__func__
async def watchdog(self):
for loop in self.loops:
if loop.__name__ == self.watchdog.__name__:
continue
if not loop.is_running():
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: Обнаружено падение {loop.__name__}, перезапуск цикла...")
loop.cancel()
@tasks.loop(seconds=60) @tasks.loop(seconds=60)
@catch_exceptions.__func__
async def SendingDeferredMessages(self): async def SendingDeferredMessages(self):
try: async with self.DataBaseManager.session() as session:
async with self.DataBaseManager.session() as session: async with session.begin():
async with session.begin(): stmt = self.DataBaseManager.select(self.DataBaseManager.model_classes['scheduled_messages']).where(
stmt = self.DataBaseManager.select(self.DataBaseManager.model_classes['scheduled_messages']).where( self.DataBaseManager.model_classes['scheduled_messages'].timestamp - datetime.datetime.now().timestamp() <= 0
self.DataBaseManager.model_classes['scheduled_messages'].timestamp - datetime.datetime.now().timestamp() <= 0 ).with_for_update()
).with_for_update() messages = (await session.execute(stmt)).scalars().all()
messages = (await session.execute(stmt)).scalars().all()
for message in messages: for message in messages:
webhook = await self.fetch_webhook(message.webhook_id) webhook = await self.fetch_webhook(message.webhook_id)
await webhook.send(**(await message.parse_message(self))) await webhook.send(**(await message.parse_message(self)))
await session.delete(message) await session.delete(message)
except Exception as error:
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: err SendingDeferredMessages: {error}")
@tasks.loop(seconds=60)
async def CheckDataBases(self):
try:
await self.CheckDataBasesRun()
except Exception as error:
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: err CheckDataBasesRun: {error}")
@tasks.loop(seconds=3600) @tasks.loop(seconds=3600)
@catch_exceptions.__func__
async def MakeBackups(self): async def MakeBackups(self):
backup_file = await self.DataBaseManager.pg_dump() backup_file = await self.DataBaseManager.pg_dump()
@@ -342,7 +359,9 @@ class MainBot(AnyBots):
backups_channel = await krekchat.fetch_channel(self.databases_backups_channel_id) backups_channel = await krekchat.fetch_channel(self.databases_backups_channel_id)
await backups_channel.send(content=f"Бэкап бд за {datetime.datetime.now()}:", file=disnake.File(backup_file)) await backups_channel.send(content=f"Бэкап бд за {datetime.datetime.now()}:", file=disnake.File(backup_file))
async def CheckDataBasesRun(self): @tasks.loop(seconds=60)
@catch_exceptions.__func__
async def CheckDataBases(self):
self.krekchat = await self.fetch_guild(self.krekchat.id) self.krekchat = await self.fetch_guild(self.krekchat.id)
members = [i async for i in self.krekchat.fetch_members(limit=None)] members = [i async for i in self.krekchat.fetch_members(limit=None)]
textmute = {'mute': [], 'unmute': list(filter(lambda m: self.text_mute in m.roles, members))} textmute = {'mute': [], 'unmute': list(filter(lambda m: self.text_mute in m.roles, members))}
@@ -524,9 +543,13 @@ class MainBot(AnyBots):
await session.execute(stmt) await session.execute(stmt)
#/преды #/преды
async def on_button_click(self, inter):
if not inter.response.is_done():
await inter.response.send_message(embed=self.ErrEmbed(description=f'Ответ не был отправлен, возможно, кнопка перестала действовать'), ephemeral=True)
async def on_message(self, msg): async def on_message(self, msg):
if msg.author.bot or not self.task_start: if msg.author.bot or not self.task_start or not self.ready_once.is_set():
return 0 return 0
if msg.author.id == 479210801891115009 and msg.content == "botsoff": if msg.author.id == 479210801891115009 and msg.content == "botsoff":
@@ -567,7 +590,7 @@ class MainBot(AnyBots):
if link_in_wl is None: if link_in_wl is None:
await log.send(f"{msg.author.mention}({msg.author.id}) отправил в чат {msg.channel.mention} сомнительную ссылку, которой нет в вайлисте:```{msg.content}```") await log.send(f"{msg.author.mention}({msg.author.id}) отправил в чат {msg.channel.mention} сомнительную ссылку, которой нет в вайлисте:```{msg.content}```")
mess = await msg.reply(embed=self.ErrEmbed(description=f'Этой ссылки нет в белом списке, но заявка на добавление уже отправлена. Если это срочно, свяжитесь с разработчиком или модераторами.', colour=0xff9900)) mess = await msg.reply(embed=self.ErrEmbed(description=f'Этой ссылки нет в белом списке, но заявка на добавление уже отправлена. Если это срочно, свяжитесь с разработчиком или модераторами.'))
await msg.delete() await msg.delete()
await asyncio.sleep(20) await asyncio.sleep(20)
await mess.delete() await mess.delete()