mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 04:31:13 +00:00
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:
committed by
GitHub
parent
8bdc35e82f
commit
ab4de1dd70
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@@ -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
5
.gitignore
vendored
@@ -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/
|
||||
|
||||
6
.pre-commit-config.yaml
vendored
6
.pre-commit-config.yaml
vendored
@@ -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
89
bots/requirements.txt
vendored
@@ -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
30
build/pyinstaller/GTFF_DEFAULTS.json
vendored
Normal 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
29
build/pyinstaller/build4mac.sh
vendored
Executable 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
1
build/pyinstaller/frozendict/VERSION
vendored
Normal file
@@ -0,0 +1 @@
|
||||
2.3.0
|
||||
19
build/pyinstaller/macOS_package_assets/Gamestonk Terminal/Gamestonk Terminal
vendored
Executable file
19
build/pyinstaller/macOS_package_assets/Gamestonk Terminal/Gamestonk Terminal
vendored
Executable 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
|
||||
1
build/pyinstaller/macOS_package_assets/README.TXT
vendored
Normal file
1
build/pyinstaller/macOS_package_assets/README.TXT
vendored
Normal file
@@ -0,0 +1 @@
|
||||
MOVE THE GAMESTONK TERMINAL FOLDER TO THE APPLICATIONS FOLDER
|
||||
161
build/pyinstaller/property_cached/__init__.py
Normal file
161
build/pyinstaller/property_cached/__init__.py
Normal 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
|
||||
1
build/pyinstaller/property_cached/_version.txt
vendored
Normal file
1
build/pyinstaller/property_cached/_version.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
1.6.4
|
||||
147
build/pyinstaller/terminal.spec
vendored
Normal file
147
build/pyinstaller/terminal.spec
vendored
Normal 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)
|
||||
4
build/pyinstaller/user_agent/__init__.py
Normal file
4
build/pyinstaller/user_agent/__init__.py
Normal 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"
|
||||
623
build/pyinstaller/user_agent/base.py
Normal file
623
build/pyinstaller/user_agent/base.py
Normal 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"],
|
||||
}
|
||||
20
build/pyinstaller/user_agent/cli.py
Normal file
20
build/pyinstaller/user_agent/cli.py
Normal 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"])
|
||||
2820
build/pyinstaller/user_agent/data/smartphone_dev_ext.json
vendored
Normal file
2820
build/pyinstaller/user_agent/data/smartphone_dev_ext.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
180
build/pyinstaller/user_agent/data/smartphone_dev_id.json
vendored
Normal file
180
build/pyinstaller/user_agent/data/smartphone_dev_id.json
vendored
Normal 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"
|
||||
]
|
||||
757
build/pyinstaller/user_agent/data/tablet_dev_ext.json
vendored
Normal file
757
build/pyinstaller/user_agent/data/tablet_dev_ext.json
vendored
Normal 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
|
||||
]
|
||||
}
|
||||
]
|
||||
52
build/pyinstaller/user_agent/data/tablet_dev_id.json
vendored
Normal file
52
build/pyinstaller/user_agent/data/tablet_dev_id.json
vendored
Normal 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"
|
||||
]
|
||||
15
build/pyinstaller/user_agent/device.py
Normal file
15
build/pyinstaller/user_agent/device.py
Normal 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")
|
||||
15
build/pyinstaller/user_agent/error.py
Normal file
15
build/pyinstaller/user_agent/error.py
Normal 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.
|
||||
"""
|
||||
12
build/pyinstaller/user_agent/warning.py
Normal file
12
build/pyinstaller/user_agent/warning.py
Normal 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)
|
||||
1
build/pyinstaller/vaderSentiment/__init__.py
Normal file
1
build/pyinstaller/vaderSentiment/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
#!/usr/bin/python
|
||||
3570
build/pyinstaller/vaderSentiment/emoji_utf8_lexicon.txt
vendored
Normal file
3570
build/pyinstaller/vaderSentiment/emoji_utf8_lexicon.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
976
build/pyinstaller/vaderSentiment/vaderSentiment.py
Normal file
976
build/pyinstaller/vaderSentiment/vaderSentiment.py
Normal 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!")
|
||||
7520
build/pyinstaller/vaderSentiment/vader_lexicon.txt
vendored
Normal file
7520
build/pyinstaller/vaderSentiment/vader_lexicon.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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(","):
|
||||
|
||||
|
||||
284
gamestonk_terminal/jupyter/dashboards/currencies.ipynb
vendored
Normal file
284
gamestonk_terminal/jupyter/dashboards/currencies.ipynb
vendored
Normal 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
|
||||
}
|
||||
42
gamestonk_terminal/jupyter/dashboards/widget_helpers.py
Normal file
42
gamestonk_terminal/jupyter/dashboards/widget_helpers.py
Normal 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
|
||||
8
gamestonk_terminal/jupyter/dashboards/widgets/card.j2
vendored
Normal file
8
gamestonk_terminal/jupyter/dashboards/widgets/card.j2
vendored
Normal 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>
|
||||
237
gamestonk_terminal/jupyter/dashboards/widgets/currencies.json
vendored
Normal file
237
gamestonk_terminal/jupyter/dashboards/widgets/currencies.json
vendored
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
54
gamestonk_terminal/jupyter/dashboards/widgets/style.css
vendored
Normal file
54
gamestonk_terminal/jupyter/dashboards/widgets/style.css
vendored
Normal 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;
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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
BIN
images/GamestonkTerminal.icns
vendored
Normal file
Binary file not shown.
BIN
images/dmg_background.png
vendored
Normal file
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
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
BIN
images/splashscreen.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
121
poetry.lock
generated
vendored
121
poetry.lock
generated
vendored
@@ -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
3
pyproject.toml
vendored
@@ -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
79
requirements-full.txt
vendored
@@ -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
133
requirements.txt
vendored
@@ -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
|
||||
|
||||
23
terminal.py
23
terminal.py
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user