refactor: rename project to LedGrab, split HA integration into separate repo
Lint & Test / test (push) Successful in 1m56s

- Rename Python package: wled_controller -> ledgrab
- Rename env var prefix: WLED_ -> LEDGRAB_ (with auto-migration for old vars)
- Rename localStorage key: wled_api_key -> ledgrab_api_key (with migration)
- Rename HA integration domain: wled_screen_controller -> ledgrab
- Update all imports, build scripts, Docker, installer, config, docs
- Remove HA integration (moved to ledgrab-haos-integration repo)
- Remove hacs.json (belongs in HA repo now)
- Add startup warning for users with old WLED_ env vars
- All tests pass (715/715), ruff clean, tsc clean, frontend builds
This commit is contained in:
2026-04-12 22:45:28 +03:00
parent 38f73badbf
commit 02cd9d519c
548 changed files with 3502 additions and 5180 deletions
@@ -10,11 +10,11 @@ import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from wled_controller.api.routes.devices import router
from wled_controller.storage.device_store import Device, DeviceStore
from wled_controller.storage.output_target_store import OutputTargetStore
from wled_controller.core.processing.processor_manager import ProcessorManager
from wled_controller.api import dependencies as deps
from ledgrab.api.routes.devices import router
from ledgrab.storage.device_store import Device, DeviceStore
from ledgrab.storage.output_target_store import OutputTargetStore
from ledgrab.core.processing.processor_manager import ProcessorManager
from ledgrab.api import dependencies as deps
# ---------------------------------------------------------------------------
@@ -31,7 +31,8 @@ def _make_app():
@pytest.fixture
def _route_db(tmp_path):
from wled_controller.storage.database import Database
from ledgrab.storage.database import Database
db = Database(tmp_path / "test.db")
yield db
db.close()
@@ -64,7 +65,8 @@ def client(device_store, output_target_store, processor_manager):
app = _make_app()
# Override auth to always pass
from wled_controller.api.auth import verify_api_key
from ledgrab.api.auth import verify_api_key
app.dependency_overrides[verify_api_key] = lambda: "test-user"
# Override stores and manager
@@ -8,13 +8,13 @@ import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from wled_controller.api.routes.game_integration import router
from wled_controller.core.game_integration.adapter_registry import AdapterRegistry
from wled_controller.core.game_integration.base_adapter import GameAdapter
from wled_controller.core.game_integration.event_bus import GameEventBus
from wled_controller.core.game_integration.events import GameEvent
from wled_controller.storage.game_integration_store import GameIntegrationStore
from wled_controller.api import dependencies as deps
from ledgrab.api.routes.game_integration import router
from ledgrab.core.game_integration.adapter_registry import AdapterRegistry
from ledgrab.core.game_integration.base_adapter import GameAdapter
from ledgrab.core.game_integration.event_bus import GameEventBus
from ledgrab.core.game_integration.events import GameEvent
from ledgrab.storage.game_integration_store import GameIntegrationStore
from ledgrab.api import dependencies as deps
# ---------------------------------------------------------------------------
@@ -75,7 +75,7 @@ def _make_app():
@pytest.fixture
def _route_db(tmp_path):
from wled_controller.storage.database import Database
from ledgrab.storage.database import Database
db = Database(tmp_path / "test.db")
yield db
@@ -105,7 +105,7 @@ def client(game_store, event_bus):
app = _make_app()
# Override auth to always pass
from wled_controller.api.auth import verify_api_key
from ledgrab.api.auth import verify_api_key
app.dependency_overrides[verify_api_key] = lambda: "test-user"
app.dependency_overrides[deps.get_game_integration_store] = lambda: game_store
@@ -8,7 +8,7 @@ without setting up the full dependency injection.
import pytest
from fastapi.testclient import TestClient
from wled_controller import __version__
from ledgrab import __version__
@pytest.fixture(scope="module")
@@ -18,7 +18,7 @@ def client():
The app module initializes stores from the default config on import,
which is acceptable for read-only endpoints tested here.
"""
from wled_controller.main import app
from ledgrab.main import app
return TestClient(app, raise_server_exceptions=False)
@@ -4,7 +4,7 @@ import time
import pytest
from wled_controller.api.routes.webhooks import _check_rate_limit, _rate_hits
from ledgrab.api.routes.webhooks import _check_rate_limit, _rate_hits
# ---------------------------------------------------------------------------
@@ -25,6 +25,7 @@ class TestRateLimiter:
for _ in range(30):
_check_rate_limit("1.2.3.4")
from fastapi import HTTPException
with pytest.raises(HTTPException) as exc_info:
_check_rate_limit("1.2.3.4")
assert exc_info.value.status_code == 429
@@ -50,7 +51,7 @@ class TestRateLimiter:
class TestWebhookPayload:
def test_valid_payload_model(self):
from wled_controller.api.routes.webhooks import WebhookPayload
from ledgrab.api.routes.webhooks import WebhookPayload
p = WebhookPayload(action="activate")
assert p.action == "activate"
@@ -60,7 +61,7 @@ class TestWebhookPayload:
def test_arbitrary_action_accepted_by_model(self):
"""The model accepts any string; validation is in the route handler."""
from wled_controller.api.routes.webhooks import WebhookPayload
from ledgrab.api.routes.webhooks import WebhookPayload
p = WebhookPayload(action="bogus")
assert p.action == "bogus"
@@ -2,10 +2,10 @@
import pytest
from wled_controller.config import get_config
from ledgrab.config import get_config
# Ensure audio filters registered
import wled_controller.core.audio.filters # noqa: F401
import ledgrab.core.audio.filters # noqa: F401
_config = get_config()
_api_key = next(iter(_config.auth.api_keys.values()), "")
@@ -16,7 +16,7 @@ AUTH = {"Authorization": f"Bearer {_api_key}"} if _api_key else {}
def client():
"""Provide a TestClient with lifespan (startup/shutdown) properly triggered."""
from fastapi.testclient import TestClient
from wled_controller.main import app
from ledgrab.main import app
with TestClient(app) as c:
yield c