Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closing in on 90% Bot Coverage #1646

Merged
merged 28 commits into from
Apr 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7849cb2
Attempting more tests
colin99d Apr 6, 2022
1acbed3
fix bots module not found issue
tehcoderer Apr 6, 2022
2429d86
try this syspath
tehcoderer Apr 6, 2022
ee91485
black
tehcoderer Apr 6, 2022
5c246fa
fix except
tehcoderer Apr 6, 2022
6ff09b2
fix import sys path errors
tehcoderer Apr 6, 2022
774e8bd
Merge branch 'morebottests' of https://github.com/OpenBB-finance/Open…
tehcoderer Apr 6, 2022
b8b98ba
remove dual import
tehcoderer Apr 6, 2022
7dc0dcd
Basic tests
colin99d Apr 8, 2022
b7cb788
Sorry Juan
colin99d Apr 8, 2022
6c8b105
Fixed conflicts
colin99d Apr 8, 2022
a396d51
Seperate discord commands
colin99d Apr 8, 2022
1f52d0f
Merge branch 'main' into morebottests
colin99d Apr 8, 2022
10efdd2
fix path issues loading cmds folder
tehcoderer Apr 8, 2022
08a8e7f
Merge branch 'morebottests' of https://github.com/OpenBB-finance/Open…
tehcoderer Apr 8, 2022
c9aca05
click dep fix
tehcoderer Apr 8, 2022
c928d09
Fixed pylint
colin99d Apr 9, 2022
0e2d2a2
Merge branch 'main' into morebottests
colin99d Apr 9, 2022
74c2edd
Expanded tests
colin99d Apr 9, 2022
eceac64
Merge branch 'morebottests' of https://github.com/OpenBB-finance/Open…
colin99d Apr 9, 2022
19142c2
Expanded tests
colin99d Apr 9, 2022
7a8c0e1
Improve imports
colin99d Apr 9, 2022
65f5297
Merge branch 'main' into morebottests
colin99d Apr 9, 2022
3513305
improve paths, clean up ext load, fixes
tehcoderer Apr 10, 2022
36e9b45
Merge branch 'main' into morebottests
colin99d Apr 10, 2022
eea5084
Merge branch 'main' into morebottests
colin99d Apr 10, 2022
4a4d17a
Update pyproject.toml
colin99d Apr 10, 2022
67a4c51
resolving windows test issues
colin99d Apr 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions bots/config_discordbot.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import sys
from distutils.util import strtobool
from pathlib import Path
from typing import List, Optional
Expand All @@ -10,15 +9,13 @@

# Path to bots
bots_path = Path(__file__).parent.resolve()
GST_PATH = Path(__file__).parent.parent.resolve()

env_files = [f for f in bots_path.iterdir() if f.__str__().endswith(".env")]

if env_files:
load_dotenv(env_files[0])

# Relative path to the terminal
sys.path.append("..")

# https://discord.com/developers/applications/
DISCORD_BOT_TOKEN = os.getenv("OPENBB_DISCORD_BOT_TOKEN") or "REPLACE_ME"

Expand All @@ -32,6 +29,9 @@
API_BINANCE_KEY = os.getenv("OPENBB_API_BINANCE_KEY") or "REPLACE_ME"
API_BINANCE_SECRET = os.getenv("OPENBB_API_BINANCE_SECRET") or "REPLACE_ME"

# https://stocksera.pythonanywhere.com/accounts/developers/
API_STOCKSERA_TOKEN = os.getenv("OPENBB_API_STOCKSERA_TOKEN") or "REPLACE_ME"

# https://finnhub.io
API_FINNHUB_KEY = os.getenv("OPENBB_API_FINNHUB_KEY") or "REPLACE_ME"

Expand All @@ -58,13 +58,11 @@

DEBUG = strtobool(os.getenv("OPENBB_DEBUG", "False"))

GST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))

gst_imgur = pyimgur.Imgur(IMGUR_CLIENT_ID)

