def show_infodialog(dbid="", media_type=""): '''shows the special info dialog for this media''' cont_prefix = get_cont_prefix() metadatautils = MetadataUtils() item_details = {} # if dbid is provided we prefer that info else we try to locate the dbid and dbtype if not (dbid and media_type): dbid, media_type = get_cur_listitem(cont_prefix) if media_type.endswith("s"): media_type = media_type[:-1] # get basic details from kodi db if we have a valid dbid and dbtype if dbid and media_type: if hasattr(metadatautils.kodidb.__class__, media_type): item_details = getattr(metadatautils.kodidb, media_type)(dbid) # only proceed if we have a media_type if media_type: title = xbmc.getInfoLabel("%sListItem.Title" % cont_prefix).decode('utf-8') # music content if media_type in ["album", "artist", "song"]: artist = xbmc.getInfoLabel("%sListItem.AlbumArtist" % cont_prefix).decode('utf-8') if not artist: artist = xbmc.getInfoLabel("%sListItem.Artist" % cont_prefix).decode('utf-8') album = xbmc.getInfoLabel("%sListItem.Album" % cont_prefix).decode('utf-8') disc = xbmc.getInfoLabel("%sListItem.DiscNumber" % cont_prefix).decode('utf-8') if artist: item_details = extend_dict( item_details, metadatautils.get_music_artwork(artist, album, title, disc)) # movieset elif media_type == "movieset" and dbid: item_details = extend_dict(item_details, metadatautils.get_moviesetdetails(dbid)) # pvr item elif media_type in [ "tvchannel", "tvrecording", "channel", "recording" ]: channel = xbmc.getInfoLabel("%sListItem.ChannelName" % cont_prefix).decode('utf-8') genre = xbmc.getInfoLabel("%sListItem.Genre" % cont_prefix) item_details["type"] = media_type item_details = extend_dict( item_details, metadatautils.get_pvr_artwork(title, channel, genre)) metadatautils.close() # proceed with infodialog if we have details if item_details: win = DialogVideoInfo("DialogVideoInfo.xml", "", listitem=item_details) win.doModal() del win
def process_artist(self, item): '''transform the json received from kodi into something we can use''' if self.enable_artwork: extend_dict(item, self.metadatautils.get_music_artwork(item["label"][0])) item["file"] = "musicdb://artists/%s" % item["artistid"] item["isFolder"] = True return item
def process_song(self, item): '''additional actions on a song item''' if self.enable_artwork: extend_dict( item, self.metadatautils.get_music_artwork(item["artist"][0], item["album"], item["title"], str(item["disc"]))) return item
def process_album(self, item): '''transform the json received from kodi into something we can use''' if self.enable_artwork: extend_dict( item, self.metadatautils.get_music_artwork(item["artist"][0], item["title"])) if self.browse_album: item["file"] = "musicdb://albums/%s" % item["albumid"] item["isFolder"] = True else: item[ "file"] = u"plugin://script.skin.helper.service?action=playalbum&albumid=%s" % item[ "albumid"] return item
def show_infodialog(dbid="", media_type=""): '''shows the special info dialog for this media''' cont_prefix = get_cont_prefix() metadatautils = MetadataUtils() item_details = {} # if dbid is provided we prefer that info else we try to locate the dbid and dbtype if not (dbid and media_type): dbid, media_type = get_cur_listitem(cont_prefix) if media_type.endswith("s"): media_type = media_type[:-1] # get basic details from kodi db if we have a valid dbid and dbtype if dbid and media_type: if hasattr(metadatautils.kodidb.__class__, media_type): item_details = getattr(metadatautils.kodidb, media_type)(dbid) # only proceed if we have a media_type if media_type: title = xbmc.getInfoLabel("%sListItem.Title" % cont_prefix).decode('utf-8') # music content if media_type in ["album", "artist", "song"]: artist = xbmc.getInfoLabel("%sListItem.AlbumArtist" % cont_prefix).decode('utf-8') if not artist: artist = xbmc.getInfoLabel("%sListItem.Artist" % cont_prefix).decode('utf-8') album = xbmc.getInfoLabel("%sListItem.Album" % cont_prefix).decode('utf-8') disc = xbmc.getInfoLabel("%sListItem.DiscNumber" % cont_prefix).decode('utf-8') if artist: item_details = extend_dict(item_details, metadatautils.get_music_artwork(artist, album, title, disc)) # movieset elif media_type == "movieset" and dbid: item_details = extend_dict(item_details, metadatautils.get_moviesetdetails(dbid)) # pvr item elif media_type in ["tvchannel", "tvrecording", "channel", "recording"]: channel = xbmc.getInfoLabel("%sListItem.ChannelName" % cont_prefix).decode('utf-8') genre = xbmc.getInfoLabel("%sListItem.Genre" % cont_prefix) item_details["type"] = media_type item_details = extend_dict(item_details, metadatautils.get_pvr_artwork(title, channel, genre)) metadatautils.close() # proceed with infodialog if we have details if item_details: win = DialogVideoInfo("DialogVideoInfo.xml", "", listitem=item_details) win.doModal() del win
def find_media_match(self, fav, media_filter): ''' try to get a match for movie/episode/song/musicvideo for favourite''' match = {} # apparently only the filepath can be used for the search filename = fav["path"] if "/" in filename: sep = "/" else: sep = "\\" file_path = filename.split(sep)[-1] filters = [{ "operator": "contains", "field": "filename", "value": file_path }] # is this a movie? if not match and (not media_filter or media_filter in ["movies", "media"]): for item in self.metadatautils.kodidb.movies(filters=filters): if item['file'] == fav["path"]: match = item # is this an episode ? if not match and (not media_filter or media_filter in ["episodes", "media"]): for item in self.metadatautils.kodidb.episodes(filters=filters): if item['file'] == fav["path"]: match = item # is this a song ? if not match and (not media_filter or media_filter in ["songs", "media"]): for item in self.metadatautils.kodidb.songs(filters=filters): if item['file'] == fav["path"]: if self.enable_artwork: extend_dict( item, self.metadatautils.get_music_artwork( item["title"], item["artist"][0])) match = item # is this a musicvideo ? if not match and (not media_filter or media_filter in ["musicvideos", "media"]): for item in self.metadatautils.kodidb.musicvideos(filters=filters): if item['file'] == fav["path"]: match = item return match
def process_timer(self, item): '''transform the json received from kodi into something we can use''' item["file"] = "plugin://script.skin.helper.service/?action=launch&path=" + \ quote_plus("ReplaceWindow(tvtimers),return") channel_details = self.metadatautils.kodidb.channel(item["channelid"]) channelname = channel_details["label"] item["channel"] = channelname item["plot"] = item.get("summary", "") item["type"] = "recording" item["isFolder"] = False if self.enable_artwork: extend_dict( item, self.metadatautils.get_pvr_artwork(item["title"], item["channel"])) item["type"] = "recording" item["channellogo"] = self.metadatautils.get_channellogo( item["channel"]) return item
def process_recording(self, item): '''transform the json received from kodi into something we can use''' if self.enable_artwork: extend_dict( item, self.metadatautils.get_pvr_artwork(item["title"], item["channel"])) item["type"] = "recording" item["channellogo"] = self.metadatautils.get_channellogo( item["channel"]) item["file"] = u"plugin://script.skin.helper.service?action=playrecording&recordingid=%s"\ % (item["recordingid"]) item["dateadded"] = item["endtime"].split(" ")[0] if item["resume"].get("position"): item["lastplayed"] = item["endtime"].split(" ")[0] else: item["lastplayed"] = "" if not item["art"].get("thumb"): item["art"]["thumb"] = item["channellogo"] return item
def set_video_properties(self, mediatype, li_dbid): '''sets the window props for a playing video item''' if not mediatype: mediatype = self.get_mediatype() details = self.get_player_infolabels() li_title = details["title"] li_year = details["year"] li_imdb = details["imdbnumber"] li_showtitle = details["tvshowtitle"] details = {"art": {}} # video content if mediatype in ["movie", "episode", "musicvideo"]: # get imdb_id li_imdb, li_tvdb = self.metadatautils.get_imdbtvdb_id( li_title, mediatype, li_year, li_imdb, li_showtitle) # generic video properties (studio, streamdetails, omdb, top250) details = extend_dict(details, self.metadatautils.get_omdb_info(li_imdb)) if li_dbid: details = extend_dict( details, self.metadatautils.get_streamdetails(li_dbid, mediatype)) details = extend_dict( details, self.metadatautils.get_top250_rating(li_imdb)) # tvshows-only properties (tvdb) if mediatype == "episode": details = extend_dict( details, self.metadatautils.get_tvdb_details(li_imdb, li_tvdb)) # movies-only properties (tmdb, animated art) if mediatype == "movie": details = extend_dict( details, self.metadatautils.get_tmdb_details(li_imdb)) if li_imdb and xbmc.getCondVisibility( "Skin.HasSetting(SkinHelper.EnableAnimatedPosters)"): details = extend_dict( details, self.metadatautils.get_animated_artwork(li_imdb)) # extended art if xbmc.getCondVisibility( "Skin.HasSetting(SkinHelper.EnableExtendedArt)"): tmdbid = details.get("tmdb_id", "") details = extend_dict( details, self.metadatautils.get_extended_artwork( li_imdb, li_tvdb, tmdbid, mediatype)) if li_title == xbmc.getInfoLabel("Player.Title").decode('utf-8'): all_props = prepare_win_props(details, u"SkinHelper.Player.") process_method_on_list(self.set_win_prop, all_props)
def find_window_match(self, fav, media_filter): '''try to get a match for tvshow or album favourites listing''' match = {} # check for tvshow if not media_filter or media_filter == "tvshows": if fav["windowparameter"].startswith("videodb://tvshows/titles"): try: tvshowid = int(fav["windowparameter"].split("/")[-2]) result = self.metadatautils.kodidb.tvshow(tvshowid) if result: result[ "file"] = "videodb://tvshows/titles/%s" % tvshowid result["isFolder"] = True match = result except Exception: pass # check for album if not match and (not media_filter or media_filter in ["albums", "media"]): if "musicdb://albums/" in fav["windowparameter"]: result = self.metadatautils.kodidb.album( fav["windowparameter"].replace("musicdb://albums/", "")) if result: if self.enable_artwork: extend_dict( result, self.metadatautils.get_music_artwork( result["label"], result["artist"][0])) if self.browse_album: result[ "file"] = "musicdb://albums/%s" % result["albumid"] result["isFolder"] = True else: result["file"] = u"plugin://script.skin.helper.service?action=playalbum&albumid=%s" \ % result["albumid"] match = result return match
def process_channel(self, channeldata): '''transform the json received from kodi into something we can use''' item = {} channelname = channeldata["label"] channellogo = get_clean_image(channeldata['thumbnail']) if channeldata.get('broadcastnow'): # channel with epg data item = channeldata['broadcastnow'] item["runtime"] = item["runtime"] * 60 item["genre"] = u" / ".join(item["genre"]) # del firstaired as it's value doesn't make any sense at all del item["firstaired"] # append artwork if self.enable_artwork: extend_dict( item, self.metadatautils.get_pvr_artwork(item["title"], channelname, item["genre"])) else: # channel without epg item = channeldata item["title"] = xbmc.getLocalizedString(161) item["file"] = u"plugin://script.skin.helper.service?action=playchannel&channelid=%s"\ % (channeldata["channelid"]) item["channel"] = channelname item["type"] = "channel" item["label"] = channelname item["channelid"] = channeldata["channelid"] if not channellogo: channellogo = self.metadatautils.get_channellogo(channelname).get( "ChannelLogo", "") if channellogo: item["art"] = {"thumb": channellogo} item["channellogo"] = channellogo item["isFolder"] = False return item
def get_pvr_artwork(self, listitem, prefix): '''get pvr artwork from artwork module''' if self.enable_pvrart: if xbmc.getCondVisibility("%sListItem.IsFolder" % prefix) and not listitem[ "channelname"] and not listitem["title"]: listitem["title"] = listitem["label"] listitem = extend_dict( listitem, self.metadatautils.get_pvr_artwork( listitem["title"], listitem["channelname"], listitem["genre"]), ["title", "genre", "genres", "thumb"]) # pvr channellogo if listitem["channelname"]: listitem["art"]["ChannelLogo"] = self.metadatautils.get_channellogo(listitem["channelname"]) elif listitem.get("pvrchannel"): listitem["art"]["ChannelLogo"] = self.metadatautils.get_channellogo(listitem["pvrchannel"]) return listitem
def set_video_properties(self, mediatype, li_dbid): '''sets the window props for a playing video item''' if not mediatype: mediatype = self.get_mediatype() details = self.get_player_infolabels() li_title = details["title"] li_year = details["year"] li_imdb = details["imdbnumber"] li_showtitle = details["tvshowtitle"] details = {"art": {}} # video content if mediatype in ["movie", "episode", "musicvideo"]: # get imdb_id li_imdb, li_tvdb = self.metadatautils.get_imdbtvdb_id(li_title, mediatype, li_year, li_imdb, li_showtitle) # generic video properties (studio, streamdetails, omdb, top250) details = extend_dict(details, self.metadatautils.get_omdb_info(li_imdb)) if li_dbid: details = extend_dict(details, self.metadatautils.get_streamdetails(li_dbid, mediatype)) details = extend_dict(details, self.metadatautils.get_top250_rating(li_imdb)) # tvshows-only properties (tvdb) if mediatype == "episode": details = extend_dict(details, self.metadatautils.get_tvdb_details(li_imdb, li_tvdb)) # movies-only properties (tmdb, animated art) if mediatype == "movie": details = extend_dict(details, self.metadatautils.get_tmdb_details(li_imdb)) if li_imdb and xbmc.getCondVisibility("Skin.HasSetting(SkinHelper.EnableAnimatedPosters)"): details = extend_dict(details, self.metadatautils.get_animated_artwork(li_imdb)) # extended art if xbmc.getCondVisibility("Skin.HasSetting(SkinHelper.EnableExtendedArt)"): tmdbid = details.get("tmdb_id", "") details = extend_dict(details, self.metadatautils.get_extended_artwork( li_imdb, li_tvdb, tmdbid, mediatype)) if li_title == xbmc.getInfoLabel("Player.Title").decode('utf-8'): all_props = prepare_win_props(details, u"SkinHelper.Player.") process_method_on_list(self.set_win_prop, all_props)
def get_pvr_artwork(self, listitem, prefix): '''get pvr artwork from artwork module''' if self.enable_pvrart: if xbmc.getCondVisibility( "%sListItem.IsFolder" % prefix ) and not listitem["channelname"] and not listitem["title"]: listitem["title"] = listitem["label"] listitem = extend_dict( listitem, self.metadatautils.get_pvr_artwork(listitem["title"], listitem["channelname"], listitem["genre"]), ["title", "genre", "genres", "thumb"]) # pvr channellogo if listitem["channelname"]: listitem["art"][ "ChannelLogo"] = self.metadatautils.get_channellogo( listitem["channelname"]) elif listitem.get("pvrchannel"): listitem["art"][ "ChannelLogo"] = self.metadatautils.get_channellogo( listitem["pvrchannel"]) return listitem
def set_listitem_details(self, cur_listitem, content_type, prefix): '''set the window properties based on the current listitem''' self.bgtasks += 1 try: if cur_listitem in self.listitem_details: # data already in memory all_props = self.listitem_details[cur_listitem] else: # prefer listitem's contenttype over container's contenttype dbtype = xbmc.getInfoLabel("%sListItem.DBTYPE" % prefix) if not dbtype: dbtype = xbmc.getInfoLabel("%sListItem.Property(DBTYPE)" % prefix) if dbtype: content_type = dbtype + "s" # collect all details from listitem listitem = self.get_listitem_details(content_type, prefix) if prefix and cur_listitem == self.last_listitem: # for widgets we immediately set all normal properties as window prop self.set_win_props(prepare_win_props(listitem)) # if another lookup for the same listitem already in progress... wait for it to complete while self.lookup_busy.get(cur_listitem): xbmc.sleep(250) if self.exit: return self.lookup_busy[cur_listitem] = True # music content if content_type in ["albums", "artists", "songs" ] and self.enable_musicart: listitem = extend_dict( listitem, self.metadatautils.get_music_artwork( listitem["artist"], listitem["album"], listitem["title"], listitem["discnumber"])) # moviesets elif listitem["path"].startswith( "videodb://movies/sets/") and listitem["dbid"]: listitem = extend_dict( listitem, self.metadatautils.get_moviesetdetails( listitem["title"], listitem["dbid"])) content_type = "sets" # video content elif content_type in [ "movies", "setmovies", "tvshows", "seasons", "episodes", "musicvideos" ]: # get imdb and tvdbid listitem[ "imdbnumber"], tvdbid = self.metadatautils.get_imdbtvdb_id( listitem["title"], content_type, listitem["year"], listitem["imdbnumber"], listitem["tvshowtitle"]) # generic video properties (studio, streamdetails, omdb, top250) listitem = extend_dict( listitem, self.get_directors_writers(listitem["director"], listitem["writer"])) if self.enable_extrafanart: if not listitem["filenameandpath"]: listitem["filenameandpath"] = listitem["path"] if "videodb://" not in listitem["filenameandpath"]: listitem = extend_dict( listitem, self.metadatautils.get_extrafanart( listitem["filenameandpath"])) listitem = extend_dict(listitem, self.get_genres(listitem["genre"])) listitem = extend_dict( listitem, self.metadatautils.get_duration(listitem["duration"])) listitem = extend_dict( listitem, self.metadatautils.get_studio_logo(listitem["studio"])) listitem = extend_dict( listitem, self.metadatautils.get_omdb_info( listitem["imdbnumber"])) listitem = extend_dict( listitem, self.get_streamdetails(listitem["dbid"], listitem["path"], content_type)) if self.exit: return listitem = extend_dict( listitem, self.metadatautils.get_top250_rating( listitem["imdbnumber"])) if self.exit: return # tvshows-only properties (tvdb) if content_type in ["tvshows", "seasons", "episodes"]: listitem = extend_dict( listitem, self.metadatautils.get_tvdb_details( listitem["imdbnumber"], tvdbid)) # movies-only properties (tmdb, animated art) if content_type in ["movies", "setmovies"]: listitem = extend_dict( listitem, self.metadatautils.get_tmdb_details( listitem["imdbnumber"])) if listitem["imdbnumber"] and self.enable_animatedart: listitem = extend_dict( listitem, self.metadatautils.get_animated_artwork( listitem["imdbnumber"])) # extended art if self.enable_extendedart: tmdbid = listitem.get("tmdb_id", "") listitem = extend_dict( listitem, self.metadatautils.get_extended_artwork( listitem["imdbnumber"], tvdbid, tmdbid, content_type), ["posters", "clearlogos", "banners"]) if self.exit: return # monitor listitem props when PVR is active elif content_type in [ "tvchannels", "tvrecordings", "channels", "recordings", "timers", "tvtimers" ]: listitem = self.get_pvr_artwork(listitem, prefix) # process all properties all_props = prepare_win_props(listitem) if content_type not in ["weathers", "systeminfos", "sets"]: self.listitem_details[cur_listitem] = all_props self.lookup_busy.pop(cur_listitem, None) if cur_listitem == self.last_listitem: self.set_win_props(all_props) except Exception as exc: log_exception(__name__, exc) self.bgtasks -= 1
def handle_request(self, headers_only=False): '''send headers and reponse''' image = "" try: artwork = {} params = self.get_params() action = params.get("action", "") title = params.get("title", "") preferred_types = params.get("type") if preferred_types: preferred_types = preferred_types.split(",") else: preferred_types = [] fallback = params.get("fallback", "") is_json_request = params.get("json", "") == "true" if fallback and not xbmcvfs.exists(fallback): fallback = "special://skin/media/" + fallback if not xbmcvfs.exists(fallback): fallback = "" log_msg( "Webservice --> Non existent fallback image detected - " "please use a full path to the fallback image!", xbmc.LOGWARNING) log_msg("webservice called with params: %s" % params) # search image on google if action == "getthumb": image = self.server.metadatautils.google.search_image(title) # get pvr image elif "pvrthumb" in action: channel = params.get("channel", "") genre = params.get("genre", "") artwork = self.server.metadatautils.get_pvr_artwork( title, channel, genre) if action == "getallpvrthumb": is_json_request = True # get video artwork and metadata elif action == "getartwork": if not preferred_types: is_json_request = True year = params.get("year", "") media_type = params.get("mediatype", "") imdb_id = params.get("imdbid", "") if not imdb_id: artwork = self.server.metadatautils.get_tmdb_details( "", "", title, year, media_type) if artwork: imdb_id = artwork.get("imdbnumber") if not media_type: media_type = artwork.get("media_type") if imdb_id: artwork = extend_dict( artwork, self.server.metadatautils.get_extended_artwork( imdb_id, "", "", media_type)) # music art elif action == "getmusicart": artist = params.get("artist", "") album = params.get("album", "") track = params.get("track", "") artwork = self.server.metadatautils.get_music_artwork( artist, album, track) # genre images elif "genreimages" in action and preferred_types: arttype = preferred_types[0].split(".")[0] mediatype = "tvshows" if "tvshow" in action else "movies" randomize = "true" if "random" in action else "false" lib_path = u"plugin://script.skin.helper.service/?action=genrebackground"\ "&genre=%s&arttype=%s&mediatype=%s&random=%s" % (title, arttype, mediatype, randomize) for count, item in enumerate( self.server.metadatautils.kodidb.files(lib_path, limits=(0, 5))): artwork["%s.%s" % (arttype, count)] = item["file"] # image from variable elif "getvarimage" in action: title = title.replace("{", "[").replace("}", "]") image = xbmc.getInfoLabel(title) if not xbmcvfs.exists(image): if "resource.images" in image: log_msg( "Texture packed resource addons are not supported by the webservice! - %s" % image, xbmc.LOGWARNING) image = "" if not is_json_request: if artwork and artwork.get("art"): artwork = artwork["art"] if preferred_types: for pref_type in preferred_types: if not image: image = artwork.get(pref_type, "") elif not image and artwork.get("landscape"): image = artwork["landscape"] elif not image and artwork.get("fanart"): image = artwork["fanart"] elif not image and artwork.get("poster"): image = artwork["poster"] elif not image and artwork.get("thumb"): image = artwork["thumb"] # set fallback image if nothing else worked if not image or not xbmcvfs.exists(image): image = fallback log_msg( "webservice image: %s - fallback: %s - artwork: %s - title: %s" % (image, fallback, artwork, title)) if is_json_request and artwork: # send json reponse artwork = json.dumps(artwork) self.send_response(200) self.send_header('Content-type', 'application/json') self.send_header('Content-Length', len(artwork)) self.end_headers() if not headers_only: self.wfile.write(artwork) elif image: # send single image self.send_response(200) ext = image.split(".")[-1] self.send_header('Content-type', 'image/%s' % ext) modified = xbmcvfs.Stat(image).st_mtime() self.send_header('Last-Modified', "%s" % modified) image = xbmcvfs.File(image) size = image.size() self.send_header('Content-Length', str(size)) self.end_headers() if not headers_only: log_msg("sending image for request %s" % (self.path)) self.wfile.write(image.readBytes()) image.close() else: self.send_error(404, 'No image was found') except Exception as exc: log_exception(__name__, exc) self.send_error(500, 'Exception occurred: %s' % exc) return
def set_listitem_details(self, cur_listitem, content_type, prefix): '''set the window properties based on the current listitem''' self.bgtasks += 1 try: if cur_listitem in self.listitem_details: # data already in memory all_props = self.listitem_details[cur_listitem] else: # prefer listitem's contenttype over container's contenttype dbtype = xbmc.getInfoLabel("%sListItem.DBTYPE" % prefix) if not dbtype: dbtype = xbmc.getInfoLabel("%sListItem.Property(DBTYPE)" % prefix) if dbtype: content_type = dbtype + "s" # collect all details from listitem details = self.get_listitem_details(content_type, prefix) if prefix and cur_listitem == self.last_listitem: # for widgets we immediately set all normal properties as window prop self.set_win_props(prepare_win_props(details)) # if another lookup for the same listitem already in progress... wait for it to complete while self.lookup_busy.get(cur_listitem): xbmc.sleep(250) if self.exit: return self.lookup_busy[cur_listitem] = True # music content if content_type in ["albums", "artists", "songs"] and self.enable_musicart: details = extend_dict(details, self.metadatautils.get_music_artwork( details["artist"], details["album"], details["title"], details["discnumber"])) # moviesets elif details["path"].startswith("videodb://movies/sets/") and details["dbid"]: details = extend_dict( details, self.metadatautils.get_moviesetdetails( details["title"], details["dbid"])) content_type = "sets" # video content elif content_type in ["movies", "setmovies", "tvshows", "seasons", "episodes", "musicvideos"]: # get imdb and tvdbid details["imdbnumber"], tvdbid = self.metadatautils.get_imdbtvdb_id( details["title"], content_type, details["year"], details["imdbnumber"], details["tvshowtitle"]) # generic video properties (studio, streamdetails, omdb, top250) details = merge_dict(details, self.get_directors_writers(details["director"], details["writer"])) if self.enable_extrafanart: if not details["filenameandpath"]: details["filenameandpath"] = details["path"] if "videodb://" not in details["filenameandpath"]: details = merge_dict(details, self.metadatautils.get_extrafanart(details["filenameandpath"])) details = merge_dict(details, self.metadatautils.get_duration(details["duration"])) details = merge_dict(details, self.get_genres(details["genre"])) details = merge_dict(details, self.metadatautils.get_studio_logo(details["studio"])) details = merge_dict(details, self.metadatautils.get_omdb_info(details["imdbnumber"])) details = merge_dict(details, self.get_streamdetails(details["dbid"], details["path"], content_type)) if self.exit: return details = merge_dict(details, self.metadatautils.get_top250_rating(details["imdbnumber"])) if self.exit: return # tvshows-only properties (tvdb) if content_type in ["tvshows", "seasons", "episodes"]: details = merge_dict(details, self.metadatautils.get_tvdb_details(details["imdbnumber"], tvdbid)) if self.exit: return # movies-only properties (tmdb, animated art) if content_type in ["movies", "setmovies"]: details = merge_dict(details, self.metadatautils.get_tmdb_details(details["imdbnumber"])) if details["imdbnumber"] and self.enable_animatedart: details = extend_dict( details, self.metadatautils.get_animated_artwork( details["imdbnumber"])) if self.exit: return # extended art if self.enable_extendedart: tmdbid = details.get("tmdb_id", "") details = extend_dict( details, self.metadatautils.get_extended_artwork( details["imdbnumber"], tvdbid, tmdbid, content_type), [ "posters", "clearlogos", "banners"]) if self.exit: return # monitor listitem props when PVR is active elif content_type in ["tvchannels", "tvrecordings", "channels", "recordings", "timers", "tvtimers"]: details = self.get_pvr_artwork(details, prefix) # process all properties all_props = prepare_win_props(details) if content_type not in ["weathers", "systeminfos", "sets"]: self.listitem_details[cur_listitem] = all_props self.lookup_busy.pop(cur_listitem, None) if cur_listitem == self.last_listitem: self.set_win_props(all_props) except Exception as exc: log_exception(__name__, exc) self.bgtasks -= 1
def set_listitem_details(self, cur_listitem, content_type, prefix): '''set the window properties based on the current listitem''' try: if cur_listitem in self.listitem_details: # data already in memory all_props = self.listitem_details[cur_listitem] else: # skip if another lookup for the same listitem is already in progress... if self.lookup_busy.get(cur_listitem): return self.lookup_busy[cur_listitem] = True # clear all window props, do this delayed to prevent flickering of the screen thread.start_new_thread(self.delayed_flush, (cur_listitem, )) # wait if we already have more than 5 items in the queue while len(self.lookup_busy) > 5: xbmc.sleep(100) if self.exit or cur_listitem != self.last_listitem: self.lookup_busy.pop(cur_listitem, None) return # prefer listitem's contenttype over container's contenttype dbtype = xbmc.getInfoLabel("%sListItem.DBTYPE" % prefix) if not dbtype: dbtype = xbmc.getInfoLabel("%sListItem.Property(DBTYPE)" % prefix) if dbtype: content_type = dbtype + "s" # collect details from listitem details = self.get_listitem_details(content_type, prefix) # music content if content_type in ["albums", "artists", "songs" ] and self.enable_musicart: details = extend_dict( details, self.metadatautils.get_music_artwork( details["artist"], details["album"], details["title"], details["discnumber"])) # moviesets elif details["path"].startswith( "videodb://movies/sets/") and details["dbid"]: details = extend_dict( details, self.metadatautils.get_moviesetdetails( details["title"], details["dbid"]), ["year"]) content_type = "sets" # video content elif content_type in [ "movies", "setmovies", "tvshows", "seasons", "episodes", "musicvideos" ]: # get imdb and tvdbid details[ "imdbnumber"], tvdbid = self.metadatautils.get_imdbtvdb_id( details["title"], content_type, details["year"], details["imdbnumber"], details["tvshowtitle"]) # generic video properties (studio, streamdetails, omdb, top250) details = merge_dict( details, self.get_directors_writers(details["director"], details["writer"])) if self.enable_extrafanart: if not details["filenameandpath"]: details["filenameandpath"] = details["path"] if "videodb://" not in details["filenameandpath"]: efa = self.metadatautils.get_extrafanart( details["filenameandpath"]) if efa: details["art"] = merge_dict( details["art"], efa["art"]) details = merge_dict( details, self.metadatautils.get_duration(details["duration"])) details = merge_dict(details, self.get_genres(details["genre"])) details = merge_dict( details, self.metadatautils.get_studio_logo(details["studio"])) details = merge_dict( details, self.metadatautils.get_omdb_info( details["imdbnumber"])) details = merge_dict( details, self.get_streamdetails(details["dbid"], details["path"], content_type)) details = merge_dict( details, self.metadatautils.get_top250_rating( details["imdbnumber"])) if self.exit: return # tvshows-only properties (tvdb) if content_type in ["tvshows", "seasons", "episodes"]: details = merge_dict( details, self.metadatautils.get_tvdb_details( details["imdbnumber"], tvdbid)) # movies-only properties (tmdb, animated art) if content_type in ["movies", "setmovies"]: details = merge_dict( details, self.metadatautils.get_tmdb_details( details["imdbnumber"])) if details["imdbnumber"] and self.enable_animatedart: details = extend_dict( details, self.metadatautils.get_animated_artwork( details["imdbnumber"])) if self.exit: return # extended art if self.enable_extendedart: tmdbid = details.get("tmdb_id", "") details = extend_dict( details, self.metadatautils.get_extended_artwork( details["imdbnumber"], tvdbid, tmdbid, content_type), [ "posters", "clearlogos", "banners", "discarts", "cleararts", "characterarts" ]) if self.exit: return # monitor listitem props when PVR is active elif content_type in [ "tvchannels", "tvrecordings", "channels", "recordings", "timers", "tvtimers" ]: details = self.get_pvr_artwork(details, prefix) # process all properties all_props = prepare_win_props(details) if "sets" not in content_type: self.listitem_details[cur_listitem] = all_props self.lookup_busy.pop(cur_listitem, None) if cur_listitem == self.last_listitem: self.set_win_props(all_props) except Exception as exc: log_exception(__name__, exc) self.lookup_busy.pop(cur_listitem, None)
def handle_request(self, headers_only=False): '''send headers and reponse''' image = "" try: artwork = {} params = self.get_params() action = params.get("action", "") title = params.get("title", "") preferred_types = params.get("type") if preferred_types: preferred_types = preferred_types.split(",") else: preferred_types = [] fallback = params.get("fallback", "") is_json_request = params.get("json", "") == "true" if fallback and not xbmcvfs.exists(fallback): fallback = "special://skin/media/" + fallback if not xbmcvfs.exists(fallback): fallback = "" log_msg( "Webservice --> Non existent fallback image detected - " "please use a full path to the fallback image!", xbmc.LOGWARNING) log_msg("webservice called with params: %s" % params) # search image on google if action == "getthumb": image = self.server.metadatautils.google.search_image(title) # get pvr image elif "pvrthumb" in action: channel = params.get("channel", "") genre = params.get("genre", "") artwork = self.server.metadatautils.get_pvr_artwork(title, channel, genre) if action == "getallpvrthumb": is_json_request = True # get video artwork and metadata elif action == "getartwork": if not preferred_types: is_json_request = True year = params.get("year", "") media_type = params.get("mediatype", "") imdb_id = params.get("imdbid", "") if not imdb_id: artwork = self.server.metadatautils.get_tmdb_details("", "", title, year, media_type) if artwork: imdb_id = artwork.get("imdbnumber") if not media_type: media_type = artwork.get("media_type") if imdb_id: artwork = extend_dict( artwork, self.server.metadatautils.get_extended_artwork( imdb_id, "", "", media_type)) # music art elif action == "getmusicart": artist = params.get("artist", "") album = params.get("album", "") track = params.get("track", "") artwork = self.server.metadatautils.get_music_artwork(artist, album, track) # genre images elif "genreimages" in action and preferred_types: arttype = preferred_types[0].split(".")[0] mediatype = "tvshows" if "tvshow" in action else "movies" randomize = "true" if "random" in action else "false" lib_path = u"plugin://script.skin.helper.service/?action=genrebackground"\ "&genre=%s&arttype=%s&mediatype=%s&random=%s" % (title, arttype, mediatype, randomize) for count, item in enumerate(self.server.metadatautils.kodidb.files(lib_path, limits=(0, 5))): artwork["%s.%s" % (arttype, count)] = item["file"] # image from variable elif "getvarimage" in action: title = title.replace("{", "[").replace("}", "]") image = xbmc.getInfoLabel(title) if not xbmcvfs.exists(image): if "resource.images" in image: log_msg( "Texture packed resource addons are not supported by the webservice! - %s" % image, xbmc.LOGWARNING) image = "" if not is_json_request: if artwork and artwork.get("art"): artwork = artwork["art"] if preferred_types: for pref_type in preferred_types: if not image: image = artwork.get(pref_type, "") elif not image and artwork.get("landscape"): image = artwork["landscape"] elif not image and artwork.get("fanart"): image = artwork["fanart"] elif not image and artwork.get("poster"): image = artwork["poster"] elif not image and artwork.get("thumb"): image = artwork["thumb"] # set fallback image if nothing else worked if not image or not xbmcvfs.exists(image): image = fallback log_msg("webservice image: %s - fallback: %s - artwork: %s - title: %s" % (image, fallback, artwork, title)) if is_json_request and artwork: # send json reponse artwork = json.dumps(artwork) self.send_response(200) self.send_header('Content-type', 'application/json') self.send_header('Content-Length', len(artwork)) self.end_headers() if not headers_only: self.wfile.write(artwork) elif image: # send single image self.send_response(200) ext = image.split(".")[-1] self.send_header('Content-type', 'image/%s' % ext) modified = xbmcvfs.Stat(image).st_mtime() self.send_header('Last-Modified', "%s" % modified) image = xbmcvfs.File(image) size = image.size() self.send_header('Content-Length', str(size)) self.end_headers() if not headers_only: log_msg("sending image for request %s" % (self.path)) self.wfile.write(image.readBytes()) image.close() else: self.send_error(404, 'No image was found') except Exception as exc: log_exception(__name__, exc) self.send_error(500, 'Exception occurred: %s' % exc) return