Skip to content

Commit

Permalink
feat!: refactor code again
Browse files Browse the repository at this point in the history
This redoes a lot of the config flow and sensor details and adds proper sensors for the various aspects of the library that one might want to track.
It also better handles errors and implements automated releases.
I ended up switching to a `requirements.txt` for pip just because it's easier to manage than poetry

There is the start of support for translations and testing as well.
  • Loading branch information
wolffshots committed Nov 21, 2024
1 parent a06da30 commit c7df290
Show file tree
Hide file tree
Showing 21 changed files with 559 additions and 178 deletions.
14 changes: 9 additions & 5 deletions .github/workflows/hacs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,32 @@ name: Validate

on:
push:
branches:
- "main"
pull_request:
branches:
- "main"
schedule:
- cron: "00 12 * * *"
workflow_dispatch:

jobs:
validate-hassfest:
hassfest: # https://developers.home-assistant.io/blog/2020/04/16/hassfest
name: Hassfest validation
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
uses: "actions/checkout@v4.2.2"
- name: validation
uses: home-assistant/actions/hassfest@master

validate-hacs:
validate-hacs: # https://github.com/hacs/action
name: HACS validation
runs-on: "ubuntu-latest"
steps:
- name: checkout
uses: actions/checkout@v3
uses: "actions/checkout@v4.2.2"
- name: validation
uses: "hacs/action@main"
with:
category: "integration"
category: "integration"
68 changes: 22 additions & 46 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,28 @@ on:
paths:
- '**.py'

env:
POETRY_VERSION: 1.5.1

jobs:
mypy:
runs-on: ubuntu-latest
steps:
- name: Checkout Audiobookshelf
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Load cached Poetry installation
id: cached-poetry
uses: actions/cache@v4
with:
path: ~/.local
key: poetry-${{ env.POETRY_VERSION }}
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: ${{ env.POETRY_VERSION }}
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
- name: cache dependencies
id: cache-deps
uses: actions/cache@v4
with:
path: .venv
key: pydeps-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: poetry install --no-interaction --no-root
if: steps.cache-deps.outputs.cache-hit != 'true'
- name: Run MyPy
run: |
source .venv/bin/activate \
mypy ./custom_components/audiobookshelf
ruff:
runs-on: ubuntu-latest
name: "Ruff"
runs-on: "ubuntu-latest"
steps:
- name: Checkout Audiobookshelf
uses: actions/checkout@v4
- name: Run Ruff
uses: chartboost/ruff-action@v1
with:
version: 0.0.272
src: './custom_components/audiobookshelf'
- name: "Checkout the repository"
uses: "actions/[email protected]"

- name: "Set up Python"
uses: actions/[email protected]
with:
python-version: "3.12"
cache: "pip"

- name: "Install requirements"
run: python3 -m pip install -r requirements.txt

- name: "Lint"
run: python3 -m ruff check ./custom_components/audiobookshelf

- name: Run MyPy
run: python3 -m mypy custom_components/audiobookshelf

- name: "Format"
run: python3 -m ruff format ./custom_components/audiobookshelf --check
29 changes: 29 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: "Release"

on:
release:
types:
- "published"

permissions: {}

jobs:
release:
name: "Release"
runs-on: "ubuntu-latest"
permissions:
contents: write
steps:
- name: "Checkout the repository"
uses: "actions/[email protected]"

- name: "ZIP the integration directory"
shell: "bash"
run: |
cd "${{ github.workspace }}/custom_components/audiobookshelf"
zip "Audiobookshelf_${{ github.ref_name }}.zip" -r ./
- name: "Upload the ZIP file to the release"
uses: "softprops/[email protected]"
with:
files: ${{ github.workspace }}/custom_components/audiobookshelf/Audiobookshelf_${{ github.ref_name }}.zip
55 changes: 0 additions & 55 deletions .github/workflows/test.yml

This file was deleted.

29 changes: 29 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Test

on:
push:
paths:
- '**.py'
pull_request:
paths:
- '**.py'

jobs:
ruff:
name: "Ruff"
runs-on: "ubuntu-latest"
steps:
- name: "Checkout the repository"
uses: "actions/[email protected]"

- name: "Set up Python"
uses: actions/[email protected]
with:
python-version: "3.12"
cache: "pip"

- name: "Install requirements"
run: python3 -m pip install -r requirements.txt

- name: Run tests
run: python3 -m pytest tests -W ignore::DeprecationWarning
7 changes: 5 additions & 2 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ignore = [
"D212", # multi-line-summary-first-line (incompatible with formatter)
"COM812", # incompatible with formatter
"ISC001", # incompatible with formatter
"ERA001", commented code isn't always bad
"ERA001", # commented code isn't always bad
]

[lint.flake8-pytest-style]
Expand All @@ -24,4 +24,7 @@ fixture-parentheses = false
keep-runtime-typing = true

[lint.mccabe]
max-complexity = 25
max-complexity = 25