AUTHOR_NAME = "Gamestonk Terminal"
AUTHOR_NAME = "OpenBB Bot"
AUTHOR_URL = "https://github.com/OpenBB-finance/OpenBBTerminal"
AUTHOR_ICON_URL = (
"https://github.com/OpenBB-finance/OpenBBTerminal/"
"blob/main/images/gst_logo_green_white_background.png?raw=true"
"https://raw.githubusercontent.com/OpenBB-finance/OpenBBTerminal/"
"hugo_rename/images/openbb_logo.png"
)
241 changes: 241 additions & 0 deletions bots/discord/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import hashlib
import logging
import platform
import traceback
import uuid
from typing import Any, Dict

import disnake
from disnake.ext import commands

from bots import config_discordbot as cfg
from openbb_terminal.decorators import log_start_end
from openbb_terminal.loggers import setup_logging

logger = logging.getLogger(__name__)
setup_logging("bot-app")
logger.info("START")
logger.info("Python: %s", platform.python_version())
logger.info("OS: %s", platform.system())

activity = disnake.Activity(
type=disnake.ActivityType.watching,
name="OpenBB Terminal: https://github.com/OpenBB-finance/OpenBBTerminal",
)


class _MissingSentinel:
def __eq__(self, other):
return False

def __bool__(self):
return False

def __repr__(self):
return "..."


MISSING: Any = _MissingSentinel()


def hash_user_id(user_id: str) -> str:
hash_object = hashlib.new("md4", user_id.encode("utf-8"))
return str(uuid.UUID(hash_object.hexdigest(), version=4))


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)} commands."
)
self.paginator.add_line(f"\t\t`!help {heading}` for info and options.")


@log_start_end(log=logger)
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 = cfg.bots_path.joinpath(folder)
for name in folder_path.iterdir():
if name.__str__().endswith(".py") and name.is_file():
self.load_extension(f"{folder}.{name.stem}")

async def on_command_error(
self, ctx: commands.Context, error: commands.CommandError
) -> None:
if isinstance(error, commands.CheckAnyFailure):
await ctx.message.delete()

async def on_slash_command_error(
self,
inter: disnake.AppCmdInter,
error: commands.CommandError,
) -> None:
if isinstance(error, commands.NoPrivateMessage):
logger.info("Slash No Private Message Error")
tickred = "<a:tickred:942466341082902528>"
embed = disnake.Embed(
title="Command Execution Error",
color=disnake.Color.red(),
description=f"{tickred} This command cannot be used in private messages!",
)
if inter.response._responded:
pass
else:
await inter.response.send_message(embed=embed, ephemeral=True)
elif isinstance(error, commands.MissingPermissions):
logger.info("Slash Permissions Error")
tickred = "<a:tickred:942466341082902528>"
embed = disnake.Embed(
title="Command Execution Error",
color=disnake.Color.red(),
description=f"{tickred} You do not have enough permissions to execute this command!",
)
if inter.response._responded:
pass
else:
await inter.response.send_message(embed=embed, ephemeral=True)
elif isinstance(error, commands.CheckAnyFailure):
logger.info("Slash Permissions Error")
tickred = "<a:tickred:942466341082902528>"
embed = disnake.Embed(
title="Command Execution Error",
color=0xF00,
description=f"{tickred} You do not have enough permissions to execute this command!",
)
if inter.response._responded:
pass
else:
await inter.response.send_message(embed=embed, ephemeral=True)
else:
embed = disnake.Embed(
title="",
description=f"Slash command `{inter.data.name}` failed due to `{error}`\n{fancy_traceback(error)}",
color=disnake.Color.red(),
)
if inter.response._responded:
pass
else:
await inter.response.send_message(embed=embed, ephemeral=True)

async def on_application_command(
self,
inter: disnake.AppCmdInter,
) -> None:
await self.process_application_commands(inter)
if inter.filled_options is MISSING:
filled: Dict[str, Any] = {"N/A": ""}
else:
filled = inter.filled_options
if inter.data.name is MISSING:
cmd_name: str = ""
else:
cmd_name = inter.data.name
if inter.guild:
server: Any[Dict[str, Any]] = {
"guild_id": inter.guild.id,
"name": inter.guild.name,
"channel": inter.channel.name,
"member_count": inter.guild.member_count,
}
else:
server = "DM"

