diff --git a/docker/pyproject.deps.toml b/docker/pyproject.deps.toml index aee68f8..fb38977 100644 --- a/docker/pyproject.deps.toml +++ b/docker/pyproject.deps.toml @@ -1,6 +1,6 @@ [project] name = "mcp-plex" -version = "1.0.8" +version = "1.0.9" requires-python = ">=3.11,<3.13" dependencies = [ "fastmcp>=2.11.2", diff --git a/mcp_plex/server/__init__.py b/mcp_plex/server/__init__.py index b4abf33..65e635a 100644 --- a/mcp_plex/server/__init__.py +++ b/mcp_plex/server/__init__.py @@ -225,13 +225,47 @@ async def _get_media_data(identifier: str) -> dict[str, Any]: raise ValueError("Media item not found") payload = _flatten_payload(records[0].payload) data = payload - rating_key = str(data.get("plex", {}).get("rating_key")) + + def _normalize_identifier(value: Any) -> str | None: + if value is None: + return None + if isinstance(value, str): + normalized = value.strip() + return normalized or None + try: + return str(value) + except Exception: + return None + + cache_keys: set[str] = set() + + lookup_key = _normalize_identifier(identifier) + if lookup_key: + cache_keys.add(lookup_key) + + plex_data = data.get("plex", {}) or {} + rating_key = _normalize_identifier(plex_data.get("rating_key")) + if rating_key: + cache_keys.add(rating_key) + guid = _normalize_identifier(plex_data.get("guid")) + if guid: + cache_keys.add(guid) + + for source_key in ("imdb", "tmdb", "tvdb"): + source_data = data.get(source_key) + if isinstance(source_data, dict): + source_id = _normalize_identifier(source_data.get("id")) + if source_id: + cache_keys.add(source_id) + + for cache_key in cache_keys: + server.cache.set_payload(cache_key, payload) + if rating_key: - server.cache.set_payload(rating_key, payload) - thumb = data.get("plex", {}).get("thumb") + thumb = plex_data.get("thumb") if thumb: server.cache.set_poster(rating_key, thumb) - art = data.get("plex", {}).get("art") + art = plex_data.get("art") if art: server.cache.set_background(rating_key, art) return payload diff --git a/pyproject.toml b/pyproject.toml index c539dd5..6f45a1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "mcp-plex" -version = "1.0.8" +version = "1.0.9" description = "Plex-Oriented Model Context Protocol Server" requires-python = ">=3.11,<3.13" diff --git a/tests/test_server.py b/tests/test_server.py index 0b2d230..bfdc323 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -154,6 +154,35 @@ def test_server_tools(monkeypatch): asyncio.run(server.media_background.fn(identifier="0")) +def test_get_media_data_caches_external_ids(monkeypatch): + with _load_server(monkeypatch) as server: + call_count = 0 + + original_find_records = server._find_records + + async def _counting_find_records(identifier: str, limit: int = 1): + nonlocal call_count + call_count += 1 + return await original_find_records(identifier, limit=limit) + + monkeypatch.setattr(server, "_find_records", _counting_find_records) + + imdb_id = "tt8367814" + tmdb_id = "522627" + + data = asyncio.run(server._get_media_data(imdb_id)) + assert data["plex"]["rating_key"] == "49915" + assert call_count == 1 + + cached_imdb = asyncio.run(server._get_media_data(imdb_id)) + assert cached_imdb["plex"]["rating_key"] == "49915" + assert call_count == 1 + + cached_tmdb = asyncio.run(server._get_media_data(tmdb_id)) + assert cached_tmdb["plex"]["rating_key"] == "49915" + assert call_count == 1 + + def test_new_media_tools(monkeypatch): with _load_server(monkeypatch) as server: movies = asyncio.run(server.new_movies.fn(limit=1)) diff --git a/uv.lock b/uv.lock index 5151b52..70dce72 100644 --- a/uv.lock +++ b/uv.lock @@ -730,7 +730,7 @@ wheels = [ [[package]] name = "mcp-plex" -version = "1.0.8" +version = "1.0.9" source = { editable = "." } dependencies = [ { name = "fastapi" },