Skip to content

Commit 9d98fd9

Browse files
feat: some major improvements (#19)
- Add elapsed time logging on every slash command (Close GH-15) - Switch to modern logging - Improve music extension - Updates `delete_button` to `DeleteButton` - Replace `GoogleTrans` with one of its better working fork - Rewrite error handler - Fix image generator in greeter extension - Add Extension manager commands - Close GH-15
1 parent 7aa9cf5 commit 9d98fd9

30 files changed

+1383
-451
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ repos:
66
- id: end-of-file-fixer
77
- id: trailing-whitespace
88
- repo: https://github.com/psf/black
9-
rev: 23.3.0
9+
rev: 24.4.2
1010
hooks:
1111
- id: black
1212
- repo: https://github.com/PyCQA/isort
13-
rev: 5.12.0
13+
rev: 5.13.2
1414
hooks:
1515
- id: isort
1616
exclude: '^(env)'

docker-compose.yaml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,52 @@ services:
77

88
lavalink:
99
<<: *restart_policy
10-
image: ghcr.io/freyacodes/lavalink:latest
10+
image: ghcr.io/lavalink-devs/lavalink:4a2b99f-alpine
1111
container_name: lavalink
12+
1213
environment:
1314
- _JAVA_OPTIONS=-Xmx6G
1415
- SERVER_PORT=2333
1516
- LAVALINK_SERVER_PASSWORD=youshallnotpass
17+
1618
networks:
1719
- lavalink
20+
1821
expose:
1922
- 2333
23+
2024
ports:
2125
- 2333:2333
2226

27+
volumes:
28+
- ./lavalink_application.yml:/opt/Lavalink/application.yml
29+
2330

2431
mr-robot:
2532
<<: *restart_policy
2633
image: ghcr.io/mr-robot-discord-bot/mr-robot:latest
2734
container_name: mr-robot
35+
build:
36+
context: .
37+
dockerfile: Dockerfile
2838
tty: true
39+
2940
environment:
30-
- BOT_TOKEN=YOUR BOT TOKEN
41+
- BOT_TOKEN=PUT YOUR BOT TOKEN
3142
- ON_JOIN_WEBHOOK=WEBHOOK_URL
3243
- AI_API_KEY=GEMNI AI API KEY
3344
- GIT_TOKEN=GIT_API_TOKEN
3445
- GIT_DB_REPO=OWNER/REPO
3546
- NSFW_API=NSFW API
47+
3648
networks:
37-
- lavalink
49+
- lavalink
50+
3851
depends_on:
39-
- lavalink
52+
- lavalink
53+
54+
volumes:
55+
- .:/app
4056

4157

4258
networks:

lavalink_application.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
plugins:
2+
youtube:
3+
enabled: true
4+
allowSearch: true
5+
allowDirectVideoIds: true
6+
allowDirectPlaylistIds: true
7+
8+
lavalink:
9+
plugins:
10+
- dependency: "dev.lavalink.youtube:youtube-plugin:1.3.0"
11+
snapshot: false
12+
server:
13+
sources:
14+
youtube: false

logging_config.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"version": 1,
3+
4+
"disable_exsisting_loggers": false,
5+
6+
"formatters": {
7+
"simple": {"format": "%(levelname)s: %(message)s"},
8+
"expanded": {
9+
"format": "%(levelname)s - %(name)s - %(filename)s - %(module)s - %(funcName)s - %(message)s"
10+
},
11+
"detailed": {
12+
"format": "[%(levelname)s|%(module)s|%(funcName)s|L%(lineno)d] %(asctime)s: %(message)s",
13+
"datefmt": "%Y-%m-%dT%H:%M:%S%z"
14+
}
15+
},
16+
17+
"handlers": {
18+
"stdout": {
19+
"class": "logging.StreamHandler",
20+
"formatter": "simple",
21+
"stream": "ext://sys.stdout"
22+
},
23+
"stderr": {
24+
"class": "logging.StreamHandler",
25+
"level": "WARNING",
26+
"formatter": "expanded",
27+
"stream": "ext://sys.stderr"
28+
},
29+
"debugfile": {
30+
"class": "logging.handlers.RotatingFileHandler",
31+
"level": "DEBUG",
32+
"formatter": "detailed",
33+
"filename": "logs/debug.log",
34+
"maxBytes": 200000000,
35+
"backupCount": 3
36+
},
37+
"errorfile": {
38+
"class": "logging.handlers.RotatingFileHandler",
39+
"level": "WARNING",
40+
"formatter": "detailed",
41+
"filename": "logs/error.log",
42+
"maxBytes": 200000000,
43+
"backupCount": 2
44+
},
45+
"queue_handler": {
46+
"class": "logging.handlers.QueueHandler",
47+
"handlers": ["stdout", "stderr", "errorfile", "debugfile"],
48+
"respect_handler_level": true
49+
}
50+
51+
},
52+
53+
"loggers": {
54+
"root": {"level": "DEBUG", "handlers": ["queue_handler"]}
55+
}
56+
}

