From f0349db9ad4ae435d09bcff9c9ed5546e3794a3b Mon Sep 17 00:00:00 2001 From: Anish Sane Date: Fri, 10 Apr 2026 16:53:10 +0530 Subject: [PATCH] Add search_media functionality to the `Kodi` class. This function takes 2 arguments: media_type and search_query. Currently media_type can take the value 'movies', 'tvshows' or 'episodes'. (The logic can be extended later.) The results of the corresponding get_* are filtered against the search query by a fuzzy match logic. This functionality will be used by Home Assistant for the 'Search and play' intent. In addition to search_query, the user can also provide a parameter score_cutoff % (defaults to 80%) to be used as a threshold for fuzzy filtering. --- pykodi/kodi.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pykodi/kodi.py b/pykodi/kodi.py index 2cbb5eb..09da77b 100644 --- a/pykodi/kodi.py +++ b/pykodi/kodi.py @@ -6,6 +6,7 @@ import jsonrpc_base import jsonrpc_async import jsonrpc_websocket +from rapidfuzz import fuzz, process, utils def get_kodi_connection( @@ -411,6 +412,37 @@ async def get_players(self): """Return the active player objects.""" return await self._server.Player.GetActivePlayers() + async def search_media(self, media_type, search_query=None, score_cutoff=80, **kwargs): + """ Filter the original result by the search query. """ + result = None + match media_type: + case 'movies': + result = await self.get_movies(**kwargs) + case 'tvshows': + result = await self.get_tv_shows(**kwargs) + case 'episodes': + result = await self.get_episodes(**kwargs) + case _: + return [] + + media = result.get(media_type, []) + + if search_query is None: + return media + + media_labels = [i["label"] for i in media] + matching_media_indices = process.extract( + search_query, + media_labels, + scorer=fuzz.WRatio, + processor=utils.default_process, + score_cutoff=score_cutoff + ) + + filtered_media = [{**media[idx], 'fuzz_score':fuzz_score} for (label, fuzz_score, idx) in matching_media_indices] + + return filtered_media + async def send_notification(self, title, message, icon="info", displaytime=10000): """Display on-screen message.""" await self._server.GUI.ShowNotification(title, message, icon, displaytime)