From 3ee49b17bd8a94a631f2275bd75ceed54265083c Mon Sep 17 00:00:00 2001 From: zebra Date: Mon, 8 Jun 2026 23:44:34 -0700 Subject: [PATCH] fix(lidarr): select metadata/quality profiles by name with env overrides Co-Authored-By: Claude Sonnet 4.6 --- musicfetch | 30 ++++++++++++++++++++++------- tests/test_profiles.py | 43 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 tests/test_profiles.py diff --git a/musicfetch b/musicfetch index 1ecff2a..f02ebab 100755 --- a/musicfetch +++ b/musicfetch @@ -444,14 +444,30 @@ def get_existing_artist(name: str) -> Optional[dict]: return None -def get_default_metadata_profile_id() -> int: +def _profile_id_by_name(path: str, env_var: str, default_name: str) -> int: + """Return the id of the profile whose name matches env_var (default + default_name, case-insensitive). Fall back to the first profile, then 1.""" + name = os.environ.get(env_var, default_name) try: - profiles = lidarr_get("/api/v1/metadataprofile", timeout=10) - if profiles: - return profiles[0]["id"] + profiles = lidarr_get(path, timeout=10) except RequestException as e: - dbg(f"metadataprofile fetch failed: {e}") - return 1 + dbg(f"{path} fetch failed: {e}") + return 1 + if not profiles: + return 1 + for p in profiles: + if p.get("name", "").casefold() == name.casefold(): + return p["id"] + dbg(f"profile '{name}' not found at {path}; using first ('{profiles[0].get('name')}')") + return profiles[0]["id"] + + +def get_default_metadata_profile_id() -> int: + return _profile_id_by_name("/api/v1/metadataprofile", "LIDARR_METADATA_PROFILE", "Standard") + + +def get_quality_profile_id() -> int: + return _profile_id_by_name("/api/v1/qualityprofile", "LIDARR_QUALITY_PROFILE", "Any") def add_artist(meta: dict, root: str, search_all: bool, dry_run: bool) -> Optional[dict]: @@ -463,7 +479,7 @@ def add_artist(meta: dict, root: str, search_all: bool, dry_run: bool) -> Option payload = { "foreignArtistId": foreign_id, "artistName": name, - "qualityProfileId": 1, + "qualityProfileId": get_quality_profile_id(), "metadataProfileId": get_default_metadata_profile_id(), "rootFolderPath": root, "monitored": True, diff --git a/tests/test_profiles.py b/tests/test_profiles.py new file mode 100644 index 0000000..8d42d47 --- /dev/null +++ b/tests/test_profiles.py @@ -0,0 +1,43 @@ +import server.mf # noqa: F401 +import musicfetch_core as mf + +META = [{"id": 1, "name": "Standard"}, {"id": 2, "name": "None"}, {"id": 3, "name": "OST"}] +QUAL = [{"id": 1, "name": "Any"}, {"id": 2, "name": "Lossless"}] + + +def test_metadata_profile_default_standard_by_name(monkeypatch): + monkeypatch.delenv("LIDARR_METADATA_PROFILE", raising=False) + monkeypatch.setattr(mf, "lidarr_get", lambda path, timeout=10: META) + assert mf.get_default_metadata_profile_id() == 1 + + +def test_metadata_profile_env_override(monkeypatch): + monkeypatch.setenv("LIDARR_METADATA_PROFILE", "OST") + monkeypatch.setattr(mf, "lidarr_get", lambda path, timeout=10: META) + assert mf.get_default_metadata_profile_id() == 3 + + +def test_metadata_profile_unknown_name_falls_back_to_first(monkeypatch): + monkeypatch.setenv("LIDARR_METADATA_PROFILE", "Nonexistent") + monkeypatch.setattr(mf, "lidarr_get", lambda path, timeout=10: META) + assert mf.get_default_metadata_profile_id() == 1 + + +def test_quality_profile_default_any_by_name(monkeypatch): + monkeypatch.delenv("LIDARR_QUALITY_PROFILE", raising=False) + monkeypatch.setattr(mf, "lidarr_get", lambda path, timeout=10: QUAL) + assert mf.get_quality_profile_id() == 1 + + +def test_quality_profile_env_override(monkeypatch): + monkeypatch.setenv("LIDARR_QUALITY_PROFILE", "Lossless") + monkeypatch.setattr(mf, "lidarr_get", lambda path, timeout=10: QUAL) + assert mf.get_quality_profile_id() == 2 + + +def test_profile_fetch_error_returns_one(monkeypatch): + def boom(path, timeout=10): + raise mf.RequestException("down") + monkeypatch.setattr(mf, "lidarr_get", boom) + assert mf.get_default_metadata_profile_id() == 1 + assert mf.get_quality_profile_id() == 1