11import asyncio
22from collections import Counter
33
4+ from loguru import logger
5+
46from app .services .stremio_service import StremioService
57from app .services .tmdb_service import TMDBService
68
@@ -59,6 +61,32 @@ async def get_watched_loved_catalogs(self, library_items: list[dict]):
5961
6062 return catalogs
6163
64+ async def _get_item_genres (self , item_id : str , item_type : str ) -> list [str ]:
65+ """Fetch genres for a specific item from TMDB."""
66+ try :
67+ # Convert IMDB ID to TMDB ID
68+ tmdb_id = None
69+ media_type = "movie" if item_type == "movie" else "tv"
70+
71+ if item_id .startswith ("tt" ):
72+ tmdb_id , _ = await self .tmdb_service .find_by_imdb_id (item_id )
73+ elif item_id .startswith ("tmdb:" ):
74+ tmdb_id = int (item_id .split (":" )[1 ])
75+
76+ if not tmdb_id :
77+ return []
78+
79+ # Fetch details
80+ if media_type == "movie" :
81+ details = await self .tmdb_service .get_movie_details (tmdb_id )
82+ else :
83+ details = await self .tmdb_service .get_tv_details (tmdb_id )
84+
85+ return [g .get ("name" ) for g in details .get ("genres" , [])]
86+ except Exception as e :
87+ logger .warning (f"Failed to fetch genres for { item_id } : { e } " )
88+ return []
89+
6290 async def get_genre_based_catalogs (self , library_items : list [dict ]):
6391 # get separate movies and series lists from loved items
6492 loved_movies = [item for item in library_items .get ("loved" , []) if item .get ("type" ) == "movie" ]
@@ -68,22 +96,19 @@ async def get_genre_based_catalogs(self, library_items: list[dict]):
6896 loved_movies = loved_movies [:5 ]
6997 loved_series = loved_series [:5 ]
7098
71- # fetch details:: genre details from tmdb addon
72- movie_tasks = [self .tmdb_service .get_addon_meta ("movie" , item .get ("_id" ).strip ()) for item in loved_movies ]
73- series_tasks = [self .tmdb_service .get_addon_meta ("series" , item .get ("_id" ).strip ()) for item in loved_series ]
74- movie_details = await asyncio .gather (* movie_tasks )
75- series_details = await asyncio .gather (* series_tasks )
99+ # fetch genres concurrently
100+ movie_tasks = [self ._get_item_genres (item .get ("_id" ).strip (), "movie" ) for item in loved_movies ]
101+ series_tasks = [self ._get_item_genres (item .get ("_id" ).strip (), "series" ) for item in loved_series ]
76102
77- # now fetch all genres for moviees and series and sort them by their occurance
78- movie_genres = [detail .get ("meta" , {}).get ("genres" , []) for detail in movie_details ]
79- series_genres = [detail .get ("meta" , {}).get ("genres" , []) for detail in series_details ]
103+ movie_genres_list = await asyncio .gather (* movie_tasks )
104+ series_genres_list = await asyncio .gather (* series_tasks )
80105
81106 # now flatten list and count the occurance of each genre for both movies and series separately
82107 movie_genre_counts = Counter (
83- [genre for sublist in movie_genres for genre in sublist if genre in MOVIE_GENRE_TO_ID_MAP ]
108+ [genre for sublist in movie_genres_list for genre in sublist if genre in MOVIE_GENRE_TO_ID_MAP ]
84109 )
85110 series_genre_counts = Counter (
86- [genre for sublist in series_genres for genre in sublist if genre in SERIES_GENRE_TO_ID_MAP ]
111+ [genre for sublist in series_genres_list for genre in sublist if genre in SERIES_GENRE_TO_ID_MAP ]
87112 )
88113 sorted_movie_genres = sorted (movie_genre_counts .items (), key = lambda x : x [1 ], reverse = True )
89114 sorted_series_genres = sorted (series_genre_counts .items (), key = lambda x : x [1 ], reverse = True )
@@ -97,22 +122,24 @@ async def get_genre_based_catalogs(self, library_items: list[dict]):
97122 top_2_series_genres = [str (SERIES_GENRE_TO_ID_MAP [genre_name ]) for genre_name in top_2_series_genre_names ]
98123 catalogs = []
99124
100- catalogs .append (
101- {
102- "type" : "movie" ,
103- "id" : f"watchly.genre.{ '_' .join (top_2_movie_genres )} " ,
104- "name" : "You might also Like" ,
105- "extra" : [],
106- }
107- )
108-
109- catalogs .append (
110- {
111- "type" : "series" ,
112- "id" : f"watchly.genre.{ '_' .join (top_2_series_genres )} " ,
113- "name" : "You might also Like" ,
114- "extra" : [],
115- }
116- )
125+ if top_2_movie_genres :
126+ catalogs .append (
127+ {
128+ "type" : "movie" ,
129+ "id" : f"watchly.genre.{ '_' .join (top_2_movie_genres )} " ,
130+ "name" : "You might also Like" ,
131+ "extra" : [],
132+ }
133+ )
134+
135+ if top_2_series_genres :
136+ catalogs .append (
137+ {
138+ "type" : "series" ,
139+ "id" : f"watchly.genre.{ '_' .join (top_2_series_genres )} " ,
140+ "name" : "You might also Like" ,
141+ "extra" : [],
142+ }
143+ )
117144
118145 return catalogs
0 commit comments