diff --git a/README.md b/README.md index b12ab62..fa5a161 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ The information displayed can then be customised by editing the `config.ini` con [general] currency = eur currency_symbol = € +spacer_symbol = | display = price,percent_change_24h,percent_change_7d api_key = your_coinmarketcap_api_key @@ -91,6 +92,7 @@ volume_precision = 2 - **currency:** Any valid currency code should be accepted - **currency_symbol:** A corresponding symbol of the currency you wish to display +- **spacer_symbol:** A string/character to use as a spacer between tickers. Comment out to disable. - **api_key:** CoinmarketCap API key obtained from their [API Dashboard](https://coinmarketcap.com/api). - **display:** A list of metrics you wish to display for each crypto currency. No spaces. Valid options are: diff --git a/config.ini.example b/config.ini.example index a5a0447..4384867 100644 --- a/config.ini.example +++ b/config.ini.example @@ -1,10 +1,8 @@ [general] currency = eur currency_symbol = € -# display options: price,percent_change_1h,percent_change_24h,percent_change_7d,percent_change_30d,percent_change_60d,percent_change_90d,volume_24h,volume_change_24h display = price,percent_change_24h - -# set the key here, or with env COINMARKETCAP_API_KEY +spacer_symbol = | api_key = your_coinmarketcap_api_key [btc] @@ -16,6 +14,20 @@ volume_precision = 2 [eth] icon =  +in_tooltip = false +price_precision = 2 +change_precision = 2 +volume_precision = 2 + +[avax] +icon = AVAX +in_tooltip = true +price_precision = 2 +change_precision = 2 +volume_precision = 2 + +[dot] +icon = DOT in_tooltip = true price_precision = 2 change_precision = 2 diff --git a/poetry.lock b/poetry.lock index 5c99f8c..baa7e38 100644 --- a/poetry.lock +++ b/poetry.lock @@ -35,6 +35,17 @@ files = [ {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -212,6 +223,17 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "distlib" +version = "0.3.8" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] + [[package]] name = "exceptiongroup" version = "1.2.1" @@ -226,6 +248,36 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "filelock" +version = "3.14.0" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, + {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "identify" +version = "2.5.36" +description = "File identification library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, + {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, +] + +[package.extras] +license = ["ukkonen"] + [[package]] name = "idna" version = "3.7" @@ -283,6 +335,20 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "nodeenv" +version = "1.8.0" +description = "Node.js virtual environment builder" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, +] + +[package.dependencies] +setuptools = "*" + [[package]] name = "packaging" version = "24.0" @@ -305,6 +371,22 @@ files = [ {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, ] +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + [[package]] name = "pluggy" version = "1.5.0" @@ -320,6 +402,24 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "pre-commit" +version = "3.7.1" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.9" +files = [ + {file = "pre_commit-3.7.1-py2.py3-none-any.whl", hash = "sha256:fae36fd1d7ad7d6a5a1c0b0d5adb2ed1a3bda5a21bf6c3e5372073d7a11cd4c5"}, + {file = "pre_commit-3.7.1.tar.gz", hash = "sha256:8ca3ad567bc78a4972a3f1a477e94a79d4597e8140a6e0b651c5e33899c3654a"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + [[package]] name = "pygments" version = "2.18.0" @@ -469,7 +569,6 @@ files = [ [package.dependencies] markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] @@ -500,6 +599,21 @@ files = [ {file = "ruff-0.4.5.tar.gz", hash = "sha256:286eabd47e7d4d521d199cab84deca135557e6d1e0f0d01c29e757c3cb151b54"}, ] +[[package]] +name = "setuptools" +version = "70.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, + {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "stevedore" version = "5.2.0" @@ -525,17 +639,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "typing-extensions" -version = "4.12.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"}, - {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"}, -] - [[package]] name = "urllib3" version = "2.2.1" @@ -553,7 +656,27 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "virtualenv" +version = "20.26.2" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.7" +files = [ + {file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"}, + {file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + [metadata] lock-version = "2.0" -python-versions = "^3.8" -content-hash = "6de561bb6a5c9d140adcb5046d63f6c9bb8c4a9e1915d0e9984ea6841318d0c7" +python-versions = "^3.9" +content-hash = "286a2688d847d7940e6dd887850a3d6ed7de26265d85536be94ad0afe7780e04" diff --git a/pyproject.toml b/pyproject.toml index 7e829c2..17c1ba9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "waybar-crypto" -version = "v1.3.1" +version = "v1.4.0" description = "A Waybar module for displaying cryptocurrency market information from CoinMarketCap." authors = ["Ross "] license = "MIT" [tool.poetry.dependencies] -python = "^3.8" +python = "^3.9" requests = "^2.32.0" [tool.poetry.group.dev.dependencies] @@ -14,6 +14,7 @@ ruff = "^0.4.5" bandit = "^1.7.8" pytest = "^8.2.1" pytest-cov = "^5.0.0" +pre-commit = "^3.7.1" [tool.ruff] line-length = 100 diff --git a/tests/test_waybar_crypto.py b/tests/test_waybar_crypto.py index 7542a5f..4e7fa9b 100644 --- a/tests/test_waybar_crypto.py +++ b/tests/test_waybar_crypto.py @@ -53,6 +53,36 @@ def quotes_latest(): } }, }, + "AVAX": { + "quote": { + "EUR": { + "price": 34.15081432131667, + "volume_24h": 206005212.6801803, + "volume_change_24h": -21.5639, + "percent_change_1h": -0.1101364, + "percent_change_24h": -2.21628843, + "percent_change_7d": 2.46514204, + "percent_change_30d": 3.78312279, + "percent_change_60d": -30.74974196, + "percent_change_90d": -0.83220421, + } + }, + }, + "DOT": { + "quote": { + "EUR": { + "price": 6.9338115798384905, + "volume_24h": 145060142.27706677, + "volume_change_24h": 0.3964, + "percent_change_1h": 0.59467025, + "percent_change_24h": 3.37180336, + "percent_change_7d": 7.19067559, + "percent_change_30d": 8.73368475, + "percent_change_60d": -19.8413195, + "percent_change_90d": -2.24744556, + } + } + }, }, } diff --git a/waybar_crypto.py b/waybar_crypto.py index 3502f7e..7973839 100755 --- a/waybar_crypto.py +++ b/waybar_crypto.py @@ -46,6 +46,7 @@ class ConfigGeneral(TypedDict): currency: str currency_symbol: str + spacer_symbol: str display_options: list[str] display_options_format: dict[str, str] api_key: str @@ -176,6 +177,10 @@ def __parse_config_path(self, config_path: str) -> Config: currency = cfp.get("general", "currency").upper() currency_symbol = cfp.get("general", "currency_symbol") + spacer_symbol = "" + if "spacer_symbol" in cfp["general"]: + spacer_symbol = cfp.get("general", "spacer_symbol") + # Get a list of the chosen display options display_options: list[str] = cfp.get("general", "display").split(",") @@ -205,6 +210,7 @@ def __parse_config_path(self, config_path: str) -> Config: "general": { "currency": currency, "currency_symbol": currency_symbol, + "spacer_symbol": spacer_symbol, "display_options": display_options, "display_options_format": display_options_format, "api_key": api_key, @@ -258,6 +264,9 @@ def waybar_output(self, quotes_latest: ResponseQuotesLatest) -> WaybarOutput: currency = self.config["general"]["currency"] display_options = self.config["general"]["display_options"] display_options_format = self.config["general"]["display_options_format"] + spacer = self.config["general"]["spacer_symbol"] + if spacer != "": + spacer = f" {spacer}" output_obj: WaybarOutput = { "text": "", @@ -298,7 +307,7 @@ def waybar_output(self, quotes_latest: ResponseQuotesLatest) -> WaybarOutput: output_obj["tooltip"] += output else: if output_obj["text"] != "": - output = f" {output}" + output = f"{spacer} {output}" output_obj["text"] += output return output_obj