Skip to content

support choosing bar / tooltip display #71

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 35 additions & 32 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- "pyproject.toml"
- "config.ini.example"

pull_request_target:
pull_request:
paths:
- ".github/workflows/test.yml"
- "**/*.py"
Expand All @@ -24,50 +24,53 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install Python 3
uses: actions/setup-python@v5
with:
python-version: "3.12"
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Lint
uses: psf/black@stable
uses: psf/black@stable
with:
use_pyproject: true


test:
needs: lint
strategy:
fail-fast: true
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v4
- name: Install Python 3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- uses: actions/checkout@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root
- name: Run Pytest
env:
COINMARKETCAP_API_KEY: ${{ secrets.COINMARKETCAP_API_KEY }}
run: |
source .venv/bin/activate
pytest -vv --cov=./ --cov-report=xml tests/
env:
COINMARKETCAP_API_KEY: ${{ secrets.COINMARKETCAP_API_KEY }}
run: |
source .venv/bin/activate
pytest -vv --cov=./ --cov-report=xml tests/
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Run Bandit
run: |
source .venv/bin/activate
bandit ./waybar_crypto.py
run: |
source .venv/bin/activate
bandit ./waybar_crypto.py
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ For each cryptocurrency you wish to display, add a section as shown in the examp
Valid options:

- **icon:** A character symbol to display next to this cryptocurrency's metrics.
- **in_tooltip:** Whether to display the data in the tooltip instead of the bar (defaults to false).
- **price_precision** The decimal precision at which to display the price value of the cryptocurrency.
- **change_precision** The decimal precision at which to display the change value(s) of the cryptocurrency.
- **volume_precision** The decimal precision at which to display the volume value of the cryptocurrency.
2 changes: 2 additions & 0 deletions config.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ api_key = your_coinmarketcap_api_key

[btc]
icon = 
in_tooltip = false
price_precision = 2
change_precision = 2
volume_precision = 2

[eth]
icon = 
in_tooltip = true
price_precision = 2
change_precision = 2
volume_precision = 2
47 changes: 29 additions & 18 deletions waybar_crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)

FLOAT_FORMATTER = "{val:.{dp}f}"
DISPLAY_OPTIONS_FORMAT: dict[str, str] = {
DEFAULT_DISPLAY_OPTIONS_FORMAT: dict[str, str] = {
"price": f"{FLOAT_FORMATTER}",
"percent_change_1h": f"1h:{FLOAT_FORMATTER}%",
"percent_change_24h": f"24h:{FLOAT_FORMATTER}%",
Expand All @@ -38,6 +38,8 @@
}
DEFAULT_DISPLAY_OPTIONS: list[str] = ["price"]

DEFAULT_COIN_CONFIG_TOOLTIP = False

TIMEOUT_SECONDS = 10


Expand All @@ -51,6 +53,7 @@ class ConfigGeneral(TypedDict):

class ConfigCoin(TypedDict):
icon: str
in_tooltip: bool
price_precision: int
change_precision: int
volume_precision: int
Expand Down Expand Up @@ -142,8 +145,13 @@ def __parse_config_path(self, config_path: str) -> Config:
# duplicate entry, skip
continue

display_in_tooltip = DEFAULT_COIN_CONFIG_TOOLTIP
if "in_tooltip" in cfp[coin_name]:
display_in_tooltip = cfp.getboolean(coin_name, "in_tooltip")

coins[coin_name] = {
"icon": cfp[coin_name]["icon"],
"icon": cfp.get(coin_name, "icon"),
"in_tooltip": display_in_tooltip,
"price_precision": DEFAULT_PRECISION,
"change_precision": DEFAULT_PRECISION,
"volume_precision": DEFAULT_PRECISION,
Expand All @@ -156,7 +164,7 @@ def __parse_config_path(self, config_path: str) -> Config:
f"configured option '{coin_precision_option}' for cryptocurrency '{coin_name}' must be an integer"
)

precision_value = int(cfp[coin_name][coin_precision_option])
precision_value = cfp.getint(coin_name, coin_precision_option)
if precision_value < MIN_PRECISION:
raise WaybarCryptoException(
f"value of option '{coin_precision_option}' for cryptocurrency '{coin_name}' must be greater than {MIN_PRECISION}",
Expand All @@ -165,27 +173,26 @@ def __parse_config_path(self, config_path: str) -> Config:
coins[coin_name][coin_precision_option] = precision_value

# The fiat currency used in the trading pair
currency = cfp["general"]["currency"].upper()
currency_symbol = cfp["general"]["currency_symbol"]
currency = cfp.get("general", "currency").upper()
currency_symbol = cfp.get("general", "currency_symbol")

# Get a list of the chosen display options
display_options: list[str] = cfp["general"]["display"].split(",")
display_options: list[str] = cfp.get("general", "display").split(",")

if len(display_options) == 0:
display_options = DEFAULT_DISPLAY_OPTIONS

for display_option in display_options:
if display_option not in DISPLAY_OPTIONS_FORMAT:
if display_option not in DEFAULT_DISPLAY_OPTIONS_FORMAT:
raise WaybarCryptoException(f"invalid display option '{display_option}")

display_options_format = DISPLAY_OPTIONS_FORMAT
display_options_format["price"] = (
f"{currency_symbol}{display_options_format["price"]}"
)
display_options_format = DEFAULT_DISPLAY_OPTIONS_FORMAT
display_format_price = display_options_format["price"]
display_options_format["price"] = f"{currency_symbol}{display_format_price}"

api_key: str | None = None
if "api_key" in cfp["general"]:
api_key = cfp["general"]["api_key"]
api_key = cfp.get("general", "api_key")

# If API_KEY_ENV exists, take precedence over the config file value
api_key = os.getenv(key=API_KEY_ENV, default=api_key)
Expand Down Expand Up @@ -254,13 +261,13 @@ def waybar_output(self, quotes_latest: ResponseQuotesLatest) -> WaybarOutput:

output_obj: WaybarOutput = {
"text": "",
"tooltip": "Cryptocurrency metrics from Coinmarketcap:\n",
"tooltip": "",
"class": CLASS_NAME,
}

# For each coin, populate our output_obj
# with a string according to the display_options
for i, (coin_name, coin_config) in enumerate(self.config["coins"].items()):
for coin_name, coin_config in self.config["coins"].items():
icon = coin_config["icon"]
price_precision = coin_config["price_precision"]
volume_precision = coin_config["volume_precision"]
Expand All @@ -270,8 +277,6 @@ def waybar_output(self, quotes_latest: ResponseQuotesLatest) -> WaybarOutput:
pair_info = quotes_latest["data"][coin_name.upper()]["quote"][currency]

output = f"{icon}"
if i > 0:
output = f" {output}"

for display_option in display_options:
precision = DEFAULT_PRECISION
Expand All @@ -287,8 +292,14 @@ def waybar_output(self, quotes_latest: ResponseQuotesLatest) -> WaybarOutput:
dp=precision, val=value
)

output_obj["text"] += output
output_obj["tooltip"] += output
if coin_config["in_tooltip"]:
if output_obj["tooltip"] != "":
output = f"\n{output}"
output_obj["tooltip"] += output
else:
if output_obj["text"] != "":
output = f" {output}"
output_obj["text"] += output

return output_obj

Expand Down
Loading