From fde4b9e721eeb4eb380550452bb0a6a8c4413411 Mon Sep 17 00:00:00 2001 From: HypoxiE Date: Wed, 20 Aug 2025 23:20:27 +0700 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B2=D0=B5=D1=80=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B3=D0=BE=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BA=20=D0=BC=D0=B8=D0=B3=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20?= =?UTF-8?q?=D0=B2=20docker=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD?= =?UTF-8?q?=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 59 ++++++++++++++++ .gitignore | 2 +- Dockerfile | 8 +++ docker-compose.yml | 16 +++++ src/CoreFun.py | 64 +++++++++++------- src/data/service_information/animals.xlsx | Bin 0 -> 30957 bytes .../rebalance_animals.xlsx | Bin 0 -> 10491 bytes src/database/settings/db_settings.py | 12 ++-- src/libs/tokens_formatter.py | 14 ++++ src/test.py | 6 +- 10 files changed, 147 insertions(+), 34 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 src/data/service_information/animals.xlsx create mode 100644 src/data/service_information/rebalance_animals.xlsx create mode 100644 src/libs/tokens_formatter.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1935f14 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,59 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +pythonenv/ + +# Package files +*.egg +*.egg-info/ +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg +lib/ +lib64/ +pip-log.txt +pip-delete-this-directory.txt + +# Logs and databases +*.log +*.sqlite3 +*.db + +# Environment variables +.env +.env.local +.env.production + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Docker +Dockerfile +.dockerignore + +# Temp files +tmp/ +temp/ + +backups/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7e0d3bc..53b7f5d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,5 @@ __pycache__/ .env .secrets -src/data/secrets/ +secrets/ src/backups/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b758cd7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3 + +WORKDIR /usr/src/economy-bot +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . +CMD [ "python", "src/CoreFun.py" ] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7aefa39 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.8' + +services: + economy-discord-bot: + build: . + image: discord-economy-bot + container_name: discord-economy-bot + restart: always + networks: + - postgres-network + env_file: + - .env + +networks: + postgres-network: + external: true diff --git a/src/CoreFun.py b/src/CoreFun.py index 391d70d..934e395 100644 --- a/src/CoreFun.py +++ b/src/CoreFun.py @@ -18,7 +18,7 @@ import re from constants.rimagochi_constants import * from constants.global_constants import * -from data.secrets.TOKENS import TOKENS +from libs.tokens_formatter import TOKENS from database.db_classes import all_data as DataBaseClasses from managers.DataBaseManager import DatabaseManager from database.settings import config @@ -304,7 +304,7 @@ class AnyBots(commands.Bot): matches = re.findall(pattern, time_str) for value, _, unit in matches: - time_units[unit] += float(value) + time_units[unit] += value return FormatedTime(time_units) @@ -358,7 +358,7 @@ class AdminBot(AnyBots): self.task_start = task_start self.stop_event = stop_event - async def on_ready(self): + async def on_ready(self, inherited = True): await super().on_ready(inherited = True) if self.task_start: @@ -391,7 +391,7 @@ class AdminBot(AnyBots): async def check_bt_channel(self): async def moder_dataparser(data: dict): if not 'type' in data.keys(): - raise json.JSONDecodeError() + raise json.JSONDecodeError("Некорректный JSON", '{"type":value}', 0) async with self.DataBaseManager.session() as session: async with session.begin(): async with self.DataBaseManager.models['users'] as users_model: @@ -444,6 +444,8 @@ class AdminBot(AnyBots): while True: stopflag = False + if not isinstance(bt_channel, disnake.TextChannel): + raise ValueError("В bt_channel как-то оказалось не disnake.TextChannel") batch = await bt_channel.history(limit=10, before=last_msg).flatten() for message in batch: msg_stopflag = False @@ -452,15 +454,15 @@ class AdminBot(AnyBots): msg_stopflag = True break else: + data = json.loads(message.content) try: - data = json.loads(message.content) result = 0 if not 'sender' in data: - raise json.JSONDecodeError() + raise json.JSONDecodeError("Некорректный JSON", '{"sender":value}', 0) if data['sender'] == "ModBot": result = await moder_dataparser(data) if result: - raise json.JSONDecodeError() + raise json.JSONDecodeError("Некорерктный JSON", '', 0) await message.add_reaction("✅") except json.JSONDecodeError as e: await message.add_reaction("❎") @@ -478,18 +480,18 @@ class AdminBot(AnyBots): add_crumbs = (incoming_crumbs * modifier) if incoming_crumbs * modifier >= 0 else 0 return add_crumbs - async def on_message(self, msg): - if msg.author.id == 479210801891115009 and msg.content == "botsoff": - await msg.reply(embed=disnake.Embed(description=f'Бот отключён', colour=0xff9900)) + async def on_message(self, message): + if message.author.id == 479210801891115009 and message.content == "botsoff": + await message.reply(embed=disnake.Embed(description=f'Бот отключён', colour=0xff9900)) await self.BotOff() - if msg.guild is None: + if message.guild is None: return - if msg.channel.id == self.bots_talk_protocol_channel_id: + if message.channel.id == self.bots_talk_protocol_channel_id: await self.check_bt_channel() - if msg.author.bot: + if message.author.bot: return crumb_per_word = 1 / 2 - text = msg.content + text = message.content while " " in text: text = text.replace(" ", " ") add_crumbs = len(text.split(" ")) * crumb_per_word @@ -497,35 +499,38 @@ class AdminBot(AnyBots): async with self.DataBaseManager.session() as session: async with session.begin(): async with self.DataBaseManager.models['users'] as users_model: - stmt = self.DataBaseManager.select(users_model).where(users_model.id == msg.author.id) + stmt = self.DataBaseManager.select(users_model).where(users_model.id == message.author.id) user = (await session.execute(stmt)).scalars().first() if user is None: - user = users_model(id = msg.author.id, period_messages = 1, summary_messages = 1, crumbs = (await self.give_crumbs_counter(incoming_crumbs = add_crumbs, sponsor_roles = self.sponsors, member = msg.author))) + user = users_model(id = message.author.id, period_messages = 1, summary_messages = 1, crumbs = (await self.give_crumbs_counter(incoming_crumbs = add_crumbs, sponsor_roles = self.sponsors, member = message.author))) session.add(user) period_messages, period_voice_activity = 1, 0 else: - stmt = self.DataBaseManager.update(users_model).where(users_model.id == msg.author.id).values( + stmt = self.DataBaseManager.update(users_model).where(users_model.id == message.author.id).values( period_messages = users_model.period_messages + 1, summary_messages = users_model.summary_messages + 1, - crumbs = users_model.crumbs + (await self.give_crumbs_counter(incoming_crumbs = add_crumbs, sponsor_roles = self.sponsors, member = msg.author, carma = user.carma)) + crumbs = users_model.crumbs + (await self.give_crumbs_counter(incoming_crumbs = add_crumbs, sponsor_roles = self.sponsors, member = message.author, carma = user.carma)) ) await session.execute(stmt) period_messages, period_voice_activity = user.period_messages + 1, user.period_voice_activity - await self.LevelRolesGiver(msg.author, self.CalculateLevel(period_messages, period_voice_activity)) + await self.LevelRolesGiver(message.author, self.CalculateLevel(period_messages, period_voice_activity)) + _url_cache = {} @tasks.loop(seconds=3600) async def UpdatingTournamentData(self): krekchat = await self.fetch_guild(self.krekchat.id) tournament_channel = await krekchat.fetch_channel(1396785366882582538) + if not isinstance(tournament_channel, disnake.TextChannel): + raise webhooks = await tournament_channel.webhooks() webhook = webhooks[0] if not hasattr(self, 'tournament_table_client'): SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"] - creds = Credentials.from_service_account_file("src/data/secrets/krekbottable-9a40985c56e2.json", scopes=SCOPES) + creds = Credentials.from_service_account_file("secrets/krekbottable-9a40985c56e2.json", scopes=SCOPES) self.tournament_table_client = gspread.authorize(creds) async def shorten_url_tinyurl(url: str) -> str: @@ -570,7 +575,7 @@ class AdminBot(AnyBots): def __ge__(self, other): return (self.points, self.cost) >= (other.points, other.cost) - async def to_str(self, num: int = None): + async def to_str(self, num: int | None = None): try: member = await krekchat.fetch_member(int(row.discord_id)) except: @@ -580,6 +585,7 @@ class AdminBot(AnyBots): result = f"**{num}) " else: result = f"**-" + num = -2 result += f"[{self.nick}](" result += f"https://docs.google.com/spreadsheets/d/1QkaNYezumeb-QJHSZ3x1vIi5ktf0ooDklYkrP6xSMZc/edit?gid=0&range=A{num+2}" @@ -658,7 +664,7 @@ class AdminBot(AnyBots): embed = disnake.Embed(description = "**Эта таблица обновляется каждый час и может содержать только топ-20 участников.\n\nБолее детальную и актуальную информацию можете найти в [оригинальной таблице](https://docs.google.com/spreadsheets/d/1QkaNYezumeb-QJHSZ3x1vIi5ktf0ooDklYkrP6xSMZc/edit?usp=sharing).**", colour=color) embeds.append(embed) - await webhook.edit_message(1400936701131624549, content = "", embeds = embeds) + await webhook.edit_message(1405594708016889909, content = "", embeds = embeds) @tasks.loop(seconds=60) async def VoiceXpAdder(self): @@ -666,9 +672,12 @@ class AdminBot(AnyBots): channels = await self.krekchat.fetch_channels() async with self.DataBaseManager.session() as session: for channel in channels: + + channel = self.get_channel(channel.id) + if (not isinstance(channel, disnake.VoiceChannel)) or channel.id == 1250314784914669598: continue - channel = self.get_channel(channel.id) + for member in channel.members: if member.bot: continue @@ -737,6 +746,9 @@ class AdminBot(AnyBots): backup_file = await self.DataBaseManager.pg_dump() krekchat = await self.fetch_guild(self.krekchat.id) backups_channel = await krekchat.fetch_channel(self.databases_backups_channel_id) + if not isinstance(backups_channel, disnake.TextChannel): + raise ValueError("backups_channel is not disnake.TextChannel") + if "Backup failed" in backup_file: await backups_channel.send(content=backup_file) else: @@ -816,13 +828,15 @@ async def main(): except Exception as e: print(f"Произошла критическая ошибка: {e}") finally: - await admin_bot.BotOff() + if admin_bot is not None: + await admin_bot.BotOff() for bot in all_bots: if not bot.is_closed(): await bot.close() - await DataBase.close() + if DataBase is not None: + await DataBase.close() current_task = asyncio.current_task() pending = [t for t in asyncio.all_tasks() if t is not current_task and not t.done()] diff --git a/src/data/service_information/animals.xlsx b/src/data/service_information/animals.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e53d9b4950dddd43fb489f4598af289eaa36df01 GIT binary patch literal 30957 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 literal 0 HcmV?d00001 diff --git a/src/data/service_information/rebalance_animals.xlsx b/src/data/service_information/rebalance_animals.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e3aa04505eb5aab9d2f443f820f066d4ac1dabeb GIT binary patch literal 10491 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