* initial slack files

* improving messages

* updated slack and telegram dependencies

* added website content

* added images in docs

* fixed functions docs

Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
This commit is contained in:
jose-donato
2022-03-10 14:31:05 +00:00
committed by GitHub
parent 35cd91881f
commit 545e256b09
11 changed files with 484 additions and 41 deletions

View File

@@ -292,6 +292,35 @@ class ShowView:
message = f"{title}\n{clean_desc}"
send_message(message, group_id)
def slack(self, func, channel_id, user_id, client, *args, **kwargs):
data = func(*args, **kwargs)
if "imagefile" in data:
client.files_upload(
file=data["imagefile"],
initial_comment=data.get("title", ""),
channels=channel_id,
user_id=user_id,
)
os.remove(data["imagefile"])
elif "embeds_img" in data:
client.files_upload(
file=data["embeds_img"][0],
initial_comment=data.get("title", ""),
channels=channel_id,
user_id=user_id,
)
os.remove(data["embeds_img"][0])
elif "description" in data:
title = data.get("title", "")
description = data.get("description")
if isinstance(description, List):
clean_desc = description[0].replace("Page ", "")
else:
clean_desc = description.replace("Page ", "")
message = f"{title}\n{clean_desc}"
payload = {"channel": channel_id, "username": user_id, "text": message}
client.chat_postMessage(**payload)
def telegram(self, func, message, bot, cmd, *args, **kwargs):
data = func(*args, **kwargs)
if "imagefile" in data:
@@ -306,7 +335,6 @@ class ShowView:
os.remove(data["embeds_img"][0])
elif "description" in data:
title = data.get("title", "")
# TODO: Allow navigation through pages
description = data.get("description")
if isinstance(description, List):
clean_desc = description[0].replace("Page ", "")

69
bots/requirements.txt vendored
View File

