def show_infodialog(dbid="", media_type=""): '''shows the special info dialog for this media''' cont_prefix = get_cont_prefix() artutils = ArtUtils() 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(artutils.kodidb.__class__, media_type): item_details = getattr(artutils.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, artutils.get_music_artwork(artist, album, title, disc)) # movieset elif media_type == "movieset" and dbid: item_details = extend_dict(item_details, artutils.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, artutils.get_pvr_artwork(title, channel, genre)) artutils.close() # proceed with infodialog if we have details if item_details: win = DialogVideoInfo("DialogVideoInfo.xml", "", listitem=item_details) win.doModal() del win
def __init__(self): self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.artutils = ArtUtils() self.addonname = self.addon.getAddonInfo('name').decode("utf-8") self.addonversion = self.addon.getAddonInfo('version').decode("utf-8") self.kodimonitor = KodiMonitor(artutils=self.artutils, win=self.win) listitem_monitor = ListItemMonitor(artutils=self.artutils, win=self.win, monitor=self.kodimonitor) webservice = WebService(artutils=self.artutils) # start the extra threads listitem_monitor.start() webservice.start() self.win.clearProperty("SkinHelperShutdownRequested") log_msg('%s version %s started' % (self.addonname, self.addonversion), xbmc.LOGNOTICE) # run as service, check skin every 10 seconds and keep the other threads alive while not self.kodimonitor.abortRequested(): # check skin version info self.check_skin_version() # sleep for 10 seconds self.kodimonitor.waitForAbort(10) # Abort was requested while waiting. We should exit self.win.setProperty("SkinHelperShutdownRequested", "shutdown") log_msg('Shutdown requested !', xbmc.LOGNOTICE) # stop the extra threads listitem_monitor.stop() webservice.stop() # cleanup objects self.close()
def __init__(self): ''' Initialization ''' self.artutils = ArtUtils() self.cache = SimpleCache() self.addon = xbmcaddon.Addon(ADDON_ID) self.win = xbmcgui.Window(10000) self.options = self.get_options() # skip if shutdown requested if self.win.getProperty("SkinHelperShutdownRequested"): log_msg("Not forfilling request: Kodi is exiting!", xbmc.LOGWARNING) xbmcplugin.endOfDirectory(handle=ADDON_HANDLE) return if not "mediatype" in self.options or not "action" in self.options: # we need both mediatype and action, so show the main listing self.mainlisting() else: # we have a mediatype and action so display the widget listing self.show_widget_listing() self.close()
def __init__(self): self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.artutils = ArtUtils() self.addonname = self.addon.getAddonInfo('name').decode("utf-8") self.addonversion = self.addon.getAddonInfo('version').decode("utf-8") self.kodimonitor = KodiMonitor(artutils=self.artutils, win=self.win) listitem_monitor = ListItemMonitor( artutils=self.artutils, win=self.win, monitor=self.kodimonitor) webservice = WebService(artutils=self.artutils) widget_task_interval = 520 # start the extra threads listitem_monitor.start() webservice.start() self.win.clearProperty("SkinHelperShutdownRequested") log_msg('%s version %s started' % (self.addonname, self.addonversion), xbmc.LOGNOTICE) # run as service, check skin every 10 seconds and keep the other threads alive while not self.kodimonitor.abortRequested(): # check skin version info self.check_skin_version() # set generic widget reload widget_task_interval += 10 if widget_task_interval >= 300: self.win.setProperty("widgetreload2", time.strftime("%Y%m%d%H%M%S", time.gmtime())) widget_task_interval = 0 # sleep for 10 seconds self.kodimonitor.waitForAbort(10) # Abort was requested while waiting. We should exit self.win.setProperty("SkinHelperShutdownRequested", "shutdown") log_msg('Shutdown requested !', xbmc.LOGNOTICE) # stop the extra threads listitem_monitor.stop() webservice.stop() # cleanup objects self.close()
# -*- coding: utf-8 -*- ''' script.skin.helper.service Contextmenu for Music art ''' import xbmc import xbmcgui from artutils import ArtUtils # Kodi contextmenu item to configure music artwork if __name__ == '__main__': ##### Music Artwork ######## win = xbmcgui.Window(10000) artutils = ArtUtils() win.setProperty("SkinHelper.Artwork.ManualLookup", "busy") track = xbmc.getInfoLabel("ListItem.Title").decode('utf-8') album = xbmc.getInfoLabel("ListItem.Album").decode('utf-8') artist = xbmc.getInfoLabel("ListItem.Artist").decode('utf-8') disc = xbmc.getInfoLabel("ListItem.DiscNumber").decode('utf-8') artutils.music_artwork_options(artist, album, track, disc) win.clearProperty("SkinHelper.Artwork.ManualLookup") artutils.close() del win del artutils
log_msg( "Animated Art: lookup imdbid by title and year: (%s - %s)" % (title, year), xbmc.LOGNOTICE) imdb_id = artutils.get_omdb_info("", title, year, content_type).get( "imdbnumber", "") if not imdb_id: return title return imdb_id # Kodi contextmenu item to configure the artwork if __name__ == '__main__': xbmc.executebuiltin("ActivateWindow(busydialog)") log_msg("Contextmenu for Animated Art opened", xbmc.LOGNOTICE) ARTUTILS = ArtUtils() WIN = xbmcgui.Window(10000) imdb_id = get_imdb_id(WIN, ARTUTILS) WIN.setProperty("SkinHelper.Artwork.ManualLookup", "busy") log_msg("Animated Art: Query animated art by IMDBID: %s" % imdb_id, xbmc.LOGNOTICE) artwork = ARTUTILS.get_animated_artwork(imdb_id, ignore_cache=True, manual_select=True) log_msg("Animated Art result: %s" % artwork, xbmc.LOGNOTICE) xbmc.executebuiltin("Dialog.Close(busydialog)") xbmc.executebuiltin("Container.Refresh") WIN.clearProperty("SkinHelper.Artwork.ManualLookup") del WIN ARTUTILS.close()
# -*- coding: utf-8 -*- ''' script.skin.helper.service Contextmenu for Pvr art ''' import xbmc import xbmcgui from artutils import ArtUtils # Kodi contextmenu item to configure pvr artwork if __name__ == '__main__': ##### PVR Artwork ######## win = xbmcgui.Window(10000) win.setProperty("SkinHelper.Artwork.ManualLookup", "busy") xbmc.executebuiltin("ActivateWindow(busydialog)") title = xbmc.getInfoLabel("ListItem.Title").decode('utf-8') if not title: title = xbmc.getInfoLabel("ListItem.Label").decode('utf-8') channel = xbmc.getInfoLabel("ListItem.ChannelName").decode('utf-8') genre = xbmc.getInfoLabel("ListItem.Genre").decode('utf-8') artutils = ArtUtils() artutils.pvr_artwork_options(title, channel, genre) xbmc.executebuiltin("Dialog.Close(busydialog)") win.clearProperty("SkinHelper.Artwork.ManualLookup") artutils.close() del win
class MainService: '''our main background service running the various threads''' last_skin = "" def __init__(self): self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.artutils = ArtUtils() self.addonname = self.addon.getAddonInfo('name').decode("utf-8") self.addonversion = self.addon.getAddonInfo('version').decode("utf-8") self.kodimonitor = KodiMonitor(artutils=self.artutils, win=self.win) listitem_monitor = ListItemMonitor( artutils=self.artutils, win=self.win, monitor=self.kodimonitor) webservice = WebService(artutils=self.artutils) widget_task_interval = 520 # start the extra threads listitem_monitor.start() webservice.start() self.win.clearProperty("SkinHelperShutdownRequested") log_msg('%s version %s started' % (self.addonname, self.addonversion), xbmc.LOGNOTICE) # run as service, check skin every 10 seconds and keep the other threads alive while not self.kodimonitor.abortRequested(): # check skin version info self.check_skin_version() # set generic widget reload widget_task_interval += 10 if widget_task_interval >= 300: self.win.setProperty("widgetreload2", time.strftime("%Y%m%d%H%M%S", time.gmtime())) widget_task_interval = 0 # sleep for 10 seconds self.kodimonitor.waitForAbort(10) # Abort was requested while waiting. We should exit self.win.setProperty("SkinHelperShutdownRequested", "shutdown") log_msg('Shutdown requested !', xbmc.LOGNOTICE) # stop the extra threads listitem_monitor.stop() webservice.stop() # cleanup objects self.close() def close(self): '''Cleanup Kodi Cpython instances''' self.artutils.close() del self.win del self.kodimonitor del self.artutils log_msg('%s version %s stopped' % (self.addonname, self.addonversion), xbmc.LOGNOTICE) def check_skin_version(self): '''check if skin changed''' try: skin = xbmc.getSkinDir() skin_addon = xbmcaddon.Addon(id=skin) skin_label = skin_addon.getAddonInfo('name').decode("utf-8") skin_version = skin_addon.getAddonInfo('version').decode("utf-8") del skin_addon if self.last_skin != skin_label + skin_version: # auto correct skin settings self.last_skin = skin_label + skin_version self.win.setProperty("SkinHelper.skinTitle", "%s - %s: %s" % (skin_label, xbmc.getLocalizedString(19114), skin_version)) self.win.setProperty("SkinHelper.skin_version", "%s: %s" % (xbmc.getLocalizedString(19114), skin_version)) self.win.setProperty("SkinHelper.Version", self.addonversion.replace(".", "")) SkinSettings().correct_skin_settings() except Exception as exc: log_exception(__name__, exc)
imdb_id = xbmc.getInfoLabel("ListItem.IMDBNumber").decode('utf-8') if not imdb_id: imdb_id = xbmc.getInfoLabel("ListItem.Property(IMDBNumber)").decode('utf-8') if imdb_id and not imdb_id.startswith("tt"): imdb_id = "" if not imdb_id: year = xbmc.getInfoLabel("ListItem.Year").decode('utf-8') title = xbmc.getInfoLabel("ListItem.Title").decode('utf-8') if content_type in ["episodes", "seasons"]: title = xbmc.getInfoLabel("ListItem.TvShowTitle").decode('utf-8') if title: imdb_id = artutils.get_omdb_info("", title, year, content_type).get("imdbnumber", "") if not imdb_id: return title return imdb_id # Kodi contextmenu item to configure the artwork if __name__ == '__main__': xbmc.executebuiltin("ActivateWindow(busydialog)") ARTUTILS = ArtUtils() WIN = xbmcgui.Window(10000) imdb_id = get_imdb_id(WIN, ARTUTILS) if imdb_id: WIN.setProperty("SkinHelper.Artwork.ManualLookup", "busy") artwork = ARTUTILS.get_animated_artwork(imdb_id, ignore_cache=True, manual_select=True) xbmc.executebuiltin("Dialog.Close(busydialog)") xbmc.executebuiltin("Container.Refresh") WIN.clearProperty("SkinHelper.Artwork.ManualLookup") del WIN ARTUTILS.close()
class Main(object): '''Main entry path for our widget listing. Process the arguments and load correct class and module''' def __init__(self): ''' Initialization ''' self.artutils = ArtUtils() self.cache = SimpleCache() self.addon = xbmcaddon.Addon(ADDON_ID) self.win = xbmcgui.Window(10000) self.options = self.get_options() # skip if shutdown requested if self.win.getProperty("SkinHelperShutdownRequested"): log_msg("Not forfilling request: Kodi is exiting!", xbmc.LOGWARNING) xbmcplugin.endOfDirectory(handle=ADDON_HANDLE) return if not "mediatype" in self.options or not "action" in self.options: # we need both mediatype and action, so show the main listing self.mainlisting() else: # we have a mediatype and action so display the widget listing self.show_widget_listing() self.close() def close(self): '''Cleanup Kodi Cpython instances''' self.artutils.close() self.cache.close() del self.addon del self.win log_msg("MainModule exited") def get_options(self): '''get the options provided to the plugin path''' options = dict( urlparse.parse_qsl(sys.argv[2].replace( '?', '').lower().decode("utf-8"))) if not "mediatype" in options and "action" in options: # get the mediatype and action from the path (for backwards compatability with old style paths) for item in [("movies", "movies"), ("shows", "tvshows"), ("episode", "episodes"), ("musicvideos", "musicvideos"), ("pvr", "pvr"), ("albums", "albums"), ("songs", "songs"), ("artists", "artists"), ("media", "media"), ("favourites", "favourites")]: if item[0] in options["action"]: options["mediatype"] = item[1] options["action"] = options["action"].replace( item[1], "").replace(item[0], "") break # prefer reload param for the mediatype if "mediatype" in options: alt_reload = self.win.getProperty("widgetreload-%s" % options["mediatype"]) if options["mediatype"] == "favourites" or "favourite" in options[ "action"]: options["skipcache"] = "true" elif alt_reload: options["reload"] = alt_reload if not options.get( "action") and options["mediatype"] == "favourites": options["action"] = "favourites" elif not options.get("action"): options["action"] = "listing" if "listing" in options["action"]: options["skipcache"] = "true" # set the widget settings as options options["hide_watched"] = self.addon.getSetting( "hide_watched") == "true" if self.addon.getSetting( "hide_watched_recent") == "true" and "recent" in options.get( "action", ""): options["hide_watched"] = True options["next_inprogress_only"] = self.addon.getSetting( "nextup_inprogressonly") == "true" options["episodes_enable_specials"] = self.addon.getSetting( "episodes_enable_specials") == "true" options["group_episodes"] = self.addon.getSetting( "episodes_grouping") == "true" if "limit" in options: options["limit"] = int(options["limit"]) else: options["limit"] = int(self.addon.getSetting("default_limit")) return options def show_widget_listing(self): '''display the listing for the provided action and mediatype''' media_type = self.options["mediatype"] action = self.options["action"] # set widget content type xbmcplugin.setContent(ADDON_HANDLE, media_type) # try to get from cache first... # we use a checksum based on the options to make sure the cache is ignored when needed all_items = [] cache_str = "SkinHelper.Widgets.%s.%s" % (media_type, action) if not self.win.getProperty("widgetreload2"): # at startup we simply accept whatever is in the cache cache_checksum = None else: cache_checksum = "" for key in sorted(self.options): cache_checksum += "%s.%s" % (key, self.options[key]) cache = self.cache.get(cache_str, checksum=cache_checksum) if cache and not self.options.get("skipcache") == "true": log_msg( "MEDIATYPE: %s - ACTION: %s -- got items from cache - CHECKSUM: %s" % (media_type, action, cache_checksum)) all_items = cache # Call the correct method to get the content from json when no cache if not all_items: log_msg( "MEDIATYPE: %s - ACTION: %s -- no cache, quering kodi api to get items - CHECKSUM: %s" % (media_type, action, cache_checksum)) # dynamically import and load the correct module, class and function try: media_module = __import__(media_type) media_class = getattr(media_module, media_type.capitalize())(self.addon, self.artutils, self.options) all_items = getattr(media_class, action)() del media_class except AttributeError: log_exception(__name__, "Incorrect widget action or type called") except Exception as exc: log_exception(__name__, exc) # randomize output if requested by skinner or user if self.options.get("randomize", "") == "true": all_items = sorted(all_items, key=lambda k: random.random()) # prepare listitems and store in cache all_items = process_method_on_list( self.artutils.kodidb.prepare_listitem, all_items) self.cache.set(cache_str, all_items, checksum=cache_checksum) # fill that listing... xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_UNSORTED) all_items = process_method_on_list( self.artutils.kodidb.create_listitem, all_items) xbmcplugin.addDirectoryItems(ADDON_HANDLE, all_items, len(all_items)) # end directory listing xbmcplugin.endOfDirectory(handle=ADDON_HANDLE) def mainlisting(self): '''main listing''' all_items = [] # movie node if xbmc.getCondVisibility("Library.HasContent(movies)"): all_items.append((xbmc.getLocalizedString(342), "movieslisting", "DefaultMovies.png")) # tvshows and episodes nodes if xbmc.getCondVisibility("Library.HasContent(tvshows)"): all_items.append((xbmc.getLocalizedString(20343), "tvshowslisting", "DefaultTvShows.png")) all_items.append((xbmc.getLocalizedString(20360), "episodeslisting", "DefaultTvShows.png")) # pvr node if xbmc.getCondVisibility("Pvr.HasTVChannels"): all_items.append((self.addon.getLocalizedString(32054), "pvrlisting", "DefaultAddonPVRClient.png")) # music nodes if xbmc.getCondVisibility("Library.HasContent(music)"): all_items.append((xbmc.getLocalizedString(132), "albumslisting", "DefaultAlbumCover.png")) all_items.append((xbmc.getLocalizedString(134), "songslisting", "DefaultMusicSongs.png")) all_items.append((xbmc.getLocalizedString(133), "artistslisting", "DefaultArtist.png")) # musicvideo node if xbmc.getCondVisibility("Library.HasContent(musicvideos)"): all_items.append( (xbmc.getLocalizedString(20389), "musicvideoslisting", "DefaultAddonAlbumInfo.png")) # media node if xbmc.getCondVisibility( "Library.HasContent(movies) | Library.HasContent(tvshows) | Library.HasContent(music)" ): all_items.append((self.addon.getLocalizedString(32057), "medialisting", "DefaultAddonAlbumInfo.png")) # favourites node all_items.append((xbmc.getLocalizedString(10134), "favouriteslisting", "DefaultAddonAlbumInfo.png")) # process the listitems and display listing all_items = process_method_on_list(create_main_entry, all_items) all_items = process_method_on_list( self.artutils.kodidb.prepare_listitem, all_items) all_items = process_method_on_list( self.artutils.kodidb.create_listitem, all_items) xbmcplugin.addDirectoryItems(ADDON_HANDLE, all_items, len(all_items)) xbmcplugin.endOfDirectory(handle=ADDON_HANDLE)
class MainService: '''our main background service running the various threads''' last_skin = "" def __init__(self): self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.artutils = ArtUtils() self.addonname = self.addon.getAddonInfo('name').decode("utf-8") self.addonversion = self.addon.getAddonInfo('version').decode("utf-8") self.kodimonitor = KodiMonitor(artutils=self.artutils, win=self.win) listitem_monitor = ListItemMonitor(artutils=self.artutils, win=self.win, monitor=self.kodimonitor) webservice = WebService(artutils=self.artutils) # start the extra threads listitem_monitor.start() webservice.start() self.win.clearProperty("SkinHelperShutdownRequested") log_msg('%s version %s started' % (self.addonname, self.addonversion), xbmc.LOGNOTICE) # run as service, check skin every 10 seconds and keep the other threads alive while not self.kodimonitor.abortRequested(): # check skin version info self.check_skin_version() # sleep for 10 seconds self.kodimonitor.waitForAbort(10) # Abort was requested while waiting. We should exit self.win.setProperty("SkinHelperShutdownRequested", "shutdown") log_msg('Shutdown requested !', xbmc.LOGNOTICE) # stop the extra threads listitem_monitor.stop() webservice.stop() # cleanup objects self.close() def close(self): '''Cleanup Kodi Cpython instances''' self.artutils.close() del self.win del self.kodimonitor del self.artutils log_msg('%s version %s stopped' % (self.addonname, self.addonversion), xbmc.LOGNOTICE) def check_skin_version(self): '''check if skin changed''' try: skin = xbmc.getSkinDir() skin_addon = xbmcaddon.Addon(id=skin) skin_label = skin_addon.getAddonInfo('name').decode("utf-8") skin_version = skin_addon.getAddonInfo('version').decode("utf-8") del skin_addon if self.last_skin != skin_label + skin_version: # auto correct skin settings self.last_skin = skin_label + skin_version self.win.setProperty( "SkinHelper.skinTitle", "%s - %s: %s" % (skin_label, xbmc.getLocalizedString(19114), skin_version)) self.win.setProperty( "SkinHelper.skin_version", "%s: %s" % (xbmc.getLocalizedString(19114), skin_version)) self.win.setProperty("SkinHelper.Version", self.addonversion.replace(".", "")) SkinSettings().correct_skin_settings() except Exception as exc: log_exception(__name__, exc)