mr_robot/__main__.py

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import asyncio
2-
import logging
2+
import atexit
3+
import json
4+
import logging.config
5+
import logging.handlers
6+
import os
37
import signal
48
import sys
59

@@ -11,37 +15,29 @@
1115
from mr_robot.bot import MrRobot
1216
from mr_robot.constants import Client
1317

14-
# from mr_robot.utils.helpers import proxy_generator
15-
16-
proxy_mode = False
17-
PROXY = None
18-
19-
file_handler = logging.FileHandler(Client.log_file_name, mode="w")
20-
console_handler = logging.StreamHandler()
21-
22-
file_handler.setLevel(logging.DEBUG)
23-
console_handler.setLevel(logging.INFO)
24-
logging.basicConfig(
25-
level=logging.NOTSET,
26-
format="%(levelname)s - %(name)s - %(filename)s - %(module)s - %(funcName)s - %(message)s",
27-
handlers=[console_handler, file_handler],
28-
)
29-
30-
logging.getLogger("httpx").setLevel(logging.WARNING)
31-
logging.getLogger("httpcore").setLevel(logging.WARNING)
32-
logging.getLogger("disnake").setLevel(logging.INFO)
33-
logging.getLogger("aiosqlite").setLevel(logging.INFO)
34-
logger = logging.getLogger(__name__)
18+
load_dotenv()
3519

3620

37-
load_dotenv()
21+
def setup_logging() -> None:
22+
with open(Client.logging_config_file, "r") as file:
23+
config = json.load(file)
24+
try:
25+
os.mkdir("logs")
26+
except FileExistsError:
27+
...
28+
logging.config.dictConfig(config)
29+
queue_handler = logging.getHandlerByName("queue_handler")
30+
if queue_handler is not None:
31+
queue_handler.listener.start() # type: ignore[reportAttributeAccessIssue]
32+
atexit.register(queue_handler.listener.stop) # type: ignore[reportAttributeAccessIssue]
3833

3934

