11
22from urllib .parse import unquote
33from difflib import SequenceMatcher
4+ import json
5+ import xml .etree .ElementTree as ET
46
57import xbmc
68import xbmcaddon
@@ -29,21 +31,111 @@ def get_media_data():
2931 "season_number" : str (xbmc .getInfoLabel ("VideoPlayer.Season" )),
3032 "episode_number" : str (xbmc .getInfoLabel ("VideoPlayer.Episode" )),
3133 "tv_show_title" : normalize_string (xbmc .getInfoLabel ("VideoPlayer.TVshowtitle" )),
32- "original_title" : normalize_string (xbmc .getInfoLabel ("VideoPlayer.OriginalTitle" ))}
34+ "original_title" : normalize_string (xbmc .getInfoLabel ("VideoPlayer.OriginalTitle" )),
35+ "parent_tmdb_id" : None ,
36+ "parent_imdb_id" : None ,
37+ "imdb_id" : None ,
38+ "tmdb_id" : None }
3339
3440
3541
3642
3743 if item ["tv_show_title" ]:
44+ item ["tvshowid" ] = xbmc .getInfoLabel ("VideoPlayer.TvShowDBID" )
3845 item ["query" ] = item ["tv_show_title" ]
3946 item ["year" ] = None # Kodi gives episode year, OS searches by series year. Without year safer.
40- item [ "imdb_id" ] = None # Kodi gives strange id. Without id safer.
47+ # Reset movie-specific IDs for TV shows
4148 # TODO if no season and episode numbers use guessit
49+
50+ # Extract TMDB and IMDB IDs for TV shows to improve search results
51+ if len (item ["tvshowid" ]) != 0 :
52+ try :
53+ TVShowDetails = xbmc .executeJSONRPC ('{ "jsonrpc": "2.0", "id":"1", "method": "VideoLibrary.GetTVShowDetails", "params":{"tvshowid":' + item ["tvshowid" ]+ ', "properties": ["episodeguide", "imdbnumber"]} }' )
54+ TVShowDetails_dict = json .loads (TVShowDetails )
55+ if "result" in TVShowDetails_dict and "tvshowdetails" in TVShowDetails_dict ["result" ]:
56+ tvshow_details = TVShowDetails_dict ["result" ]["tvshowdetails" ]
57+
58+ # Extract parent IMDB ID from imdbnumber field
59+ if "imdbnumber" in tvshow_details and tvshow_details ["imdbnumber" ]:
60+ imdb_raw = str (tvshow_details ["imdbnumber" ])
61+ # Extract numeric part from IMDB ID (remove 'tt' prefix if present)
62+ if imdb_raw .startswith ('tt' ):
63+ imdb_number = imdb_raw [2 :]
64+ else :
65+ imdb_number = imdb_raw
66+ # Validate it's numeric and reasonable length (IMDB IDs are typically 6-8 digits)
67+ if imdb_number .isdigit () and 6 <= len (imdb_number ) <= 8 :
68+ item ["parent_imdb_id" ] = int (imdb_number )
69+ log (__name__ , f"Found parent IMDB ID for TV show: { item ['parent_imdb_id' ]} " )
70+
71+ # Extract parent TMDB ID from episodeguide
72+ if "episodeguide" in tvshow_details and tvshow_details ["episodeguide" ]:
73+ episodeguideXML = tvshow_details ["episodeguide" ]
74+ episodeguide = ET .fromstring (episodeguideXML )
75+ if episodeguide .text :
76+ episodeguideJSON = json .loads (episodeguide .text )
77+ if "tmdb" in episodeguideJSON and episodeguideJSON ["tmdb" ]:
78+ tmdb_id = int (episodeguideJSON ["tmdb" ])
79+ if tmdb_id > 0 :
80+ item ["parent_tmdb_id" ] = tmdb_id
81+ log (__name__ , f"Found parent TMDB ID for TV show: { item ['parent_tmdb_id' ]} " )
82+ except (json .JSONDecodeError , ET .ParseError , ValueError , KeyError ) as e :
83+ log (__name__ , f"Failed to extract TV show IDs: { e } " )
84+ item ["parent_tmdb_id" ] = None
85+ item ["parent_imdb_id" ] = None
4286
4387 elif item ["original_title" ]:
4488 item ["query" ] = item ["original_title" ]
45-
46-
89+
90+ # For movies, try to extract IMDB and TMDB IDs
91+ try :
92+ # Get IMDB ID from VideoPlayer
93+ imdb_raw = xbmc .getInfoLabel ("VideoPlayer.IMDBNumber" )
94+ if imdb_raw :
95+ # Extract numeric part from IMDB ID (remove 'tt' prefix if present)
96+ if imdb_raw .startswith ('tt' ):
97+ imdb_number = imdb_raw [2 :]
98+ else :
99+ imdb_number = imdb_raw
100+ # Validate it's numeric and reasonable length (IMDB IDs are typically 6-8 digits)
101+ if imdb_number .isdigit () and 6 <= len (imdb_number ) <= 8 :
102+ item ["imdb_id" ] = int (imdb_number )
103+ log (__name__ , f"Found IMDB ID for movie: { item ['imdb_id' ]} " )
104+
105+ # Try to get TMDB ID (might be available in some library setups)
106+ # This is less common but worth trying
107+ tmdb_raw = xbmc .getInfoLabel ("VideoPlayer.DBID" )
108+ if tmdb_raw and tmdb_raw .isdigit ():
109+ tmdb_id = int (tmdb_raw )
110+ if tmdb_id > 0 :
111+ item ["tmdb_id" ] = tmdb_id
112+ log (__name__ , f"Found TMDB ID for movie: { item ['tmdb_id' ]} " )
113+ except (ValueError , KeyError ) as e :
114+ log (__name__ , f"Failed to extract movie IDs: { e } " )
115+
116+
117+ # Clean up and apply fallback logic for IDs
118+ # Remove zero or invalid IDs
119+ if item .get ("parent_tmdb_id" ) == 0 :
120+ item ["parent_tmdb_id" ] = None
121+ if item .get ("parent_imdb_id" ) == 0 :
122+ item ["parent_imdb_id" ] = None
123+ if item .get ("tmdb_id" ) == 0 :
124+ item ["tmdb_id" ] = None
125+ if item .get ("imdb_id" ) == 0 :
126+ item ["imdb_id" ] = None
127+
128+ # Apply fallback strategy: prefer one ID type to avoid conflicts
129+ # For TV shows: prefer parent_tmdb_id over parent_imdb_id
130+ if item .get ("parent_tmdb_id" ) and item .get ("parent_imdb_id" ):
131+ log (__name__ , f"Both parent TMDB and IMDB IDs found, preferring TMDB ID: { item ['parent_tmdb_id' ]} " )
132+ item ["parent_imdb_id" ] = None
133+
134+ # For movies: prefer tmdb_id over imdb_id
135+ if item .get ("tmdb_id" ) and item .get ("imdb_id" ):
136+ log (__name__ , f"Both TMDB and IMDB IDs found for movie, preferring TMDB ID: { item ['tmdb_id' ]} " )
137+ item ["imdb_id" ] = None
138+
47139 if not item ["query" ]:
48140 log (__name__ , "query still blank, fallback to title" )
49141 item ["query" ] = normalize_string (xbmc .getInfoLabel ("VideoPlayer.Title" )) # no original title, get just Title
@@ -53,6 +145,10 @@ def get_media_data():
53145 item ["season_number" ] = "0" #
54146 item ["episode_number" ] = item ["episode_number" ][- 1 :]
55147
148+ # Remove tvshowid since it's only used internally and not needed by API
149+ if "tvshowid" in item :
150+ del item ["tvshowid" ]
151+
56152 return item
57153
58154
@@ -134,6 +230,7 @@ def convert_language(language, reverse=False):
134230 "English" : "en" ,
135231 "Portuguese (Brazil)" : "pt-br" ,
136232 "Portuguese" : "pt-pt" ,
233+ "Chinese" : "zh-cn" ,
137234 "Chinese (simplified)" : "zh-cn" ,
138235 "Chinese (traditional)" : "zh-tw" }
139236
0 commit comments