stats_log = {
"data": [
{
"server": server,
"command": {
"name": cmd_name,
"cmd_data": filled,
},
}
],
}

log_uid = {"user_id": hash_user_id(str(inter.author.id))}
logger.info(stats_log, extra=log_uid)

pass

async def on_user_command_error(
self,
inter: disnake.AppCmdInter,
error: commands.CommandError,
) -> None:
embed = disnake.Embed(
title="",
description=f"User command `{inter.data.name}` failed due to `{error}`\n{fancy_traceback(error)}",
color=disnake.Color.red(),
)
if inter.response._responded:
pass
else:
await inter.response.send_message(embed=embed, ephemeral=True)

async def on_message_command_error(
self,
inter: disnake.AppCmdInter,
error: commands.CommandError,
) -> None:
embed = disnake.Embed(
title="",
description=f"Message command `{inter.data.name}` failed due to `{error}`\n{fancy_traceback(error)}",
color=disnake.Color.red(),
)
if inter.response._responded:
pass
else:
await inter.response.send_message(embed=embed, ephemeral=True)

async def on_ready(self):
# fmt: off
guildname = []
for guild in self.guilds:
guildname.append(guild.name)
members = []
for guild in self.guilds:
for member in guild.members:
members.append(member)

dindex = len(members)
logger.info(
"Servers connected to:"
f"{guildname}"
f"Total members: {dindex}"
)
logger.info(
f"The bot is ready."
f"User: {self.user}"
f"ID: {self.user.id}"
)
# fmt: on
3 changes: 2 additions & 1 deletion bots/economy/reverse_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def reverse_repo_command(days: int = 50):

df = pd.DataFrame(
requests.get(
f"https://stocksera.pythonanywhere.com/api/reverse_repo/?days={str(days)}"
f"https://stocksera.pythonanywhere.com/api/reverse_repo/?days={str(days)}",
headers={"Authorization": f"Api-Key {imps.API_STOCKSERA_TOKEN}"},
).json()
)

Expand Down
2 changes: 1 addition & 1 deletion bots/etf/whatetf.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def by_ticker_command(ticker="", sort="fund_percent", num: int = 15):
options.headless = True
options.add_argument("--headless")
options.add_argument("--incognito")
driver = uc.Chrome(options=options, version_main=98)
driver = uc.Chrome(options=options, version_main=100)
driver.set_window_size(1920, 1080)
driver.get(f"http://etf.com/stock/{ticker.upper()}/")

