Create a packaged app bundle with Pyinstaller (#1525)

* Add dashboard widget assets

* Add ipywidgets and ipyflex to project

* Add currencies dashboard notebook

* Update docs and docstrings

* Add pyinstaller to project deps

* Add pyinstaller artifacts to gitignore

* Fix linter errors in terminal.py

* Update cspell hook and action with a pyinstaller specific word

* Add pyinstaller specfile and artifacts

* Add splashscreen image

* Add app icon

* adding splash screen support to terminal.spec and terminal.py

* Restore the conda env build files

* Sync deps

* Add border to the splashscreen image

* Clean up terminal launcher

* Add support for default feature flags in packages apps

* Fix types and linting

* Add splashscreen management to app bootup

* Check prediction feature flag when entering crypto/pred

* Update pyinstaller spec file

* fix .spec file to work for splash and icon - removed the ".."

* Allows to export when using installer (#1568)

* fix export for packaged apps

* fix filename

* Git : replace commit_hash when it is set in config_terminal

* Add update of the git commit hash in gtff default during build

* Add packaged app name and feature flag to logs

* Add platform specific icon assignment

* Add macOS build assets

* Add tensorflow to hidden imports

* Move LOGGING_COMMIT_HASH to gtff

* Adding files/folders needed to .spec  and pyinstaller folder. This will make certain commands work again.

* Linting

* Workflow : ignore ./build/pyinstaller from codespell

* Workflow : exclude ./build/pyinstaller from flake8

* Poetry + Workflow : add types-six

* Pyinstaller : remove property_cached, user_agent and vaderSentiment

* Revert "Pyinstaller : remove property_cached, user_agent and vaderSentiment"

This reverts commit dbb3e2b810.

* Clean up local paths in specfile

* Validate deps have correct Jinja version (they do)

* Fix logging commit hash to be set correctly for the logger to see it

Co-authored-by: Andrew <andrew.kenreich@gmail.com>
Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
Co-authored-by: Chavithra PARANA <chavithra@gmail.com>
This commit is contained in:
Theodore Aptekarev
2022-03-29 02:35:56 +03:00
committed by GitHub
parent 8bdc35e82f
commit ab4de1dd70
45 changed files with 18083 additions and 208 deletions

View File

@@ -29,11 +29,11 @@ jobs:
- run: python custom_pre_commit/check_doc.py --ignore-files=settings_controller.py,keys_controller.py,degiro_controller.py,oanda_controller.py --ignore-commands=login,al_swe,info_swe,goodness,resources,yf,yolo
- run: pip install bandit black codespell flake8 mypy pyupgrade safety pylint==2.12.2
- run: pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools
- run: pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools types-six
- run: bandit -x ./tests -r . || true
- run: black --check .
- run: codespell --ignore-words-list=zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml
- run: flake8 . --count --ignore=E203,W503 --max-line-length=122 --show-source --statistics
- run: codespell --ignore-words-list=zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller
- run: flake8 . --count --ignore=E203,W503 --max-line-length=122 --show-source --statistics --exclude ./build/pyinstaller
- run: mypy --ignore-missing-imports --exclude="/setup\.py$" .
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py
- run: safety check

5
.gitignore vendored
View File

@@ -30,6 +30,11 @@ gamestonk_terminal/portfolio/portfolios/*
*.swp
*.http
# pyinstaller artifacts
*.pyo
dist/*
build/terminal
# Jupyter Lab Extension build files
jupyterlab/*/*.bundle.*
jupyterlab/*/lib/

View File

@@ -26,7 +26,7 @@ repos:
rev: 4.0.1
hooks:
- id: flake8
entry: flake8 --ignore=E203,W503 --max-line-length=122
entry: flake8 --ignore=E203,W503 --max-line-length=122 --exclude ./build/pyinstaller/*
- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
hooks:
@@ -34,9 +34,9 @@ repos:
entry: codespell
args:
[
"--ignore-words-list=zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian",
"--ignore-words-list=zlot,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas",
"--quiet-level=2",
"--skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml",
"--skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,build/pyinstaller/*",
]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v0.940"

89
bots/requirements.txt vendored
View File

@@ -1,23 +1,23 @@
aiohttp==3.8.1; python_version >= "3.6" and python_full_version >= "3.8.0"
aiosignal==1.2.0; python_version >= "3.6" and python_full_version >= "3.8.0"
aiosignal==1.2.0; python_version >= "3.6"
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"
appnope==0.1.2; platform_system == "Darwin" and python_version >= "3.8" and sys_platform == "darwin" and python_full_version >= "3.6.2"
argon2-cffi-bindings==21.2.0; python_version >= "3.7"
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==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.11.1; python_full_version >= "3.6.2"
asttokens==2.0.5; python_full_version >= "3.6.2" and python_version >= "3.8"
asttokens==2.0.5; python_version >= "3.8"
async-generator==1.10; python_version >= "3.7" and python_version < "4.0"
async-timeout==4.0.2; python_version >= "3.6" and python_full_version >= "3.8.0"
async-timeout==4.0.2; python_version >= "3.6"
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_full_version >= "3.8.0" and python_version >= "3.7" and (python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.5.0") 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")
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"
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_full_version >= "3.6.2" and python_version >= "3.8"
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.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"
@@ -28,17 +28,17 @@ boto3==1.21.26; python_version >= "3.6"
botocore==1.24.26; 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")
cffi==1.15.0; python_version >= "3.7"
certifi==2021.10.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4"
cffi==1.15.0
cfgv==3.3.1; python_full_version >= "3.6.1"
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")
charset-normalizer==2.0.12; python_full_version >= "3.6.0" and python_version >= "3.6"
click==8.0.4; python_version >= "3.7" 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 >= "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.8"
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")
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"
cryptography==36.0.2; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
cryptography==36.0.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.6"
cssselect==1.1.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
cvxpy==1.2.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.7"
cycler==0.11.0; python_version >= "3.7"
@@ -46,7 +46,7 @@ cython==0.29.28; python_version >= "3.7" and python_full_version < "3.0.0" and s
dateparser==1.1.1; python_version >= "3.5"
datetime==4.4; python_version >= "3.5"
debugpy==1.6.0; python_version >= "3.7"
decorator==5.1.1; python_full_version >= "3.6.2" and python_version >= "3.8" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5")
decorator==5.1.1; python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.8"
defusedxml==0.7.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
degiro-connector==2.0.18; python_full_version >= "3.7.1" and python_full_version < "4.0.0"
deprecation==2.1.0
@@ -57,10 +57,10 @@ distlib==0.3.4; python_full_version >= "3.6.1"
dnspython==2.2.1; 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.7"
entrypoints==0.4; python_full_version >= "3.7.0" and python_version >= "3.7"
entrypoints==0.4; python_full_version >= "3.6.1" and python_version >= "3.7"
et-xmlfile==1.1.0; python_version >= "3.6"
exchange-calendars==3.6.1; python_version >= "3.7" and python_full_version >= "3.7.0"
executing==0.8.3; python_full_version >= "3.6.2" and python_version >= "3.8"
executing==0.8.3; python_version >= "3.8"
fastapi==0.73.0; python_full_version >= "3.6.1"
fear-greed-index==0.1.4; python_version >= "3.7"
ffn==0.3.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
@@ -75,7 +75,7 @@ formulaic==0.3.2; 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" and python_full_version >= "3.8.0"
frozenlist==1.3.0; python_version >= "3.7"
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"
@@ -85,7 +85,7 @@ h11==0.13.0; python_version >= "3.7" and python_version < "4.0" and python_full_
hijri-converter==2.2.3; python_version >= "3.6"
holidays==0.11.3.1; python_version >= "3.6"
identify==2.4.12; python_version >= "3.7" and python_full_version >= "3.6.1"
idna==3.3; python_full_version >= "3.8.0" and python_version >= "3.8" and python_version < "4" 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")
idna==3.3; python_full_version >= "3.6.2" and python_version >= "3.7" and python_version < "4"
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"
@@ -98,15 +98,15 @@ ipython==8.1.1; python_full_version >= "3.6.2" and python_version >= "3.8"
ipywidgets==7.7.0
iso8601==0.1.16
isort==5.10.1; python_full_version >= "3.6.2" and python_version < "4.0"
jedi==0.18.1; python_full_version >= "3.6.2" and python_version >= "3.8"
jinja2==3.1.0; python_version >= "3.7"
jedi==0.18.1; python_version >= "3.8"
jinja2==3.0.3; python_version >= "3.7"
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"
joblib==1.1.0; 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.3; python_version >= "3.6"
jupyter-core==4.9.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-core==4.9.2; python_full_version >= "3.6.1" and python_version >= "3.7"
jupyter-server==1.15.6; python_version >= "3.7"
jupyter==1.0.0
jupyterlab-pygments==0.1.2; python_version >= "3.7"
@@ -122,7 +122,7 @@ lxml==4.8.0; python_version >= "3.7" and python_full_version < "3.0.0" or python
m2r2==0.2.8; python_version >= "3.7"
markdown-it-py==1.1.0; python_version >= "3.6" and python_version < "4.0"
markupsafe==2.1.1; python_version >= "3.7"
matplotlib-inline==0.1.3; python_full_version >= "3.6.2" and python_version >= "3.8"
matplotlib-inline==0.1.3; python_version >= "3.8"
matplotlib==3.5.1; python_version >= "3.7"
mccabe==0.6.1; python_full_version >= "3.6.2"
mdit-py-plugins==0.2.8; python_version >= "3.6" and python_version < "4.0"
@@ -130,7 +130,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" and python_full_version >= "3.8.0"
multidict==6.0.2; python_version >= "3.7"
multitasking==0.0.10
mypy-extensions==0.4.3; python_version >= "3.7" and python_full_version >= "3.6.2"
mypy==0.930; python_version >= "3.6"
@@ -158,12 +158,12 @@ pandas-ta==0.3.14b
pandas==1.3.5; python_full_version >= "3.7.1"
pandocfilters==1.5.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
papermill==2.3.4; python_version >= "3.6"
parso==0.8.3; python_full_version >= "3.6.2" and python_version >= "3.8"
parso==0.8.3; python_version >= "3.8"
pathspec==0.9.0; python_full_version >= "3.6.2"
patsy==0.5.2; python_version >= "3.7"
pbr==5.8.1; python_version >= "3.7"
pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8" and python_full_version >= "3.6.2"
pickleshare==0.7.5; python_full_version >= "3.6.2" and python_version >= "3.8"
pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8"
pickleshare==0.7.5; python_version >= "3.8"
pillow==9.0.1; python_version >= "3.7" and python_version < "4"
platformdirs==2.5.1; python_version >= "3.7" and python_full_version >= "3.6.2"
plotly==5.6.0; python_version >= "3.6"
@@ -178,13 +178,13 @@ 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"
psutil==5.9.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
ptyprocess==0.7.0; os_name != "nt" and python_version >= "3.8" and sys_platform != "win32" and python_full_version >= "3.6.2"
pure-eval==0.2.2; python_full_version >= "3.6.2" and python_version >= "3.8"
py==1.11.0; python_full_version >= "3.7.0" and python_version >= "3.7" and implementation_name == "pypy"
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"
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
pycparser==2.21; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" and os_name == "nt" and implementation_name != "pypy" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" and os_name == "nt" and implementation_name != "pypy"
pycparser==2.21; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
pydantic==1.8.2; 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"
@@ -198,13 +198,13 @@ pymongo==3.11.0; (python_version >= "2.7" and python_full_version < "3.0.0") or
pynacl==1.5.0; python_version >= "3.6"
pyobjc-core==8.4.1; python_version >= "3.6" and sys_platform == "darwin"
pyobjc-framework-cocoa==8.4.1; python_version >= "3.6" and sys_platform == "darwin"
pyopenssl==22.0.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
pyopenssl==22.0.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.6"
pyotp==2.6.0; python_version >= "3"
pyparsing==3.0.7; python_version >= "3.7"
pyportfolioopt==1.5.2; 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"
pysocks==1.7.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4"
pytelegrambotapi==4.4.0
pytest-cov==3.0.0; python_version >= "3.6"
pytest-mock==3.7.0; python_version >= "3.7"
@@ -212,16 +212,16 @@ 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_full_version < "4.0.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") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6")
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") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6")
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==2022.1; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.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")
pytz==2022.1; 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")
pyupgrade==2.31.1; python_version >= "3.7"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7"
pywinpty==2.0.5; 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.7.0" and python_version >= "3.7"
pyzmq==22.3.0; python_full_version >= "3.6.1" 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.7"
qtconsole==5.2.2; python_version >= "3.6"
qtpy==2.0.1; python_version >= "3.6"
@@ -235,7 +235,7 @@ 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"
s3transfer==0.5.2; python_version >= "3.6"
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") and (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")
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.7"
seaborn==0.11.2; python_version >= "3.6"
@@ -243,7 +243,7 @@ selenium==4.1.3; python_version >= "3.7" and python_version < "4.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.8" and python_full_version < "4.0.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.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5")
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.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5") 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")
slack-bolt==1.13.0; 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"
@@ -262,7 +262,7 @@ sphinxcontrib-qthelp==1.0.3; python_version >= "3.7"
sphinxcontrib-serializinghtml==1.1.5; python_version >= "3.7"
squarify==0.4.3
sseclient==0.0.27
stack-data==0.2.0; python_full_version >= "3.6.2" and python_version >= "3.8"
stack-data==0.2.0; python_version >= "3.8"
starlette==0.17.1; python_version >= "3.6" and python_full_version >= "3.6.1"
statsmodels==0.13.2; python_version >= "3.7"
stevedore==3.5.0; python_version >= "3.7"
@@ -273,12 +273,12 @@ terminado==0.13.3; python_version >= "3.7"
testpath==0.6.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" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
threadpoolctl==3.1.0; python_version >= "3.7"
tokenize-rt==4.2.1; python_full_version >= "3.6.2" and python_version >= "3.7"
toml==0.10.2; python_full_version >= "3.6.1" 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==2.0.1; python_version >= "3.7" and python_full_version >= "3.6.2" and python_version < "3.11"
toolz==0.11.2; python_version >= "3.7" and python_full_version >= "3.7.0"
tornado==6.1; python_full_version >= "3.7.0" and python_version >= "3.7"
tornado==6.1; python_full_version >= "3.6.1" and python_version >= "3.7"
tqdm==4.63.1; 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"
@@ -289,6 +289,7 @@ types-pytz==2021.3.6
types-pyyaml==6.0.5
types-requests==2.27.14
types-setuptools==57.4.11
types-six==1.16.12
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")
@@ -297,7 +298,7 @@ ujson==5.1.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"
urllib3==1.26.9; 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") and (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 < "4" and python_version >= "3.7") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.6")
urllib3==1.26.9; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
user-agent==0.1.10
uvicorn==0.17.6; python_version >= "3.7"
vadersentiment==3.3.2
@@ -305,13 +306,13 @@ valinvest==0.0.2; python_version >= "3.6"
vcrpy==4.1.1; python_version >= "3.5"
virtualenv==20.13.4; python_full_version >= "3.6.1"
voila==0.3.4; python_version >= "3.7"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.8"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.6"
webencodings==0.5.1; python_version >= "3.7"
websocket-client==1.3.1; 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.6.0
wrapt==1.14.0; 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")
wsproto==1.1.0; python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.7.0"
yarl==1.7.2; python_version >= "3.6" and python_full_version >= "3.8.0"
yarl==1.7.2; python_version >= "3.6"
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"

30
build/pyinstaller/GTFF_DEFAULTS.json vendored Normal file
View File

@@ -0,0 +1,30 @@
{
"GTFF_PACKAGED_APPLICATION": "True",
"GTFF_LOGGING_COMMIT_HASH": "sha:15bde4e2",
"GTFF_ENABLE_PREDICT": "False",
"GTFF_ENABLE_CHECK_API": "True",
"GTFF_ENABLE_THOUGHTS_DAY": "False",
"GTFF_REMEMBER_CONTEXTS": "True",
"GTFF_USE_FLAIR": ":bb",
"GTFF_USE_WATERMARK": "True",
"GTFF_USE_CMD_LOCATION_FIGURE": "True",
"GTFF_USE_PROMPT_TOOLKIT": "True",
"GTFF_USE_COLOR": "True",
"GTFF_USE_ION": "True",
"GTFF_USE_PLOT_AUTOSCALING": "False",
"GTFF_ENABLE_RICH": "True",
"GTFF_ENABLE_RICH_PANEL": "True",
"GT_MPLSTYLE": "dark",
"GT_MPFSTYLE": "dark",
"GT_RICHSTYLE": "dark",
"GT_LOGGING_VERBOSITY": "0",
"GT_DEBUG_MODE": "False",
"GTFF_LOG_COLLECTION": "False",
"GTFF_ONLY_SEND_FILE_SIZE": "False",
"GTFF_USE_TABULATE_DF": "True",
"GTFF_USE_CLEAR_AFTER_CMD": "False",
"GTFF_USE_DATETIME": "True",
"GTFF_OPEN_REPORT_AS_HTML": "True",
"GTFF_ENABLE_QUICK_EXIT": "False",
"GTFF_ENABLE_EXIT_AUTO_HELP": "False"
}

29
build/pyinstaller/build4mac.sh vendored Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
DISK_IMAGE_NAME="Gamestonk Terminal"
# exit when any command fails
set -e
# Clean Up artifacts from previous builds
rm -rf build/terminal && rm -rf dist && rm -rf DMG
pyinstaller build/pyinstaller/terminal.spec
# Create the folder that is used for packaging
mkdir DMG
# Copy relevant artifacts to the packaging folder
cp -r build/pyinstaller/macOS_package_assets/* DMG/
mv dist/GamestonkTerminal DMG/"$DISK_IMAGE_NAME"/Gamestonk
# Copy launcher and other artifacts to the
hdiutil create \
-volname "$DISK_IMAGE_NAME" \
-srcfolder DMG \
-ov \
-format UDZO \
"$DISK_IMAGE_NAME".dmg
# Clean Up artifacts from this build
rm -rf build/terminal && rm -rf dist && rm -rf DMG

1
build/pyinstaller/frozendict/VERSION vendored Normal file
View File

@@ -0,0 +1 @@
2.3.0

View File

@@ -0,0 +1,19 @@
#!/bin/bash
clear
echo " _ _ _ "
echo " | | | (_) "
echo " | | ___ __ _ __| |_ _ __ __ _ "
echo " | | / _ \ / _\` |/ _\` | | '_ \ / _\` | "
echo " | |___| (_) | (_| | (_| | | | | | (_| |_ _ _ "
echo " |______\___/ \__,_|\__,_|_|_| |_|\__, (_|_|_)"
echo " __/ | "
echo " |___/ "
BOOTUP_MESSAGE="
The boot up process might take a while. Please be patient...
"
echo "$BOOTUP_MESSAGE"
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
"$SCRIPTDIR"/Gamestonk/GamestonkTerminal

View File

@@ -0,0 +1 @@
MOVE THE GAMESTONK TERMINAL FOLDER TO THE APPLICATIONS FOLDER

View File

@@ -0,0 +1,161 @@
import asyncio
import functools
import pkg_resources
import threading
import weakref
from time import time
# pylint: skip-file
__author__ = "Martin Larralde"
__email__ = "martin.larralde@ens-paris-saclay.fr"
__license__ = "BSD"
__version__ = (
pkg_resources.resource_string(__name__, "_version.txt").decode("utf-8").strip()
)
class cached_property(property):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Deleting the attribute resets the property.
Source: https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76
""" # noqa
_sentinel = object()
_update_wrapper = functools.update_wrapper
def __init__(self, func):
self.cache = weakref.WeakKeyDictionary()
self.func = func
self._update_wrapper(func)
def __get__(self, obj, cls):
if obj is None:
return self
if asyncio and asyncio.iscoroutinefunction(self.func):
return self._wrap_in_coroutine(obj)
value = self.cache.get(obj, self._sentinel)
if value is self._sentinel:
value = self.cache[obj] = self.func(obj)
return value
def __set_name__(self, owner, name):
self.__name__ = name
def __set__(self, obj, value):
self.cache[obj] = value
def __delete__(self, obj):
del self.cache[obj]
def _wrap_in_coroutine(self, obj):
@functools.wraps(obj)
@asyncio.coroutine
def wrapper():
value = self.cache.get(obj, self._sentinel)
if value is self._sentinel:
self.cache[obj] = value = asyncio.ensure_future(self.func(obj))
return value
return wrapper()
class threaded_cached_property(cached_property):
"""
A cached_property version for use in environments where multiple threads
might concurrently try to access the property.
"""
def __init__(self, func):
super().__init__(func)
self.lock = threading.RLock()
def __get__(self, obj, cls):
if obj is None:
return self
with self.lock:
return super().__get__(obj, cls)
def __set__(self, obj, value):
with self.lock:
super().__set__(obj, value)
def __delete__(self, obj):
with self.lock:
super().__delete__(obj)
class cached_property_with_ttl(cached_property):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Setting the ttl to a number expresses how long
the property will last before being timed out.
"""
def __init__(self, ttl=None):
if callable(ttl):
func = ttl
ttl = None
else:
func = None
self.ttl = ttl
super().__init__(func)
def __call__(self, func):
super().__init__(func)
return self
def __get__(self, obj, cls):
if obj is None:
return self
now = time()
if obj in self.cache:
value, last_updated = self.cache[obj]
if not self.ttl or self.ttl > now - last_updated:
return value
value, _ = self.cache[obj] = (self.func(obj), now)
return value
def __set__(self, obj, value):
super().__set__(obj, (value, time()))
# Aliases to make cached_property_with_ttl easier to use
cached_property_ttl = cached_property_with_ttl
timed_cached_property = cached_property_with_ttl
class threaded_cached_property_with_ttl(
cached_property_with_ttl, threaded_cached_property
):
"""
A cached_property version for use in environments where multiple threads
might concurrently try to access the property.
"""
def __init__(self, ttl=None):
super().__init__(ttl)
self.lock = threading.RLock()
def __get__(self, obj, cls):
with self.lock:
return super().__get__(obj, cls)
def __set__(self, obj, value):
with self.lock:
return super().__set__(obj, value)
def __delete__(self, obj):
with self.lock:
return super().__delete__(obj)
# Alias to make threaded_cached_property_with_ttl easier to use
threaded_cached_property_ttl = threaded_cached_property_with_ttl
timed_threaded_cached_property = threaded_cached_property_with_ttl

View File

@@ -0,0 +1 @@
1.6.4

147
build/pyinstaller/terminal.spec vendored Normal file
View File

@@ -0,0 +1,147 @@
# -*- mode: python ; coding: utf-8 -*-
import os
import sys
import json
from PyInstaller.compat import is_darwin, is_win
from PyInstaller.building.api import PYZ, EXE, COLLECT
from PyInstaller.building.splash import Splash
from PyInstaller.building.build_main import Analysis
from gamestonk_terminal.loggers import get_commit_hash
NAME = "GamestonkTerminal"
build_type = (
os.getenv("GT_BUILD_TYPE") if bool(os.getenv("GT_BUILD_TYPE")) else "folder"
)
# Local python environment packages folder
pathex = os.path.join(
os.path.dirname(sys.executable), "..", "lib", "python3.8", "site-packages"
)
# Get latest commit
commit_hash = get_commit_hash()
build_assets_folder = os.path.join(os.getcwd(), "build", "pyinstaller")
default_feature_flags_path = os.path.join(build_assets_folder, "GTFF_DEFAULTS.json")
with open(default_feature_flags_path, "r") as f:
default_gtff = json.load(f)
default_gtff["GTFF_LOGGING_COMMIT_HASH"] = commit_hash
with open(default_feature_flags_path, "w") as f:
json.dump(default_gtff, f, indent=4)
# Files that are explicitly pulled into the bundle
added_files = [
(os.path.join(os.getcwd(), "gamestonk_terminal"), "gamestonk_terminal"),
(os.path.join(os.getcwd(), "routines"), "routines"),
(os.path.join(os.getcwd(), "styles"), "styles"),
("property_cached", "property_cached"),
("user_agent", "user_agent"),
("vaderSentiment", "vaderSentiment"),
(
os.path.join("frozendict", "VERSION"),
"frozendict",
),
("GTFF_DEFAULTS.json", "gamestonk_terminal"),
]
# Python libraries that are explicitly pulled into the bundle
hidden_imports = [
"sklearn.utils._cython_blas",
"sklearn.utils._typedefs",
"sklearn.neighbors.quad_tree",
"sklearn.tree._utils",
"sklearn.neighbors._partition_nodes",
"squarify",
"linearmodels",
"user_agent",
"vaderSentiment",
"frozendict",
"boto3",
"textwrap3",
"pyEX",
"tensorflow",
]
analysis_kwargs = dict(
scripts=[os.path.join(os.getcwd(), "terminal.py")],
pathex=[pathex, "."],
binaries=[],
datas=added_files,
hiddenimports=hidden_imports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False,
)
a = Analysis(**analysis_kwargs)
pyz = PYZ(a.pure, a.zipped_data, cipher=analysis_kwargs["cipher"])
exe_args = [
pyz,
a.scripts,
[],
]
exe_kwargs = dict(
name=NAME,
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
upx_exclude=[],
console=True,
disable_windowed_traceback=False,
target_arch="x86_64",
codesign_identity=None,
entitlements_file=None,
)
# Packaging settings
if build_type == "onefile":
exe_args += [a.binaries, a.zipfiles, a.datas]
exe_kwargs["runtime_tmpdir"] = None
elif build_type == "folder":
exe_kwargs["exclude_binaries"] = True
collect_args = [
a.binaries,
a.zipfiles,
a.datas,
]
collect_kwargs = dict(
strip=False,
upx=True,
upx_exclude=[],
name=NAME,
)
# Platform specific settings
if is_win:
splash = Splash(
os.path.join(os.getcwd(), "images", "splashscreen.png"),
binaries=a.binaries,
datas=a.datas,
text_pos=(200, 400),
text_size=12,
text_color="white",
)
exe_args += [splash, splash.binaries]
exe_kwargs["icon"] = (os.path.join(os.getcwd(), "images", "gst_app.ico"),)
if is_darwin:
exe_kwargs["icon"] = (
os.path.join(os.getcwd(), "images", "GamestonkTerminal.icns"),
)
exe = EXE(*exe_args, **exe_kwargs)
if build_type == "folder":
coll = COLLECT(*([exe] + collect_args), **collect_kwargs)

View File

@@ -0,0 +1,4 @@
from user_agent.base import * # noqa: F403 pylint: disable=wildcard-import
from user_agent.error import * # noqa: F403 pylint: disable=wildcard-import
__version__ = "0.1.10"

View File

@@ -0,0 +1,623 @@
# pylint: skip-file
"""
This module is for generating random, valid web navigator's
configs & User-Agent HTTP headers.
Functions:
* generate_user_agent: generates User-Agent HTTP header
* generate_navigator: generates web navigator's config
* generate_navigator_js: generates web navigator's config with keys
identical keys used in navigator object
FIXME:
* add Edge, Safari and Opera support
* add random config i.e. windows is more common than linux
Specs:
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox
* http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
* https://developer.chrome.com/multidevice/user-agent
* http://www.javascriptkit.com/javatutors/navigator.shtml
Release history:
* https://en.wikipedia.org/wiki/Firefox_release_history
* https://en.wikipedia.org/wiki/Google_Chrome_release_history
* https://en.wikipedia.org/wiki/Internet_Explorer_version_history
* https://en.wikipedia.org/wiki/Android_version_history
Lists of user agents:
* http://www.useragentstring.com/
* http://www.user-agents.org/
* http://www.webapps-online.com/online-tools/user-agent-strings
"""
# pylint: enable=line-too-long
from random import SystemRandom
from datetime import datetime, timedelta
from itertools import product
import six
from .warning import warn
# pylint: disable=unused-import
from .device import SMARTPHONE_DEV_IDS, TABLET_DEV_IDS
# pylint: enable=unused-import
from .error import InvalidOption
__all__ = ["generate_user_agent", "generate_navigator", "generate_navigator_js"]
randomizer = SystemRandom()
DEVICE_TYPE_OS = {
"desktop": ("win", "mac", "linux"),
"smartphone": ("android",),
"tablet": ("android",),
}
OS_DEVICE_TYPE = {
"win": ("desktop",),
"linux": ("desktop",),
"mac": ("desktop",),
"android": ("smartphone", "tablet"),
}
DEVICE_TYPE_NAVIGATOR = {
"desktop": ("chrome", "firefox", "ie"),
"smartphone": ("firefox", "chrome"),
"tablet": ("firefox", "chrome"),
}
NAVIGATOR_DEVICE_TYPE = {
"ie": ("desktop",),
"chrome": ("desktop", "smartphone", "tablet"),
"firefox": ("desktop", "smartphone", "tablet"),
}
OS_PLATFORM = {
"win": (
"Windows NT 5.1", # Windows XP
"Windows NT 6.1", # Windows 7
"Windows NT 6.2", # Windows 8
"Windows NT 6.3", # Windows 8.1
"Windows NT 10.0", # Windows 10
),
"mac": (
"Macintosh; Intel Mac OS X 10.8",
"Macintosh; Intel Mac OS X 10.9",
"Macintosh; Intel Mac OS X 10.10",
"Macintosh; Intel Mac OS X 10.11",
"Macintosh; Intel Mac OS X 10.12",
),
"linux": (
"X11; Linux",
"X11; Ubuntu; Linux",
),
"android": (
"Android 4.4", # 2013-10-31
"Android 4.4.1", # 2013-12-05
"Android 4.4.2", # 2013-12-09
"Android 4.4.3", # 2014-06-02
"Android 4.4.4", # 2014-06-19
"Android 5.0", # 2014-11-12
"Android 5.0.1", # 2014-12-02
"Android 5.0.2", # 2014-12-19
"Android 5.1", # 2015-03-09
"Android 5.1.1", # 2015-04-21
"Android 6.0", # 2015-10-05
"Android 6.0.1", # 2015-12-07
#'Android 7.0', # 2016-08-22
#'Android 7.1', # 2016-10-04
#'Android 7.1.1', # 2016-12-05
),
}
OS_CPU = {
"win": (
"", # 32bit
"Win64; x64", # 64bit
"WOW64", # 32bit process on 64bit system
),
"linux": (
"i686", # 32bit
"x86_64", # 64bit
"i686 on x86_64", # 32bit process on 64bit system
),
"mac": ("",),
"android": (
"armv7l", # 32bit
"armv8l", # 64bit
),
}
OS_NAVIGATOR = {
"win": ("chrome", "firefox", "ie"),
"mac": ("firefox", "chrome"),
"linux": ("chrome", "firefox"),
"android": ("firefox", "chrome"),
}
NAVIGATOR_OS = {
"chrome": ("win", "linux", "mac", "android"),
"firefox": ("win", "linux", "mac", "android"),
"ie": ("win",),
}
FIREFOX_VERSION = (
("45.0", datetime(2016, 3, 8)),
("46.0", datetime(2016, 4, 26)),
("47.0", datetime(2016, 6, 7)),
("48.0", datetime(2016, 8, 2)),
("49.0", datetime(2016, 9, 20)),
("50.0", datetime(2016, 11, 15)),
("51.0", datetime(2017, 1, 24)),
)
# Top chrome builds from website access log
# for september, october 2020
CHROME_BUILD = """
80.0.3987.132
80.0.3987.149
80.0.3987.99
81.0.4044.117
81.0.4044.138
83.0.4103.101
83.0.4103.106
83.0.4103.96
84.0.4147.105
84.0.4147.111
84.0.4147.125
84.0.4147.135
84.0.4147.89
85.0.4183.101
85.0.4183.102
85.0.4183.120
85.0.4183.121
85.0.4183.127
85.0.4183.81
85.0.4183.83
86.0.4240.110
86.0.4240.111
86.0.4240.114
86.0.4240.183
86.0.4240.185
86.0.4240.75
86.0.4240.78
86.0.4240.80
86.0.4240.96
86.0.4240.99
""".strip().splitlines()
IE_VERSION = (
# (numeric ver, string ver, trident ver) # release year
(8, "MSIE 8.0", "4.0"), # 2009
(9, "MSIE 9.0", "5.0"), # 2011
(10, "MSIE 10.0", "6.0"), # 2012
(11, "MSIE 11.0", "7.0"), # 2013
)
USER_AGENT_TEMPLATE = {
"firefox": (
"Mozilla/5.0"
" ({system[ua_platform]}; rv:{app[build_version]})"
" Gecko/{app[geckotrail]}"
" Firefox/{app[build_version]}"
),
"chrome": (
"Mozilla/5.0"
" ({system[ua_platform]}) AppleWebKit/537.36"
" (KHTML, like Gecko)"
" Chrome/{app[build_version]} Safari/537.36"
),
"chrome_smartphone": (
"Mozilla/5.0"
" ({system[ua_platform]}) AppleWebKit/537.36"
" (KHTML, like Gecko)"
" Chrome/{app[build_version]} Mobile Safari/537.36"
),
"chrome_tablet": (
"Mozilla/5.0"
" ({system[ua_platform]}) AppleWebKit/537.36"
" (KHTML, like Gecko)"
" Chrome/{app[build_version]} Safari/537.36"
),
"ie_less_11": (
"Mozilla/5.0"
" (compatible; {app[build_version]}; {system[ua_platform]};"
" Trident/{app[trident_version]})"
),
"ie_11": (
"Mozilla/5.0"
" ({system[ua_platform]}; Trident/{app[trident_version]};"
" rv:11.0) like Gecko"
),
}
def get_firefox_build():
build_ver, date_from = randomizer.choice(FIREFOX_VERSION)
try:
idx = FIREFOX_VERSION.index((build_ver, date_from))
_, date_to = FIREFOX_VERSION[idx + 1]
except IndexError:
date_to = date_from + timedelta(days=1)
sec_range = (date_to - date_from).total_seconds() - 1
build_rnd_time = date_from + timedelta(
seconds=randomizer.randint(0, int(sec_range))
)
return build_ver, build_rnd_time.strftime("%Y%m%d%H%M%S")
def get_chrome_build():
return randomizer.choice(CHROME_BUILD)
def get_ie_build():
"""
Return random IE version as tuple
(numeric_version, us-string component)
Example: (8, 'MSIE 8.0')
"""
return randomizer.choice(IE_VERSION)
MACOSX_CHROME_BUILD_RANGE = {
# https://en.wikipedia.org/wiki/MacOS#Release_history
"10.8": (0, 8),
"10.9": (0, 5),
"10.10": (0, 5),
"10.11": (0, 6),
"10.12": (0, 2),
}
def fix_chrome_mac_platform(platform):
"""
Chrome on Mac OS adds minor version number and uses underscores instead
of dots. E.g. platform for Firefox will be: 'Intel Mac OS X 10.11'
but for Chrome it will be 'Intel Mac OS X 10_11_6'.
:param platform: - string like "Macintosh; Intel Mac OS X 10.8"
:return: platform with version number including minor number and formatted
with underscores, e.g. "Macintosh; Intel Mac OS X 10_8_2"
"""
ver = platform.split("OS X ")[1]
build_range = range(*MACOSX_CHROME_BUILD_RANGE[ver])
build = randomizer.choice(build_range)
mac_ver = ver.replace(".", "_") + "_" + str(build)
return "Macintosh; Intel Mac OS X %s" % mac_ver
def build_system_components(device_type, os_id, navigator_id):
"""
For given os_id build random platform and oscpu
components
Returns dict {platform_version, platform, ua_platform, oscpu}
platform_version is OS name used in different places
ua_platform goes to navigator.platform
platform is used in building navigator.userAgent
oscpu goes to navigator.oscpu
"""
if os_id == "win":
platform_version = randomizer.choice(OS_PLATFORM["win"])
cpu = randomizer.choice(OS_CPU["win"])
if cpu:
platform = f"{platform_version}; {cpu}"
else:
platform = platform_version
res = {
"platform_version": platform_version,
"platform": platform,
"ua_platform": platform,
"oscpu": platform,
}
elif os_id == "linux":
cpu = randomizer.choice(OS_CPU["linux"])
platform_version = randomizer.choice(OS_PLATFORM["linux"])
platform = f"{platform_version} {cpu}"
res = {
"platform_version": platform_version,
"platform": platform,
"ua_platform": platform,
"oscpu": "Linux %s" % cpu,
}
elif os_id == "mac":
cpu = randomizer.choice(OS_CPU["mac"])
platform_version = randomizer.choice(OS_PLATFORM["mac"])
platform = platform_version
if navigator_id == "chrome":
platform = fix_chrome_mac_platform(platform)
res = {
"platform_version": platform_version,
"platform": "MacIntel",
"ua_platform": platform,
"oscpu": "Intel Mac OS X %s" % platform.split(" ")[-1],
}
elif os_id == "android":
assert navigator_id in ("firefox", "chrome")
assert device_type in ("smartphone", "tablet")
platform_version = randomizer.choice(OS_PLATFORM["android"])
if navigator_id == "firefox":
if device_type == "smartphone":
ua_platform = "%s; Mobile" % platform_version
elif device_type == "tablet":
ua_platform = "%s; Tablet" % platform_version
elif navigator_id == "chrome":
device_id = randomizer.choice(SMARTPHONE_DEV_IDS)
ua_platform = f"Linux; {platform_version}; {device_id}"
oscpu = "Linux %s" % randomizer.choice(OS_CPU["android"])
res = {
"platform_version": platform_version,
"ua_platform": ua_platform,
"platform": oscpu,
"oscpu": oscpu,
}
return res
def build_app_components(os_id, navigator_id):
"""
For given navigator_id build app features
Returns dict {name, product_sub, vendor, build_version, build_id}
"""
if navigator_id == "firefox":
build_version, build_id = get_firefox_build()
if os_id in ("win", "linux", "mac"):
geckotrail = "20100101"
else:
geckotrail = build_version
res = {
"name": "Netscape",
"product_sub": "20100101",
"vendor": "",
"build_version": build_version,
"build_id": build_id,
"geckotrail": geckotrail,
}
elif navigator_id == "chrome":
res = {
"name": "Netscape",
"product_sub": "20030107",
"vendor": "Google Inc.",
"build_version": get_chrome_build(),
"build_id": None,
}
elif navigator_id == "ie":
num_ver, build_version, trident_version = get_ie_build()
if num_ver >= 11:
app_name = "Netscape"
else:
app_name = "Microsoft Internet Explorer"
res = {
"name": app_name,
"product_sub": None,
"vendor": "",
"build_version": build_version,
"build_id": None,
"trident_version": trident_version,
}
return res
def get_option_choices(opt_name, opt_value, default_value, all_choices):
"""
Generate possible choices for the option `opt_name`
limited to `opt_value` value with default value
as `default_value`
"""
choices = []
if isinstance(opt_value, str):
choices = [opt_value]
elif isinstance(opt_value, (list, tuple)):
choices = list(opt_value)
elif opt_value is None:
choices = default_value
else:
raise InvalidOption(
"Option %s has invalid" " value: %s" % (opt_name, opt_value)
)
if "all" in choices:
choices = all_choices
for item in choices:
if item not in all_choices:
raise InvalidOption(
"Choices of option %s contains invalid" " item: %s" % (opt_name, item)
)
return choices
def pick_config_ids(device_type, os, navigator):
"""
Select one random pair (device_type, os_id, navigator_id) from
all possible combinations matching the given os and
navigator filters.
:param os: allowed os(es)
:type os: string or list/tuple or None
:param navigator: allowed browser engine(s)
:type navigator: string or list/tuple or None
:param device_type: limit possible oses by device type
:type device_type: list/tuple or None, possible values:
"desktop", "smartphone", "tablet", "all"
"""
if os is None:
default_dev_types = ["desktop"]
else:
default_dev_types = list(DEVICE_TYPE_OS.keys())
dev_type_choices = get_option_choices(
"device_type", device_type, default_dev_types, list(DEVICE_TYPE_OS.keys())
)
os_choices = get_option_choices(
"os", os, list(OS_NAVIGATOR.keys()), list(OS_NAVIGATOR.keys())
)
nav_choices = get_option_choices(
"navigator", navigator, list(NAVIGATOR_OS.keys()), list(NAVIGATOR_OS.keys())
)
variants = []
for dev, os, nav in product(dev_type_choices, os_choices, nav_choices):
if (
os in DEVICE_TYPE_OS[dev]
and nav in DEVICE_TYPE_NAVIGATOR[dev]
and nav in OS_NAVIGATOR[os]
):
variants.append((dev, os, nav))
if not variants:
raise InvalidOption(
"Options device_type, os and navigator" " conflicts with each other"
)
device_type, os_id, navigator_id = randomizer.choice(variants)
assert os_id in OS_PLATFORM
assert navigator_id in NAVIGATOR_OS
assert device_type in DEVICE_TYPE_OS
return device_type, os_id, navigator_id
def choose_ua_template(device_type, navigator_id, app):
tpl_name = navigator_id
if navigator_id == "ie":
tpl_name = "ie_11" if app["build_version"] == "MSIE 11.0" else "ie_less_11"
if navigator_id == "chrome":
if device_type == "smartphone":
tpl_name = "chrome_smartphone"
if device_type == "tablet":
tpl_name = "chrome_tablet"
return USER_AGENT_TEMPLATE[tpl_name]
def build_navigator_app_version(os_id, navigator_id, platform_version, user_agent):
if navigator_id in ("chrome", "ie"):
assert user_agent.startswith("Mozilla/")
app_version = user_agent.split("Mozilla/", 1)[1]
elif navigator_id == "firefox":
if os_id == "android":
app_version = "5.0 (%s)" % platform_version
else:
os_token = {
"win": "Windows",
"mac": "Macintosh",
"linux": "X11",
}[os_id]
app_version = "5.0 (%s)" % os_token
return app_version
def generate_navigator(os=None, navigator=None, platform=None, device_type=None):
"""
Generates web navigator's config
:param os: limit list of oses for generation
:type os: string or list/tuple or None
:param navigator: limit list of browser engines for generation
:type navigator: string or list/tuple or None
:param device_type: limit possible oses by device type
:type device_type: list/tuple or None, possible values:
"desktop", "smartphone", "tablet", "all"
:return: User-Agent config
:rtype: dict with keys (os, name, platform, oscpu, build_version,
build_id, app_version, app_name, app_code_name,
product, product_sub, vendor, vendor_sub,
user_agent)
:raises InvalidOption: if could not generate user-agent for
any combination of allowed platforms and navigators
:raise InvalidOption: if any of passed options is invalid
"""
if platform is not None:
os = platform
warn(
"The `platform` option is deprecated." " Use `os` option instead.",
stacklevel=3,
)
device_type, os_id, navigator_id = pick_config_ids(device_type, os, navigator)
system = build_system_components(device_type, os_id, navigator_id)
app = build_app_components(os_id, navigator_id)
ua_template = choose_ua_template(device_type, navigator_id, app)
user_agent = ua_template.format(system=system, app=app)
app_version = build_navigator_app_version(
os_id, navigator_id, system["platform_version"], user_agent
)
return {
# ids
"os_id": os_id,
"navigator_id": navigator_id,
# system components
"platform": system["platform"],
"oscpu": system["oscpu"],
# app components
"build_version": app["build_version"],
"build_id": app["build_id"],
"app_version": app_version,
"app_name": app["name"],
"app_code_name": "Mozilla",
"product": "Gecko",
"product_sub": app["product_sub"],
"vendor": app["vendor"],
"vendor_sub": "",
# compiled user agent
"user_agent": user_agent,
}
def generate_user_agent(os=None, navigator=None, platform=None, device_type=None):
"""
Generates HTTP User-Agent header
:param os: limit list of os for generation
:type os: string or list/tuple or None
:param navigator: limit list of browser engines for generation
:type navigator: string or list/tuple or None
:param device_type: limit possible oses by device type
:type device_type: list/tuple or None, possible values:
"desktop", "smartphone", "tablet", "all"
:return: User-Agent string
:rtype: string
:raises InvalidOption: if could not generate user-agent for
any combination of allowed oses and navigators
:raise InvalidOption: if any of passed options is invalid
"""
return generate_navigator(
os=os, navigator=navigator, platform=platform, device_type=device_type
)["user_agent"]
def generate_navigator_js(os=None, navigator=None, platform=None, device_type=None):
"""
Generates web navigator's config with keys corresponding
to keys of `windows.navigator` JavaScript object.
:param os: limit list of oses for generation
:type os: string or list/tuple or None
:param navigator: limit list of browser engines for generation
:type navigator: string or list/tuple or None
:param device_type: limit possible oses by device type
:type device_type: list/tuple or None, possible values:
"desktop", "smartphone", "tablet", "all"
:return: User-Agent config
:rtype: dict with keys (TODO)
:raises InvalidOption: if could not generate user-agent for
any combination of allowed oses and navigators
:raise InvalidOption: if any of passed options is invalid
"""
config = generate_navigator(
os=os, navigator=navigator, platform=platform, device_type=device_type
)
return {
"appCodeName": config["app_code_name"],
"appName": config["app_name"],
"appVersion": config["app_version"],
"platform": config["platform"],
"userAgent": config["user_agent"],
"oscpu": config["oscpu"],
"product": config["product"],
"productSub": config["product_sub"],
"vendor": config["vendor"],
"vendorSub": config["vendor_sub"],
"buildID": config["build_id"],
}

View File

@@ -0,0 +1,20 @@
from argparse import ArgumentParser
import json
from user_agent import generate_navigator_js
def script_ua():
parser = ArgumentParser()
parser.add_argument("-e", "--extended", action="store_true", default=False)
parser.add_argument("-o", "--os")
parser.add_argument("-n", "--navigator")
parser.add_argument("-d", "--device-type")
opts = parser.parse_args()
nav = generate_navigator_js(
os=opts.os, navigator=opts.navigator, device_type=opts.device_type
)
if opts.extended:
print(json.dumps(nav, indent=2))
else:
print(nav["userAgent"])

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
[
"6043D Build/KOT49H",
"7045Y Build/KOT49H",
"7050Y Build/JLS36C",
"ALE-L21 Build/HuaweiALE-L21",
"Archos 50c Oxygen Build/KOT49H",
"D2005 Build/20.1.A.2.19",
"D2105 Build/20.1.B.2.29",
"D2203 Build/18.5.C.0.19",
"D2212 Build/18.4.B.1.20",
"D2302 Build/18.6.A.0.182",
"D2403 Build/18.6.A.0.182",
"D2502 Build/19.2.1.A.0.72",
"D5322 Build/19.1.C.0.116",
"D5503 Build/14.6.A.1.236",
"E2003 Build/25.0.A.2.14",
"E2003 Build/25.0.A.2.31",
"E2033 Build/25.0.B.2.31",
"E2115 Build/24.0.B.5.14",
"E2303 Build/26.1.A.3.111",
"E5303 Build/27.2.A.0.169",
"E5533 Build/29.1.B.0.101",
"E6533 Build/32.2.A.0.253",
"E6553 Build/32.1.A.1.185",
"E6653 Build/32.2.A.0.305",
"E6683 Build/32.2.A.0.253",
"E6853 Build/32.2.A.0.224",
"F3311 Build/37.0.A.2.108",
"F5121 Build/34.2.A.0.292",
"F8132 Build/35.0.A.1.297",
"F8331 Build/39.2.A.0.417",
"GSmart Mika M3 Build/GSmart",
"GT-I9060 Build/JDQ39",
"GT-I9300 Build/JRO03C",
"GT-I9301I Build/LMY48Y",
"H60-L04 Build/HDH60-L04",
"H60-L12 Build/HDH60-L12",
"HTC Desire 210 dual sim Build/JDQ39",
"HTC Desire 320 Build/KOT49H",
"HTC Desire 326G dual sim Build/KOT49H",
"HTC Desire 516 dual sim Build/JWR66Y",
"HTC Desire 526G dual sim Build/KOT49H",
"HTC Desire 610 Build/KOT49H",
"HTC Desire 616 dual sim Build/JDQ39",
"HTC Desire 620G dual sim Build/KOT49H",
"HTC Desire 628 Build/LMY47D",
"HTC Desire 628 dual sim Build/LMY47D",
"HTC Desire 728G dual sim Build/LMY47D",
"HTC Desire EYE Build/MMB29M",
"HTC One M8s Build/MMB29M",
"HUAWEI MT2-L02 Build/HuaweiMT2-L02",
"HUAWEI P8max Build/HUAWEIDAV-703L",
"HUAWEI TIT-AL00 Build/HUAWEITIT-AL00",
"HUAWEI TIT-U02 Build/HUAWEITIT-U02",
"LGLS675 Build/LMY47V",
"LGLS990 Build/KVT49L.LS990ZV4",
"LGLS992 Build/NRD90U",
"LGMS330 Build/LMY47V",
"Lenovo A316i Build/JDQ39",
"Lenovo A319 Build/MocorDroid4.4.2",
"Lenovo A328 Build/KOT49H",
"Lenovo A5000 Build/LRX22G",
"Lenovo A526 Build/JDQ39",
"Lenovo A536 Build/KOT49H",
"Lenovo A606 Build/KOT49H",
"Lenovo A806 Build/KOT49H",
"Lenovo A859 Build/JDQ39",
"Lenovo A916 Build/KOT49H",
"Lenovo K10a40 Build/MRA58K",
"Lenovo K30-T Build/KTU84Q",
"Lenovo K50-t5 Build/LRX21M",
"Lenovo K920 Build/LRX22G",
"Lenovo P1a42 Build/LMY47V",
"Lenovo PB1-770M Build/S100",
"Lenovo S580 Build/JLS36C",
"Lenovo S660 Build/KOT49H",
"Lenovo S850 Build/KOT49H",
"Lenovo S856 Build/KVT49L",
"Lenovo S860 Build/JDQ39",
"Lenovo S90-A Build/LRX22G",
"MI 5s Plus Build/MXB48T",
"MI NOTE Pro Build/LMY47V",
"MX4 Pro Build/LMY48W",
"Mi 4i Build/LRX22G",
"Micromax A104 Build/KOT49H",
"Micromax A106 Build/KOT49H",
"Micromax AQ5001 Build/LRX21M",
"Micromax D303 Build/KOT49H",
"Micromax D320 Build/KOT49H",
"Micromax Q324 Build/KOT49H",
"Micromax Q380 Build/LRX22G",
"Micromax Q392 Build/LMY47I",
"Nexus 5X Build/NMF26F",
"NokiaX2DS Build/JLS36C",
"Nokia_XL Build/JZO54K",
"Philips I908 Build/KOT49H",
"Philips S337 Build/LMY47D",
"Philips S388 Build/JDQ39",
"Philips W6610 Build/JDQ39",
"Phoenix 2 Build/JDQ39",
"RIDGE 4G Build/LRX22G",
"ROBBY Build/MRA58K",
"Redmi Note 2 Build/LRX22G",
"Rover Build/LMY47D",
"SAMSUNG SM-A5100 Build/LMY47X",
"SAMSUNG SM-A710F Build/MMB29K",
"SAMSUNG SM-A710L Build/MMB29K",
"SAMSUNG SM-G361F Build/LMY48B",
"SAMSUNG SM-G906S Build/LRX22C",
"SAMSUNG SM-J110H Build/KTU84P",
"SAMSUNG SM-J500F Build/LMY48B",
"SAMSUNG SM-J500FN Build/MMB29M",
"SAMSUNG SM-J500G Build/LMY48B",
"SAMSUNG SM-J500H Build/LMY48B",
"SAMSUNG SM-J500H Build/MMB29M",
"SAMSUNG SM-J510FN Build/MMB29M",
"SM-A310F Build/MMB29K",
"SM-A500FU Build/LRX22G",
"SM-A510F Build/LMY47X",
"SM-A700F Build/LRX22G",
"SM-A700FD Build/MMB29M",
"SM-A700H Build/LRX22G",
"SM-A710F Build/LMY47X",
"SM-C111 Build/KOT49H",
"SM-E500F Build/LMY47X",
"SM-E500H Build/LMY47X",
"SM-G313HU Build/KOT49H",
"SM-G318H Build/KTU84P",
"SM-G355H Build/KOT49H",
"SM-G360F Build/KTU84P",
"SM-G360H Build/KTU84P",
"SM-G360T Build/LMY47X",
"SM-G530FZ Build/LRX22G",
"SM-G530H Build/LRX22G",
"SM-G531F Build/LMY48B",
"SM-G7102 Build/KOT49H",
"SM-G800F Build/LMY47X",
"SM-G850F Build/LRX22G",
"SM-G900F Build/MMB29M",
"SM-G900H Build/LRX21T",
"SM-G900I Build/LRX21T",
"SM-G900V Build/KTU84P",
"SM-G903F Build/MMB29K",
"SM-G920F Build/LRX22G",
"SM-G925F Build/MMB29K",
"SM-G935F Build/MMB29K",
"SM-G935V Build/MMB29M",
"SM-J100FN Build/KTU84P",
"SM-J100H Build/KTU84P",
"SM-J120F Build/LMY47X",
"SM-J120H Build/LMY47V",
"SM-J120M Build/LMY47X",
"SM-J200H Build/LMY48B",
"SM-J320F Build/LMY47V",
"SM-J500FN Build/LMY48B",
"SM-J500M Build/LMY48B",
"SM-J510FN Build/MMB29M",
"SM-J700H Build/MMB29K",
"SM-N910C Build/LMY47X",
"SM-N920G Build/LMY47X",
"SM-N920T Build/MMB29K",
"VIE-L29 Build/HUAWEIVIE-L29",
"X5pro Build/LMY47D",
"XT1068 Build/LXB22.46-28",
"XT1562 Build/MPD24.107-52",
"XT1572 Build/MPHS24.107-58-1",
"XT1585 Build/MCK24.78-13.16",
"Z220 Build/LRX21M",
"ZB551KL Build/LMY47V",
"ZTE A2017G Build/MMB29M",
"ZTE BLADE A610 Build/MRA58K",
"ZTE Blade A5 Build/KOT49H",
"ZTE Star 1 Build/KVT49L",
"ZTE T320 Build/LRX21M",
"ZTE T620 Build/LMY47D",
"m1 note Build/KTU84P",
"m2 note Build/LMY47D",
"m3 note Build/LMY47I",
"vivo V3Max Build/LMY47V"
]

View File

@@ -0,0 +1,757 @@
[
{
"android_versionss": [
"v4.2.2",
"v4.2.2"
],
"cpu": "Quad-core 1.3 GHz Cortex-A7",
"dev_ids": [
"Lenovo A5500-F Build/KOT49H"
],
"name": "Lenovo A8-50 A5500",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.2.2",
"v4.2.2"
],
"cpu": "Quad-core 1.3 GHz Cortex-A7",
"dev_ids": [
"Lenovo A5500-H Build/KOT49H"
],
"name": "Lenovo A8-50 A5500",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.2.2",
"v4.4.2"
],
"cpu": "Quad-core 1.3 GHz Cortex-A7",
"dev_ids": [
"Lenovo A7600-H Build/KOT49H"
],
"name": "Lenovo A10-70 A7600",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.2.2",
"v4.4.2"
],
"cpu": "Quad-core 1.3 GHz Cortex-A7",
"dev_ids": [
"Lenovo A3500-H Build/KOT49H"
],
"name": "Lenovo A7-50 A3500",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.4.2",
"v5.0.2"
],
"cpu": "Quad-core 1.2 GHz",
"dev_ids": [
"SM-T531 Build/KOT49H"
],
"name": "Samsung Galaxy Tab 4 10.1 3G",
"released": 2014,
"resolution": [
1280,
800
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz",
"dev_ids": [
"SM-T230 Build/KOT49H"
],
"name": "Samsung Galaxy Tab 4 7.0",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.4",
"v4.4"
],
"cpu": "Octa-core (4x1.9 GHz Cortex-A15 & 4x1.3 GHz Cortex-A7)",
"dev_ids": [
"SM-P901 Build/KOT49H"
],
"name": "Samsung Galaxy Note Pro 12.2 3G",
"released": 2014,
"resolution": [
2560,
1600
]
},
{
"android_versionss": [
"v4.4",
"v4.4"
],
"cpu": "Quad-core 2.3 GHz Krait 400",
"dev_ids": [
"SM-T325 Build/KOT49H"
],
"name": "Samsung Galaxy Tab Pro 8.4 3G/LTE",
"released": 2014,
"resolution": [
1600,
2560
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz Cortex-A7",
"dev_ids": [
"SM-T231 Build/KOT49H"
],
"name": "Samsung Galaxy Tab 4 7.0 3G",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.4.4",
"v4.4.4"
],
"cpu": "Quad-core 1.7 GHz",
"dev_ids": [
"Lenovo TAB 2 A10-70L Build/KTU84P"
],
"name": "Lenovo Tab 2 A10-70",
"released": 2015,
"resolution": [
1200,
1920
]
},
{
"android_versionss": [
"v5.1",
"v5.1"
],
"cpu": "Quad-core 1.3 GHzQuad-core 1.2 GHz - USA model",
"dev_ids": [
"SM-T560 Build/KTU84P"
],
"name": "Samsung Galaxy Tab E 9.6",
"released": 2015,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.4.4",
"v4.4.4"
],
"cpu": "Quad-core 1.3 GHz",
"dev_ids": [
"SM-T113 Build/KTU84P"
],
"name": "Samsung Galaxy Tab 3 Lite 7.0 VE",
"released": 2015,
"resolution": [
600,
1024
]
},
{
"android_versionss": [
"v5.1",
"v5.1"
],
"cpu": "Quad-core 1.3 GHzQuad-core 1.2 GHz - USA model",
"dev_ids": [
"SM-T561 Build/KTU84P"
],
"name": "Samsung Galaxy Tab E 9.6",
"released": 2015,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v5.0",
"v5.0"
],
"cpu": "Quad-core 1.33 GHz",
"dev_ids": [
"A3-A30 Build/LRX22G"
],
"name": "Acer Iconia Tab 10 A3-A30",
"released": 2015,
"resolution": [
1920,
1200
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.33 GHz",
"dev_ids": [
"YOGA Tablet 2 Pro-1380F Build/LRX22C"
],
"name": "Lenovo Yoga Tablet 2 Pro",
"released": 2014,
"resolution": [
2560,
1440
]
},
{
"android_versionss": [
"v5.0",
"v6.0.1"
],
"cpu": "Quad-core 1.2 GHz",
"dev_ids": [
"SM-T555 Build/LRX22G"
],
"name": "Samsung Galaxy Tab A 9.7",
"released": 2015,
"resolution": [
768,
1024
]
},
{
"android_versionss": [
"v5.0.2",
"v6.0.1"
],
"cpu": "Octa-core (4x1.9 GHz & 4x1.3 GHz) - T710, T715Octa-core (4x1.8 GHz Cortex-A72 & 4x1.4 GHz Cortex-A53) - T719N",
"dev_ids": [
"SM-T710 Build/LRX22G"
],
"name": "Samsung Galaxy Tab S2 8.0",
"released": 2015,
"resolution": [
1536,
2048
]
},
{
"android_versionss": [
"v4.4.2",
"v6.0"
],
"cpu": "Quad-core 2.3 GHz Krait 400 (S800)Quad-core 1.9GHz Cortex-A15 & quad-core 1.3 GHz Cortex-A7 (Exynos 5420)",
"dev_ids": [
"SM-T705 Build/LRX22G"
],
"name": "Samsung Galaxy Tab S 8.4 LTE",
"released": 2014,
"resolution": [
1600,
2560
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz",
"dev_ids": [
"SM-T331 Build/LMY47X"
],
"name": "Samsung Galaxy Tab 4 8.0 3G",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v5.0.2",
"v6.0.1"
],
"cpu": "Octa-core (4x1.9 GHz & 4x1.3 GHz) - T810, T815Octa-core (4x1.8 GHz Cortex-A72 & 4x1.4 GHz Cortex-A53) - T813N, T819N",
"dev_ids": [
"SM-T813 Build/MMB29M"
],
"name": "Samsung Galaxy Tab S2 9.7",
"released": 2015,
"resolution": [
1536,
2048
]
},
{
"android_versionss": [
"v4.3",
"v4.3"
],
"cpu": "Quad-core 1.2 GHz Cortex-A7",
"dev_ids": [
"Archos 80 Helium 4G Build/JLS36C"
],
"name": "Archos 80 Helium 4G",
"released": 2014,
"resolution": [
768,
1024
]
},
{
"android_versionss": [
"v4.4.2",
"v6.0.1"
],
"cpu": "Octa-core (4x1.9 GHz Cortex-A15 & 4x1.3 GHz Cortex-A7)",
"dev_ids": [
"SM-T800 Build/MMB29K"
],
"name": "Samsung Galaxy Tab S 10.5",
"released": 2014,
"resolution": [
2560,
1600
]
},
{
"android_versionss": [
"v4.4.2",
"v6.0"
],
"cpu": "Quad-core 2.3 GHz Krait 400 (S800)Quad-core 1.9GHz Cortex-A15 & quad-core 1.3 GHz Cortex-A7 (Exynos 5420)",
"dev_ids": [
"SM-T805 Build/KOT49H"
],
"name": "Samsung Galaxy Tab S 10.5 LTE",
"released": 2014,
"resolution": [
2560,
1600
]
},
{
"android_versionss": [
"v4.4",
"v4.4"
],
"cpu": "Quad-core 1.3 GHz",
"dev_ids": [
"SM-T116 Build/KTU84P"
],
"name": "Samsung Galaxy Tab 3 V",
"released": 2015,
"resolution": [
600,
1024
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz Cortex-A7",
"dev_ids": [
"SM-T235 Build/LMY47X"
],
"name": "Samsung Galaxy Tab 4 7.0 LTE",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v5.0",
"v7.1.1"
],
"cpu": "Dual-core 2.3 GHz Denver",
"dev_ids": [
"Nexus 9 Build/MOB30M",
"Nexus 9 Build/NRD91N"
],
"name": "HTC Nexus 9",
"released": 2014,
"resolution": [
1536,
2048
]
},
{
"android_versionss": [
"v4.4",
"v4.4"
],
"cpu": "Quad-core 2.3 GHz Krait 400",
"dev_ids": [
"SM-T525 Build/KOT49H"
],
"name": "Samsung Galaxy Tab Pro 10.1 LTE",
"released": 2014,
"resolution": [
2560,
1600
]
},
{
"android_versionss": [
"v5.0.2",
"v6.0.1"
],
"cpu": "Octa-core (4x1.9 GHz & 4x1.3 GHz) - T810, T815Octa-core (4x1.8 GHz Cortex-A72 & 4x1.4 GHz Cortex-A53) - T813N, T819N",
"dev_ids": [
"SAMSUNG SM-T815Y Build/MMB29K"
],
"name": "Samsung Galaxy Tab S2 9.7",
"released": 2015,
"resolution": [
1536,
2048
]
},
{
"android_versionss": [
"v5.0",
"v5.0"
],
"cpu": "Quad-core 1.3 GHz",
"dev_ids": [
"Lenovo TAB 2 A8-50LC Build/LRX22G",
"Lenovo TAB 2 A8-50LC Build/LMY47D"
],
"name": "Lenovo Tab 2 A8-50",
"released": 2015,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.3",
"v4.3"
],
"cpu": "Quad-core 1.2 GHz Cortex-A7",
"dev_ids": [
"MediaPad T1 8.0 Build/HuaweiMediaPad"
],
"name": "Huawei MediaPad T1 8.0",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core",
"dev_ids": [
"A1-713HD Build/KOT49H"
],
"name": "Acer Iconia Tab 7 A1-713HD",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v6.0",
"v6.0"
],
"cpu": "Octa-core (4x2.3 GHz Cortex-A72 & 4x1.8 GHz Cortex A53)",
"dev_ids": [
"BTV-DL09 Build/HUAWEIBEETHOVEN-DL09"
],
"name": "Huawei MediaPad M3 8.4",
"released": 2016,
"resolution": [
1600,
2560
]
},
{
"android_versionss": [
"v4.2.2",
"v4.4.2"
],
"cpu": "Quad-core 1.3 GHz Cortex-A7",
"dev_ids": [
"Lenovo A3500-HV Build/KOT49H"
],
"name": "Lenovo A7-50 A3500",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz",
"dev_ids": [
"SM-T535 Build/KOT49H"
],
"name": "Samsung Galaxy Tab 4 10.1 LTE",
"released": 2014,
"resolution": [
1280,
800
]
},
{
"android_versionss": [
"v5.1",
"v5.1"
],
"cpu": "Octa-core (4x2.0 GHz Cortex A53 & 4x1.5 GHz Cortex-A53)",
"dev_ids": [
"HUAWEI M2-A01L Build/HUAWEIM2-A01L"
],
"name": "Huawei MediaPad M2 10.0",
"released": 2016,
"resolution": [
1200,
1920
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz Cortex-A7",
"dev_ids": [
"T1-701u Build/HuaweiMediaPad"
],
"name": "Huawei MediaPad T1 7.0 Plus",
"released": 2016,
"resolution": [
600,
1024
]
},
{
"android_versionss": [
"v5.0.2",
"v6.0.1"
],
"cpu": "Octa-core (4x1.9 GHz & 4x1.3 GHz) - T710, T715Octa-core (4x1.8 GHz Cortex-A72 & 4x1.4 GHz Cortex-A53) - T719N",
"dev_ids": [
"SM-T719 Build/MMB29M"
],
"name": "Samsung Galaxy Tab S2 8.0",
"released": 2015,
"resolution": [
1536,
2048
]
},
{
"android_versionss": [
"v4.2",
"v4.2"
],
"cpu": "Dual-core 1.2 GHz",
"dev_ids": [
"SM-T110 Build/JDQ39"
],
"name": "Samsung Galaxy Tab 3 Lite 7.0",
"released": 2014,
"resolution": [
600,
1024
]
},
{
"android_versionss": [
"v4.4",
"v4.4"
],
"cpu": "Quad-core 1.3 GHz",
"dev_ids": [
"SM-T116BU Build/KTU84P"
],
"name": "Samsung Galaxy Tab 3 V",
"released": 2015,
"resolution": [
600,
1024
]
},
{
"android_versionss": [
"v5.1",
"v5.1"
],
"cpu": "Octa-core (4x1.2 GHz Cortex-A53 & 4x1.5 GHz Cortex-A53)",
"dev_ids": [
"FDR-A01L Build/HuaweiMediaPad"
],
"name": "Huawei MediaPad T2 10.0 Pro",
"released": 2016,
"resolution": [
1200,
1920
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz",
"dev_ids": [
"SM-T530 Build/KOT49H",
"SM-T530 Build/LRX22G"
],
"name": "Samsung Galaxy Tab 4 10.1",
"released": 2014,
"resolution": [
1280,
800
]
},
{
"android_versionss": [
"v4.4.2",
"v4.4.2"
],
"cpu": "Quad-core 1.2 GHz Cortex-A7",
"dev_ids": [
"SM-T365 Build/LMY47X"
],
"name": "Samsung Galaxy Tab Active LTE",
"released": 2014,
"resolution": [
800,
1280
]
},
{
"android_versionss": [
"v5.0",
"v5.0"
],
"cpu": "Octa-core (4x1.5 GHz Cortex-A53 & 4x2.0 GHz Cortex-A57)",
"dev_ids": [
"SGP771 Build/28.0.A.8.260"
],
"name": "Sony Xperia Z4 Tablet LTE",
"released": 2015,
"resolution": [
2560,
1600
]
},
{
"android_versionss": [
"v5.0.2",
"v6.0.1"
],
"cpu": "Octa-core (4x1.9 GHz & 4x1.3 GHz) - T710, T715Octa-core (4x1.8 GHz Cortex-A72 & 4x1.4 GHz Cortex-A53) - T719N",
"dev_ids": [
"SM-T715 Build/MMB29K"
],
"name": "Samsung Galaxy Tab S2 8.0",
"released": 2015,
"resolution": [
1536,
2048
]
},
{
"android_versionss": [
"v4.2.2",
"v4.4.2"
],
"cpu": "Quad-core 1.6 GHz Cortex-A9",
"dev_ids": [
"X1 7.0 Build/HuaweiMediaPad"
],
"name": "Huawei MediaPad X1",
"released": 2014,
"resolution": [
1200,
1920
]
},
{
"android_versionss": [
"v4.4.2",
"v6.0"
],
"cpu": "Quad-core 2.3 GHz Krait 400 (S800)Quad-core 1.9GHz Cortex-A15 & quad-core 1.3 GHz Cortex-A7 (Exynos 5420)",
"dev_ids": [
"SAMSUNG SM-T805 Build/LRX22G"
],
"name": "Samsung Galaxy Tab S 10.5 LTE",
"released": 2014,
"resolution": [
2560,
1600
]
},
{
"android_versionss": [
"v4.4.2",
"v6.0"
],
"cpu": "Octa-core (4x1.9 GHz Cortex-A15 & 4x1.3 GHz Cortex-A7)",
"dev_ids": [
"SM-T700 Build/LRX22G"
],
"name": "Samsung Galaxy Tab S 8.4",
"released": 2014,
"resolution": [
1600,
2560
]
}
]

View File

@@ -0,0 +1,52 @@
[
"A1-713HD Build/KOT49H",
"A3-A30 Build/LRX22G",
"Archos 80 Helium 4G Build/JLS36C",
"BTV-DL09 Build/HUAWEIBEETHOVEN-DL09",
"FDR-A01L Build/HuaweiMediaPad",
"HUAWEI M2-A01L Build/HUAWEIM2-A01L",
"Lenovo A3500-H Build/KOT49H",
"Lenovo A3500-HV Build/KOT49H",
"Lenovo A5500-F Build/KOT49H",
"Lenovo A5500-H Build/KOT49H",
"Lenovo A7600-H Build/KOT49H",
"Lenovo TAB 2 A10-70L Build/KTU84P",
"Lenovo TAB 2 A8-50LC Build/LMY47D",
"Lenovo TAB 2 A8-50LC Build/LRX22G",
"MediaPad T1 8.0 Build/HuaweiMediaPad",
"Nexus 9 Build/MOB30M",
"Nexus 9 Build/NRD91N",
"SAMSUNG SM-T805 Build/LRX22G",
"SAMSUNG SM-T815Y Build/MMB29K",
"SGP771 Build/28.0.A.8.260",
"SM-P901 Build/KOT49H",
"SM-T110 Build/JDQ39",
"SM-T113 Build/KTU84P",
"SM-T116 Build/KTU84P",
"SM-T116BU Build/KTU84P",
"SM-T230 Build/KOT49H",
"SM-T231 Build/KOT49H",
"SM-T235 Build/LMY47X",
"SM-T325 Build/KOT49H",
"SM-T331 Build/LMY47X",
"SM-T365 Build/LMY47X",
"SM-T525 Build/KOT49H",
"SM-T530 Build/KOT49H",
"SM-T530 Build/LRX22G",
"SM-T531 Build/KOT49H",
"SM-T535 Build/KOT49H",
"SM-T555 Build/LRX22G",
"SM-T560 Build/KTU84P",
"SM-T561 Build/KTU84P",
"SM-T700 Build/LRX22G",
"SM-T705 Build/LRX22G",
"SM-T710 Build/LRX22G",
"SM-T715 Build/MMB29K",
"SM-T719 Build/MMB29M",
"SM-T800 Build/MMB29K",
"SM-T805 Build/KOT49H",
"SM-T813 Build/MMB29M",
"T1-701u Build/HuaweiMediaPad",
"X1 7.0 Build/HuaweiMediaPad",
"YOGA Tablet 2 Pro-1380F Build/LRX22C"
]

View File

@@ -0,0 +1,15 @@
import os.path
import json
PACKAGE_DIR = os.path.dirname(os.path.realpath(__file__))
def load_json_data(rel_path):
path = os.path.join(PACKAGE_DIR, rel_path)
with open(path, encoding="utf-8") as inp:
return json.load(inp)
SMARTPHONE_DEV_IDS = load_json_data("data/smartphone_dev_id.json")
TABLET_DEV_IDS = load_json_data("data/tablet_dev_id.json")

View File

@@ -0,0 +1,15 @@
__all__ = ("UserAgentError", "InvalidOption")
class UserAgentError(Exception):
"""
Base class for all errors
raising from the user_agent library
"""
class InvalidOption(Exception):
"""
Raises when user call user_agent library methods
with incorrect arguments.
"""

View File

@@ -0,0 +1,12 @@
import warnings
class UserAgentDeprecationWarning(UserWarning):
"""
Warning category used to generate warning message
about deprecated feature of user_agent library.
"""
def warn(msg, stacklevel=2):
warnings.warn(msg, category=UserAgentDeprecationWarning, stacklevel=stacklevel)

View File

@@ -0,0 +1 @@
#!/usr/bin/python

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,976 @@
# pylint: skip-file
# Author: C.J. Hutto
# Thanks to George Berry for reducing the time complexity from something like O(N^4) to O(N).
# Thanks to Ewan Klein and Pierpaolo Pantone for bringing VADER into NLTK. Those modifications were awesome.
# For license information, see LICENSE.TXT
"""
If you use the VADER sentiment analysis tools, please cite:
Hutto, C.J. & Gilbert, E.E. (2014). VADER: A Parsimonious Rule-based Model for
Sentiment Analysis of Social Media Text. Eighth International Conference on
Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.
"""
import os
import re
import math
import string
import codecs
import json
from itertools import product
from inspect import getsourcefile
# ##Constants##
# (empirically derived mean sentiment intensity rating increase for booster words)
B_INCR = 0.293
B_DECR = -0.293
# (empirically derived mean sentiment intensity rating increase for using ALLCAPs to emphasize a word)
C_INCR = 0.733
N_SCALAR = -0.74
NEGATE = [
"aint",
"arent",
"cannot",
"cant",
"couldnt",
"darent",
"didnt",
"doesnt",
"ain't",
"aren't",
"can't",
"couldn't",
"daren't",
"didn't",
"doesn't",
"dont",
"hadnt",
"hasnt",
"havent",
"isnt",
"mightnt",
"mustnt",
"neither",
"don't",
"hadn't",
"hasn't",
"haven't",
"isn't",
"mightn't",
"mustn't",
"neednt",
"needn't",
"never",
"none",
"nope",
"nor",
"not",
"nothing",
"nowhere",
"oughtnt",
"shant",
"shouldnt",
"uhuh",
"wasnt",
"werent",
"oughtn't",
"shan't",
"shouldn't",
"uh-uh",
"wasn't",
"weren't",
"without",
"wont",
"wouldnt",
"won't",
"wouldn't",
"rarely",
"seldom",
"despite",
]
# booster/dampener 'intensifiers' or 'degree adverbs'
# http://en.wiktionary.org/wiki/Category:English_degree_adverbs
BOOSTER_DICT = {
"absolutely": B_INCR,
"amazingly": B_INCR,
"awfully": B_INCR,
"completely": B_INCR,
"considerable": B_INCR,
"considerably": B_INCR,
"decidedly": B_INCR,
"deeply": B_INCR,
"effing": B_INCR,
"enormous": B_INCR,
"enormously": B_INCR,
"entirely": B_INCR,
"especially": B_INCR,
"exceptional": B_INCR,
"exceptionally": B_INCR,
"extreme": B_INCR,
"extremely": B_INCR,
"fabulously": B_INCR,
"flipping": B_INCR,
"flippin": B_INCR,
"frackin": B_INCR,
"fracking": B_INCR,
"fricking": B_INCR,
"frickin": B_INCR,
"frigging": B_INCR,
"friggin": B_INCR,
"fully": B_INCR,
"fuckin": B_INCR,
"fucking": B_INCR,
"fuggin": B_INCR,
"fugging": B_INCR,
"greatly": B_INCR,
"hella": B_INCR,
"highly": B_INCR,
"hugely": B_INCR,
"incredible": B_INCR,
"incredibly": B_INCR,
"intensely": B_INCR,
"major": B_INCR,
"majorly": B_INCR,
"more": B_INCR,
"most": B_INCR,
"particularly": B_INCR,
"purely": B_INCR,
"quite": B_INCR,
"really": B_INCR,
"remarkably": B_INCR,
"so": B_INCR,
"substantially": B_INCR,
"thoroughly": B_INCR,
"total": B_INCR,
"totally": B_INCR,
"tremendous": B_INCR,
"tremendously": B_INCR,
"uber": B_INCR,
"unbelievably": B_INCR,
"unusually": B_INCR,
"utter": B_INCR,
"utterly": B_INCR,
"very": B_INCR,
"almost": B_DECR,
"barely": B_DECR,
"hardly": B_DECR,
"just enough": B_DECR,
"kind of": B_DECR,
"kinda": B_DECR,
"kindof": B_DECR,
"kind-of": B_DECR,
"less": B_DECR,
"little": B_DECR,
"marginal": B_DECR,
"marginally": B_DECR,
"occasional": B_DECR,
"occasionally": B_DECR,
"partly": B_DECR,
"scarce": B_DECR,
"scarcely": B_DECR,
"slight": B_DECR,
"slightly": B_DECR,
"somewhat": B_DECR,
"sort of": B_DECR,
"sorta": B_DECR,
"sortof": B_DECR,
"sort-of": B_DECR,
}
# check for sentiment laden idioms that do not contain lexicon words (future work, not yet implemented)
SENTIMENT_LADEN_IDIOMS = {
"cut the mustard": 2,
"hand to mouth": -2,
"back handed": -2,
"blow smoke": -2,
"blowing smoke": -2,
"upper hand": 1,
"break a leg": 2,
"cooking with gas": 2,
"in the black": 2,
"in the red": -2,
"on the ball": 2,
"under the weather": -2,
}
# check for special case idioms and phrases containing lexicon words
SPECIAL_CASES = {
"the shit": 3,
"the bomb": 3,
"bad ass": 1.5,
"badass": 1.5,
"bus stop": 0.0,
"yeah right": -2,
"kiss of death": -1.5,
"to die for": 3,
"beating heart": 3.5,
}
# #Static methods# #
def negated(input_words, include_nt=True):
"""
Determine if input contains negation words
"""
input_words = [str(w).lower() for w in input_words]
neg_words = []
neg_words.extend(NEGATE)
for word in neg_words:
if word in input_words:
return True
if include_nt:
for word in input_words:
if "n't" in word:
return True
"""if "least" in input_words:
i = input_words.index("least")
if i > 0 and input_words[i - 1] != "at":
return True"""
return False
def normalize(score, alpha=15):
"""
Normalize the score to be between -1 and 1 using an alpha that
approximates the max expected value
"""
norm_score = score / math.sqrt((score * score) + alpha)
if norm_score < -1.0:
return -1.0
elif norm_score > 1.0:
return 1.0
else:
return norm_score
def allcap_differential(words):
"""
Check whether just some words in the input are ALL CAPS
:param list words: The words to inspect
:returns: `True` if some but not all items in `words` are ALL CAPS
"""
is_different = False
allcap_words = 0
for word in words:
if word.isupper():
allcap_words += 1
cap_differential = len(words) - allcap_words
if 0 < cap_differential < len(words):
is_different = True
return is_different
def scalar_inc_dec(word, valence, is_cap_diff):
"""
Check if the preceding words increase, decrease, or negate/nullify the
valence
"""
scalar = 0.0
word_lower = word.lower()
if word_lower in BOOSTER_DICT:
scalar = BOOSTER_DICT[word_lower]
if valence < 0:
scalar *= -1
# check if booster/dampener word is in ALLCAPS (while others aren't)
if word.isupper() and is_cap_diff:
if valence > 0:
scalar += C_INCR
else:
scalar -= C_INCR
return scalar
class SentiText:
"""
Identify sentiment-relevant string-level properties of input text.
"""
def __init__(self, text):
if not isinstance(text, str):
text = str(text).encode("utf-8")
self.text = text
self.words_and_emoticons = self._words_and_emoticons()
# doesn't separate words from\
# adjacent punctuation (keeps emoticons & contractions)
self.is_cap_diff = allcap_differential(self.words_and_emoticons)
@staticmethod
def _strip_punc_if_word(token):
"""
Removes all trailing and leading punctuation
If the resulting string has two or fewer characters,
then it was likely an emoticon, so return original string
(ie ":)" stripped would be "", so just return ":)"
"""
stripped = token.strip(string.punctuation)
if len(stripped) <= 2:
return token
return stripped
def _words_and_emoticons(self):
"""
Removes leading and trailing puncutation
Leaves contractions and most emoticons
Does not preserve punc-plus-letter emoticons (e.g. :D)
"""
wes = self.text.split()
stripped = list(map(self._strip_punc_if_word, wes))
return stripped
class SentimentIntensityAnalyzer:
"""
Give a sentiment intensity score to sentences.
"""
def __init__(
self, lexicon_file="vader_lexicon.txt", emoji_lexicon="emoji_utf8_lexicon.txt"
):
_this_module_file_path_ = os.path.abspath(getsourcefile(lambda: 0))
lexicon_full_filepath = os.path.join(
os.path.dirname(_this_module_file_path_), lexicon_file
)
with codecs.open(lexicon_full_filepath, encoding="utf-8") as f:
self.lexicon_full_filepath = f.read()
self.lexicon = self.make_lex_dict()
emoji_full_filepath = os.path.join(
os.path.dirname(_this_module_file_path_), emoji_lexicon
)
with codecs.open(emoji_full_filepath, encoding="utf-8") as f:
self.emoji_full_filepath = f.read()
self.emojis = self.make_emoji_dict()
def make_lex_dict(self):
"""
Convert lexicon file to a dictionary
"""
lex_dict = {}
for line in self.lexicon_full_filepath.rstrip("\n").split("\n"):
if not line:
continue
(word, measure) = line.strip().split("\t")[0:2]
lex_dict[word] = float(measure)
return lex_dict
def make_emoji_dict(self):
"""
Convert emoji lexicon file to a dictionary
"""
emoji_dict = {}
for line in self.emoji_full_filepath.rstrip("\n").split("\n"):
(emoji, description) = line.strip().split("\t")[0:2]
emoji_dict[emoji] = description
return emoji_dict
def polarity_scores(self, text):
"""
Return a float for sentiment strength based on the input text.
Positive values are positive valence, negative value are negative
valence.
"""
# convert emojis to their textual descriptions
text_no_emoji = ""
prev_space = True
for chr in text:
if chr in self.emojis:
# get the textual description
description = self.emojis[chr]
if not prev_space:
text_no_emoji += " "
text_no_emoji += description
prev_space = False
else:
text_no_emoji += chr
prev_space = chr == " "
text = text_no_emoji.strip()
sentitext = SentiText(text)
sentiments = []
words_and_emoticons = sentitext.words_and_emoticons
for i, item in enumerate(words_and_emoticons):
valence = 0
# check for vader_lexicon words that may be used as modifiers or negations
if item.lower() in BOOSTER_DICT:
sentiments.append(valence)
continue
if (
i < len(words_and_emoticons) - 1
and item.lower() == "kind"
and words_and_emoticons[i + 1].lower() == "of"
):
sentiments.append(valence)
continue
sentiments = self.sentiment_valence(valence, sentitext, item, i, sentiments)
sentiments = self._but_check(words_and_emoticons, sentiments)
valence_dict = self.score_valence(sentiments, text)
return valence_dict
def sentiment_valence(self, valence, sentitext, item, i, sentiments):
is_cap_diff = sentitext.is_cap_diff
words_and_emoticons = sentitext.words_and_emoticons
item_lowercase = item.lower()
if item_lowercase in self.lexicon:
# get the sentiment valence
valence = self.lexicon[item_lowercase]
# check for "no" as negation for an adjacent lexicon item vs "no" as its own stand-alone lexicon item
if (
item_lowercase == "no"
and i != len(words_and_emoticons) - 1
and words_and_emoticons[i + 1].lower() in self.lexicon
):
# don't use valence of "no" as a lexicon item. Instead set it's valence to 0.0 and negate the next item
valence = 0.0
if (
(i > 0 and words_and_emoticons[i - 1].lower() == "no")
or (i > 1 and words_and_emoticons[i - 2].lower() == "no")
or (
i > 2
and words_and_emoticons[i - 3].lower() == "no"
and words_and_emoticons[i - 1].lower() in ["or", "nor"]
)
):
valence = self.lexicon[item_lowercase] * N_SCALAR
# check if sentiment laden word is in ALL CAPS (while others aren't)
if item.isupper() and is_cap_diff:
if valence > 0:
valence += C_INCR
else:
valence -= C_INCR
for start_i in range(0, 3):
# dampen the scalar modifier of preceding words and emoticons
# (excluding the ones that immediately preceed the item) based
# on their distance from the current item.
if (
i > start_i
and words_and_emoticons[i - (start_i + 1)].lower()
not in self.lexicon
):
s = scalar_inc_dec(
words_and_emoticons[i - (start_i + 1)], valence, is_cap_diff
)
if start_i == 1 and s != 0:
s = s * 0.95
if start_i == 2 and s != 0:
s = s * 0.9
valence = valence + s
valence = self._negation_check(
valence, words_and_emoticons, start_i, i
)
if start_i == 2:
valence = self._special_idioms_check(
valence, words_and_emoticons, i
)
valence = self._least_check(valence, words_and_emoticons, i)
sentiments.append(valence)
return sentiments
def _least_check(self, valence, words_and_emoticons, i):
# check for negation case using "least"
if (
i > 1
and words_and_emoticons[i - 1].lower() not in self.lexicon
and words_and_emoticons[i - 1].lower() == "least"
):
if (
words_and_emoticons[i - 2].lower() != "at"
and words_and_emoticons[i - 2].lower() != "very"
):
valence = valence * N_SCALAR
elif (
i > 0
and words_and_emoticons[i - 1].lower() not in self.lexicon
and words_and_emoticons[i - 1].lower() == "least"
):
valence = valence * N_SCALAR
return valence
@staticmethod
def _but_check(words_and_emoticons, sentiments):
# check for modification in sentiment due to contrastive conjunction 'but'
words_and_emoticons_lower = [str(w).lower() for w in words_and_emoticons]
if "but" in words_and_emoticons_lower:
bi = words_and_emoticons_lower.index("but")
for sentiment in sentiments:
si = sentiments.index(sentiment)
if si < bi:
sentiments.pop(si)
sentiments.insert(si, sentiment * 0.5)
elif si > bi:
sentiments.pop(si)
sentiments.insert(si, sentiment * 1.5)
return sentiments
@staticmethod
def _special_idioms_check(valence, words_and_emoticons, i):
words_and_emoticons_lower = [str(w).lower() for w in words_and_emoticons]
onezero = "{} {}".format(
words_and_emoticons_lower[i - 1], words_and_emoticons_lower[i]
)
twoonezero = "{} {} {}".format(
words_and_emoticons_lower[i - 2],
words_and_emoticons_lower[i - 1],
words_and_emoticons_lower[i],
)
twoone = "{} {}".format(
words_and_emoticons_lower[i - 2], words_and_emoticons_lower[i - 1]
)
threetwoone = "{} {} {}".format(
words_and_emoticons_lower[i - 3],
words_and_emoticons_lower[i - 2],
words_and_emoticons_lower[i - 1],
)
threetwo = "{} {}".format(
words_and_emoticons_lower[i - 3], words_and_emoticons_lower[i - 2]
)
sequences = [onezero, twoonezero, twoone, threetwoone, threetwo]
for seq in sequences:
if seq in SPECIAL_CASES:
valence = SPECIAL_CASES[seq]
break
if len(words_and_emoticons_lower) - 1 > i:
zeroone = "{} {}".format(
words_and_emoticons_lower[i], words_and_emoticons_lower[i + 1]
)
if zeroone in SPECIAL_CASES:
valence = SPECIAL_CASES[zeroone]
if len(words_and_emoticons_lower) - 1 > i + 1:
zeroonetwo = "{} {} {}".format(
words_and_emoticons_lower[i],
words_and_emoticons_lower[i + 1],
words_and_emoticons_lower[i + 2],
)
if zeroonetwo in SPECIAL_CASES:
valence = SPECIAL_CASES[zeroonetwo]
# check for booster/dampener bi-grams such as 'sort of' or 'kind of'
n_grams = [threetwoone, threetwo, twoone]
for n_gram in n_grams:
if n_gram in BOOSTER_DICT:
valence = valence + BOOSTER_DICT[n_gram]
return valence
@staticmethod
def _sentiment_laden_idioms_check(valence, senti_text_lower):
# Future Work
# check for sentiment laden idioms that don't contain a lexicon word
idioms_valences = []
for idiom in SENTIMENT_LADEN_IDIOMS:
if idiom in senti_text_lower:
print(idiom, senti_text_lower)
valence = SENTIMENT_LADEN_IDIOMS[idiom]
idioms_valences.append(valence)
if len(idioms_valences) > 0:
valence = sum(idioms_valences) / float(len(idioms_valences))
return valence
@staticmethod
def _negation_check(valence, words_and_emoticons, start_i, i):
words_and_emoticons_lower = [str(w).lower() for w in words_and_emoticons]
if start_i == 0:
if negated(
[words_and_emoticons_lower[i - (start_i + 1)]]
): # 1 word preceding lexicon word (w/o stopwords)
valence = valence * N_SCALAR
if start_i == 1:
if words_and_emoticons_lower[i - 2] == "never" and (
words_and_emoticons_lower[i - 1] == "so"
or words_and_emoticons_lower[i - 1] == "this"
):
valence = valence * 1.25
elif (
words_and_emoticons_lower[i - 2] == "without"
and words_and_emoticons_lower[i - 1] == "doubt"
):
valence = valence
elif negated(
[words_and_emoticons_lower[i - (start_i + 1)]]
): # 2 words preceding the lexicon word position
valence = valence * N_SCALAR
if start_i == 2:
if (
words_and_emoticons_lower[i - 3] == "never"
and (
words_and_emoticons_lower[i - 2] == "so"
or words_and_emoticons_lower[i - 2] == "this"
)
or (
words_and_emoticons_lower[i - 1] == "so"
or words_and_emoticons_lower[i - 1] == "this"
)
):
valence = valence * 1.25
elif words_and_emoticons_lower[i - 3] == "without" and (
words_and_emoticons_lower[i - 2] == "doubt"
or words_and_emoticons_lower[i - 1] == "doubt"
):
valence = valence
elif negated(
[words_and_emoticons_lower[i - (start_i + 1)]]
): # 3 words preceding the lexicon word position
valence = valence * N_SCALAR
return valence
def _punctuation_emphasis(self, text):
# add emphasis from exclamation points and question marks
ep_amplifier = self._amplify_ep(text)
qm_amplifier = self._amplify_qm(text)
punct_emph_amplifier = ep_amplifier + qm_amplifier
return punct_emph_amplifier
@staticmethod
def _amplify_ep(text):
# check for added emphasis resulting from exclamation points (up to 4 of them)
ep_count = text.count("!")
if ep_count > 4:
ep_count = 4
# (empirically derived mean sentiment intensity rating increase for
# exclamation points)
ep_amplifier = ep_count * 0.292
return ep_amplifier
@staticmethod
def _amplify_qm(text):
# check for added emphasis resulting from question marks (2 or 3+)
qm_count = text.count("?")
qm_amplifier = 0
if qm_count > 1:
if qm_count <= 3:
# (empirically derived mean sentiment intensity rating increase for
# question marks)
qm_amplifier = qm_count * 0.18
else:
qm_amplifier = 0.96
return qm_amplifier
@staticmethod
def _sift_sentiment_scores(sentiments):
# want separate positive versus negative sentiment scores
pos_sum = 0.0
neg_sum = 0.0
neu_count = 0
for sentiment_score in sentiments:
if sentiment_score > 0:
pos_sum += (
float(sentiment_score) + 1
) # compensates for neutral words that are counted as 1
if sentiment_score < 0:
neg_sum += (
float(sentiment_score) - 1
) # when used with math.fabs(), compensates for neutrals
if sentiment_score == 0:
neu_count += 1
return pos_sum, neg_sum, neu_count
def score_valence(self, sentiments, text):
if sentiments:
sum_s = float(sum(sentiments))
# compute and add emphasis from punctuation in text
punct_emph_amplifier = self._punctuation_emphasis(text)
if sum_s > 0:
sum_s += punct_emph_amplifier
elif sum_s < 0:
sum_s -= punct_emph_amplifier
compound = normalize(sum_s)
# discriminate between positive, negative and neutral sentiment scores
pos_sum, neg_sum, neu_count = self._sift_sentiment_scores(sentiments)
if pos_sum > math.fabs(neg_sum):
pos_sum += punct_emph_amplifier
elif pos_sum < math.fabs(neg_sum):
neg_sum -= punct_emph_amplifier
total = pos_sum + math.fabs(neg_sum) + neu_count
pos = math.fabs(pos_sum / total)
neg = math.fabs(neg_sum / total)
neu = math.fabs(neu_count / total)
else:
compound = 0.0
pos = 0.0
neg = 0.0
neu = 0.0
sentiment_dict = {
"neg": round(neg, 3),
"neu": round(neu, 3),
"pos": round(pos, 3),
"compound": round(compound, 4),
}
return sentiment_dict
if __name__ == "__main__":
# --- examples -------
sentences = [
"VADER is smart, handsome, and funny.", # positive sentence example
"VADER is smart, handsome, and funny!",
# punctuation emphasis handled correctly (sentiment intensity adjusted)
"VADER is very smart, handsome, and funny.",
# booster words handled correctly (sentiment intensity adjusted)
"VADER is VERY SMART, handsome, and FUNNY.", # emphasis for ALLCAPS handled
"VADER is VERY SMART, handsome, and FUNNY!!!",
# combination of signals - VADER appropriately adjusts intensity
"VADER is VERY SMART, uber handsome, and FRIGGIN FUNNY!!!",
# booster words & punctuation make this close to ceiling for score
"VADER is not smart, handsome, nor funny.", # negation sentence example
"The book was good.", # positive sentence
"At least it isn't a horrible book.", # negated negative sentence with contraction
"The book was only kind of good.",
# qualified positive sentence is handled correctly (intensity adjusted)
"The plot was good, but the characters are uncompelling and the dialog is not great.",
# mixed negation sentence
"Today SUX!", # negative slang with capitalization emphasis
"Today only kinda sux! But I'll get by, lol",
# mixed sentiment example with slang and constrastive conjunction "but"
"Make sure you :) or :D today!", # emoticons handled
"Catch utf-8 emoji such as 💘 and 💋 and 😁", # emojis handled
"Not bad at all", # Capitalized negation
]
analyzer = SentimentIntensityAnalyzer()
print("----------------------------------------------------")
print(" - Analyze typical example cases, including handling of:")
print(" -- negations")
print(" -- punctuation emphasis & punctuation flooding")
print(" -- word-shape as emphasis (capitalization difference)")
print(
" -- degree modifiers (intensifiers such as 'very' and dampeners such as 'kind of')"
)
print(" -- slang words as modifiers such as 'uber' or 'friggin' or 'kinda'")
print(
" -- contrastive conjunction 'but' indicating a shift in sentiment; sentiment of later text is dominant"
)
print(" -- use of contractions as negations")
print(" -- sentiment laden emoticons such as :) and :D")
print(" -- utf-8 encoded emojis such as 💘 and 💋 and 😁")
print(" -- sentiment laden slang words (e.g., 'sux')")
print(" -- sentiment laden initialisms and acronyms (for example: 'lol') \n")
for sentence in sentences:
vs = analyzer.polarity_scores(sentence)
print(f"{sentence:-<65} {str(vs)}")
print("----------------------------------------------------")
print(" - About the scoring: ")
print(
""" -- The 'compound' score is computed by summing the valence scores of each word in the lexicon, adjusted
according to the rules, and then normalized to be between -1 (most extreme negative) and +1 (most extreme positive).
This is the most useful metric if you want a single unidimensional measure of sentiment for a given sentence.
Calling it a 'normalized, weighted composite score' is accurate."""
)
print(
""" -- The 'pos', 'neu', and 'neg' scores are ratios for proportions of text that fall in each category (so these
should all add up to be 1... or close to it with float operation). These are the most useful metrics if
you want multidimensional measures of sentiment for a given sentence."""
)
print("----------------------------------------------------")
# input("\nPress Enter to continue the demo...\n") # for DEMO purposes...
tricky_sentences = [
"Sentiment analysis has never been good.",
"Sentiment analysis has never been this good!",
"Most automated sentiment analysis tools are shit.",
"With VADER, sentiment analysis is the shit!",
"Other sentiment analysis tools can be quite bad.",
"On the other hand, VADER is quite bad ass",
"VADER is such a badass!", # slang with punctuation emphasis
"Without a doubt, excellent idea.",
"Roger Dodger is one of the most compelling variations on this theme.",
"Roger Dodger is at least compelling as a variation on the theme.",
"Roger Dodger is one of the least compelling variations on this theme.",
"Not such a badass after all.", # Capitalized negation with slang
"Without a doubt, an excellent idea.", # "without {any} doubt" as negation
]
print("----------------------------------------------------")
print(
" - Analyze examples of tricky sentences that cause trouble to other sentiment analysis tools."
)
print(
" -- special case idioms - e.g., 'never good' vs 'never this good', or 'bad' vs 'bad ass'."
)
print(" -- special uses of 'least' as negation versus comparison \n")
for sentence in tricky_sentences:
vs = analyzer.polarity_scores(sentence)
print(f"{sentence:-<69} {str(vs)}")
print("----------------------------------------------------")
# input("\nPress Enter to continue the demo...\n") # for DEMO purposes...
print("----------------------------------------------------")
print(
" - VADER works best when analysis is done at the sentence level (but it can work on single words or entire novels)."
)
paragraph = "It was one of the worst movies I've seen, despite good reviews. Unbelievably bad acting!! Poor direction. VERY poor production. The movie was bad. Very bad movie. VERY BAD movie!"
print(
" -- For example, given the following paragraph text from a hypothetical movie review:\n\t'{}'".format(
paragraph
)
)
print(
" -- You could use NLTK to break the paragraph into sentence tokens for VADER, then average the results for the paragraph like this: \n"
)
# simple example to tokenize paragraph into sentences for VADER
from nltk import tokenize
sentence_list = tokenize.sent_tokenize(paragraph)
paragraphSentiments = 0.0
for sentence in sentence_list:
vs = analyzer.polarity_scores(sentence)
print("{:-<69} {}".format(sentence, str(vs["compound"])))
paragraphSentiments += vs["compound"]
print(
"AVERAGE SENTIMENT FOR PARAGRAPH: \t"
+ str(round(paragraphSentiments / len(sentence_list), 4))
)
print("----------------------------------------------------")
# input("\nPress Enter to continue the demo...\n") # for DEMO purposes...
print("----------------------------------------------------")
print(
" - Analyze sentiment of IMAGES/VIDEO data based on annotation 'tags' or image labels. \n"
)
conceptList = [
"balloons",
"cake",
"candles",
"happy birthday",
"friends",
"laughing",
"smiling",
"party",
]
conceptSentiments = 0.0
for concept in conceptList:
vs = analyzer.polarity_scores(concept)
print("{:-<15} {}".format(concept, str(vs["compound"])))
conceptSentiments += vs["compound"]
print(
"AVERAGE SENTIMENT OF TAGS/LABELS: \t"
+ str(round(conceptSentiments / len(conceptList), 4))
)
print("\t")
conceptList = ["riot", "fire", "fight", "blood", "mob", "war", "police", "tear gas"]
conceptSentiments = 0.0
for concept in conceptList:
vs = analyzer.polarity_scores(concept)
print("{:-<15} {}".format(concept, str(vs["compound"])))
conceptSentiments += vs["compound"]
print(
"AVERAGE SENTIMENT OF TAGS/LABELS: \t"
+ str(round(conceptSentiments / len(conceptList), 4))
)
print("----------------------------------------------------")
# input("\nPress Enter to continue the demo...") # for DEMO purposes...
do_translate = input(
"\nWould you like to run VADER demo examples with NON-ENGLISH text? \n (Note: requires Internet access and uses the 'requests' library) \n Type 'y' or 'n', then press Enter: "
)
if do_translate.lower().lstrip().__contains__("y"):
import requests
print("\n----------------------------------------------------")
print(" - Analyze sentiment of NON ENGLISH text...for example:")
print(
" -- French, German, Spanish, Italian, Russian, Japanese, Arabic, Chinese(Simplified) , Chinese(Traditional)"
)
print(" -- many other languages supported. \n")
languages = [
"English",
"French",
"German",
"Spanish",
"Italian",
"Russian",
"Japanese",
"Arabic",
"Chinese(Simplified)",
"Chinese(Traditional)",
]
language_codes = [
"en",
"fr",
"de",
"es",
"it",
"ru",
"ja",
"ar",
"zh-CN",
"zh-TW",
]
nonEnglish_sentences = [
"I'm surprised to see just how amazingly helpful VADER is!",
"Je suis surpris de voir comment VADER est incroyablement utile !",
"Ich bin überrascht zu sehen, nur wie erstaunlich nützlich VADER!",
"Me sorprende ver sólo cómo increíblemente útil VADER!",
"Sono sorpreso di vedere solo come incredibilmente utile VADER è!",
"Я удивлен увидеть, как раз как удивительно полезно ВЕЙДЕРА!",
"私はちょうどどのように驚くほど役に立つベイダーを見て驚いています!",
"أنا مندهش لرؤية فقط كيف مثير للدهشة فيدر فائدة!",
"我很惊讶地看到VADER是如此有用!",
"我很驚訝地看到VADER是如此有用!",
]
for sentence in nonEnglish_sentences:
to_lang = "en"
from_lang = language_codes[nonEnglish_sentences.index(sentence)]
if (from_lang == "en") or (from_lang == "en-US"):
translation = sentence
translator_name = "No translation needed"
else: # please note usage limits for My Memory Translation Service: http://mymemory.translated.net/doc/usagelimits.php
# using MY MEMORY NET http://mymemory.translated.net
api_url = (
"http://mymemory.translated.net/api/get?q={}&langpair={}|{}".format(
sentence, from_lang, to_lang
)
)
hdrs = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
"Accept-Encoding": "none",
"Accept-Language": "en-US,en;q=0.8",
"Connection": "keep-alive",
}
response = requests.get(api_url, headers=hdrs)
response_json = json.loads(response.text)
translation = response_json["responseData"]["translatedText"]
translator_name = "MemoryNet Translation Service"
vs = analyzer.polarity_scores(translation)
print(
"- {: <8}: {: <69}\t {} ({})".format(
languages[nonEnglish_sentences.index(sentence)],
sentence,
str(vs["compound"]),
translator_name,
)
)
print("----------------------------------------------------")
print("\n\n Demo Done!")

File diff suppressed because it is too large Load Diff

View File

@@ -529,28 +529,34 @@ class CryptoController(CryptoBaseController):
@log_start_end(log=logger)
def call_pred(self, _):
"""Process pred command"""
if self.coin:
try:
from gamestonk_terminal.cryptocurrency.prediction_techniques import (
pred_controller,
)
if self.current_interval != "1day":
console.print("Only interval `1day` is possible for now.\n")
else:
self.queue = self.load_class(
pred_controller.PredictionTechniquesController,
self.coin,
self.current_df,
self.queue,
if gtff.ENABLE_PREDICT:
if self.coin:
try:
from gamestonk_terminal.cryptocurrency.prediction_techniques import (
pred_controller,
)
except ImportError:
logger.exception("Tensorflow not available")
console.print("[red]Run pip install tensorflow to continue[/red]\n")
if self.current_interval != "1day":
console.print("Only interval `1day` is possible for now.\n")
else:
self.queue = self.load_class(
pred_controller.PredictionTechniquesController,
self.coin,
self.current_df,
self.queue,
)
except ImportError:
logger.exception("Tensorflow not available")
console.print("[red]Run pip install tensorflow to continue[/red]\n")
else:
console.print(
"No coin selected. Use 'load' to load the coin you want to look at.\n"
)
else:
console.print(
"No coin selected. Use 'load' to load the coin you want to look at.\n"
"Predict is disabled. Check ENABLE_PREDICT flag on feature_flags.py",
"\n",
)
@log_start_end(log=logger)

View File

@@ -1,71 +1,130 @@
import os
import json
from distutils.util import strtobool
from typing import Union, Optional
from dotenv import load_dotenv
gtff_defaults_path = os.path.join(os.path.dirname(__file__), "GTFF_DEFAULTS.json")
if os.path.exists(gtff_defaults_path):
with open(gtff_defaults_path) as f:
GTFF_DEFAULTS = json.load(f)
else:
GTFF_DEFAULTS = dict()
env_files = [f for f in os.listdir() if f.endswith(".env")]
if env_files:
load_dotenv(env_files[0])
def assign_feature_flag(
feature_flag: str, fallback_value: str, return_bool: bool = False
) -> Optional[Union[str, bool]]:
"""Get the feature flag value in order of priority.
- Env variables have the highest priority
- The GTFF_DEFAULTS dictionary has the defaults for the bundled app
- Fallback value is used if none of the above mentioned places have feature flag settings
Parameters
----------
feature_flag : str
Feature flag as upper-case string
fallback_value : str
Fallback vabue
return_bool : bool, optional
If a boolean should be returned vs a string, by default False
Returns
-------
Optional[Union[str, bool]]
The feature flag value or None
"""
if bool(os.getenv(feature_flag)):
feature_flag_value = (
strtobool(os.getenv(feature_flag)) # type: ignore
if return_bool
else os.getenv(feature_flag)
)
elif feature_flag in GTFF_DEFAULTS:
feature_flag_value = (
strtobool(GTFF_DEFAULTS[feature_flag])
if return_bool
else GTFF_DEFAULTS[feature_flag]
)
else:
feature_flag_value = (
strtobool(fallback_value) if return_bool else fallback_value
)
return feature_flag_value
# Use tabulate to print dataframes
USE_TABULATE_DF = strtobool(os.getenv("GTFF_USE_TABULATE_DF", "True"))
USE_TABULATE_DF = assign_feature_flag("GTFF_USE_TABULATE_DF", "True", True)
# Use clear console after each command
USE_CLEAR_AFTER_CMD = strtobool(os.getenv("GTFF_USE_CLEAR_AFTER_CMD", "False"))
USE_CLEAR_AFTER_CMD = assign_feature_flag("GTFF_USE_CLEAR_AFTER_CMD", "False", True)
# Use coloring features
USE_COLOR = strtobool(os.getenv("GTFF_USE_COLOR", "True"))
USE_COLOR = assign_feature_flag("GTFF_USE_COLOR", "True", True)
# Select console flair (choose from config_terminal.py list)
USE_FLAIR = os.getenv("GTFF_USE_FLAIR") or ":stars"
USE_FLAIR = assign_feature_flag("GTFF_USE_FLAIR", ":stars")
# Add date and time to command line
USE_DATETIME = strtobool(os.getenv("GTFF_USE_DATETIME", "True"))
USE_DATETIME = assign_feature_flag("GTFF_USE_DATETIME", "True", True)
# Enable interactive matplotlib mode
USE_ION = strtobool(os.getenv("GTFF_USE_ION", "True"))
USE_ION = assign_feature_flag("GTFF_USE_ION", "True", True)
# Enable watermark in the figures
USE_WATERMARK = strtobool(os.getenv("GTFF_USE_WATERMARK", "True"))
USE_WATERMARK = assign_feature_flag("GTFF_USE_WATERMARK", "True", True)
# Enable command and source in the figures
USE_CMD_LOCATION_FIGURE = strtobool(os.getenv("GTFF_USE_CMD_LOCATION_FIGURE", "True"))
USE_CMD_LOCATION_FIGURE = assign_feature_flag(
"GTFF_USE_CMD_LOCATION_FIGURE", "True", True
)
# Enable Prompt Toolkit
USE_PROMPT_TOOLKIT = strtobool(os.getenv("GTFF_USE_PROMPT_TOOLKIT", "True"))
USE_PROMPT_TOOLKIT = assign_feature_flag("GTFF_USE_PROMPT_TOOLKIT", "True", True)
# Enable Prediction features
ENABLE_PREDICT = strtobool(os.getenv("GTFF_ENABLE_PREDICT", "True"))
ENABLE_PREDICT = assign_feature_flag("GTFF_ENABLE_PREDICT", "True", True)
# Enable plot autoscaling
USE_PLOT_AUTOSCALING = strtobool(os.getenv("GTFF_USE_PLOT_AUTOSCALING", "False"))
USE_PLOT_AUTOSCALING = assign_feature_flag("GTFF_USE_PLOT_AUTOSCALING", "False", True)
# Enable thoughts of the day
ENABLE_THOUGHTS_DAY = strtobool(os.getenv("GTFF_ENABLE_THOUGHTS_DAY", "False"))
ENABLE_THOUGHTS_DAY = assign_feature_flag("GTFF_ENABLE_THOUGHTS_DAY", "False", True)
# Quick exit for testing
ENABLE_QUICK_EXIT = strtobool(os.getenv("GTFF_ENABLE_QUICK_EXIT", "False"))
ENABLE_QUICK_EXIT = assign_feature_flag("GTFF_ENABLE_QUICK_EXIT", "False", True)
# Open report as HTML, otherwise notebook
OPEN_REPORT_AS_HTML = strtobool(os.getenv("GTFF_OPEN_REPORT_AS_HTML", "True"))
OPEN_REPORT_AS_HTML = assign_feature_flag("GTFF_OPEN_REPORT_AS_HTML", "True", True)
# Enable auto print_help when exiting menus
ENABLE_EXIT_AUTO_HELP = strtobool(os.getenv("GTFF_ENABLE_EXIT_AUTO_HELP", "False"))
ENABLE_EXIT_AUTO_HELP = assign_feature_flag("GTFF_ENABLE_EXIT_AUTO_HELP", "False", True)
# Remember contexts during session
REMEMBER_CONTEXTS = strtobool(os.getenv("GTFF_REMEMBER_CONTEXTS", "True"))
REMEMBER_CONTEXTS = assign_feature_flag("GTFF_REMEMBER_CONTEXTS", "True", True)
# Use the colorful rich terminal
ENABLE_RICH = strtobool(os.getenv("GTFF_ENABLE_RICH", "True"))
ENABLE_RICH = assign_feature_flag("GTFF_ENABLE_RICH", "True", True)
# Use the colorful rich terminal
ENABLE_RICH_PANEL = strtobool(os.getenv("GTFF_ENABLE_RICH_PANEL", "True"))
ENABLE_RICH_PANEL = assign_feature_flag("GTFF_ENABLE_RICH_PANEL", "True", True)
# Check API KEYS before running a command
ENABLE_CHECK_API = strtobool(os.getenv("GTFF_ENABLE_CHECK_API", "True"))
ENABLE_CHECK_API = assign_feature_flag("GTFF_ENABLE_CHECK_API", "True", True)
# Send logs to data lake
LOG_COLLECTION = strtobool(os.getenv("GTFF_LOG_COLLECTION", "True"))
LOG_COLLECTION = bool(assign_feature_flag("GTFF_LOG_COLLECTION", "True", True))
# Provide export folder path. If empty that means default.
EXPORT_FOLDER_PATH = os.getenv("GTFF_EXPORT_FOLDER_PATH", "")
EXPORT_FOLDER_PATH = assign_feature_flag("GTFF_EXPORT_FOLDER_PATH", "")
# Set a flag if the application is running from a packaged bundle
PACKAGED_APPLICATION = assign_feature_flag("GTFF_PACKAGED_APPLICATION", "False", True)
LOGGING_COMMIT_HASH = str(assign_feature_flag("GTFF_LOGGING_COMMIT_HASH", "REPLACE_ME"))

View File

@@ -966,7 +966,11 @@ def get_flair() -> str:
":yy": "(☯)",
}
flair = flairs[gtff.USE_FLAIR] if gtff.USE_FLAIR in flairs else gtff.USE_FLAIR
flair = (
flairs[str(gtff.USE_FLAIR)]
if str(gtff.USE_FLAIR) in flairs
else str(gtff.USE_FLAIR)
)
if gtff.USE_DATETIME and get_user_timezone_or_invalid() != "INVALID":
dtime = datetime.now(pytz.timezone(get_user_timezone())).strftime(
"%Y %b %d, %H:%M"
@@ -1174,13 +1178,30 @@ def export_data(
now = datetime.now()
if gtff.EXPORT_FOLDER_PATH:
full_path_dir = gtff.EXPORT_FOLDER_PATH
full_path_dir = str(gtff.EXPORT_FOLDER_PATH)
path_cmd = dir_path.split("gamestonk_terminal/")[1].replace("/", "_")
default_filename = f"{now.strftime('%Y%m%d_%H%M%S')}_{path_cmd}_{func_name}"
else:
full_path_dir = dir_path.replace("gamestonk_terminal", "exports")
default_filename = f"{func_name}_{now.strftime('%Y%m%d_%H%M%S')}"
if gtff.PACKAGED_APPLICATION:
default_filename = (
f"{now.strftime('%Y%m%d_%H%M%S')}_{path_cmd}_{func_name}"
)
full_path_dir = os.path.join(
os.environ["HOME"], "Desktop", "GST-exports"
)
if not os.path.isdir(full_path_dir):
try:
os.makedirs(full_path_dir)
except Exception:
console.print(
f"[red]Couldn't create a folder in {full_path_dir}. Exporting failed.[/red]"
)
return
else:
default_filename = f"{func_name}_{now.strftime('%Y%m%d_%H%M%S')}"
full_path_dir = dir_path.replace("gamestonk_terminal", "exports")
for exp_type in export_type.split(","):

View File

@@ -0,0 +1,284 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "da655985-c9b7-492e-aefa-fbe3bc1865d5",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"import time\n",
"from datetime import datetime, timedelta\n",
"from typing import Optional\n",
"\n",
"import ipywidgets as ipw\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib_inline.backend_inline\n",
"from ipyflex import FlexLayout\n",
"from widget_helpers import price_card, stylesheet\n",
"\n",
"from gamestonk_terminal import api as gst\n",
"\n",
"%matplotlib widget\n",
"gst.theme.applyMPLstyle()\n",
"ipw.HTML(f\"<style>{stylesheet()}</style>\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f5905453-4de6-4f5f-8012-9acdfca50987",
"metadata": {},
"outputs": [],
"source": [
"def get_exchange_rate(currency_pair: str) -> str:\n",
" \"\"\"Get exchange rate for a currency pair.\"\"\"\n",
" from_symbol, to_symbol = currency_pair.split(\"/\")\n",
" exchange_data = gst.forex.models.av.get_quote(\n",
" to_symbol=to_symbol, from_symbol=from_symbol\n",
" )\n",
" return exchange_data[\"Realtime Currency Exchange Rate\"][\"5. Exchange Rate\"][:6]\n",
"\n",
"\n",
"def get_candle_widget(\n",
" output: Optional[ipw.Output],\n",
" to_symbol: str,\n",
" from_symbol: str,\n",
") -> ipw.Output:\n",
" \"\"\"Plot a candle chart for a currency pair.\"\"\"\n",
" start_date = datetime.now() - timedelta(days=1)\n",
" start_date = start_date.strftime(\"%Y-%m-%d\")\n",
"\n",
" exchange_rate_data = gst.forex.models.av.get_historical(\n",
" to_symbol=to_symbol,\n",
" from_symbol=from_symbol,\n",
" start_date=start_date,\n",
" resolution=\"i\",\n",
" interval=\"15\",\n",
" )\n",
" fig, ax = plt.subplots(1, 1, figsize=(11, 4))\n",
" gst.forex.candle(\n",
" data=exchange_rate_data,\n",
" to_symbol=to_symbol,\n",
" from_symbol=from_symbol,\n",
" external_axes=[ax],\n",
" )\n",
"\n",
" ax.set_xlim(0, len(exchange_rate_data.index))\n",
" fig.canvas.header_visible = False\n",
" fig.canvas.footer_visible = False\n",
" with output:\n",
" output.clear_output(True)\n",
" fig.canvas.show()\n",
" return output\n",
"\n",
"\n",
"def on_dropdown_change(change):\n",
" \"\"\"Update charts on change of dropdown selection.\"\"\"\n",
" if change[\"type\"] == \"change\" and change[\"name\"] == \"value\":\n",
" output = ipw.Output()\n",
" get_candle_widget(\n",
" to_symbol=to_widget.value,\n",
" from_symbol=from_widget.value,\n",
" )\n",
" dashboard.children[\"Candle\"] = output"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c768d15-37ad-441b-b069-506c4bdbb9a7",
"metadata": {},
"outputs": [],
"source": [
"exchange_rates = {\n",
" \"EUR/USD\": {\"latest\": None, \"previous\": None},\n",
" \"USD/JPY\": {\"latest\": None, \"previous\": None},\n",
" \"GBP/USD\": {\"latest\": None, \"previous\": None},\n",
" \"AUD/USD\": {\"latest\": None, \"previous\": None},\n",
" \"USD/CAD\": {\"latest\": None, \"previous\": None},\n",
" # \"USD/CNY\": {\"latest\": None, \"previous\": None},\n",
" # \"USD/CHF\": {\"latest\": None, \"previous\": None},\n",
" # \"USD/HKD\": {\"latest\": None, \"previous\": None},\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4968ab89-aafe-4234-933c-963bd672715d",
"metadata": {},
"outputs": [],
"source": [
"def compose_widgets():\n",
" widgets = {}\n",
" for currency_pair in exchange_rates:\n",
" price = exchange_rates[currency_pair][\"latest\"]\n",
" price_color = \"neutral_color\"\n",
" if exchange_rates[currency_pair][\"previous\"] is not None:\n",
" if (\n",
" exchange_rates[currency_pair][\"latest\"]\n",
" > exchange_rates[currency_pair][\"previous\"]\n",
" ):\n",
" price_color = \"up_color\"\n",
" elif (\n",
" exchange_rates[currency_pair][\"latest\"]\n",
" < exchange_rates[currency_pair][\"previous\"]\n",
" ):\n",
" price_color = \"down_color\"\n",
" widgets[currency_pair] = ipw.HTML(\n",
" price_card(ticker=currency_pair, price=price, price_color=price_color)\n",
" )\n",
" return widgets"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f35d1500-a411-4cff-94ee-d65d4d1810f9",
"metadata": {},
"outputs": [],
"source": [
"# for currency_code in rates_to_usd:\n",
"# rates_to_usd[currency_code][\"previous\"] = rates_to_usd[currency_code][\"latest\"]\n",
"# rates_to_usd[currency_code][\"latest\"] = get_rate_against_usd(currency_code)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8a72837b-4ddd-4c01-a493-ebb430202cbc",
"metadata": {},
"outputs": [],
"source": [
"widgets = compose_widgets()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c636543c-42fe-4dd6-a900-1552a3c28c7e",
"metadata": {},
"outputs": [],
"source": [
"currency_list = gst.forex.models.av.get_currency_list()\n",
"from_widget = ipw.Dropdown(\n",
" options=currency_list,\n",
" value=\"EUR\",\n",
" description=\"From:\",\n",
" disabled=False,\n",
" layout=ipw.Layout(margin=\"130\"),\n",
")\n",
"to_widget = ipw.Dropdown(\n",
" options=currency_list,\n",
" value=\"USD\",\n",
" description=\"To:\",\n",
" disabled=False,\n",
")\n",
"exchange_selection = ipw.VBox([from_widget, to_widget])\n",
"\n",
"widgets[\"Select\"] = exchange_selection"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9d069845-d622-4878-8b18-b385c6cb7a7f",
"metadata": {},
"outputs": [],
"source": [
"output = ipw.Output()\n",
"output = get_candle_widget(\n",
" output=output,\n",
" to_symbol=to_widget.value,\n",
" from_symbol=from_widget.value,\n",
")\n",
"widgets[\"Candle\"] = output"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "81c7e5c7-2e52-45ba-bf7d-aa240f95be2d",
"metadata": {},
"outputs": [],
"source": [
"from_widget.observe(on_dropdown_change)\n",
"to_widget.observe(on_dropdown_change)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a0c7d921-e5dc-4ce8-97f1-a59b414a676a",
"metadata": {},
"outputs": [],
"source": [
"dashboard = FlexLayout(\n",
" layout_config={\"borderLeft\": False, \"borderRight\": False, \"enableSection\": False},\n",
" style={\n",
" \"height\": \"calc(100vh - 80px)\",\n",
" \"backgroundColor\": \"rgb(0 0 0)\",\n",
" \"fontFamily\": \"Consolas\",\n",
" \"fontWeight\": 800,\n",
" },\n",
" header={\n",
" \"title\": \"Currencies\",\n",
" \"style\": {\n",
" \"backgroundColor\": \"rgb(0 0 0)\",\n",
" \"fontWeight\": 400,\n",
" \"fontSize\": \"28px\",\n",
" },\n",
" \"buttons\": [],\n",
" },\n",
" widgets=widgets,\n",
" template=os.path.join(\"widgets\", \"currencies.json\"),\n",
" editable=False,\n",
")\n",
"dashboard"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5fedac44-5e09-44f0-bbbe-fbad7c8716cd",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "3c850ba2-408b-4061-947e-5a1b8a284d22",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.12"
},
"voila": {
"theme": "dark"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,42 @@
"""Widgets Helper Library.
A library of `ipywidgets` wrappers for notebook based reports and voila dashboards.
The library includes both python code and html/css/js elements that can be found in the
`./widgets` folder.
"""
import os
from jinja2 import Template
def stylesheet():
"""Load a default CSS stylesheet from file."""
with open(
os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "style.css")
) as f:
style = f.read()
return style
def price_card(ticker: str, price: str, price_color: str = "neutral_color") -> str:
"""Prepare a styled HTML element of a 128 by 128 price card.
Parameters
----------
ticker : str
Instrument ticker for the price card
price : str
Instrument price as a string
price_color : str, optional
The color of the price. Accepts "up_color", "down_color" and default "neutral_color"
Returns
-------
str
HTML code as string
"""
with open(
os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "card.j2")
) as f:
template = Template(f.read())
card = template.render(ticker=ticker, price=price, price_color=price_color)
return card

View File

@@ -0,0 +1,8 @@
<div class="container">
<div class="card">
<div class="contentBx">
<h1>{{ ticker }}</h1>
<h2 class="{{ price_color }}">{{ price }}</h2>
</div>
</div>
</div>

View File

@@ -0,0 +1,237 @@
{
"global": {
"tabSetEnableClose": true,
"tabSetEnableTabStrip": false,
"tabSetTabLocation": "bottom"
},
"borders": [],
"layout": {
"type": "row",
"id": "#1",
"children": [
{
"type": "tabset",
"id": "#2",
"children": [
{
"type": "tab",
"id": "#3",
"name": "New section ",
"component": "sub",
"config": {
"model": {
"global": {
"tabSetEnableClose": true
},
"borders": [],
"layout": {
"type": "row",
"id": "#1",
"children": [
{
"type": "row",
"id": "#930eb3e5-1999-46b8-afc6-01d731dcb211",
"children": [
{
"type": "row",
"id": "#5debcdc6-eaaf-4224-83a7-17f9908a7a78",
"height": 145,
"children": [
{
"type": "tabset",
"id": "#ca43de5d-5956-4fe3-8f55-94eb954a2886",
"width": 142,
"children": [
{
"type": "tab",
"id": "#ff22f410-6265-4a7b-b975-1dc8676fb138",
"name": "EUR/USD",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#6bf131b1-a6eb-4b8f-941a-14e0655acd79",
"width": 142,
"children": [
{
"type": "tab",
"id": "#8b10c77b-40f2-40e6-9673-13ddcc8238c1",
"name": "USD/JPY",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#6939401f-4c4d-41dd-9849-fd3178320122",
"width": 142,
"children": [
{
"type": "tab",
"id": "#7bd5f16d-d127-46f8-86a0-f413feff3b92",
"name": "GBP/USD",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#61c25933-b899-4d59-aad8-e1e98df13b7d",
"width": 142,
"children": [
{
"type": "tab",
"id": "#762d37fc-312e-4f16-8541-af486fe2ec4f",
"name": "AUD/USD",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#d44c4bf6-c879-46fc-bb57-80fd352ae872",
"width": 142,
"children": [
{
"type": "tab",
"id": "#fc1a8e88-160f-41d3-b5d8-d4d9abc5ac44",
"name": "USD/CAD",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#298c01a6-e058-4e2d-8ac6-ebb279716761",
"width": 142,
"children": [
{
"type": "tab",
"id": "#c2dfcb8c-9078-44f1-9118-3beebc3181d4",
"name": "USD/CNY",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#f544d439-5557-470f-ad2b-8f6168a40b77",
"width": 142,
"children": [
{
"type": "tab",
"id": "#d1f5dcf1-5643-49dd-aa28-725287f1b3f2",
"name": "USD/CHF",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#bcbbac20-d71f-4e6a-990e-b2a5d0a11255",
"width": 142,
"children": [
{
"type": "tab",
"id": "#65907a81-d976-482a-b1df-45de9317cad2",
"name": "USD/HKD",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
}
]
},
{
"type": "row",
"id": "#410cd13c-0d14-4ada-8aad-5cfc522d1421",
"weight": 15,
"children": [
{
"type": "tabset",
"id": "#d83b1943-b895-43bd-9f0f-d36672194a58",
"width": 256,
"children": [
{
"type": "tab",
"id": "#044a38ed-6f61-4586-ae3f-8c76c494351b",
"name": "Select",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
},
{
"type": "tabset",
"id": "#239aa076-2c4d-44da-a9ed-6f8ad9b27c30",
"weight": 75,
"children": [
{
"type": "tab",
"id": "#3f45998e-34f5-42b0-9980-d07f9fff2eb5",
"name": "Historical",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
}
]
},
{
"type": "tabset",
"id": "#1fd33f67-3fdd-4f36-822a-ac0ee05ad8ab",
"weight": 85,
"children": [
{
"type": "tab",
"id": "#4b4ab553-fc3a-4984-93ad-99b89def2dc4",
"name": "Candle",
"component": "Widget",
"config": {
"layoutID": "#3"
}
}
]
}
]
}
]
}
}
}
}
],
"active": true
}
]
}
}

View File

@@ -0,0 +1,54 @@
.container {
position: relative;
}
.container .card {
font-family: Consolas, sans-serif;
position: relative;
width: 128px;
height: 128px;
background: #000000;
border-radius: 5px;
border-color: rgb(142, 142, 142);
border-style: solid;
border-width: 0.5px;
overflow: hidden;
}
.container .card .contentBx {
position: absolute;
top: 28;
bottom: 32;
width: 100%;
text-align: center;
z-index: 10;
}
.container .card .contentBx h1 {
position: relative;
font-size: 28;
font-weight: 600;
letter-spacing: 1px;
color: #fff;
margin-top: 28px;
margin-bottom: 10px;
}
.container .card .contentBx h2 {
position: relative;
font-size: 28px;
font-weight: 600;
letter-spacing: 1px;
}
.up_color {
color: #00ACFF;
}
.down_color {
color: #e4003a;
}
.neutral_color {
color: #ffed00;
}

View File

@@ -10,9 +10,13 @@ from pathlib import Path
from typing import Optional
# IMPORTATION THIRDPARTY
import git
try:
import git
except ImportError:
pass
# IMPORTATION INTERNAL
import gamestonk_terminal.feature_flags as gtff
from gamestonk_terminal.config_terminal import (
LOGGING_APP_NAME,
LOGGING_AWS_ACCESS_KEY_ID,
@@ -55,6 +59,9 @@ def get_app_id() -> str:
def get_commit_hash() -> str:
"""Get Commit Short Hash"""
if gtff.LOGGING_COMMIT_HASH != "REPLACE_ME":
return gtff.LOGGING_COMMIT_HASH
file_path = Path(__file__)
git_dir = file_path.parent.parent.absolute().joinpath(".git")

View File

@@ -66,6 +66,10 @@ def sha256sum(filename):
def update_terminal():
"""Updates the terminal by running git pull in the directory. Runs poetry install if needed"""
if gtff.LOGGING_COMMIT_HASH != "REPLACE_ME":
return 0
poetry_hash = sha256sum("poetry.lock")
completed_process = subprocess.run("git pull", shell=True, check=False) # nosec
@@ -81,9 +85,9 @@ def update_terminal():
"Seems like more modules have been added, grab a coke, this may take a while."
)
completed_process = subprocess.run(
completed_process = subprocess.run( # nosec
"poetry install", shell=True, check=False
) # nosec
)
if completed_process.returncode != 0:
return completed_process.returncode
@@ -110,30 +114,52 @@ def about_us():
console.print(
"[green]Thanks for using Gamestonk Terminal. This is our way![/green]\n"
"\n"
"[cyan]Join our community on discord: [/cyan]https://discord.gg/Up2QGbMKHY\n"
"[cyan]Follow our twitter for updates: [/cyan]https://twitter.com/gamestonkt\n"
"[cyan]Access our landing page: [/cyan]https://gamestonkterminal.github.io/GamestonkTerminal/\n"
"\n"
"[yellow]Partnerships:[/yellow]\n"
"[cyan]FinBrain: [/cyan]https://finbrain.tech\n"
"[cyan]Quiver Quantitative: [/cyan]https://www.quiverquant.com\n"
"[cyan]SentimentInvestor: [/cyan]https://sentimentinvestor.com\n"
"\n[red]"
"DISCLAIMER: Trading in financial instruments involves high risks including the risk of losing some, "
"or all, of your investment amount, and may not be suitable for all investors. Before deciding to trade in "
"financial instrument you should be fully informed of the risks and costs associated with trading the financial "
"markets, carefully consider your investment objectives, level of experience, and risk appetite, and seek "
"professional advice where needed. The data contained in Gamestonk Terminal (GST) is not necessarily accurate. "
"GST and any provider of the data contained in this website will not accept liability for any loss or damage "
"as a result of your trading, or your reliance on the information displayed.[/red]\n"
+ "\n"
+ "[cyan]Join our community on discord: [/cyan]https://discord.gg/Up2QGbMKHY\n"
+ "[cyan]Follow our twitter for updates: [/cyan]https://twitter.com/gamestonkt\n"
+ "[cyan]Access our landing page: [/cyan]https://gamestonkterminal.github.io/GamestonkTerminal/\n"
+ "\n"
+ "[yellow]Partnerships:[/yellow]\n"
+ "[cyan]FinBrain: [/cyan]https://finbrain.tech\n"
+ "[cyan]Quiver Quantitative: [/cyan]https://www.quiverquant.com\n"
+ "[cyan]SentimentInvestor: [/cyan]https://sentimentinvestor.com\n"
+ "\n[red]"
+ "DISCLAIMER: Trading in financial instruments involves high risks including the risk of losing some, "
+ "or all, of your investment amount, and may not be suitable for all investors. Before deciding to "
+ "trade in financial instrument you should be fully informed of the risks and costs associated with "
+ "trading the financial markets, carefully consider your investment objectives, level of experience, "
+ "and risk appetite, and seek professional advice where needed.\n"
+ "The data contained in Gamestonk Terminal (GST) is not necessarily accurate. GST and any provider "
+ "of the data contained in this software will not accept liability for any loss or damage "
+ "as a result of your trading, or your reliance on the information displayed.[/red]\n"
)
def hide_splashscreen():
"""Hide the splashscreen on Windows bundles.
`pyi_splash` is a PyInstaller "fake-package" that's used to communicate
with the splashscreen on Windows.
Sending the `close` signal to the splash screen is required.
The splash screen remains open until this function is called or the Python
program is terminated.
"""
try:
import pyi_splash # type: ignore # pylint: disable=import-outside-toplevel
pyi_splash.update_text("Terminal Loaded!")
pyi_splash.close()
except Exception as e:
logger.info(e)
def bootup():
# Enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607
if sys.platform == "win32":
# Enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607
os.system("") # nosec
# Hide splashscreen loader of the packaged app
if gtff.PACKAGED_APPLICATION:
hide_splashscreen()
try:
if os.name == "nt":

BIN
images/GamestonkTerminal.icns vendored Normal file

Binary file not shown.

BIN
images/dmg_background.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
images/gst_app.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
images/splashscreen.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

121
poetry.lock generated vendored
View File

@@ -60,6 +60,14 @@ python-versions = "*"
aiohttp = "*"
requests = "*"
[[package]]
name = "altgraph"
version = "0.17.2"
description = "Python graph (network) package"
category = "main"
optional = true
python-versions = "*"
[[package]]
name = "ansiwrap"
version = "0.8.4"
@@ -1413,11 +1421,11 @@ pygls = ">=0.11.1,<0.12.0"
[[package]]
name = "jinja2"
version = "3.1.0"
version = "3.0.3"
description = "A very fast and expressive template engine."
category = "main"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.6"
[package.dependencies]
MarkupSafe = ">=2.0"
@@ -1773,6 +1781,17 @@ python-versions = "*"
docutils = "*"
mistune = "*"
[[package]]
name = "macholib"
version = "1.16"
description = "Mach-O header analysis and editing"
category = "main"
optional = true
python-versions = "*"
[package.dependencies]
altgraph = ">=0.15"
[[package]]
name = "markdown"
version = "3.3.6"
@@ -2370,6 +2389,17 @@ category = "dev"
optional = false
python-versions = ">=2.6"
[[package]]
name = "pefile"
version = "2021.9.3"
description = "Python PE parsing module"
category = "main"
optional = true
python-versions = ">=3.6.0"
[package.dependencies]
future = "*"
[[package]]
name = "pexpect"
version = "4.8.0"
@@ -2752,6 +2782,33 @@ python-versions = "*"
[package.dependencies]
requests = "*"
[[package]]
name = "pyinstaller"
version = "4.10"
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
category = "main"
optional = true
python-versions = "<3.11,>=3.6"
[package.dependencies]
altgraph = "*"
macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""}
pefile = {version = ">=2017.8.1", markers = "sys_platform == \"win32\""}
pyinstaller-hooks-contrib = ">=2020.6"
pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""}
[package.extras]
encryption = ["tinyaes (>=1.0.0)"]
hook_testing = ["pytest (>=2.7.3)", "execnet (>=1.5.0)", "psutil"]
[[package]]
name = "pyinstaller-hooks-contrib"
version = "2022.2"
description = "Community maintained hooks for PyInstaller"
category = "main"
optional = true
python-versions = ">=3.7"
[[package]]
name = "pylint"
version = "2.13.0"
@@ -3093,6 +3150,14 @@ category = "main"
optional = false
python-versions = "*"
[[package]]
name = "pywin32-ctypes"
version = "0.2.0"
description = ""
category = "main"
optional = true
python-versions = "*"
[[package]]
name = "pywinpty"
version = "2.0.5"
@@ -4069,6 +4134,14 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "types-six"
version = "1.16.12"
description = "Typing stubs for six"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "types-urllib3"
version = "1.26.11"
@@ -4407,13 +4480,14 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
[extras]
bots = ["boto3", "pyimgur", "fastapi", "uvicorn", "disnake", "PyNaCl", "pyTelegramBotAPI", "slack-bolt", "undetected-chromedriver", "natsort", "kaleido"]
installer = ["pyinstaller"]
jupyterlab = ["jupyterlab-code-formatter", "jupyterlab-lsp", "jedi-language-server"]
prediction = ["tensorflow"]
[metadata]
lock-version = "1.1"
python-versions = "^3.8,<3.10"
content-hash = "23c984180dd26ed0132f110d22bc2477c8af574e40572a8106c1ccf39a1fb4ec"
content-hash = "7fb477dbddc934c73cbe49e0c20b1620ff5d2e7bfb0fddc669ed242ab4951e01"
[metadata.files]
absl-py = [
@@ -4506,6 +4580,10 @@ alpha-vantage = [
{file = "alpha_vantage-2.3.1-py3-none-any.whl", hash = "sha256:5d05355febe6f0fafc4bd11dc6ce3504a02d9d3c105d60202539855c0f608661"},
{file = "alpha_vantage-2.3.1.tar.gz", hash = "sha256:0ce76908c3e2a22f9bbdacead90195ec3a4fa41ef8ae7c69a4a2fc99459bfbec"},
]
altgraph = [
{file = "altgraph-0.17.2-py2.py3-none-any.whl", hash = "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857"},
{file = "altgraph-0.17.2.tar.gz", hash = "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158"},
]
ansiwrap = [
{file = "ansiwrap-0.8.4-py2.py3-none-any.whl", hash = "sha256:7b053567c88e1ad9eed030d3ac41b722125e4c1271c8a99ade797faff1f49fb1"},
{file = "ansiwrap-0.8.4.zip", hash = "sha256:ca0c740734cde59bf919f8ff2c386f74f9a369818cdc60efe94893d01ea8d9b7"},
@@ -5313,8 +5391,8 @@ jedi-language-server = [
{file = "jedi_language_server-0.35.1-py3-none-any.whl", hash = "sha256:532c16a9199d902bdc88ca991da176fe177f0b3019b826b50bf568a0b0081167"},
]
jinja2 = [
{file = "Jinja2-3.1.0-py3-none-any.whl", hash = "sha256:da424924c069a4013730d8dd010cbecac7e7bb752be388db3741688bffb48dc6"},
{file = "Jinja2-3.1.0.tar.gz", hash = "sha256:a2f09a92f358b96b5f6ca6ecb4502669c4acb55d8733bbb2b2c9c4af5564c605"},
{file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"},
{file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"},
]
jmespath = [
{file = "jmespath-1.0.0-py3-none-any.whl", hash = "sha256:e8dcd576ed616f14ec02eed0005c85973b5890083313860136657e24784e4c04"},
@@ -5582,6 +5660,10 @@ m2r2 = [
{file = "m2r2-0.2.8-py3-none-any.whl", hash = "sha256:613934a5d02999574c0256407e6a0e71f8c436f2d2757d6e43d52d2faf8dff1c"},
{file = "m2r2-0.2.8.tar.gz", hash = "sha256:ca39e1db74991818d667c7367e4fc2de13ecefd2a04d69d83b0ffa76d20d7e29"},
]
macholib = [
{file = "macholib-1.16-py2.py3-none-any.whl", hash = "sha256:5a0742b587e6e57bfade1ab90651d4877185bf66fd4a176a488116de36878229"},
{file = "macholib-1.16.tar.gz", hash = "sha256:001bf281279b986a66d7821790d734e61150d52f40c080899df8fefae056e9f7"},
]
markdown = [
{file = "Markdown-3.3.6-py3-none-any.whl", hash = "sha256:9923332318f843411e9932237530df53162e29dc7a4e2b91e35764583c46c9a3"},
{file = "Markdown-3.3.6.tar.gz", hash = "sha256:76df8ae32294ec39dcf89340382882dfa12975f87f45c3ed1ecdb1e8cefc7006"},
@@ -5965,6 +6047,9 @@ pbr = [
{file = "pbr-5.8.1-py2.py3-none-any.whl", hash = "sha256:27108648368782d07bbf1cb468ad2e2eeef29086affd14087a6d04b7de8af4ec"},
{file = "pbr-5.8.1.tar.gz", hash = "sha256:66bc5a34912f408bb3925bf21231cb6f59206267b7f63f3503ef865c1a292e25"},
]
pefile = [
{file = "pefile-2021.9.3.tar.gz", hash = "sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"},
]
pexpect = [
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
@@ -6235,6 +6320,23 @@ pyimgur = [
{file = "pyimgur-0.6.0-py2-none-any.whl", hash = "sha256:ad22deea062fe8e7412d0bdfc70cbf305a828c6390096d3523ed3d7dbeb2bdff"},
{file = "pyimgur-0.6.0.tar.gz", hash = "sha256:f776ca7f14663bd9ac14a1380db62c87ed32231d159d2d167ad1cb817dcb9144"},
]
pyinstaller = [
{file = "pyinstaller-4.10-py3-none-macosx_10_13_universal2.whl", hash = "sha256:15557cd1a79d182967f0a5040750e6902e13ebd6cab41e3ed84d7b28a306357b"},
{file = "pyinstaller-4.10-py3-none-manylinux2014_aarch64.whl", hash = "sha256:f2166ff2cd95eefb0d377ae8d1071f186fa25edd410ede65b376162d5ec41909"},
{file = "pyinstaller-4.10-py3-none-manylinux2014_i686.whl", hash = "sha256:7d94518ba1f8e9a8577345312276891ad7d6cd9785e453e9951b35647e2c7078"},
{file = "pyinstaller-4.10-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:70c71e827f4b34602cbc7a0947a067b662c1cbdc4db51832e13b97cca3c54dd7"},
{file = "pyinstaller-4.10-py3-none-manylinux2014_s390x.whl", hash = "sha256:05c21117b84199272ebd355b556af4714f6e79245e1c435d6f16653786d7d17e"},
{file = "pyinstaller-4.10-py3-none-manylinux2014_x86_64.whl", hash = "sha256:714c4dcc319a41416744d1e30c6317405dfaed80d2adc45f8bfa70dc7367e664"},
{file = "pyinstaller-4.10-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:581620bdcd32f01e89b13231256b807bb090e7eadf40c81c864ec402afa4758a"},
{file = "pyinstaller-4.10-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:d4f79c0a774451f12baca4e476376418f011fa3039dde8fd172ea2aa8ff67bad"},
{file = "pyinstaller-4.10-py3-none-win32.whl", hash = "sha256:cfed0b3a43e73550a43a094610328109564710b9514afa093ef7199d072cae87"},
{file = "pyinstaller-4.10-py3-none-win_amd64.whl", hash = "sha256:0dcaf6557cdb2da763c46e06e95a94a7634ab03fb09d91bc77988b01ee05c907"},
{file = "pyinstaller-4.10.tar.gz", hash = "sha256:7749c868d2e2dc84df7d6f65437226183c8a366f3a99bb2737785625c3a3cca1"},
]
pyinstaller-hooks-contrib = [
{file = "pyinstaller-hooks-contrib-2022.2.tar.gz", hash = "sha256:ab1d14fe053016fff7b0c6aea51d980bac6d02114b04063b46ef7dac70c70e1e"},
{file = "pyinstaller_hooks_contrib-2022.2-py2.py3-none-any.whl", hash = "sha256:7605e440ccb55904cb2a87d72e83642ef176fb7030c77e52ac4d9679bb3d1537"},
]
pylint = [
{file = "pylint-2.13.0-py3-none-any.whl", hash = "sha256:ea1692d409487a93cdcc015ddf2fd92f2367fb1193d46ece76df98b6fefc0dda"},
{file = "pylint-2.13.0.tar.gz", hash = "sha256:f04508086a0772f1a459b4e9facd02416943b47dda5a98ed79d4d87e709da04f"},
@@ -6446,6 +6548,10 @@ pywin32 = [
{file = "pywin32-303-cp39-cp39-win32.whl", hash = "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352"},
{file = "pywin32-303-cp39-cp39-win_amd64.whl", hash = "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34"},
]
pywin32-ctypes = [
{file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"},
{file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"},
]
pywinpty = [
{file = "pywinpty-2.0.5-cp310-none-win_amd64.whl", hash = "sha256:f86c76e2881c37e69678cbbf178109f8da1fa8584db24d58e1b9369b0276cfcb"},
{file = "pywinpty-2.0.5-cp37-none-win_amd64.whl", hash = "sha256:ff9b52f182650cfdf3db1b264a6fe0963eb9d996a7a1fa843ac406c1e32111f8"},
@@ -7010,7 +7116,6 @@ tensorflow = [
tensorflow-io-gcs-filesystem = [
{file = "tensorflow_io_gcs_filesystem-0.24.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:9c00f9a9880477b1dff0c71ee6734421ce99ac484ca2151793ebf2681fc0cb4c"},
{file = "tensorflow_io_gcs_filesystem-0.24.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b6ca3a9f751aa9c2f9851520e666d905ad14667281bbafeabe611b7b8f3e1bc5"},
{file = "tensorflow_io_gcs_filesystem-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a9c7f26ef9248bdfccc91fdddd66623754a6b08bd4440a780f23feaed8c5be7"},
{file = "tensorflow_io_gcs_filesystem-0.24.0-cp310-cp310-win_amd64.whl", hash = "sha256:2f67d19a2f2579dc55f1590faf48c2e882cabb860992b5a9c7edb0ed8b3eb187"},
{file = "tensorflow_io_gcs_filesystem-0.24.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:cde835e68b2b43ddade07c999e7c3251bcd62b1ff165c34fbe9fc6e0f12c3ac9"},
{file = "tensorflow_io_gcs_filesystem-0.24.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:71c00638c9b6048480095f2738dfefd8f4b2e7b534190c91d699aee769bfa86e"},
@@ -7154,6 +7259,10 @@ types-setuptools = [
{file = "types-setuptools-57.4.11.tar.gz", hash = "sha256:262f7406e0c7d705ad6bb4526b5b761fa500bf99eab74de85ac3592187d62935"},
{file = "types_setuptools-57.4.11-py3-none-any.whl", hash = "sha256:fbb0647569d6fb2f6bc472402265250c0ffa53e60180d2cbfee9e84f085921f0"},
]
types-six = [
{file = "types-six-1.16.12.tar.gz", hash = "sha256:557435f8ad73e91562797ac7efac8e6554f0fa7893b6431b928de8ec635d866a"},
{file = "types_six-1.16.12-py3-none-any.whl", hash = "sha256:6857be934cfa884e166fb3bab8c0bc6f967b051af09e4f87c5ea8b166c16d2f5"},
]
types-urllib3 = [
{file = "types-urllib3-1.26.11.tar.gz", hash = "sha256:24d64e441168851eb05f1d022de18ae31558f5649c8f1117e384c2e85e31315b"},
{file = "types_urllib3-1.26.11-py3-none-any.whl", hash = "sha256:bd0abc01e9fb963e4fddd561a56d21cc371b988d1245662195c90379077139cd"},

3
pyproject.toml vendored
View File

@@ -92,6 +92,7 @@ linearmodels = "^4.25"
black = "22.1"
undetected-chromedriver = {version = "^3.1.5", optional = true}
ipywidgets = "^7.7.0"
pyinstaller = {version = "^4.10", optional = true}
boto3 = {version = "^1.21.14", optional = true}
natsort = {version = "^8.1.0", optional = true}
kaleido = {version = "^0.2.1", optional = true}
@@ -124,11 +125,13 @@ types-setuptools = "^57.4.7"
pre-commit = "^2.16.0"
pandas-market-calendars = "~3.2"
pytest-cov = "^3.0.0"
types-six = "^1.16.12"
[tool.poetry.extras]
prediction = ["tensorflow"]
bots = ["boto3", "pyimgur", "fastapi", "uvicorn", "disnake", "PyNaCl", "pyTelegramBotAPI", "slack-bolt", "undetected-chromedriver", "natsort", "kaleido"]
jupyterlab = ["jupyterlab-code-formatter", "jupyterlab-lsp", "jedi-language-server"]
installer = ["pyinstaller"]
[build-system]
requires = ["poetry-core>=1.0.0"]

79
requirements-full.txt vendored
View File

@@ -5,20 +5,20 @@ 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"
appnope==0.1.2; platform_system == "Darwin" and python_version >= "3.8" and sys_platform == "darwin" and python_full_version >= "3.6.2"
argon2-cffi-bindings==21.2.0; python_version >= "3.7"
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==21.3.0; python_version >= "3.7"
ascii-magic==1.6; python_version >= "3.5"
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.11.1; python_full_version >= "3.6.2"
asttokens==2.0.5; python_full_version >= "3.6.2" and python_version >= "3.8"
asttokens==2.0.5; python_version >= "3.8"
astunparse==1.6.3
async-generator==1.10; python_version >= "3.7" and python_version < "4.0"
async-timeout==4.0.2; python_version >= "3.6"
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_full_version >= "3.7.0" and python_version >= "3.7" and python_version < "4.0" and (python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.5.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"
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_full_version >= "3.6.2" and python_version >= "3.8"
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.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"
@@ -28,17 +28,17 @@ 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")
cachetools==5.0.0; python_version >= "3.7" and python_version < "4.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
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")
cffi==1.15.0; python_version >= "3.7"
certifi==2021.10.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4"
cffi==1.15.0
cfgv==3.3.1; python_full_version >= "3.6.1"
charset-normalizer==2.0.12; 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")
charset-normalizer==2.0.12; python_full_version >= "3.6.0" and python_version >= "3.6"
click==8.0.4; python_version >= "3.6" 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 >= "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.8"
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")
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"
cryptography==36.0.2; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
cryptography==36.0.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.6"
cssselect==1.1.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
cvxpy==1.2.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.7"
cycler==0.11.0; python_version >= "3.7"
@@ -46,7 +46,7 @@ cython==0.29.28; python_version >= "3.7" and python_full_version < "3.0.0" and s
dateparser==1.1.1; python_version >= "3.5"
datetime==4.4; python_version >= "3.5"
debugpy==1.6.0; python_version >= "3.7"
decorator==5.1.1; python_full_version >= "3.6.2" and python_version >= "3.8" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5")
decorator==5.1.1; python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.8"
defusedxml==0.7.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
degiro-connector==2.0.18; python_full_version >= "3.7.1" and python_full_version < "4.0.0"
deprecation==2.1.0
@@ -56,10 +56,10 @@ distlib==0.3.4; python_full_version >= "3.6.1"
dnspython==2.2.1; 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.7"
entrypoints==0.4; python_full_version >= "3.7.0" and python_version >= "3.7"
entrypoints==0.4; python_full_version >= "3.6.1" and python_version >= "3.7"
et-xmlfile==1.1.0; python_version >= "3.6"
exchange-calendars==3.6.1; python_version >= "3.7" and python_full_version >= "3.7.0"
executing==0.8.3; python_full_version >= "3.6.2" and python_version >= "3.8"
executing==0.8.3; python_version >= "3.8"
fear-greed-index==0.1.4; python_version >= "3.7"
ffn==0.3.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
filelock==3.6.0; python_version >= "3.7" and python_full_version >= "3.6.1"
@@ -89,7 +89,7 @@ h5py==3.6.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.12; python_version >= "3.7" and python_full_version >= "3.6.1"
idna==3.3; python_full_version >= "3.7.1" and python_version >= "3.8" and python_version < "4" 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")
idna==3.3; python_full_version >= "3.6.2" and python_version >= "3.7" and python_version < "4"
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"
importlib-metadata==4.11.3; python_version < "3.10" and python_version >= "3.7"
inflection==0.5.1; python_version >= "3.6"
@@ -103,14 +103,14 @@ ipython==8.1.1; python_full_version >= "3.6.2" and python_version >= "3.8"
ipywidgets==7.7.0
iso8601==0.1.16
isort==5.10.1; python_full_version >= "3.6.2" and python_version < "4.0"
jedi==0.18.1; python_full_version >= "3.6.2" and python_version >= "3.8"
jinja2==3.1.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"
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.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.3; python_version >= "3.6"
jupyter-core==4.9.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-core==4.9.2; python_full_version >= "3.6.1" and python_version >= "3.7"
jupyter-server==1.15.6; python_version >= "3.7"
jupyter==1.0.0
jupyterlab-pygments==0.1.2; python_version >= "3.7"
@@ -129,7 +129,7 @@ m2r2==0.2.8; python_version >= "3.7"
markdown-it-py==1.1.0; python_version >= "3.6" and python_version < "4.0"
markdown==3.3.6; python_version >= "3.6"
markupsafe==2.1.1; python_version >= "3.7"
matplotlib-inline==0.1.3; python_full_version >= "3.6.2" and python_version >= "3.8"
matplotlib-inline==0.1.3; python_version >= "3.8"
matplotlib==3.5.1; python_version >= "3.7"
mccabe==0.6.1; python_full_version >= "3.6.2"
mdit-py-plugins==0.2.8; python_version >= "3.6" and python_version < "4.0"
@@ -165,12 +165,12 @@ pandas-ta==0.3.14b
pandas==1.3.5; python_full_version >= "3.7.1"
pandocfilters==1.5.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
papermill==2.3.4; python_version >= "3.6"
parso==0.8.3; python_full_version >= "3.6.2" and python_version >= "3.8"
parso==0.8.3; python_version >= "3.8"
pathspec==0.9.0; python_full_version >= "3.6.2"
patsy==0.5.2; python_version >= "3.7"
pbr==5.8.1; python_version >= "3.7"
pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8" and python_full_version >= "3.6.2"
pickleshare==0.7.5; python_full_version >= "3.6.2" and python_version >= "3.8"
pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8"
pickleshare==0.7.5; python_version >= "3.8"
pillow==9.0.1; python_version >= "3.7" and python_version < "4"
platformdirs==2.5.1; python_version >= "3.7" and python_full_version >= "3.6.2"
plotly==5.6.0; python_version >= "3.6"
@@ -185,15 +185,15 @@ 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.6"
psaw==0.0.12; python_version >= "3"
psutil==5.9.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
ptyprocess==0.7.0; os_name != "nt" and python_version >= "3.8" and sys_platform != "win32" and python_full_version >= "3.6.2"
pure-eval==0.2.2; python_full_version >= "3.6.2" and python_version >= "3.8"
py==1.11.0; python_full_version >= "3.7.0" and python_version >= "3.7" and implementation_name == "pypy"
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"
pyally==1.1.2
pyasn1-modules==0.2.8; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
pyasn1==0.4.8; python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") or python_full_version >= "3.6.0" and python_version >= "3.6" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
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
pycparser==2.21; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
pycparser==2.21; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
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"
@@ -204,29 +204,29 @@ 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")
pyobjc-core==8.4.1; python_version >= "3.6" and sys_platform == "darwin"
pyobjc-framework-cocoa==8.4.1; python_version >= "3.6" and sys_platform == "darwin"
pyopenssl==22.0.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
pyopenssl==22.0.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.6"
pyotp==2.6.0; python_version >= "3"
pyparsing==3.0.7; python_version >= "3.7"
pyportfolioopt==1.5.2; 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"
pysocks==1.7.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4"
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_full_version < "4.0.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-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-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==2022.1; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.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")
pytz==2022.1; 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")
pyupgrade==2.31.1; python_version >= "3.7"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7"
pywinpty==2.0.5; 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.7.0" and python_version >= "3.7"
pyzmq==22.3.0; python_full_version >= "3.6.1" 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.7"
qtconsole==5.2.2; python_version >= "3.6"
qtpy==2.0.1; python_version >= "3.6"
@@ -240,7 +240,7 @@ 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"
rsa==4.8; python_version >= "3.6" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
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") and (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")
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.7"
seaborn==0.11.2; python_version >= "3.6"
@@ -248,7 +248,7 @@ selenium==4.1.3; python_version >= "3.7" and python_version < "4.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.8" and python_full_version < "4.0.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.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") 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.6.0" and python_version >= "3.6")
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.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or 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.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") and (python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.8")
smmap==5.0.0; python_version >= "3.7"
sniffio==1.2.0; python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.6.2"
snowballstemmer==2.2.0; python_version >= "3.7"
@@ -265,7 +265,7 @@ sphinxcontrib-qthelp==1.0.3; python_version >= "3.7"
sphinxcontrib-serializinghtml==1.1.5; python_version >= "3.7"
squarify==0.4.3
sseclient==0.0.27
stack-data==0.2.0; python_full_version >= "3.6.2" and python_version >= "3.8"
stack-data==0.2.0; python_version >= "3.8"
statsmodels==0.13.2; python_version >= "3.7"
stevedore==3.5.0; python_version >= "3.7"
tabulate==0.8.9; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
@@ -282,12 +282,12 @@ testpath==0.6.0; python_version >= "3.7"
textwrap3==0.9.2; python_version >= "3.6"
tf-estimator-nightly==2.8.0.dev2021122109
thepassiveinvestor==1.0.10
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"
threadpoolctl==3.1.0; python_version >= "3.7"
tokenize-rt==4.2.1; python_full_version >= "3.6.2" and python_version >= "3.7"
toml==0.10.2; python_full_version >= "3.6.1" 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==2.0.1; python_version >= "3.7" and python_full_version >= "3.6.2" and python_version < "3.11"
toolz==0.11.2; python_version >= "3.7" and python_full_version >= "3.7.0"
tornado==6.1; python_full_version >= "3.7.0" and python_version >= "3.7"
tornado==6.1; python_full_version >= "3.6.1" and python_version >= "3.7"
tqdm==4.63.1; 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"
@@ -298,6 +298,7 @@ types-pytz==2021.3.6
types-pyyaml==6.0.5
types-requests==2.27.14
types-setuptools==57.4.11
types-six==1.16.12
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")
@@ -305,14 +306,14 @@ tzlocal==4.1; python_version >= "3.6"
ujson==5.1.0; python_version >= "3.7"
unidecode==1.3.4; python_version >= "3.7"
update-checker==0.18.0; python_version >= "3.6" and python_version < "4.0"
urllib3==1.26.9; 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")
urllib3==1.26.9; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
user-agent==0.1.10
vadersentiment==3.3.2
valinvest==0.0.2; python_version >= "3.6"
vcrpy==4.1.1; python_version >= "3.5"
virtualenv==20.13.4; python_full_version >= "3.6.1"
voila==0.3.4; python_version >= "3.7"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.8"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.6"
webencodings==0.5.1; python_version >= "3.7"
websocket-client==1.3.1; python_version >= "3.8" and python_version < "4.0"
websockets==9.1; python_full_version >= "3.6.1" and python_version >= "3.7"

133
requirements.txt vendored
View File

@@ -4,32 +4,38 @@ 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"
appnope==0.1.2; platform_system == "Darwin" and python_version >= "3.8" and sys_platform == "darwin" and python_full_version >= "3.6.2"
argon2-cffi-bindings==21.2.0; python_version >= "3.7"
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==21.3.0; python_version >= "3.7"
ascii-magic==1.6; python_version >= "3.5"
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"
asttokens==2.0.5; python_full_version >= "3.6.2" and python_version >= "3.8"
astroid==2.11.1; python_full_version >= "3.6.2"
asttokens==2.0.5; python_version >= "3.8"
async-generator==1.10; python_version >= "3.7" and python_version < "4.0"
async-timeout==4.0.2; python_version >= "3.6"
attrs==21.4.0; python_full_version >= "3.7.0" and python_version >= "3.7" and python_version < "4.0" and (python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.5.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"
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_full_version >= "3.6.2" and python_version >= "3.8"
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.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"
black==22.1.0; 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_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")
cffi==1.15.0; python_version >= "3.7"
charset-normalizer==2.0.12; 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")
certifi==2021.10.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4"
cffi==1.15.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"
click==8.0.4; python_version >= "3.6" and python_full_version >= "3.6.2"
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.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.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.8" and sys_platform == "win32"
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")
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"
cryptography==36.0.2; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
coverage==6.3.2; python_version >= "3.7"
cryptography==36.0.2; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.6"
cssselect==1.1.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
cvxpy==1.2.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.7"
cycler==0.11.0; python_version >= "3.7"
@@ -37,23 +43,28 @@ cython==0.29.28; python_version >= "3.7" and python_full_version < "3.0.0" and s
dateparser==1.1.1; python_version >= "3.5"
datetime==4.4; python_version >= "3.5"
debugpy==1.6.0; python_version >= "3.7"
decorator==5.1.1; python_full_version >= "3.6.2" and python_version >= "3.8" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5")
decorator==5.1.1; python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.8"
defusedxml==0.7.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
degiro-connector==2.0.18; python_full_version >= "3.7.1" and python_full_version < "4.0.0"
deprecation==2.1.0
detecta==0.0.5; python_version >= "3.6"
dill==0.3.4; python_full_version >= "3.6.2"
distlib==0.3.4; python_full_version >= "3.6.1"
dnspython==2.2.1; 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.7"
entrypoints==0.4; python_full_version >= "3.7.0" and python_version >= "3.7"
entrypoints==0.4; python_full_version >= "3.6.1" and python_version >= "3.7"
et-xmlfile==1.1.0; python_version >= "3.6"
executing==0.8.3; python_full_version >= "3.6.2" and python_version >= "3.8"
exchange-calendars==3.6.1; python_version >= "3.7" and python_full_version >= "3.7.0"
executing==0.8.3; python_version >= "3.8"
fear-greed-index==0.1.4; python_version >= "3.7"
ffn==0.3.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
filelock==3.6.0; python_version >= "3.7" and python_full_version >= "3.6.1"
financedatabase==1.0.2
finnhub-python==2.4.11
finviz==1.4.4
finvizfinance==0.12.2; 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"
formulaic==0.3.2; python_version >= "3.7"
fred==3.1
@@ -68,9 +79,11 @@ grpcio==1.45.0; python_full_version >= "3.7.1" and python_full_version < "4.0.0"
h11==0.13.0; python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.7.0"
hijri-converter==2.2.3; python_version >= "3.6"
holidays==0.11.3.1; python_version >= "3.6"
idna==3.3; python_full_version >= "3.7.1" and python_version >= "3.8" and python_version < "4" 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")
identify==2.4.12; 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" and python_version < "4"
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.5; python_version >= "3.7"
investpy==1.0.8; python_version >= "3.7"
ipykernel==6.9.2; python_version >= "3.7"
@@ -79,14 +92,15 @@ ipython-genutils==0.2.0; python_version >= "3.6"
ipython==8.1.1; python_full_version >= "3.6.2" and python_version >= "3.8"
ipywidgets==7.7.0
iso8601==0.1.16
jedi==0.18.1; python_full_version >= "3.6.2" and python_version >= "3.8"
jinja2==3.1.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"
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.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.3; python_version >= "3.6"
jupyter-core==4.9.2; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-core==4.9.2; python_full_version >= "3.6.1" and python_version >= "3.7"
jupyter-server==1.15.6; python_version >= "3.7"
jupyter==1.0.0
jupyterlab-pygments==0.1.2; python_version >= "3.7"
@@ -94,25 +108,32 @@ jupyterlab-server==2.11.2; python_version >= "3.7"
jupyterlab-widgets==1.1.0; python_version >= "3.6"
jupyterlab==3.3.2; python_version >= "3.7"
kiwisolver==1.4.0; python_version >= "3.7"
korean-lunar-calendar==0.2.1; python_version >= "3.6"
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"
markupsafe==2.1.1; python_version >= "3.7"
matplotlib-inline==0.1.3; python_full_version >= "3.6.2" and python_version >= "3.8"
matplotlib-inline==0.1.3; python_version >= "3.8"
matplotlib==3.5.1; python_version >= "3.7"
mccabe==0.6.1; python_full_version >= "3.6.2"
mdit-py-plugins==0.2.8; python_version >= "3.6" and python_version < "4.0"
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"
multitasking==0.0.10
mypy-extensions==0.4.3; python_version >= "3.7" and python_full_version >= "3.6.2"
mypy==0.930; python_version >= "3.6"
myst-parser==0.15.2; python_version >= "3.6"
nbclassic==0.3.7; python_version >= "3.7"
nbclient==0.5.13; python_full_version >= "3.7.0" and python_version >= "3.7"
nbconvert==6.4.4; python_version >= "3.7"
nbformat==5.2.0; python_full_version >= "3.7.0" and python_version >= "3.7"
nest-asyncio==1.5.4; python_full_version >= "3.7.0" and python_version >= "3.7"
nodeenv==1.6.0; python_full_version >= "3.6.1"
notebook-shim==0.1.0; python_version >= "3.7"
notebook==6.4.10; python_version >= "3.7"
numpy==1.21.2; python_version >= "3.7" and python_version < "3.11"
@@ -124,58 +145,71 @@ osqp==0.6.2.post5; python_full_version >= "3.6.1" and python_full_version < "4.0
outcome==1.1.0; python_version >= "3.7" and python_version < "4.0"
packaging==21.3; python_version >= "3.7"
pandas-datareader==0.10.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
pandas-market-calendars==3.2; python_full_version >= "3.7.0"
pandas-ta==0.3.14b
pandas==1.3.5; python_full_version >= "3.7.1"
pandocfilters==1.5.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
papermill==2.3.4; python_version >= "3.6"
parso==0.8.3; python_full_version >= "3.6.2" and python_version >= "3.8"
parso==0.8.3; python_version >= "3.8"
pathspec==0.9.0; python_full_version >= "3.6.2"
patsy==0.5.2; python_version >= "3.7"
pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8" and python_full_version >= "3.6.2"
pickleshare==0.7.5; python_full_version >= "3.6.2" and python_version >= "3.8"
pbr==5.8.1; python_version >= "3.7"
pexpect==4.8.0; sys_platform != "win32" and python_version >= "3.8"
pickleshare==0.7.5; python_version >= "3.8"
pillow==9.0.1; python_version >= "3.7" and python_version < "4"
platformdirs==2.5.1; python_version >= "3.7" and python_full_version >= "3.6.2"
plotly==5.6.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.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"
psutil==5.9.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
ptyprocess==0.7.0; os_name != "nt" and python_version >= "3.8" and sys_platform != "win32" and python_full_version >= "3.6.2"
pure-eval==0.2.2; python_full_version >= "3.6.2" and python_version >= "3.8"
py==1.11.0; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.7.0"
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"
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
pycparser==2.21; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
pycparser==2.21; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
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"
pylint==2.13.0; 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")
pyobjc-core==8.4.1; python_version >= "3.6" and sys_platform == "darwin"
pyobjc-framework-cocoa==8.4.1; python_version >= "3.6" and sys_platform == "darwin"
pyopenssl==22.0.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
pyopenssl==22.0.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.6"
pyotp==2.6.0; python_version >= "3"
pyparsing==3.0.7; python_version >= "3.7"
pyportfolioopt==1.5.2; 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"
pysocks==1.7.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4"
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_full_version < "4.0.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-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-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==2022.1; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.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")
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pytz==2022.1; 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")
pyupgrade==2.31.1; python_version >= "3.7"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7"
pywinpty==2.0.5; os_name == "nt" and python_version >= "3.7"
pyyaml==6.0; python_version >= "3.6"
pyzmq==22.3.0; python_full_version >= "3.7.0" 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"
qdldl==0.1.5.post0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.7"
qtconsole==5.2.2; python_version >= "3.6"
qtpy==2.0.1; python_version >= "3.6"
@@ -188,7 +222,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") and (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")
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.7"
seaborn==0.11.2; python_version >= "3.6"
@@ -196,7 +230,7 @@ selenium==4.1.3; python_version >= "3.7" and python_version < "4.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.8" and python_full_version < "4.0.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")
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.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5") 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")
smmap==5.0.0; python_version >= "3.7"
sniffio==1.2.0; python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.6.2"
snowballstemmer==2.2.0; python_version >= "3.7"
@@ -213,8 +247,9 @@ sphinxcontrib-qthelp==1.0.3; python_version >= "3.7"
sphinxcontrib-serializinghtml==1.1.5; python_version >= "3.7"
squarify==0.4.3
sseclient==0.0.27
stack-data==0.2.0; python_full_version >= "3.6.2" and python_version >= "3.8"
stack-data==0.2.0; python_version >= "3.8"
statsmodels==0.13.2; python_version >= "3.7"
stevedore==3.5.0; python_version >= "3.7"
tabulate==0.8.9; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
temporal-cache==0.1.4
tenacity==8.0.1; python_version >= "3.6"
@@ -222,31 +257,43 @@ terminado==0.13.3; python_version >= "3.7"
testpath==0.6.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" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
tomli==2.0.1; python_version >= "3.7" and python_full_version >= "3.6.2"
tornado==6.1; python_full_version >= "3.7.0" and python_version >= "3.7"
threadpoolctl==3.1.0; python_version >= "3.7"
tokenize-rt==4.2.1; python_full_version >= "3.6.2" and python_version >= "3.7"
toml==0.10.2; python_full_version >= "3.6.1" 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==2.0.1; python_version >= "3.7" and python_full_version >= "3.6.2" and python_version < "3.11"
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"
tqdm==4.63.1; 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"
trio-websocket==0.9.2; python_version >= "3.7" and python_version < "4.0"
trio==0.20.0; python_version >= "3.7" and python_version < "4.0"
types-python-dateutil==2.8.10
types-pytz==2021.3.6
types-pyyaml==6.0.5
types-requests==2.27.14
types-setuptools==57.4.11
types-six==1.16.12
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.1; python_version >= "3.6"
ujson==5.1.0; python_version >= "3.7"
unidecode==1.3.4; python_version >= "3.7"
update-checker==0.18.0; python_version >= "3.6" and python_version < "4.0"
urllib3==1.26.9; 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")
urllib3==1.26.9; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
user-agent==0.1.10
vadersentiment==3.3.2
valinvest==0.0.2; python_version >= "3.6"
vcrpy==4.1.1; python_version >= "3.5"
virtualenv==20.13.4; python_full_version >= "3.6.1"
voila==0.3.4; python_version >= "3.7"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.8"
wcwidth==0.2.5; python_full_version >= "3.6.2" and python_version >= "3.6"
webencodings==0.5.1; python_version >= "3.7"
websocket-client==1.3.1; 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.6.0
wrapt==1.14.0; python_full_version >= "3.7.1" and python_full_version < "4.0.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")
wrapt==1.14.0; 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")
wsproto==1.1.0; python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.7.0"
yarl==1.7.2; python_version >= "3.6"
yfinance==0.1.70

View File

@@ -89,7 +89,7 @@ class TerminalController(BaseController):
if jobs_cmds:
self.queue = " ".join(jobs_cmds).split("/")
self.update_succcess = False
self.update_success = False
def print_help(self):
"""Print help"""
@@ -145,7 +145,7 @@ class TerminalController(BaseController):
def call_update(self, _):
"""Process update command"""
self.update_succcess = not update_terminal()
self.update_success = not update_terminal()
def call_keys(self, _):
"""Process keys command"""
@@ -320,7 +320,8 @@ class TerminalController(BaseController):
else "DEFAULT (folder: exports/)"
)
console.print(
f"[yellow]Export data to keep being saved in the selected folder: {path_display}[/yellow]"
"[yellow]Export data to keep being saved in"
+ f"the selected folder: {path_display}[/yellow]"
)
success_export = True
@@ -439,6 +440,10 @@ class TerminalController(BaseController):
# pylint: disable=global-statement
def terminal(jobs_cmds: List[str] = None, appName: str = "gst"):
"""Terminal Menu"""
# TODO: HELP WANTED! Refactor the appName setting if a more elegant solution comes up
if gtff.PACKAGED_APPLICATION:
appName = "gst_packaged"
setup_logging(appName)
logger.info("START")
log_settings()
@@ -538,7 +543,7 @@ def terminal(jobs_cmds: List[str] = None, appName: str = "gst"):
break
# Check if the user wants to reset application
if an_input in ("r", "reset") or t_controller.update_succcess:
if an_input in ("r", "reset") or t_controller.update_success:
ret_code = reset(t_controller.queue if t_controller.queue else [])
if ret_code != 0:
print_goodbye()
@@ -604,6 +609,7 @@ def log_settings() -> None:
settings_dict["watermark"] = "True" if gtff.USE_WATERMARK else "False"
settings_dict["autoscaling"] = "True" if gtff.USE_PLOT_AUTOSCALING else "False"
settings_dict["dt"] = "True" if gtff.USE_DATETIME else "False"
settings_dict["packaged"] = "True" if gtff.PACKAGED_APPLICATION else "False"
settings_dict["python"] = str(platform.python_version())
settings_dict["os"] = str(platform.system())
@@ -671,6 +677,7 @@ def run_scripts(
else:
with suppress_stdout():
terminal(file_cmds, appName="gst_script")
else:
console.print(f"File '{path}' doesn't exist. Launching base terminal.\n")
if not test_mode:
@@ -734,7 +741,9 @@ def main(
console.print("[green]Gamestonk Terminal Integrated Tests:\n[/green]")
for file in test_files:
file = file.replace("//", "/")
file_name = file[file.rfind("GamestonkTerminal") :].replace("\\", "/")
file_name = file[file.rfind("GamestonkTerminal") :].replace( # noqa: E203
"\\", "/"
)
console.print(f"{file_name} {((i/length)*100):.1f}%")
try:
if not os.path.isfile(file):
@@ -748,7 +757,9 @@ def main(
if fails:
console.print("\n[red]Failures:[/red]\n")
for key, value in fails.items():
file_name = key[key.rfind("GamestonkTerminal") :].replace("\\", "/")
file_name = key[key.rfind("GamestonkTerminal") :].replace( # noqa: E203
"\\", "/"
)
logger.error("%s: %s failed", file_name, value)
console.print(f"{file_name}: {value}\n")
console.print(