Skip to content

Commit 5c80d6b

Browse files
committed
Organize code.
1 parent ada7ebc commit 5c80d6b

File tree

8 files changed

+260
-300
lines changed

8 files changed

+260
-300
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ This project is licensed under the GNU General Public License v3.
1010

1111
# TODO:
1212
- [ ] Make better README
13-
- [x] Make code readable
14-
- [ ] Use DB instead of json
13+
- [x] Make code readable

example_config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Example configuration file for CommitBot"""
2+
13
TOKEN = ""
24
PREFIX = ""
35
VERSION = ""

main.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
# This project is licensed under GPL-v3.
1+
"""This project is licensed under GPL-v3."""
22

3-
import disnake
43
import json
54
import os
65
import asyncio
76
import time
87

8+
import disnake
9+
910
from disnake.ext import commands
1011

1112
import config as cfg
@@ -16,20 +17,33 @@
1617

1718
start_time = time.time()
1819

20+
def bot_embed(inter):
21+
"""Create a standard reponse embed"""
22+
err_embed = disnake.Embed(title="Ошибка", color=disnake.Color.red())
23+
user_avatar = (
24+
inter.author.display_avatar.url
25+
if inter.author.display_avatar
26+
else client.user.display_avatar.url
27+
)
28+
err_embed.set_footer(text=f"{inter.author.name}", icon_url=user_avatar)
29+
1930

2031
def load_data():
32+
"""Load data from the JSON file"""
2133
if not os.path.exists(DATA_FILE):
2234
return {}
2335
with open(DATA_FILE, "r", encoding="utf-8") as f:
2436
return json.load(f)
2537

2638

2739
def save_data(data):
40+
"""Save data to the JSON file"""
2841
with open(DATA_FILE, "w", encoding="utf-8") as f:
2942
json.dump(data, f, indent=4)
3043

3144

3245
def ensure_defaults():
46+
"""Ensure that all guilds have the default data structure"""
3347
data = load_data()
3448
updated = False
3549
for guild in client.guilds:
@@ -38,7 +52,10 @@ def ensure_defaults():
3852
data[sid] = {
3953
"forumchannels": [],
4054
"closeAfter": 1,
41-
"welcomeMessage": "Hello! {thread_author}, welcome to your thread {thread_id} - {thread_name}",
55+
"welcomeMessage": (
56+
"Hello! {thread_author}, welcome to your thread "
57+
"{thread_id} - {thread_name}"
58+
),
4259
"delete_closed": True,
4360
"welcome_enabled": True,
4461
}
@@ -63,6 +80,7 @@ def ensure_defaults():
6380

6481

6582
async def send_close_embed(thread, closer, closer_type="автоматически"):
83+
"""Send an embed when a thread is closed"""
6684
data = load_data()
6785
sid = str(thread.guild.id)
6886
auto_delete = data.get(sid, {}).get("delete_closed", True)
@@ -99,6 +117,7 @@ async def send_close_embed(thread, closer, closer_type="автоматическ
99117

100118

101119
async def check_inactivity_thread(thread_id: int):
120+
"""Check if a thread is inactive and close it if necessary"""
102121
await asyncio.sleep(5)
103122

104123
while True:
@@ -135,7 +154,7 @@ async def check_inactivity_thread(thread_id: int):
135154
try:
136155
await t.edit(locked=True, archived=True)
137156
await send_close_embed(t, client.user, "автоматически")
138-
except Exception:
157+
except (disnake.Forbidden, disnake.HTTPException, disnake.NotFound):
139158
pass
140159
del data[sid]["threads"][str(thread_id)]
141160
save_data(data)
@@ -149,15 +168,16 @@ async def check_inactivity_thread(thread_id: int):
149168
client.check_inactivity_thread = check_inactivity_thread
150169
client.send_close_embed = send_close_embed
151170
client.start_time = start_time
171+
client.bot_embed = bot_embed
152172

153173
# Load cogs
154174
for filename in os.listdir("./modules"):
155175
if filename.endswith(".py"):
156-
cog_name = f"modules.{filename[:-3]}"
176+
COG_NAME = f"modules.{filename[:-3]}"
157177
try:
158-
client.load_extension(cog_name)
178+
client.load_extension(COG_NAME)
159179
print(f"Debug: Ког {filename} загружен")
160-
except Exception as e:
180+
except (disnake.ext.commands.errors.ExtensionError, ImportError) as e:
161181
print(f"ERR: Ког {filename} не удалось загрузить: {e}")
162182

163183
client.run(cfg.TOKEN)

modules/errors.py

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,67 @@
1-
# GPL-v3
1+
"""GPL-3.0 License"""
2+
3+
import uuid
4+
import traceback
5+
import datetime
6+
import os
27

38
import disnake
4-
import uuid, traceback, datetime, os
59

610
from disnake.ext import commands
711

812

913
class NotOwner(commands.CheckFailure):
10-
pass
14+
"""Exception raised when a user is not the bot owner."""
15+
def __init__(self, message: str = "You are not the bot owner."):
16+
super().__init__(message)
1117

1218

1319
class ErrorsModule(commands.Cog):
20+
"""Cog for handling errors in commands and interactions."""
1421
def __init__(self, bot):
1522
self.bot = bot
1623

1724
### Triggers when an error occurs in a command ###
1825

1926
@commands.Cog.listener()
20-
async def on_command_error(self, ctx: commands.Context, error: Exception):
21-
errEmbed = disnake.Embed(title="Ошибка", color=disnake.Color.red())
22-
user_avatar = (
23-
ctx.author.display_avatar.url
24-
if ctx.author.display_avatar
25-
else self.bot.user.display_avatar.url
26-
)
27-
errEmbed.set_footer(text=f"{ctx.author.name}", icon_url=user_avatar)
27+
async def on_command_error(
28+
self,
29+
ctx: commands.Context,
30+
error: Exception
31+
) -> None:
32+
"""Handles errors in commands."""
33+
34+
err_embed = self.bot.bot_embed(ctx)
2835
if isinstance(error, NotOwner):
29-
errEmbed.description = "Вы не разработчик бота."
30-
return await ctx.reply(embed=errEmbed, delete_after=40)
36+
37+
err_embed.description = "Вы не разработчик бота."
38+
return await ctx.reply(embed=err_embed, delete_after=40)
3139

3240
### Triggers when an error occurs in a slash command ###
3341

3442
@commands.Cog.listener()
3543
async def on_slash_command_error(
36-
self, inter: disnake.ApplicationCommandInteraction, error: Exception
37-
):
38-
39-
errEmbed = disnake.Embed(title="Ошибка", color=disnake.Color.red())
40-
user_avatar = (
41-
inter.author.display_avatar.url
42-
if inter.author.display_avatar
43-
else self.bot.user.display_avatar.url
44-
)
45-
errEmbed.set_footer(text=f"{inter.author.name}", icon_url=user_avatar)
44+
self: any, inter: disnake.ApplicationCommandInteraction, error: Exception
45+
) -> None:
46+
"""Handles errors in slash commands."""
47+
48+
err_embed = self.bot.bot_embed(inter)
4649

4750
if isinstance(error, commands.NoPrivateMessage):
48-
errEmbed.description = "Эта команда недоступна в личных сообщениях."
49-
return await inter.response.send_message(embed=errEmbed, ephemeral=True)
51+
err_embed.description = "Эта команда недоступна в личных сообщениях."
52+
return await inter.response.send_message(embed=err_embed, ephemeral=True)
5053

5154
if isinstance(error, disnake.Forbidden):
52-
errEmbed.description = "У меня нет прав для выполнения этого действия."
53-
return await inter.response.send_message(embed=errEmbed, ephemeral=True)
55+
err_embed.description = "У меня нет прав для выполнения этого действия."
56+
return await inter.response.send_message(embed=err_embed, ephemeral=True)
5457

5558
if isinstance(error, commands.MissingPermissions):
56-
errEmbed.description = "У вас нет прав для использования этой команды."
57-
return await inter.response.send_message(embed=errEmbed, ephemeral=True)
59+
err_embed.description = "У вас нет прав для использования этой команды."
60+
return await inter.response.send_message(embed=err_embed, ephemeral=True)
5861

5962
if isinstance(error, commands.CheckFailure):
60-
errEmbed.description = "Вы не можете использовать эту команду здесь."
61-
return await inter.response.send_message(embed=errEmbed, ephemeral=True)
63+
err_embed.description = "Вы не можете использовать эту команду здесь."
64+
return await inter.response.send_message(embed=err_embed, ephemeral=True)
6265

6366
error_id = str(uuid.uuid4())[:8]
6467
date_str = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
@@ -67,11 +70,14 @@ async def on_slash_command_error(
6770
os.makedirs("logs", exist_ok=True)
6871
full_path = os.path.join("logs", filename)
6972

73+
def ifdm(inter):
74+
return inter.guild.name if inter.guild else 'DM'
75+
7076
with open(full_path, "w", encoding="utf-8") as f:
7177
f.write(f"=== Ошибка {error_id} ({date_str}) ===\n")
7278
f.write(f"Пользователь: {inter.author} (ID: {inter.author.id})\n")
7379
f.write(
74-
f"Гильдия: {inter.guild.name if inter.guild else 'DM'} (ID: {inter.guild.id if inter.guild else 'DM'})\n"
80+
f"Гильдия: {ifdm(inter)} (ID: {ifdm(inter)})\n"
7581
)
7682
f.write(f"Команда: {inter.application_command.name}\n\n")
7783
traceback.print_exception(type(error), error, error.__traceback__, file=f)
@@ -80,12 +86,17 @@ async def on_slash_command_error(
8086
f"[ERROR] ID={error_id} | {type(error).__name__}: {error} (сохранено в {full_path})"
8187
)
8288

83-
errEmbed.description = f"Произошла неизвестная ошибка.\nСообщите UUID разработчику.\n\nUUID: `{error_id}"
89+
err_embed.description = (
90+
f"Произошла неизвестная ошибка.\n"
91+
f"Сообщите UUID разработчику.\n\n"
92+
f"UUID: `{error_id}"
93+
)
8494
try:
85-
await inter.response.send_message(embed=errEmbed, ephemeral=True)
95+
await inter.response.send_message(embed=err_embed, ephemeral=True)
8696
except disnake.InteractionResponded:
87-
await inter.followup.send(embed=errEmbed, ephemeral=True)
97+
await inter.followup.send(embed=err_embed, ephemeral=True)
8898

8999

90100
def setup(bot):
101+
"""Setup function to connect ErrorsModule"""
91102
bot.add_cog(ErrorsModule(bot))

0 commit comments

Comments
 (0)