Expand Down
Binary file added bots/files/bg-dark_openbb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 13 additions & 13 deletions bots/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ backcall==0.2.0; python_full_version >= "3.6.2" and python_version >= "3.8"
backports.zoneinfo==0.2.1; python_version < "3.9" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
bandit==1.7.4; python_version >= "3.7"
beartype==0.7.1; python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.0"
beautifulsoup4==4.10.0; python_full_version > "3.0.0" and python_version >= "3.7"
beautifulsoup4==4.11.0; python_full_version >= "3.6.0" and python_version >= "3.7"
black==22.1.0; python_full_version >= "3.6.2"
bleach==4.1.0; python_version >= "3.7"
boto3==1.21.33; python_version >= "3.6"
botocore==1.24.33; python_version >= "3.6"
bleach==5.0.0; python_version >= "3.7"
boto3==1.21.36; python_version >= "3.6"
botocore==1.24.36; python_version >= "3.6"
bs4==0.0.1
bt==0.2.9; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0")
certifi==2021.10.8; python_full_version >= "3.7.1" and python_version < "4" and python_version >= "3.8" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7")
Expand Down Expand Up @@ -71,7 +71,7 @@ finnhub-python==2.4.12
finviz==1.4.4
finvizfinance==0.14.0; python_version >= "3.5"
flake8==3.9.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0")
fonttools==4.31.2; python_version >= "3.7"
fonttools==4.32.0; python_version >= "3.7"
formulaic==0.3.3; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and python_version >= "3.8"
fred==3.1
fredapi==0.4.3
Expand Down Expand Up @@ -105,15 +105,15 @@ jmespath==1.0.0; python_version >= "3.7"
joblib==1.1.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
json5==0.9.6; python_version >= "3.7"
jsonschema==3.2.0
jupyter-client==7.2.1; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-client==7.2.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-console==6.4.3; python_version >= "3.6"
jupyter-core==4.9.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-server==1.16.0; python_version >= "3.7"
jupyter==1.0.0
jupyterlab-pygments==0.1.2; python_version >= "3.7"
jupyterlab-pygments==0.2.0; python_version >= "3.7"
jupyterlab-server==2.12.0; python_version >= "3.7"
jupyterlab-widgets==1.1.0; python_version >= "3.6"
jupyterlab==3.3.2; python_version >= "3.7"
jupyterlab==3.3.3; python_version >= "3.7"
kiwisolver==1.4.2; python_version >= "3.7"
korean-lunar-calendar==0.2.1; python_version >= "3.7" and python_full_version >= "3.7.0"
lazy-object-proxy==1.7.1; python_version >= "3.6" and python_full_version >= "3.6.2"
Expand Down Expand Up @@ -166,13 +166,13 @@ pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8" and python_f
pickleshare==0.7.5; python_full_version >= "3.6.2" and python_version >= "3.8"
pillow==9.1.0; python_version >= "3.7" and python_version < "4"
platformdirs==2.5.1; python_version >= "3.7" and python_full_version >= "3.6.2" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7")
plotly==5.6.0; python_version >= "3.6"
plotly==5.7.0; python_version >= "3.6"
pluggy==1.0.0; python_version >= "3.7"
pmdarima==1.8.5; python_version >= "3.7"
praw==7.5.0; python_version >= "3.6" and python_version < "4.0"
prawcore==2.3.0; python_version >= "3.6" and python_version < "4.0"
pre-commit==2.18.1; python_version >= "3.7"
prometheus-client==0.13.1; python_version >= "3.7"
prometheus-client==0.14.1; python_version >= "3.7"
prompt-toolkit==3.0.29; python_full_version >= "3.6.2"
property-cached==1.6.4; python_version >= "3.8"
protobuf==3.20.0; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and python_version >= "3.7"
Expand All @@ -191,7 +191,7 @@ pyflakes==2.3.1; python_version >= "2.7" and python_full_version < "3.0.0" or py
pygments==2.11.2; python_version >= "3.5"
pyhdfe==0.1.0; python_version >= "3.8"
pyimgur==0.6.0
pylint==2.13.4; python_full_version >= "3.6.2"
pylint==2.13.5; python_full_version >= "3.6.2"
pyluach==1.4.1; python_version >= "3.7" and python_full_version >= "3.7.0"
pymeeus==0.5.11; python_version >= "3.7" and python_version < "4"
pymongo==3.11.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0")
Expand Down Expand Up @@ -251,7 +251,7 @@ sniffio==1.2.0; python_version >= "3.7" and python_version < "4.0" and python_fu
snowballstemmer==2.2.0; python_version >= "3.7"
socketio-client-nexus==0.7.6
sortedcontainers==2.4.0; python_version >= "3.7" and python_version < "4.0"
soupsieve==2.3.1; python_version >= "3.6" and python_full_version > "3.0.0"
soupsieve==2.3.2; python_version >= "3.6" and python_full_version >= "3.6.0"
sphinx-rtd-theme==0.5.2; python_version >= "3.7"
sphinx==4.1.1; python_version >= "3.6"
sphinxcontrib-applehelp==1.0.2; python_version >= "3.7"
Expand Down Expand Up @@ -294,7 +294,7 @@ types-urllib3==1.26.11
typing-extensions==4.1.1; python_version < "3.10" and python_full_version >= "3.6.2" and python_version >= "3.6"
tzdata==2022.1; platform_system == "Windows" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
tzlocal==4.2; python_version >= "3.6"
ujson==5.1.0; python_version >= "3.7"
ujson==5.2.0; python_version >= "3.7"
undetected-chromedriver==3.1.5.post4
unidecode==1.3.4; python_version >= "3.7"
update-checker==0.18.0; python_version >= "3.6" and python_version < "4.0"
Expand Down
Loading