[lint.per-file-ignores]
"tests/*.py" = ["S101"]
8 changes: 6 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
"configurations": [
{
"name": "Python: Module",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": ["tests", "--cov=custom_components", "--cov-report=term-missing"],
"args": [
"tests",
"--cov=custom_components",
"--cov-report=term-missing"
],
"justMyCode": false
}
]
Expand Down
45 changes: 35 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,44 @@
[![Project Maintenance][maintenance-shield]][user_profile]
[![BuyMeCoffee][buymecoffeebadge]][buymecoffee]

**This component will set up the following sensors.**
## This component will set up the following general sensors:

| Entity | Type | Description |
| --------------- | ---------------- | ------------------------------------ |
| `connectivity` | `binary_sensor` | Show whether the server is connected |
| `sessions` | `sensor` | Show number of open audio sessions |
| `open_sessions` | `sensor` | Show number of open audio sessions |
| `libraries` | `sensor` | Number of libraries on the server |
| `users` | `sensor` | Number of users on the server |

## It also adds the following library specific sensors (for each library that it finds during setup):
| Entity | Type | Description |
| ------------------ | -------------- | -------------------------------------------------------- |
| `items` | `sensor` | Number of items in the library |
| `duration` | `sensor` | Total time in hours of playable content in library |
| `size` | `sensor` | Total disk space used by library in GB |

## Examples

![Example of sensors on device](docs/hass-audiobookshelf-example.png)

## Installation

### Installation with HACS

1. Make sure you have HACS fully set up (if you don't you can do so [here](https://hacs.xyz/docs/use/))
2. Open up HACS in you Home Assistant instance and search for "Audiobookshelf" and add it
3. Restart Home Assistant once it is installed
4. In the Home Assistant UI go to "Configuration" -> "Integrations" click "+" and search for "Audiobookshelf"
5. Click on "Audiobookshelf" and proceed to [Configuration](#configuration)

### Manual installation

1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`).
2. If you do not have a `custom_components` directory (folder) there, you need to create it.
3. In the `custom_components` directory (folder) create a new folder called `audiobookshelf`.
4. Download _all_ the files from the `custom_components/audiobookshelf/` directory (folder) in this repository.
5. Place the files you downloaded in the new directory (folder) you created.
6. Restart Home Assistant
7. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Audiobookshelf"
1. Using the tool of choice open the directory (folder) for your Home Assistant configuration (where you find `configuration.yaml`)
2. If you do not have a `custom_components` directory (folder) there, you need to create it
3. Download the `Audiobookshelf_vX.X.X.zip` file from the [latest release](https://github.com/wolffshots/hass-audiobookshelf/releases/latest)
4. Unzip the folder and place it into `custom_components`
5. Restart Home Assistant
6. In the Home Assistant UI go to "Configuration" -> "Integrations" click "+" and search for "Audiobookshelf"
7. Click on "Audiobookshelf" and proceed to [Configuration](#configuration)

## Configuration

Expand All @@ -45,6 +64,12 @@ For more info on what the token can be used for see: https://api.audiobookshelf.
### Setting up via the UI
![Config in UI](docs/hass-audiobookshelf-config.png)

| Variable | Description |
| --------------- | --------------------------------------------------------------------------------------------------------- |
| `URL` | The URL and port of your Audiobookshelf instance (must start with the protocol, http:// or https://) |
| `API key` | The API key that you got in the previous step |
| `Scan interval` | How regularly the data should be fetched from your Audiobookshelf instance (in seconds), defaults to 300s |

## Credits

This project was generated from [@oncleben31](https://github.com/oncleben31)'s [Home Assistant Custom Component Cookiecutter](https://github.com/oncleben31/cookiecutter-homeassistant-custom-component) template.
Expand Down
29 changes: 25 additions & 4 deletions custom_components/audiobookshelf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv

from .const import DOMAIN, PLATFORMS
from custom_components.audiobookshelf.config_flow import validate_config

from .const import DOMAIN, ISSUE_URL, PLATFORMS, VERSION

CONFIG_SCHEMA = vol.Schema(
{
Expand All @@ -27,10 +29,13 @@
_LOGGER = logging.getLogger(__name__)


def clean_config(data: dict) -> dict:
def clean_config(data: dict[str, str]) -> dict[str, str]:
"""Remove the api key from config."""
if bool(data[CONF_API_KEY]):
data[CONF_API_KEY] = "<redacted>"
try:
if bool(data[CONF_API_KEY]):
data[CONF_API_KEY] = "<redacted>"
except Exception:
_LOGGER.exception("Failed to clean config, most likely not valid")
return data


Expand All @@ -40,10 +45,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
error_message = "Configuration not found"
raise ConfigEntryNotReady(error_message)

_LOGGER.info(
"""
-------------------------------------------------------------------
Audiobookshelf
Version: %s
This is a custom integration!
If you have any issues with this you need to open an issue here:
%s
-------------------------------------------------------------------
""",
VERSION,
ISSUE_URL,
)

_LOGGER.debug(
"Setting up Audiobookshelf with config: %s", clean_config(entry.data.copy())
)

validate_config(entry.data.copy())

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True

Expand Down
Loading

0 comments on commit c7df290

Please sign in to comment.