@@ -1,37 +1,38 @@
aiohttp==3.8.1; python_version >= "3.6" and python_full_version >= "3.8.0"
aiosignal==1.2.0; python_version >= "3.6"
aiosignal==1.2.0; python_version >= "3.6" and python_full_version >= "3.8.0"
alabaster==0.7.12; python_version >= "3.7"
alpha-vantage==2.3.1
ansiwrap==0.8.4; python_version >= "3.6"
anyio==3.5.0; python_full_version >= "3.6.2" and python_version >= "3.7"
appdirs==1.4.4; python_full_version >= "3.6.2" and python_version >= "3.8"
appnope==0.1.2; platform_system == "Darwin" and python_version >= "3.8" and sys_platform == "darwin"
argon2-cffi-bindings==21.2.0; python_version >= "3.6"
argon2-cffi-bindings==21.2.0; python_version >= "3.7"
argon2-cffi==21.3.0; python_version >= "3.7"
ascii-magic==1.6; python_version >= "3.5"
asgiref==3.5.0; python_version >= "3.7"
astor==0.8.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
astroid==2.9.3; python_full_version >= "3.6.2"
asttokens==2.0.5; python_version >= "3.8"
async-timeout==4.0.2; python_version >= "3.6"
async-timeout==4.0.2; python_version >= "3.6" and python_full_version >= "3.8.0"
atomicwrites==1.4.0; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.7" and python_full_version >= "3.4.0"
attrs==21.4.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.5.0" and python_version >= "3.7" and python_version < "4.0"
attrs==21.4.0; python_full_version >= "3.8.0" and python_version >= "3.7" and (python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.6" and python_version < "4.0" and python_full_version >= "3.5.0") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7")
babel==2.9.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
backcall==0.2.0; 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.2; 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.5"
beautifulsoup4==4.10.0; python_full_version > "3.0.0" and python_version >= "3.7"
black==21.7b0; python_full_version >= "3.6.2"
bleach==4.1.0; python_version >= "3.7"
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_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
cffi==1.15.0; implementation_name == "pypy" and python_version >= "3.6"
certifi==2021.10.8; python_full_version >= "3.7.1" and python_version >= "3.8" and python_version < "4.0" 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")
cffi==1.15.0; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.7.0"
cfgv==3.3.1; python_full_version >= "3.6.1"
charset-normalizer==2.0.12; python_full_version >= "3.6.0" and python_version >= "3.6"
charset-normalizer==2.0.12; python_full_version >= "3.8.0" and python_version >= "3.8" and python_version < "4.0" 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")
click==8.0.4; python_version >= "3.8" and python_full_version >= "3.6.2"
codespell==2.1.0; python_version >= "3.5"
colorama==0.4.4; python_full_version >= "3.6.2" and python_full_version < "4.0.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") and (python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.5.0") and sys_platform == "win32" and (python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.7" and python_full_version >= "3.5.0") and (python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0") and (python_version >= "2.7" and python_full_version < "3.0.0" and platform_system == "Windows" or python_full_version >= "3.5.0" and platform_system == "Windows") and (python_version >= "3.6" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.6" and python_full_version >= "3.5.0") and (python_version >= "3.8" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.8" and python_full_version >= "3.5.0")
colorama==0.4.4; python_full_version >= "3.6.2" and python_full_version < "4.0.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") and (python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.5.0") and sys_platform == "win32" and (python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.7" and python_full_version >= "3.5.0") and (python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0") and (python_version >= "3.6" and python_full_version < "3.0.0" and platform_system == "Windows" or python_full_version >= "3.5.0" and platform_system == "Windows" and python_version >= "3.6") and platform_system == "Windows" and python_version >= "3.7" and (python_version >= "3.8" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.8" and python_full_version >= "3.5.0")
commonmark==0.9.1; python_full_version >= "3.6.2" and python_full_version < "4.0.0"
convertdate==2.4.0; python_version >= "3.7" and python_version < "4"
coverage==6.3.2; python_version >= "3.7"
@@ -54,7 +55,7 @@ distlib==0.3.4; python_full_version >= "3.6.1"
dnspython==2.2.0; python_version >= "3.6" and python_version < "4.0"
docutils==0.16; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
ecos==2.0.10; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
entrypoints==0.4; python_full_version >= "3.6.1" and python_version >= "3.7"
entrypoints==0.4; python_full_version >= "3.7.0" and python_version >= "3.7"
et-xmlfile==1.1.0; python_version >= "3.6"
exchange-calendars==3.6; python_version >= "3.7" and python_full_version >= "3.7.0"
executing==0.8.2; python_version >= "3.8"
@@ -68,10 +69,11 @@ finviz==1.4.3
finvizfinance==0.9.10; 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.29.1; python_version >= "3.7"
formulaic==0.2.4; python_version >= "3.7"
fred==3.1
fredapi==0.4.3
frozendict==2.3.0; python_version >= "3.6"
frozenlist==1.3.0; python_version >= "3.7"
frozenlist==1.3.0; python_version >= "3.7" and python_full_version >= "3.8.0"
fundamentalanalysis==0.2.12
future==0.18.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
gitdb==4.0.9; python_version >= "3.7"
@@ -81,26 +83,27 @@ h11==0.13.0; python_version >= "3.7"
hijri-converter==2.2.3; python_version >= "3.6"
holidays==0.11.3.1; python_version >= "3.6"
identify==2.4.11; python_version >= "3.7" and python_full_version >= "3.6.1"
idna==3.3; python_full_version >= "3.6.2" and python_version >= "3.7"
idna==3.3; python_full_version >= "3.8.0" and python_version >= "3.8" and python_version < "4.0" 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")
imagesize==1.3.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
inflection==0.5.1; python_version >= "3.6"
iniconfig==1.1.1; python_version >= "3.7"
interface-meta==1.2.4; python_version >= "3.7"
investpy==1.0.8; python_version >= "3.7"
ipykernel==6.9.1; python_version >= "3.7"
ipympl==0.8.8
ipython-genutils==0.2.0; python_version >= "3.7"
ipython-genutils==0.2.0; python_full_version >= "3.7.0" and python_version >= "3.7"
ipython==8.0.1; python_version >= "3.8"
ipywidgets==7.6.5
iso8601==0.1.16
isort==5.10.1; python_full_version >= "3.6.2" and python_version < "4.0"
jedi==0.18.1; python_version >= "3.8"
jinja2==3.0.3; python_version >= "3.7"
joblib==1.1.0; python_version >= "3.7"
json5==0.9.6; python_version >= "3.6"
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.1.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-console==6.4.0; python_version >= "3.6"
jupyter-core==4.9.2; python_full_version >= "3.6.1" and python_version >= "3.7"
jupyter-core==4.9.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-server==1.13.5; python_version >= "3.7"
jupyter==1.0.0
jupyterlab-pygments==0.1.2; python_version >= "3.7"
@@ -111,6 +114,7 @@ kaleido==0.2.1; python_version >= "3.8" and python_version < "4.0"
kiwisolver==1.3.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"
linearmodels==4.25; python_version >= "3.7"
lxml==4.8.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
m2r2==0.2.8; python_version >= "3.7"
markdown-it-py==1.1.0; python_version >= "3.6" and python_version < "4.0"
@@ -123,7 +127,7 @@ mistune==0.8.4; python_version >= "3.7"
mock==4.0.3; python_version >= "3.6"
more-itertools==8.12.0; python_version >= "3.6"
mplfinance==0.12.8b9
multidict==6.0.2; python_version >= "3.7"
multidict==6.0.2; python_version >= "3.7" and python_full_version >= "3.8.0"
multitasking==0.0.10
mypy-extensions==0.4.3; python_version >= "3.8" and python_full_version >= "3.6.2"
mypy==0.930; python_version >= "3.6"
@@ -164,11 +168,12 @@ prawcore==2.3.0; python_version >= "3.6" and python_version < "4.0"
pre-commit==2.17.0; python_full_version >= "3.6.1"
prometheus-client==0.13.1; python_version >= "3.7"
prompt-toolkit==3.0.28; python_full_version >= "3.6.2"
property-cached==1.6.4; python_version >= "3.7"
protobuf==3.19.4; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and python_version >= "3.5"
psaw==0.0.12; python_version >= "3"
ptyprocess==0.7.0; os_name != "nt" and python_version >= "3.8" and sys_platform != "win32"
pure-eval==0.2.2; python_version >= "3.8"
py==1.11.0; python_version >= "3.7" and python_full_version < "3.0.0" and implementation_name == "pypy" or python_full_version >= "3.5.0" and python_version >= "3.7" and implementation_name == "pypy"
py==1.11.0; python_full_version >= "3.7.0" and python_version >= "3.7" and implementation_name == "pypy"
pyally==1.1.2
pycodestyle==2.7.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pycoingecko==2.2.0
@@ -177,6 +182,7 @@ pydantic==1.9.0; python_full_version >= "3.6.1"
pyex==0.5.0
pyflakes==2.3.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
pygments==2.11.2; python_version >= "3.5"
pyhdfe==0.1.0; python_version >= "3.7"
pyimgur==0.6.0
pylint==2.12.2; python_full_version >= "3.6.2"
pyluach==1.4.0; python_version >= "3.7" and python_full_version >= "3.7.0"
@@ -190,22 +196,23 @@ pyparsing==3.0.7; python_version >= "3.7"
pyportfolioopt==1.5.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0"
pyprind==2.11.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
pyrsistent==0.18.1; python_version >= "3.7"
pytelegrambotapi==4.4.0
pytest-cov==3.0.0; python_version >= "3.6"
pytest-mock==3.7.0; python_version >= "3.7"
pytest-recording==0.12.0; python_version >= "3.5"
pytest==6.2.5; python_version >= "3.6"
python-binance==1.0.15
python-coinmarketcap==0.2
python-dateutil==2.8.2; python_full_version >= "3.7.1" and python_version >= "3.7" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5")
python-dateutil==2.8.2; python_full_version >= "3.7.1" and python_version >= "3.8" and python_full_version < "4.0.0" and python_version < "4.0" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5")
python-dotenv==0.19.2; python_version >= "3.5"
pytrends==4.8.0
pytz-deprecation-shim==0.1.0.post0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
pytz==2021.3; python_full_version >= "3.7.1" and python_version >= "3.7" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7")
pytz==2021.3; python_full_version >= "3.7.1" and python_version >= "3.8" and python_full_version < "4.0.0" and python_version < "4.0" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7")
pyupgrade==2.31.0; python_full_version >= "3.6.1"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.6"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pywinpty==1.1.6; os_name == "nt" and python_version >= "3.7"
pyyaml==6.0; python_version >= "3.7" and python_full_version >= "3.6.1"
pyzmq==22.3.0; python_full_version >= "3.6.1" and python_version >= "3.7"
pyzmq==22.3.0; python_full_version >= "3.7.0" and python_version >= "3.7"
qdldl==0.1.5.post0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
qtconsole==5.2.2; python_version >= "3.6"
qtpy==2.0.1; python_version >= "3.6"
@@ -218,7 +225,7 @@ requests==2.27.1; (python_version >= "2.7" and python_full_version < "3.0.0") or
rich==10.16.2; python_full_version >= "3.6.2" and python_full_version < "4.0.0"
robin-stocks==2.1.0; python_version >= "3"
scikit-learn==1.0.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
scipy==1.8.0; python_version >= "3.8" and python_version < "3.11" and python_full_version >= "3.6.1" 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")
scipy==1.8.0; python_version >= "3.8" and python_version < "3.11" and python_full_version >= "3.6.1" 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")
screeninfo==0.6.7
scs==3.2.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
seaborn==0.11.2; python_version >= "3.6"
@@ -226,7 +233,9 @@ selenium==3.141.0
send2trash==1.8.0; python_version >= "3.7"
sentiment-investor==2.1.0; python_version >= "3.8" and python_version < "4.0"
setuptools-scm==6.4.2; python_version >= "3.7"
six==1.16.0; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.0" and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.3.0") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7") and (python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.8")
six==1.16.0; python_full_version >= "3.7.1" and python_version >= "3.8" and python_full_version < "4.0.0" and python_version < "4.0" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.3.0") and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5") and (python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.8")
slack-bolt==1.11.6; python_version >= "3.6"
slack-sdk==3.15.2; python_full_version >= "3.6.0" and python_version >= "3.6"
smmap==5.0.0; python_version >= "3.7"
sniffio==1.2.0; python_full_version >= "3.6.2" and python_version >= "3.7"
snowballstemmer==2.2.0; python_version >= "3.7"
@@ -253,12 +262,12 @@ terminado==0.13.1; python_version >= "3.7"
testpath==0.5.0; python_version >= "3.7"
textwrap3==0.9.2; python_version >= "3.6"
thepassiveinvestor==1.0.10
threadpoolctl==3.1.0; python_version >= "3.7"
threadpoolctl==3.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"
tokenize-rt==4.2.1; python_full_version >= "3.6.1"
toml==0.10.2; python_full_version >= "3.6.2" and python_version >= "3.6" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7")
tomli==1.2.3; python_version >= "3.8" and python_full_version >= "3.6.2"
toolz==0.11.2; python_version >= "3.7" and python_full_version >= "3.7.0"
tornado==6.1; python_full_version >= "3.6.1" and python_version >= "3.7"
tornado==6.1; python_full_version >= "3.7.0" and python_version >= "3.7"
tqdm==4.62.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
tradingview-ta==3.2.10; python_version >= "3.6"
traitlets==5.1.1; python_full_version >= "3.7.0" and python_version >= "3.8"
@@ -274,7 +283,7 @@ tzlocal==4.1; python_version >= "3.6"
ujson==5.1.0; python_version >= "3.7"
unidecode==1.3.3; python_version >= "3.7"
update-checker==0.18.0; python_version >= "3.6" and python_version < "4.0"
urllib3==1.26.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
urllib3==1.26.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")
user-agent==0.1.10
uvicorn==0.17.5; python_version >= "3.7"
vadersentiment==3.3.2
@@ -282,12 +291,12 @@ valinvest==0.0.2; python_version >= "3.6"
vcrpy==4.1.1; python_version >= "3.5"
virtualenv==20.13.1; python_full_version >= "3.6.1"
voila==0.3.2; python_version >= "3.7"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.6"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.8"
webencodings==0.5.1; python_version >= "3.7"
websocket-client==1.2.3; python_version >= "3.8" and python_version < "4.0"
websockets==9.1; python_full_version >= "3.6.1" and python_version >= "3.7"
widgetsnbextension==3.5.2
wrapt==1.13.3; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5")
yarl==1.7.2; python_version >= "3.6"
wrapt==1.13.3; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7")
yarl==1.7.2; python_version >= "3.6" and python_full_version >= "3.8.0"
yfinance==0.1.70
zope.interface==5.4.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5"

267
bots/slack/run_slack.py Normal file
View File

@@ -0,0 +1,267 @@
import os
import logging
from typing import List, Pattern, Dict, Any, Set, Union
from dotenv import load_dotenv
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from bots.common.commands_dict import commands
from bots.helpers import ShowView
load_dotenv()
app = App(token=os.environ["GT_SLACK_APP_TOKEN"])
available_commands = list(commands.keys())
def get_syntax(selected: Dict[str, Any], cmd: str) -> str:
"""Returns the syntax for a given command
Parameters
----------
selected : Dict[str, Any]
The command object
cmd : str
The command that was attempted
Returns
---------
syntax : str
The syntax for the given command
"""
syntax = f"{cmd}/"
syntax += "/".join(selected.get("required", []))
return syntax
def get_arguments(
selected: Dict[str, Any], req_name: str, channel_id: str, user_id: str, client: Any
) -> None:
"""Returns the arguments for a given command
Parameters
----------
selected : Dict[str, Any]
The command object
req_name : str
The name of the requirement
channel_id : str
Slack channel id
user_id : str
Slack user id
client : Any
Client that sends messages to slack
"""
if req_name == "ticker":
message = "Please give a listed ticker"
elif req_name == "past_transactions_days":
message = "Please give the number of days as an integer"
elif req_name == "raw":
message = "Please type true or false"
else:
select = [str(x) for x in selected["required"].get(req_name, [])]
selections = ", ".join(select)
if len(selections) < 990:
selections = f"{selections[:990]}"
message = f"Options: {selections}"
payload = {"channel": channel_id, "username": user_id, "text": message}
client.chat_postMessage(**payload)
def send_options(
name: str,
items: Union[List[Any], Set[Any]],
channel_id: str,
user_id: str,
client: Any,
) -> None:
"""Sends the options for a user
Parameters
----------
name : str
The name of the section
items : List[str]
The items the user can select from
channel_id : str
Slack channel id
user_id : str
Slack user id
client : Any
Client that sends messages to slack
"""
message = name
clean = list(items)
clean.sort()
message += ", ".join(list(clean))
payload = {"channel": channel_id, "username": user_id, "text": message}
client.chat_postMessage(**payload)
@app.event("message")
def processMessage(event, client):
"""Process users' commands"""
channel_id = event.get("channel")
user_id = event.get("user")
text = event.get("text")
if text[0] == "!":
cmd = text[1:]
full_cmd = cmd.split("/")
if full_cmd[0] == "help":
help_text = (
"\n!disc-fidelity\n"
"!ins-last/ticker <num>\n"
"\n!opt-unu\n"
"!opt-iv/ticker\n"
"!opt-vsurf/ticker <z>\n"
"!opt-hist/ticker <strike> <expiration> <opt-typ>\n"
"!opt-oi/ticker <expiration> <min-sp> <max-sp>\n"
"!opt-vol/ticker <expiration> <min-sp> <max-sp>\n"
"!opt-overview/ticker <expiration> <min-sp> <max-sp>\n"
"!opt-chain/ticker <expiration> <opt-typ> <min-sp> <max-sp>\n"
"\n!ta-summary/ticker\n"
"!ta-view/ticker\n"
"!ta-recom/ticker\n"
"!ta-obv/ticker <START> <END>\n"
"!ta-fib/ticker <START> <END>\n"
"!ta-ad/ticker <OPEN> <START> <END>\n"
"!ta-cg/ticker <LENGTH> <START> <END>\n"
"!ta-fisher/ticker <LENGTH> <START> <END>\n"
"!ta-cci/ticker <LENGTH> <SCALAR> <START> <END>\n"
"!ta-ema/ticker <WINDOW> <OFFSET> <START> <END>\n"
"!ta-sma/ticker <WINDOW> <OFFSET> <START> <END>\n"
"!ta-wma/ticker <WINDOW> <OFFSET> <START> <END>\n"
"!ta-hma/ticker <WINDOW> <OFFSET> <START> <END>\n"
"!ta-zlma/ticker <WINDOW> <OFFSET> <START> <END>\n"
"!ta-aroon/ticker <LENGTH> <SCALAR> <START> <END>\n"
"!ta-adosc/ticker <OPEN> <FAST> <SLOW> <START> <END>\n"
"!ta-macd/ticker <FAST> <SLOW> <SIGNAL> <START> <END>\n"
"!ta-kc/ticker <LENGTH> <SCALAR> <MA-MODE> <START> <END>\n"
"!ta-adx/ticker <LENGTH> <SCALAR> <DRIFT> <START> <END>\n"
"!ta-rsi/ticker <LENGTH> <SCALAR> <DRIFT> <START> <END>\n"
"!ta-stoch/ticker <FAST-K> <SLOW-D> <SLOW-K> <START> <END>\n"
"!ta-bbands/ticker <LENGTH> <SCALAR> <MA-MODE> <START> <END>\n"
"!ta-donchian/ticker <LWR-LENGTH> <UPR-LENGTH> <START> <END>\n"
"\n!dd-est/ticker\n"
"!dd-sec/ticker\n"
"!dd-analyst/ticker\n"
"!dd-supplier/ticker\n"
"!dd-customer/ticker\n"
"!dd-arktrades/ticker\n"
"!dd-pt/ticker <RAW> <DATE-START>\n"
"\n!dps-hsi <NUM>\n"
"!dps-shorted/(NUM)\n"
"!dps-psi/ticker\n"
"!dps-spos/ticker\n"
"!dps-dpotc/ticker\n"
"!dps-pos <NUM> <SORT>\n"
"!dps-sidtc <NUM> <SORT>\n"
"!dps-ftd/ticker <DATE-START> <DATE-END>\n"
"\n!scr-presets-default\n"
"!scr-presets-custom\n"
"!scr-historical/(SIGNAL) <START>\n"
"!scr-overview/(PRESET) <SORT> <LIMIT> <ASCEND>\n"
"!scr-technical/(PRESET) <SORT> <LIMIT> <ASCEND>\n"
"!scr-valuation/(PRESET) <SORT> <LIMIT> <ASCEND>\n"
"!scr-financial/(PRESET) <SORT> <LIMIT> <ASCEND>\n"
"!scr-ownership/(PRESET) <SORT> <LIMIT> <ASCEND>\n"
"!scr-performance/(PRESET) <SORT> <LIMIT> <ASCEND>\n"
"\n!gov-histcont/ticker\n"
"!gov-lobbying/ticker <NUM>\n"
"!gov-toplobbying <NUM> <RAW>\n"
"!gov-lastcontracts <DAYS> <NUM>\n"
"!gov-contracts/ticker <DAYS> <RAW>\n"
"!gov-qtrcontracts <ANALYSIS> <NUM>\n"
"!gov-lasttrades <GOV-TYPE> <DAYS> <REP>\n"
"!gov-gtrades/ticker <GOV-TYPE> <MONTHS> <RAW>\n"
"!gov-topbuys <GOV-TYPE> <MONTHS> <NUM> <RAW>\n"
"!gov-topsells <GOV-TYPE> <MONTHS> <NUM> <RAW>\n"
"\n`<DAYS> = Past Transaction Days`\n"
"`<MONTHS> = Past Transaction Months`"
"\n!econ-softs\n"
"!econ-meats\n"
"!econ-energy\n"
"!econ-metals\n"
"!econ-grains\n"
"!econ-futures\n"
"!econ-usbonds\n"
"!econ-glbonds\n"
"!econ-indices\n"
"!econ-overview\n"
"!econ-feargreed\n"
"!econ-currencies\n"
"!econ-valuation <GROUP>\n"
"!econ-performance <GROUP>\n"
)
payload = {
"channel": channel_id,
"username": user_id,
"text": help_text,
}
client.chat_postMessage(**payload)
return True
group = full_cmd[0].split("-")[0]
parents = {x.split("-")[0] for x in commands}
if group in parents:
if full_cmd[0] in commands:
selected = commands[full_cmd[0]]
if len(full_cmd) != len(selected.get("required", [])) + 1:
syntax = get_syntax(selected, full_cmd[0])
payload = {
"channel": channel_id,
"username": user_id,
"text": f"Required syntax: {syntax}",
}
client.chat_postMessage(**payload)
return False
other_args = {}
for i, val in enumerate(full_cmd[1:]):
req_name = list(selected.get("required", {}).keys())[i]
required = selected.get("required", [])[req_name]
if isinstance(required, List) and required != [True, False]:
required = [str(x) for x in required]
if isinstance(val, str) and req_name in ["ticker"]:
val = val.upper()
elif isinstance(val, str) and req_name == "raw":
val = bool(val)
if (isinstance(required, List) and val not in required) or (
isinstance(required, Pattern) and not required.match(val)
):
syntax = get_syntax(selected, full_cmd[0])
payload = {
"channel": channel_id,
"username": user_id,
"text": f"{syntax}\nInvalid argument for: {req_name}",
}
client.chat_postMessage(**payload)
get_arguments(selected, req_name, channel_id, user_id, client)
return False
other_args[req_name] = val
func = selected["function"]
ShowView().slack(func, channel_id, user_id, client, **other_args)
return True
show_cmds = []
for command in commands:
if group == command[: len(group)]:
show_cmds.append(command)
send_options("Valid commands: ", show_cmds, channel_id, user_id, client)
return False
send_options("Valid categories: ", parents, channel_id, user_id, client)
return False
return False
if __name__ == "__main__":
# TODO: replace with GST logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
handler = SocketModeHandler(
app,
os.environ["GT_SLACK_BOT_TOKEN"],
)
handler.start()

View File

@@ -1,4 +1,5 @@
import os
import logging
from typing import List, Pattern, Dict, Any, Union, Set
import telebot
from dotenv import load_dotenv
@@ -55,8 +56,8 @@ def get_arguments(selected: Dict[str, Any], req_name: str, message: Any) -> None
The command object
req_name : str
The name of the requirement
group_id : str
The groupme chat id
message: Any
Object that contains telegram request info
"""
if req_name == "ticker":
@@ -82,8 +83,8 @@ def send_options(name: str, items: Union[List[Any], Set[Any]], message: Any) ->
The name of the section
items : List[str]
The items the user can select from
group_id : str
The groupme chat id
message: Any
Object that contains telegram request info
"""
help_message = name
clean = list(items)
@@ -120,12 +121,10 @@ Check the available commands with /cmds
bot.send_message(
chat_id=message.chat.id, text=text, reply_markup=markdown, parse_mode="MARKDOWN"
)
# bot.reply_to(markdown, text, parse_mode="MARKDOWN")
# bot.reply_to(message, text, parse_mode="MARKDOWN")
@bot.message_handler(commands=["cmds", "commands"])
def send_help(message):
def send_cmds(message):
helptext = (
"\n/disc_fidelity\n"
"/ins_last/ticker <num>\n"
@@ -259,4 +258,9 @@ def send_command(message):
return False
bot.infinity_polling()
if __name__ == "__main__":
# TODO: replace with GST logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
bot.infinity_polling()

60
poetry.lock generated vendored
View File

@@ -2729,6 +2729,22 @@ category = "main"
optional = false
python-versions = ">=3.7"
[[package]]
name = "pytelegrambotapi"
version = "4.4.0"
description = "Python Telegram bot api."
category = "main"
optional = true
python-versions = "*"
[package.dependencies]
requests = "*"
[package.extras]
PIL = ["pillow"]
json = ["ujson"]
redis = ["redis (>=3.4.1)"]
[[package]]
name = "pytest"
version = "6.2.5"
@@ -3220,6 +3236,36 @@ category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "slack-bolt"
version = "1.11.6"
description = "The Bolt Framework for Python"
category = "main"
optional = true
python-versions = ">=3.6"
[package.dependencies]
slack-sdk = ">=3.9.0,<4"
[package.extras]
adapter = ["boto3 (<=2)", "bottle (>=0.12,<1)", "chalice (>=1.26.5,<2)", "click (>=7,<8)", "CherryPy (>=18,<19)", "Django (>=3,<5)", "falcon (>=2,<4)", "fastapi (>=0.70.0,<1)", "Flask (>=1,<3)", "Werkzeug (>=2,<3)", "pyramid (>=1,<3)", "sanic (>=21,<22)", "starlette (>=0.14,<1)", "tornado (>=6,<7)", "uvicorn (<1)", "gunicorn (>=20,<21)", "websocket-client (>=1.2.3,<2)"]
adapter_testing = ["moto (>=3,<4)", "docker (>=5,<6)", "boddle (>=0.2,<0.3)", "Flask (>=1,<2)", "Werkzeug (>=1,<2)", "sanic-testing (>=0.7)", "requests (>=2,<3)"]
async = ["aiohttp (>=3,<4)", "websockets (>=8,<10)"]
testing = ["pytest (>=6.2.5,<7)", "pytest-cov (>=3,<4)", "Flask-Sockets (>=0.2,<1)", "Werkzeug (>=1,<2)", "itsdangerous (==2.0.1)", "black (==22.1.0)", "pytest-asyncio (<1)", "aiohttp (>=3,<4)"]
testing_without_asyncio = ["pytest (>=6.2.5,<7)", "pytest-cov (>=3,<4)", "Flask-Sockets (>=0.2,<1)", "Werkzeug (>=1,<2)", "itsdangerous (==2.0.1)", "black (==22.1.0)"]
[[package]]
name = "slack-sdk"
version = "3.15.2"
description = "The Slack API Platform SDK for Python"
category = "main"
optional = true
python-versions = ">=3.6.0"
[package.extras]
optional = ["aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "SQLAlchemy (>=1,<2)", "websockets (>=10,<11)", "websocket-client (>=1,<2)"]
testing = ["pytest (>=6.2.5,<7)", "pytest-asyncio (<1)", "Flask-Sockets (>=0.2,<1)", "Flask (>=1,<2)", "Werkzeug (<2)", "itsdangerous (==2.0.1)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=4,<5)", "black (==22.1.0)", "psutil (>=5,<6)", "databases (>=0.5)", "boto3 (<=2)", "moto (>=3,<4)"]
[[package]]
name = "smmap"
version = "5.0.0"
@@ -4076,12 +4122,13 @@ test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
[extras]
discord = ["pyimgur", "df2img", "fastapi", "uvicorn", "disnake", "PyNaCl"]
discord = ["pyimgur", "df2img", "fastapi", "uvicorn", "disnake", "PyNaCl", "pyTelegramBotAPI", "slack-bolt"]
prediction = ["tensorflow"]
[metadata]
lock-version = "1.1"
python-versions = "^3.8,<3.10"
content-hash = "1ef9648b6c7b7720bd8847def2696ab06cca0028839841f4e319500c6e1165b0"
[metadata.files]
absl-py = [
@@ -5946,6 +5993,9 @@ pyrsistent = [
{file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"},
{file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"},
]
pytelegrambotapi = [
{file = "pyTelegramBotAPI-4.4.0.tar.gz", hash = "sha256:e6f22356abebffe0a893dcf72fe09a0c8bdedad6f498c55a30c3dd32ce488e6a"},
]
pytest = [
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
{file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
@@ -6423,6 +6473,14 @@ six = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
slack-bolt = [
{file = "slack_bolt-1.11.6-py2.py3-none-any.whl", hash = "sha256:43aaadde470a8ed0d6737ed97b1f4f38a6ec53ab842eca076bad497cd8eb1d70"},
{file = "slack_bolt-1.11.6.tar.gz", hash = "sha256:7aad413b3d59884c74defe73f9d697ac13056c9cfcd2f5482c5eb8c9f9aa9322"},
]
slack-sdk = [
{file = "slack_sdk-3.15.2-py2.py3-none-any.whl", hash = "sha256:e1fa26786169176e707676decc287fd9d3d547bbc43c0a1a4f99eb373b07da94"},
{file = "slack_sdk-3.15.2.tar.gz", hash = "sha256:128f3bb0b5b91454a3d5f140a61f3db370a0e1b50ffe0a8d9e9ebe0e894faed7"},
]
smmap = [
{file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"},
{file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"},

4
pyproject.toml vendored
View File

@@ -84,6 +84,8 @@ fastapi = {version = "^0.73.0", optional = true}
uvicorn = {version = "^0.17.1", optional = true}
disnake = {version = "^2.3.0", optional = true}
PyNaCl = {version = "^1.5.0", optional = true}
pyTelegramBotAPI = {version = "^4.4.0", optional = true}
slack-bolt = {version = "^1.11.6", optional = true}
ascii-magic = "^1.6"
squarify = "^0.4.3"
finnhub-python = "^2.4.10"
@@ -117,7 +119,7 @@ pytest-cov = "^3.0.0"
[tool.poetry.extras]
prediction = ["tensorflow"]
discord = ["pyimgur", "df2img", "fastapi", "uvicorn", "disnake", "PyNaCl"]
discord = ["pyimgur", "df2img", "fastapi", "uvicorn", "disnake", "PyNaCl", "pyTelegramBotAPI", "slack_bolt"]
[build-system]
requires = ["poetry-core>=1.0.0"]

View File

@@ -19,3 +19,12 @@ For local or new remote server installations, follow the instructions here: http
Server administrators for Discord can invite the GameStonks Bot to their servers by clicking the invite link:
https://discord.com/oauth2/authorize?client_id=927232119346962513&permissions=510500797553&scope=bot%20applications.commands
WIP
Bot currently available for the following platforms:
- Discord
- Telegram
- Groupme
- Slack

20
website/content/bot/groupme/_index.md vendored Normal file
View File

@@ -0,0 +1,20 @@
---
geekdocCollapseSection: true
---
{{< toc-tree >}}
WIP
[GroupmeDemo.mov.zip](https://github.com/GamestonkTerminal/GamestonkTerminal/files/8178584/Screen.Recording.2022-03-03.at.9.23.58.AM.mov.zip)
No installation or signup is required, nor is there a need to be in a server setting to use the bot. Any user call it through direct messaging / commands to: [t.me/GamestonkTerminalBot](https://t.me/GamestonkTerminalBot)
You can also invite the bot
Alternatively, the bot can be installed locally, or on a privately-hosted server, using the installation instructions found here:
https://github.com/GamestonkTerminal/GamestonkTerminal/blob/main/bots/README.md
Learn how to use the GameStonksBot in less than five minutes, by reading the Introduction page.
Questions and feedback are welcome in the [official support server](https://discord.com/invite/Up2QGbMKHY)

20
website/content/bot/slack/_index.md vendored Normal file
View File

@@ -0,0 +1,20 @@
---
geekdocCollapseSection: true
---
{{< toc-tree >}}
WIP
![Slack Bot](https://user-images.githubusercontent.com/43375532/157667922-f0d9abdb-a39b-4593-b8ca-7f4f169f922f.png)
No installation or signup is required, nor is there a need to be in a server setting to use the bot. Any user call it through direct messaging / commands to: [t.me/GamestonkTerminalBot](https://t.me/GamestonkTerminalBot)
You can also invite the bot
Alternatively, the bot can be installed locally, or on a privately-hosted server, using the installation instructions found here:
https://github.com/GamestonkTerminal/GamestonkTerminal/blob/main/bots/README.md
Learn how to use the GameStonksBot in less than five minutes, by reading the Introduction page.
Questions and feedback are welcome in the [official support server](https://discord.com/invite/Up2QGbMKHY)

20
website/content/bot/telegram/_index.md vendored Normal file
View File

@@ -0,0 +1,20 @@
---
geekdocCollapseSection: true
---
{{< toc-tree >}}
WIP
![Telegram Bot](https://user-images.githubusercontent.com/43375532/157494575-72d7202f-7f1c-4093-a815-a2c3aac21835.png)
No installation or signup is required, nor is there a need to be in a server setting to use the bot. Any user call it through direct messaging / commands to: [t.me/GamestonkTerminalBot](https://t.me/GamestonkTerminalBot)
You can also invite the bot
Alternatively, the bot can be installed locally, or on a privately-hosted server, using the installation instructions found here:
https://github.com/GamestonkTerminal/GamestonkTerminal/blob/main/bots/README.md
Learn how to use the GameStonksBot in less than five minutes, by reading the Introduction page.
Questions and feedback are welcome in the [official support server](https://discord.com/invite/Up2QGbMKHY)

View File

@@ -1233,6 +1233,12 @@ main:
- name: "bot"
ref: "/bot"
sub:
- name: "GroupMe"
ref: "/bot/groupme"
- name: "Slack"
ref: "/bot/slack"
- name: "Telegram"
ref: "/bot/telegram"
- name: "Discord"
ref: "/bot/discord"
sub: