1 """Helper methods to search for Plex media."""
3 from __future__
import annotations
7 from plexapi.base
import PlexObject
8 from plexapi.exceptions
import BadRequest, NotFound
9 from plexapi.library
import LibrarySection
11 from .errors
import MediaNotFound
13 LEGACY_PARAM_MAPPING = {
14 "show_name":
"show.title",
15 "season_number":
"season.index",
16 "episode_name":
"episode.title",
17 "episode_number":
"episode.index",
18 "artist_name":
"artist.title",
19 "album_name":
"album.title",
20 "track_name":
"track.title",
21 "track_number":
"track.index",
22 "video_name":
"movie.title",
25 PREFERRED_LIBTYPE_ORDER = (
35 _LOGGER = logging.getLogger(__name__)
40 library_section: LibrarySection,
41 allow_multiple: bool =
False,
43 ) -> PlexObject | list[PlexObject]:
44 """Search for specified Plex media in the provided library section.
46 Returns a media item or a list of items if `allow_multiple` is set.
48 Raises MediaNotFound if the search was unsuccessful.
50 original_query = kwargs.copy()
52 libtype = kwargs.pop(
"libtype",
None)
55 for legacy_key, key
in LEGACY_PARAM_MAPPING.items():
56 if value := kwargs.pop(legacy_key,
None):
58 "Legacy parameter '%s' used, consider using '%s'", legacy_key, key
60 search_query[key] = value
62 search_query.update(**kwargs)
66 for preferred_libtype
in PREFERRED_LIBTYPE_ORDER:
67 if any(key.startswith(preferred_libtype)
for key
in search_query):
68 libtype = preferred_libtype
71 search_query.update(libtype=libtype)
72 _LOGGER.debug(
"Processed search query: %s", search_query)
75 results = library_section.search(**search_query)
76 except (BadRequest, NotFound)
as exc:
77 raise MediaNotFound(f
"Problem in query {original_query}: {exc}")
from exc
81 f
"No {media_type} results in '{library_section.title}' for {original_query}"
88 if title := search_query.get(
"title")
or search_query.get(
"movie.title"):
89 exact_matches = [x
for x
in results
if x.title.lower() == title.lower()]
90 if len(exact_matches) == 1:
91 return exact_matches[0]
93 "Multiple matches, make content_id more specific or use `allow_multiple`:"