4035
async def main():
41-
global PROXY
36+
setup_logging()
37+
logger = logging.getLogger(Client.name)
38+
logger.info("Logger Initialized!")
4239
async with httpx.AsyncClient(timeout=httpx.Timeout(None)) as session:
4340
client = MrRobot(
44-
proxy=PROXY,
4541
intents=disnake.Intents.all(),
4642
session=session,
4743
db=await aiosqlite.connect(Client.db_name),
@@ -68,11 +64,6 @@ async def main():
6864
await future
6965
except asyncio.CancelledError:
7066
logger.info("Received signal to terminate bot and event loop")
71-
# logger.warning(
72-
# "Unable to connect to Discord falling back to proxy mode", exc_info=True
73-
# )
74-
# proxy_mode = True
75-
# PROXY = proxy_generator() if proxy_mode else None
7667
finally:
7768
if not client.is_closed():
7869
await client.close()

mr_robot/bot.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import httpx
77
import mafic
88
from aiocache import cached
9+
from aiosqlite import Connection
910
from disnake.ext import commands
1011

1112
from mr_robot.constants import Client
12-
from mr_robot.utils.extensions import EXTENSIONS, walk_extensions
13+
from mr_robot.utils.extensions import walk_extensions
1314
from mr_robot.utils.git_api import Git
1415

1516
logger = logging.getLogger(__name__)
@@ -18,7 +19,7 @@
1819
class MrRobot(commands.AutoShardedInteractionBot):
1920
"""Mr Robot Bot"""
2021

21-
def __init__(self, session: httpx.AsyncClient, db, db_name, **kwargs):
22+
def __init__(self, session: httpx.AsyncClient, db: Connection, db_name, **kwargs):
2223
super().__init__(**kwargs)
2324
self.pool = mafic.NodePool(self)
2425
self.loop.create_task(self.add_nodes())
@@ -73,8 +74,7 @@ async def add_nodes(self):
7374

7475
def load_bot_extensions(self) -> None:
7576
"""Loads extensions released by walk_extensions()"""
76-
EXTENSIONS.update(walk_extensions())
77-
logger.info("Extension loading successful!")
7877
for ext in walk_extensions():
7978
logger.info(f"{ext} extension loaded!!")
8079
self.load_extension(ext)
80+
logger.info("Extension loading successful!")

mr_robot/constants.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,37 @@
22

33

44
class Client:
5+
"""Client Constants"""
6+
57
name = "Mr Robot"
68
token = getenv("BOT_TOKEN")
79
log_file_name = "mr-robot.log"
810
db_name = "mr-robot.db"
911
github_db_repo = getenv("GIT_DB_REPO")
1012
github_token = getenv("GIT_TOKEN")
1113
github_bot_repo = "https://github.com/Mr-Robot-Discord-Bot/Mr-Robot/"
12-
support_server = "SUPPORT SERVER"
14+
support_server = "55TQeTvU6f"
1315
version = getenv("VERSION")
1416
nsfw_api = getenv("NSFW_API")
1517
gemini_api_key = getenv("AI_API_KEY")
1618
on_join_webook = getenv("ON_JOIN_WEBHOOK")
19+
debug_mode = False
20+
debug_guilds = [1241678951307542538]
21+
logging_config_file = "logging_config.json"
22+
23+
24+
class ButtonCustomId:
25+
"""Button Custom Ids"""
26+
27+
delete = "message_delete:"
28+
29+
30+
class Colors:
31+
"""Colours"""
32+
33+
red = 0xFF0000
34+
green = 0x00FF00
35+
blue = 0x0000FF
36+
black = 0x000000
37+
orange = 0xFFA500
38+
yellow = 0xFFFF00

mr_robot/exts/ai.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import logging
22

3+
import disnake
34
import google.generativeai as genai
45
from disnake.ext import commands
56
from google.generativeai.types import BlockedPromptException
67

78
from mr_robot.bot import MrRobot
89
from mr_robot.constants import Client
9-
from mr_robot.utils.helpers import delete_button
10+
from mr_robot.utils.messages import DeleteButton
1011

1112
logger = logging.getLogger(__name__)
1213

@@ -49,10 +50,14 @@ def __init__(self, client: MrRobot):
4950
@commands.slash_command(name="ai", dm_permission=False)
5051
async def ai(self, _):
5152
"""Interact with ai"""
53+
if not Client.gemini_api_key:
54+
raise ValueError("Ai api key is not being initialised")
5255
...
5356

5457
@ai.sub_command(name="chat")
55-
async def slash_ai_generate_text(self, interaction, query: str):
58+
async def slash_ai_generate_text(
59+
self, interaction: disnake.GuildCommandInteraction, query: str
60+
):
5661
"""
5762
Talk to Mr Robot AI system
5863
@@ -64,7 +69,9 @@ async def slash_ai_generate_text(self, interaction, query: str):
6469
try:
6570
await self.conv.send_message_async(query)
6671
if self.conv.last:
67-
await interaction.send(self.conv.last.text, components=[delete_button])
72+
await interaction.send(
73+
self.conv.last.text, components=[DeleteButton(interaction.author)]
74+
)
6875
else:
6976
await interaction.send("Ai module didn't responded")
7077
except BlockedPromptException:

mr_robot/exts/backend/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)