mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 13:01:38 +00:00
* First commit * Renamed to bot * change from discordbot to bots imports * refractor cmds + autocomplete helpers + updated dps plots/candle + quote cmd * isort fix * Update helpers.py * Added first refactor * Added commands and refactor * Added description handler * Through grains * ta + image border helper * Added indices * merged * Finished econ * options refactor * dark_pool_shorts, candle, quote done * pagination/dropdown logic to helpers + fixes * dd/disc/insider done + add image logic to helpers * linting * removed plt style * Almost done with Gov * fixing conflicts * Finished gov (excpect ones mentioned) * screener done * Test bug refactor * Store changes to switch * Finished refactor * Fixed error * Delete ::40 * Fixed issue * Fixed black * finished * fixes Co-authored-by: teh_coderer <me@tehcoderer.com> Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
167 lines
5.4 KiB
Python
167 lines
5.4 KiB
Python
import asyncio
|
|
import difflib
|
|
import os
|
|
import sys
|
|
import traceback
|
|
|
|
import config_discordbot as cfg
|
|
import disnake
|
|
from config_discordbot import logger
|
|
from disnake.ext import commands
|
|
from fastapi import FastAPI
|
|
|
|
app = FastAPI()
|
|
|
|
|
|
# For next update
|
|
@app.get("/")
|
|
async def read_root():
|
|
return {"Hello": str(gst_bot.user)}
|
|
|
|
|
|
activity = disnake.Activity(
|
|
type=disnake.ActivityType.watching,
|
|
name="Gamestonk Terminal: https://github.com/GamestonkTerminal/GamestonkTerminal",
|
|
)
|
|
|
|
|
|
def fancy_traceback(exc: Exception) -> str:
|
|
"""May not fit the message content limit"""
|
|
text = "".join(traceback.format_exception(type(exc), exc, exc.__traceback__))
|
|
return f"```py\n{text[-4086:]}\n```"
|
|
|
|
|
|
class GSTHelpCommand(commands.MinimalHelpCommand):
|
|
"""Custom Help Command."""
|
|
|
|
def get_command_signature(self, command):
|
|
command_syntax = f"{self.clean_prefix}{command.qualified_name}"
|
|
command_usage = command.usage if command.usage is not None else ""
|
|
signature_text = f"""
|
|
Example usage:
|
|
`{command_syntax} {command_usage}`"""
|
|
return signature_text
|
|
|
|
def add_bot_commands_formatting(self, command, heading):
|
|
"""Add a minified bot heading with commands to the output."""
|
|
if command:
|
|
menu_header = heading.replace("Commands", " category")
|
|
self.paginator.add_line(
|
|
f"__**{menu_header}**__ " + f"contains {len(command)} command."
|
|
)
|
|
self.paginator.add_line(f"\t\t`!help {heading}` for info and options.")
|
|
|
|
|
|
class GSTBot(commands.Bot):
|
|
def __init__(self):
|
|
super().__init__(
|
|
command_prefix=cfg.COMMAND_PREFIX,
|
|
intents=disnake.Intents.all(),
|
|
help_command=GSTHelpCommand(sort_commands=False, commands_heading="list:"),
|
|
sync_commands_debug=True,
|
|
sync_permissions=True,
|
|
activity=activity,
|
|
test_guilds=cfg.SLASH_TESTING_SERVERS,
|
|
)
|
|
|
|
def load_all_extensions(self, folder: str) -> None:
|
|
folder_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), folder)
|
|
for name in os.listdir(folder_path):
|
|
if name.endswith(".py") and os.path.isfile(f"{folder_path}/{name}"):
|
|
self.load_extension(f"{folder}.{name[:-3]}")
|
|
|
|
async def on_command_error(
|
|
self, ctx: commands.Context, error: commands.CommandError
|
|
) -> None:
|
|
# Get all command names
|
|
all_cmds = gst_bot.all_commands.keys()
|
|
if isinstance(error, commands.CommandNotFound):
|
|
cmd = str(error).split('"')[1]
|
|
similar_cmd = difflib.get_close_matches(cmd, all_cmds, n=1, cutoff=0.7)
|
|
|
|
if similar_cmd:
|
|
error_help = f"Did you mean '**!{similar_cmd[0]}**'?"
|
|
else:
|
|
# TODO: This can be improved by triggering help menu
|
|
error_help = f"**Possible commands are:** {', '.join(all_cmds)}"
|
|
|
|
await ctx.send(f"_{error}_\n{error_help}\n", delete_after=30.0)
|
|
|
|
async def on_slash_command_error(
|
|
self,
|
|
inter: disnake.AppCmdInter,
|
|
error: commands.CommandError,
|
|
) -> None:
|
|
embed = disnake.Embed(
|
|
title=f"Slash command `{inter.data.name}` failed due to `{error}`",
|
|
description=fancy_traceback(error),
|
|
color=disnake.Color.red(),
|
|
)
|
|
if inter.response._responded: # pylint: disable=W0212
|
|
await inter.channel.send(embed=embed, delete_after=30.0)
|
|
else:
|
|
await inter.response.send_message(embed=embed, delete_after=30.0)
|
|
|
|
async def on_user_command_error(
|
|
self,
|
|
inter: disnake.AppCmdInter,
|
|
error: commands.CommandError,
|
|
) -> None:
|
|
embed = disnake.Embed(
|
|
title=f"User command `{inter.data.name}` failed due to `{error}`",
|
|
description=fancy_traceback(error),
|
|
color=disnake.Color.red(),
|
|
)
|
|
if inter.response._responded: # pylint: disable=W0212
|
|
await inter.channel.send(embed=embed, delete_after=30.0)
|
|
else:
|
|
await inter.response.send_message(embed=embed, delete_after=30.0)
|
|
|
|
async def on_message_command_error(
|
|
self,
|
|
inter: disnake.AppCmdInter,
|
|
error: commands.CommandError,
|
|
) -> None:
|
|
embed = disnake.Embed(
|
|
title=f"Message command `{inter.data.name}` failed due to `{error}`",
|
|
description=fancy_traceback(error),
|
|
color=disnake.Color.red(),
|
|
)
|
|
if inter.response._responded: # pylint: disable=W0212
|
|
await inter.channel.send(embed=embed, delete_after=30.0)
|
|
else:
|
|
await inter.response.send_message(embed=embed, delete_after=30.0)
|
|
|
|
async def on_ready(self):
|
|
# fmt: off
|
|
logger.info(
|
|
f"\n"
|
|
f"The bot is ready.\n"
|
|
f"User: {self.user}\n"
|
|
f"ID: {self.user.id}\n"
|
|
)
|
|
# fmt: on
|
|
|
|
|
|
if cfg.IMGUR_CLIENT_ID == "REPLACE_ME" or cfg.DISCORD_BOT_TOKEN == "REPLACE_ME":
|
|
logger.info(
|
|
"Update IMGUR_CLIENT_ID or DISCORD_BOT_TOKEN or both in %s \n",
|
|
os.path.join("discordbot", "config_discordbot"),
|
|
)
|
|
sys.exit()
|
|
print(f"disnake: {disnake.__version__}\n")
|
|
|
|
|
|
gst_bot = GSTBot()
|
|
gst_bot.load_all_extensions("cmds")
|
|
|
|
|
|
async def run():
|
|
try:
|
|
await gst_bot.start(cfg.DISCORD_BOT_TOKEN)
|
|
except KeyboardInterrupt:
|
|
await gst_bot.logout()
|
|
|
|
|
|
asyncio.create_task(run())
|