def set_music_properties(self): '''sets the window props for a playing song''' li_title = xbmc.getInfoLabel("MusicPlayer.Title").decode('utf-8') li_title_org = li_title li_artist = xbmc.getInfoLabel("MusicPlayer.Artist").decode('utf-8') li_album = xbmc.getInfoLabel("MusicPlayer.Album").decode('utf-8') li_disc = xbmc.getInfoLabel("MusicPlayer.DiscNumber").decode('utf-8') li_plot = xbmc.getInfoLabel("MusicPlayer.Comment").decode('utf-8') # fix for internet streams if not li_artist and getCondVisibility("Player.IsInternetStream"): for splitchar in [" - ", "-", ":", ";"]: if splitchar in li_title: li_artist = li_title.split(splitchar)[0].strip() li_title = li_title.split(splitchar)[1].strip() break if getCondVisibility("Skin.HasSetting(SkinHelper.EnableMusicArt)" ) and li_artist and (li_title or li_album): result = self.metadatautils.get_music_artwork( li_artist, li_album, li_title, li_disc) if result.get("extendedplot") and li_plot: li_plot = li_plot.replace('\n', ' ').replace('\r', '').rstrip() result["extendedplot"] = "%s -- %s" % (result["extendedplot"], li_plot) all_props = prepare_win_props(result, u"SkinHelper.Player.") if li_title_org == xbmc.getInfoLabel("MusicPlayer.Title").decode( 'utf-8'): process_method_on_list(self.set_win_prop, all_props)
def monitor_livetv(self): ''' for livetv we are not notified when the program changes so we have to monitor that ourself ''' if self.monitoring_stream: # another monitoring already in progress... return last_title = "" while not self.abortRequested() and getCondVisibility("Player.HasVideo"): self.monitoring_stream = True li_title = xbmc.getInfoLabel("Player.Title").decode('utf-8') if li_title and li_title != last_title: all_props = [] last_title = li_title self.reset_win_props() li_channel = xbmc.getInfoLabel("VideoPlayer.ChannelName").decode('utf-8') # pvr artwork if getCondVisibility("Skin.HasSetting(SkinHelper.EnablePVRThumbs)"): li_genre = xbmc.getInfoLabel("VideoPlayer.Genre").decode('utf-8') pvrart = self.metadatautils.get_pvr_artwork(li_title, li_channel, li_genre) all_props = prepare_win_props(pvrart, u"SkinHelper.Player.") # pvr channellogo channellogo = self.metadatautils.get_channellogo(li_channel) all_props.append(("SkinHelper.Player.ChannelLogo", channellogo)) all_props.append(("SkinHelper.Player.Art.ChannelLogo", channellogo)) if last_title == li_title: self.metadatautils.process_method_on_list(self.set_win_prop, all_props) # show infopanel if needed self.show_info_panel() self.waitForAbort(2) self.monitoring_stream = False
def set_forcedview(self, content_type): '''helper to force the view in certain conditions''' if self.enable_forcedviews: cur_forced_view = xbmc.getInfoLabel( "Skin.String(SkinHelper.ForcedViews.%s)" % content_type) if getCondVisibility( "Control.IsVisible(%s) | IsEmpty(Container.Viewmode) | System.HasModalDialog" % cur_forced_view): # skip if the view is already visible or if we're not in an actual media window return if (content_type and cur_forced_view and cur_forced_view != "None" and not getCondVisibility("Window.IsActive(MyPvrGuide.xml)")): self.win.setProperty("SkinHelper.ForcedView", cur_forced_view) count = 0 while not getCondVisibility( "Control.HasFocus(%s)" % cur_forced_view): xbmc.sleep(100) xbmc.executebuiltin("Container.SetViewMode(%s)" % cur_forced_view) xbmc.executebuiltin("SetFocus(%s)" % cur_forced_view) count += 1 if count == 50: break else: self.win.clearProperty("SkinHelper.ForcedView") else: self.win.clearProperty("SkinHelper.ForcedView")
def setview(self): '''sets the selected viewmode for the container''' xbmc.executebuiltin("ActivateWindow(busydialog)") content_type = get_current_content_type() if not content_type: content_type = "files" current_view = xbmc.getInfoLabel("Container.Viewmode").decode("utf-8") view_id, view_label = self.selectview(content_type, current_view) current_forced_view = xbmc.getInfoLabel("Skin.String(SkinHelper.ForcedViews.%s)" % content_type) if view_id is not None: # also store forced view if (content_type and current_forced_view and current_forced_view != "None" and getCondVisibility("Skin.HasSetting(SkinHelper.ForcedViews.Enabled)")): xbmc.executebuiltin("Skin.SetString(SkinHelper.ForcedViews.%s,%s)" % (content_type, view_id)) xbmc.executebuiltin("Skin.SetString(SkinHelper.ForcedViews.%s.label,%s)" % (content_type, view_label)) self.win.setProperty("SkinHelper.ForcedView", view_id) if not getCondVisibility("Control.HasFocus(%s)" % current_forced_view): xbmc.sleep(100) xbmc.executebuiltin("Container.SetViewMode(%s)" % view_id) xbmc.executebuiltin("SetFocus(%s)" % view_id) else: self.win.clearProperty("SkinHelper.ForcedView") # set view xbmc.executebuiltin("Container.SetViewMode(%s)" % view_id)
def setfocus(self): '''helper to set focus on a list or control''' control = self.params.get("control") fallback = self.params.get("fallback") position = self.params.get("position", "0") relativeposition = self.params.get("relativeposition") if relativeposition: position = int(relativeposition) - 1 count = 0 if control: while not getCondVisibility("Control.HasFocus(%s)" % control): if getCondVisibility("Window.IsActive(busydialog)"): xbmc.sleep(150) continue elif count == 20 or (getCondVisibility( "!Control.IsVisible(%s) | " "!Integer.IsGreater(Container(%s).NumItems,0)" % (control, control))): if fallback: xbmc.executebuiltin("Control.SetFocus(%s)" % fallback) break else: xbmc.executebuiltin("Control.SetFocus(%s,%s)" % (control, position)) xbmc.sleep(50) count += 1
def show_info_panel(self): '''feature to auto show the OSD infopanel for X seconds''' try: sec_to_display = int( xbmc.getInfoLabel( "Skin.String(SkinHelper.ShowInfoAtPlaybackStart)")) except Exception: return if sec_to_display > 0 and not self.infopanelshown: retries = 0 log_msg("Show OSD Infopanel - number of seconds: %s" % sec_to_display) self.infopanelshown = True if self.win.getProperty("VideoScreensaverRunning") != "true": while retries != 50 and getCondVisibility("!Player.ShowInfo"): xbmc.sleep(100) if getCondVisibility( "!Player.ShowInfo + Window.IsActive(fullscreenvideo)" ): xbmc.executebuiltin('Action(info)') retries += 1 # close info again after given amount of time xbmc.Monitor().waitForAbort(sec_to_display) if getCondVisibility( "Player.ShowInfo + Window.IsActive(fullscreenvideo)"): xbmc.executebuiltin('Action(info)')
def multi_select(options, window_header=""): '''allows the user to choose from multiple options''' listitems = [] for option in options: if not option["condition"] or getCondVisibility(option["condition"]): listitem = xbmcgui.ListItem(label=option["label"], label2=option["description"]) listitem.setProperty("id", option["id"]) if getCondVisibility("Skin.HasSetting(%s)" % option["id"]) or (not xbmc.getInfoLabel( "Skin.String(defaultset_%s)" % option["id"]) and getCondVisibility(option["default"])): listitem.select(selected=True) listitems.append(listitem) # show select dialog dialog = DialogSelect("DialogSelect.xml", "", listing=listitems, windowtitle=window_header, multiselect=True) dialog.doModal() result = dialog.result if result: for item in result: if item.isSelected(): # option is enabled xbmc.executebuiltin("Skin.SetBool(%s)" % item.getProperty("id")) else: # option is disabled xbmc.executebuiltin("Skin.Reset(%s)" % item.getProperty("id")) # always set additional prop to define the defaults xbmc.executebuiltin("Skin.SetString(defaultset_%s,defaultset)" % item.getProperty("id")) del dialog
def backup_skinshortcuts(self, dest_path): """backup skinshortcuts including images""" source_path = u'special://profile/addon_data/script.skinshortcuts/' if not xbmcvfs.exists(dest_path): xbmcvfs.mkdir(dest_path) for file in xbmcvfs.listdir(source_path)[1]: file = file.decode("utf-8") sourcefile = source_path + file destfile = dest_path + file if getCondVisibility( "String.Contains(Skin.String(skinshortcuts-sharedmenu),false)" ): # User is not sharing menu, so strip the skin name out of the destination file destfile = destfile.replace("%s." % (xbmc.getSkinDir()), "") if (file.endswith(".DATA.xml") and (not getCondVisibility( "String.Contains(Skin.String(skinshortcuts-sharedmenu),false)" ) or file.startswith(xbmc.getSkinDir()))): xbmcvfs.copy(sourcefile, destfile) # parse shortcuts file and look for any images - if found copy them to addon folder self.backup_skinshortcuts_images(destfile, dest_path) elif file.endswith(".properties") and xbmc.getSkinDir() in file: if xbmc.getSkinDir() in file: destfile = dest_path + file.replace( xbmc.getSkinDir(), "SKINPROPERTIES") copy_file(sourcefile, destfile) self.backup_skinshortcuts_properties(destfile, dest_path) else: # just copy the remaining files copy_file(sourcefile, destfile)
def onNotification(self, sender, method, data): '''builtin function for the xbmc.Monitor class''' try: log_msg("Kodi_Monitor: sender %s - method: %s - data: %s" % (sender, method, data)) data = json.loads(data.decode('utf-8')) mediatype = "" dbid = 0 transaction = False if data and isinstance(data, dict): if data.get("item"): mediatype = data["item"].get("type", "") dbid = data["item"].get("id", 0) elif data.get("type"): mediatype = data["type"] dbid = data.get("id", 0) if data.get("transaction"): transaction = True if method == "System.OnQuit": self.win.setProperty("SkinHelperShutdownRequested", "shutdown") if method == "VideoLibrary.OnUpdate": self.process_db_update(mediatype, dbid, transaction) if method == "AudioLibrary.OnUpdate": self.process_db_update(mediatype, dbid, transaction) if method == "Player.OnStop": self.monitoring_stream = False self.infopanelshown = False self.win.clearProperty("Skinhelper.PlayerPlaying") self.win.clearProperty("TrailerPlaying") self.reset_win_props() if method == "Player.OnPlay": if not self.monitoring_stream: self.reset_win_props() if self.wait_for_player(): if getCondVisibility("Player.HasAudio"): if getCondVisibility("Player.IsInternetStream"): self.monitor_radiostream() else: self.set_music_properties() if getCondVisibility("Pvr.IsPlayingRadio"): if getCondVisibility("!Player.IsInternetStream"): self.monitor_radiostream() else: self.set_music_properties() elif getCondVisibility( "VideoPlayer.Content(livetv) | String.StartsWith(Player.FileNameAndPath,pvr://)" ): self.monitor_livetv() else: self.set_video_properties(mediatype, dbid) self.show_info_panel() except Exception as exc: log_exception(__name__, exc)
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 = self.metadatautils.extend_dict( details, self.metadatautils.get_omdb_info(li_imdb)) if li_dbid: details = self.metadatautils.extend_dict( details, self.metadatautils.get_streamdetails(li_dbid, mediatype)) details = self.metadatautils.extend_dict( details, self.metadatautils.get_top250_rating(li_imdb)) # tvshows-only properties (tvdb) if mediatype == "episode": details = self.metadatautils.extend_dict( details, self.metadatautils.get_tvdb_details(li_imdb, li_tvdb)) # movies-only properties (tmdb, animated art) if mediatype == "movie": details = self.metadatautils.extend_dict( details, self.metadatautils.get_tmdb_details(li_imdb)) if li_imdb and getCondVisibility( "Skin.HasSetting(SkinHelper.EnableAnimatedPosters)"): details = self.metadatautils.extend_dict( details, self.metadatautils.get_animated_artwork(li_imdb)) # extended art if getCondVisibility( "Skin.HasSetting(SkinHelper.EnableExtendedArt)"): tmdbid = details.get("tmdb_id", "") details = self.metadatautils.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.") self.metadatautils.process_method_on_list(self.set_win_prop, all_props)
def set_generic_props(self): '''set some generic window props with item counts''' # GET TOTAL ADDONS COUNT addons_count = len(kodi_json('Addons.GetAddons')) self.win.setProperty("SkinHelper.TotalAddons", "%s" % addons_count) addontypes = [] addontypes.append(("executable", "SkinHelper.TotalProgramAddons")) addontypes.append(("video", "SkinHelper.TotalVideoAddons")) addontypes.append(("audio", "SkinHelper.TotalAudioAddons")) addontypes.append(("image", "SkinHelper.TotalPicturesAddons")) for addontype in addontypes: media_array = kodi_json('Addons.GetAddons', {"content": addontype[0]}) self.win.setProperty(addontype[1], str(len(media_array))) # GET FAVOURITES COUNT favs = kodi_json('Favourites.GetFavourites') if favs: self.win.setProperty("SkinHelper.TotalFavourites", "%s" % len(favs)) if self.exit: return # GET TV CHANNELS COUNT if getCondVisibility("Pvr.HasTVChannels"): tv_channels = kodi_json('PVR.GetChannels', {"channelgroupid": "alltv"}) self.win.setProperty("SkinHelper.TotalTVChannels", "%s" % len(tv_channels)) if self.exit: return # GET MOVIE SETS COUNT movieset_movies_count = 0 moviesets = kodi_json('VideoLibrary.GetMovieSets') for item in moviesets: for item in kodi_json('VideoLibrary.GetMovieSetDetails', {"setid": item["setid"]}): movieset_movies_count += 1 self.win.setProperty("SkinHelper.TotalMovieSets", "%s" % len(moviesets)) self.win.setProperty("SkinHelper.TotalMoviesInSets", "%s" % movieset_movies_count) if self.exit: return # GET RADIO CHANNELS COUNT if getCondVisibility("Pvr.HasRadioChannels"): radio_channels = kodi_json('PVR.GetChannels', {"channelgroupid": "allradio"}) self.win.setProperty("SkinHelper.TotalRadioChannels", "%s" % len(radio_channels))
def correct_skin_settings(self): '''correct any special skin settings''' skinconstants = {} for settingid, settingvalues in self.skinsettings.iteritems(): curvalue = xbmc.getInfoLabel("Skin.String(%s)" % settingid).decode("utf-8") curlabel = xbmc.getInfoLabel("Skin.String(%s.label)" % settingid).decode("utf-8") # first check if we have a sublevel if settingvalues and settingvalues[0]["value"].startswith("||SUBLEVEL||"): sublevel = settingvalues[0]["value"].replace("||SUBLEVEL||", "") settingvalues = self.skinsettings.get(sublevel) for settingvalue in settingvalues: value = settingvalue["value"] label = settingvalue["label"] if "%" in label: label = label % value # only correct the label if value already set if value and value == curvalue: xbmc.executebuiltin( "Skin.SetString(%s.label,%s)" % (settingid.encode("utf-8"), label.encode("utf-8"))) # set the default value if current value is empty if not (curvalue or curlabel): if settingvalue["default"] and getCondVisibility(settingvalue["default"]): xbmc.executebuiltin( "Skin.SetString(%s.label,%s)" % (settingid.encode("utf-8"), label.encode("utf-8"))) xbmc.executebuiltin( "Skin.SetString(%s,%s)" % (settingid.encode("utf-8"), value.encode("utf-8"))) # additional onselect actions for action in settingvalue["onselectactions"]: if action["condition"] and getCondVisibility(action["condition"]): command = action["command"] if "$" in command: command = xbmc.getInfoLabel(command) xbmc.executebuiltin(command.encode("utf-8")) # process any multiselects for option in settingvalue["settingoptions"]: settingid = option["id"] if (not xbmc.getInfoLabel("Skin.String(defaultset_%s)" % settingid) and option["default"] and getCondVisibility(option["default"])): xbmc.executebuiltin("Skin.SetBool(%s)" % settingid) xbmc.executebuiltin("Skin.SetString(defaultset_%s,defaultset)" % settingid) # set the default constant value if current value is empty if (not curvalue and settingvalue["constantdefault"] and getCondVisibility(settingvalue["constantdefault"])): skinconstants[settingid] = value # update skin constants if needed only if skinconstants: self.update_skin_constants(skinconstants)
def get_mediatype(): '''get current content type''' if getCondVisibility("VideoPlayer.Content(movies)"): mediatype = "movie" elif getCondVisibility("VideoPlayer.Content(episodes) | !String.IsEmpty(VideoPlayer.TvShowTitle)"): mediatype = "episode" elif xbmc.getInfoLabel("VideoPlayer.Content(musicvideos) | !String.IsEmpty(VideoPlayer.Artist)"): mediatype = "musicvideo" else: mediatype = "file" return mediatype
def downloadresourceaddons(addontype): """show dialog with all available resource addons on the repo so the user can install one""" busyDialog("activate") listitems = [] addon = xbmcaddon.Addon(ADDON_ID) for item in get_repo_resourceaddons(addontype): if not getCondVisibility("System.HasAddon(%s)" % item["addonid"]): label2 = "%s: %s" % (xbmc.getLocalizedString(21863), item["author"]) listitem = xbmcgui.ListItem(label=item["name"], label2=label2, iconImage=item["thumbnail"]) listitem.setPath(item["path"]) listitem.setProperty("addonid", item["addonid"]) listitems.append(listitem) # if no addons available show OK dialog.. if not listitems: dialog = xbmcgui.Dialog() dialog.ok(addon.getLocalizedString(32021), addon.getLocalizedString(32022)) del dialog else: # show select dialog with choices dialog = DialogSelect("DialogSelect.xml", "", listing=listitems, windowtitle=addon.getLocalizedString(32021), richlayout=True) dialog.doModal() result = dialog.result del dialog del addon # process selection... if result: addon_id = result.getProperty("addonid") # trigger install... monitor = xbmc.Monitor() if KODI_VERSION > 16: xbmc.executebuiltin("InstallAddon(%s)" % addon_id) else: xbmc.executebuiltin("RunPlugin(plugin://%s)" % addon_id) count = 0 # wait (max 2 minutes) untill install is completed install_succes = False while not monitor.waitForAbort( 1) and not install_succes and count < 120: install_succes = getCondVisibility("System.HasAddon(%s)" % addon_id) del monitor if install_succes: return True return False
def get_settings(self): '''collect our skin settings that control the monitoring''' self.enable_extendedart = getCondVisibility( "Skin.HasSetting(SkinHelper.EnableExtendedArt)") == 1 self.enable_musicart = getCondVisibility( "Skin.HasSetting(SkinHelper.EnableMusicArt)") == 1 self.enable_animatedart = getCondVisibility( "Skin.HasSetting(SkinHelper.EnableAnimatedPosters)") == 1 self.enable_extrafanart = getCondVisibility( "Skin.HasSetting(SkinHelper.EnableExtraFanart)") == 1 self.enable_extraposter = getCondVisibility( "Skin.HasSetting(SkinHelper.EnableExtraPoster)") == 1 self.enable_pvrart = getCondVisibility( "Skin.HasSetting(SkinHelper.EnablePVRThumbs) + PVR.HasTVChannels" ) == 1 self.enable_forcedviews = getCondVisibility( "Skin.HasSetting(SkinHelper.ForcedViews.Enabled)") == 1 studiologos_path = xbmc.getInfoLabel( "Skin.String(SkinHelper.StudioLogos.Path)").decode("utf-8") if studiologos_path != self.metadatautils.studiologos_path: self.listitem_details = {} self.metadatautils.studiologos_path = studiologos_path # set additional window props to control contextmenus as using the skinsetting gives unreliable results for skinsetting in [ "EnableAnimatedPosters", "EnableMusicArt", "EnablePVRThumbs" ]: if getCondVisibility("Skin.HasSetting(SkinHelper.%s)" % skinsetting): self.win.setProperty("SkinHelper.%s" % skinsetting, "enabled") else: self.win.clearProperty("SkinHelper.%s" % skinsetting)
def splashscreen(self): '''helper to show a user defined splashscreen in the skin''' import time splashfile = self.params.get("file", "") duration = int(self.params.get("duration", 5)) if (splashfile.lower().endswith("jpg") or splashfile.lower().endswith("gif") or splashfile.lower().endswith("png") or splashfile.lower().endswith("tiff")): # this is an image file self.win.setProperty("SkinHelper.SplashScreen", splashfile) # for images we just wait for X seconds to close the splash again start_time = time.time() while (time.time() - start_time) <= duration: xbmc.sleep(500) else: # for video or audio we have to wait for the player to finish... xbmc.Player().play(splashfile, windowed=True) xbmc.sleep(500) while getCondVisibility("Player.HasMedia"): xbmc.sleep(150) # replace startup window with home startupwindow = xbmc.getInfoLabel("System.StartupWindow") xbmc.executebuiltin("ReplaceWindow(%s)" % startupwindow) autostart_playlist = xbmc.getInfoLabel("$ESCINFO[Skin.String(autostart_playlist)]") if autostart_playlist: xbmc.executebuiltin("PlayMedia(%s)" % autostart_playlist)
def playtrailer(self): '''auto play windowed trailer inside video listing''' if not getCondVisibility("Container.Scrolling | Container.OnNext | " "Container.OnPrevious | !IsEmpty(Window(Home).Property(traileractionbusy))"): self.win.setProperty("traileractionbusy", "traileractionbusy") widget_container = self.params.get("widgetcontainer", "") trailer_mode = self.params.get("mode", "").replace("auto_", "") allow_youtube = self.params.get("youtube", "") == "true" if not trailer_mode: trailer_mode = "windowed" if widget_container: widget_container_prefix = "Container(%s)." % widget_container else: widget_container_prefix = "" li_title = xbmc.getInfoLabel("%sListItem.Title" % widget_container_prefix).decode('utf-8') li_trailer = xbmc.getInfoLabel("%sListItem.Trailer" % widget_container_prefix).decode('utf-8') if not li_trailer and allow_youtube: youtube_result = self.get_youtube_listing("%s Trailer" % li_title) if youtube_result: li_trailer = youtube_result[0].get("file") # always wait a bit to prevent trailer start playing when we're scrolling the list xbmc.Monitor().waitForAbort(3) if li_trailer and (li_title == xbmc.getInfoLabel("%sListItem.Title" % widget_container_prefix).decode('utf-8')): if trailer_mode == "fullscreen" and li_trailer: xbmc.executebuiltin('PlayMedia("%s")' % li_trailer) else: xbmc.executebuiltin('PlayMedia("%s",1)' % li_trailer) self.win.setProperty("TrailerPlaying", trailer_mode) self.win.clearProperty("traileractionbusy")
def load_widget(self): '''legacy entrypoint called (widgets are moved to seperate addon), start redirect...''' action = self.params.get("action", "") newaddon = "script.skin.helper.widgets" log_msg( "Deprecated method: %s. Please reassign your widgets to get rid of this message. -" "This automatic redirect will be removed in the future" % (action), xbmc.LOGWARNING) paramstring = "" for key, value in self.params.iteritems(): paramstring += ",%s=%s" % (key, value) if getCondVisibility("System.HasAddon(%s)" % newaddon): # TEMP !!! for backwards compatability reasons only - to be removed in the near future!! import imp addon = xbmcaddon.Addon(newaddon) addon_path = addon.getAddonInfo('path').decode("utf-8") imp.load_source('plugin', os.path.join(addon_path, "plugin.py")) from plugin import main main.Main() del addon else: # trigger install of the addon if KODI_VERSION > 16: xbmc.executebuiltin("InstallAddon(%s)" % newaddon) else: xbmc.executebuiltin("RunPlugin(plugin://%s)" % newaddon)
def action_textbox(self, act): '''special handler to allow direct typing to search''' action_number_0 = 58 action_number_9 = 67 action = act.getId() button = act.getButtonCode() # Upper-case values if button >= 0x2f041 and button <= 0x2f05b: self.add_character(chr(button - 0x2F000)) # Lower-case values if button >= 0xf041 and button <= 0xf05b: self.add_character(chr(button - 0xEFE0)) # Numbers if action >= action_number_0 and action <= action_number_9: self.add_character(chr(action - action_number_0 + 48)) # Backspace if button == 0xF008: if len(self.search_string) >= 1: self.remove_char() # Delete if button == 0xF02E: self.clear_search() # Space if button == 0xF020: self.add_character(" ") if getCondVisibility("Window.IsVisible(10111)"): # close shutdown window if visible xbmc.executebuiltin("Dialog.close(10111)")
def searchyoutube(self): '''helper to search youtube for the given title''' xbmc.executebuiltin("ActivateWindow(busydialog)") title = self.params.get("title", "") window_header = self.params.get("header", "") results = [] for media in self.get_youtube_listing(title): if not media["filetype"] == "directory": label = media["label"] label2 = media["plot"] image = "" if media.get('art'): if media['art'].get('thumb'): image = (media['art']['thumb']) listitem = xbmcgui.ListItem(label=label, label2=label2, iconImage=image) listitem.setProperty("path", media["file"]) results.append(listitem) # finished lookup - display listing with results xbmc.executebuiltin("dialog.Close(busydialog)") dialog = DialogSelect("DialogSelect.xml", "", listing=results, windowtitle=window_header, multiselect=False, richlayout=True) dialog.doModal() result = dialog.result del dialog if result: if getCondVisibility( "Window.IsActive(script-skin_helper_service-CustomInfo.xml) | " "Window.IsActive(movieinformation)"): xbmc.executebuiltin("Dialog.Close(movieinformation)") xbmc.executebuiltin("Dialog.Close(script-skin_helper_service-CustomInfo.xml)") xbmc.sleep(1000) xbmc.executebuiltin('PlayMedia("%s")' % result.getProperty("path")) del result
def onAction(self, action): '''Respond to Kodi actions e.g. exit''' if action.getId() in ( 9, 10, 92, 216, 247, 257, 275, 61467, 61448, ): self.close_dialog(True) # an item in the list is clicked if (action.getId() == 7 or action.getId() == 100) and getCondVisibility( "Control.HasFocus(3) | Control.HasFocus(6)"): if self.multiselect: # select/deselect the item item = self.list_control.getSelectedItem() if item.isSelected(): item.select(selected=False) else: item.select(selected=True) else: # no multiselect so just close the dialog (and return results) self.close_dialog()
def check_screensaver(self): '''Allow user to disable screensaver on fullscreen music playback''' if getCondVisibility( "Window.IsActive(visualisation) + Skin.HasSetting(SkinHelper.DisableScreenSaverOnFullScreenMusic)" ): if not self.screensaver_disabled: # disable screensaver when fullscreen music active self.screensaver_disabled = True screensaver_setting = kodi_json( 'Settings.GetSettingValue', '{"setting":"screensaver.mode"}') if screensaver_setting: self.screensaver_setting = screensaver_setting kodi_json('Settings.SetSettingValue', { "setting": "screensaver.mode", "value": None }) log_msg( "Disabled screensaver while fullscreen music playback - previous setting: %s" % self.screensaver_setting, xbmc.LOGNOTICE) elif self.screensaver_disabled and self.screensaver_setting: # enable screensaver again after fullscreen music playback was ended kodi_json('Settings.SetSettingValue', { "setting": "screensaver.mode", "value": self.screensaver_setting }) self.screensaver_disabled = False self.screensaver_setting = None log_msg( "fullscreen music playback ended - restoring screensaver: %s" % self.screensaver_setting, xbmc.LOGNOTICE)
def get_folderandprefix(self): '''get the current folder and prefix''' cur_folder = "" cont_prefix = "" try: widget_container = self.win.getProperty( "SkinHelper.WidgetContainer").decode('utf-8') if getCondVisibility("Window.IsActive(movieinformation)"): cont_prefix = "" cur_folder = xbmc.getInfoLabel( "movieinfo-$INFO[Container.FolderPath]" "$INFO[Container.NumItems]" "$INFO[Container.Content]").decode('utf-8') elif widget_container: cont_prefix = "Container(%s)." % widget_container cur_folder = xbmc.getInfoLabel( "widget-%s-$INFO[Container(%s).NumItems]-$INFO[Container(%s).ListItemAbsolute(1).Label]" % (widget_container, widget_container, widget_container)).decode('utf-8') else: cont_prefix = "" cur_folder = xbmc.getInfoLabel( "$INFO[Container.FolderPath]$INFO[Container.NumItems]$INFO[Container.Content]" ).decode('utf-8') except Exception as exc: log_exception(__name__, exc) cur_folder = "" cont_prefix = "" return (cur_folder, cont_prefix)
def getcastmedia(self): '''helper to show a dialog with all media for a specific actor''' xbmc.executebuiltin("ActivateWindow(busydialog)") name = self.params.get("name", "") window_header = self.params.get("name", "") results = [] items = self.mutils.kodidb.castmedia(name) items = self.mutils.process_method_on_list(self.mutils.kodidb.prepare_listitem, items) for item in items: if item["file"].startswith("videodb://"): item["file"] = "ActivateWindow(Videos,%s,return)" % item["file"] else: item["file"] = 'PlayMedia("%s")' % item["file"] results.append(self.mutils.kodidb.create_listitem(item, False)) # finished lookup - display listing with results xbmc.executebuiltin("dialog.Close(busydialog)") dialog = DialogSelect("DialogSelect.xml", "", listing=results, windowtitle=window_header, richlayout=True) dialog.doModal() result = dialog.result del dialog if result: while getCondVisibility("System.HasModalDialog | System.HasVisibleModalDialog"): xbmc.executebuiltin("Action(Back)") xbmc.sleep(300) xbmc.executebuiltin(result.getfilename()) del result
def wait_for_player(): '''wait for player untill it's actually playing content''' count = 0 while not getCondVisibility("Player.HasVideo | Player.HasAudio"): xbmc.sleep(100) if count == 50: return False count += 1 return True
def artwork_downloader(self, media_type, dbid): '''trigger artwork scan with artwork downloader if enabled''' if getCondVisibility( "System.HasAddon(script.artwork.downloader) + Skin.HasSetting(EnableArtworkDownloader)"): if media_type == "episode": media_type = "tvshow" dbid = self.metadatautils.kodidb.episode(dbid)["tvshowid"] xbmc.executebuiltin( "RunScript(script.artwork.downloader,silent=true,mediatype=%s,dbid=%s)" % (media_type, dbid))
def selectview(self, content_type="other", current_view=None, display_none=False): '''reads skinfile with all views to present a dialog to choose from''' cur_view_select_id = None label = "" all_views = [] if display_none: listitem = xbmcgui.ListItem(label="None") listitem.setProperty("id", "None") all_views.append(listitem) # read the special skin views file views_file = xbmc.translatePath( 'special://skin/extras/views.xml').decode("utf-8") if xbmcvfs.exists(views_file): doc = parse(views_file) listing = doc.documentElement.getElementsByTagName('view') itemcount = 0 for view in listing: label = xbmc.getLocalizedString( int(view.attributes['languageid'].nodeValue)) viewid = view.attributes['value'].nodeValue mediatypes = view.attributes['type'].nodeValue.lower().split( ",") if label.lower() == current_view.lower( ) or viewid == current_view: cur_view_select_id = itemcount if display_none: cur_view_select_id += 1 if (("all" in mediatypes or content_type.lower() in mediatypes) and (not "!" + content_type.lower() in mediatypes) and not getCondVisibility( "Skin.HasSetting(SkinHelper.view.Disabled.%s)" % viewid)): image = "special://skin/extras/viewthumbs/%s.jpg" % viewid listitem = xbmcgui.ListItem(label=label, iconImage=image) listitem.setProperty("viewid", viewid) listitem.setProperty("icon", image) all_views.append(listitem) itemcount += 1 dialog = DialogSelect("DialogSelect.xml", "", listing=all_views, windowtitle=self.addon.getLocalizedString(32012), richlayout=True) dialog.autofocus_id = cur_view_select_id dialog.doModal() result = dialog.result del dialog if result: viewid = result.getProperty("viewid") label = result.getLabel().decode("utf-8") return (viewid, label) else: return (None, None)
def plugin_widgetlisting(pluginpath, sublevel=""): """get all nodes in a plugin listing""" widgets = [] if sublevel: media_array = kodi_json('Files.GetDirectory', { "directory": pluginpath, "media": "files" }) else: if not getCondVisibility("System.HasAddon(%s)" % pluginpath): return [] media_array = kodi_json('Files.GetDirectory', { "directory": "plugin://%s" % pluginpath, "media": "files" }) for item in media_array: log_msg("skinshortcuts widgets processing: %s" % (item["file"])) content = item["file"] label = item["label"] # extendedinfo has some login-required widgets, skip those if ("script.extendedinfo" in pluginpath and not EXTINFO_CREDS and ("info=starred" in content or "info=rated" in content or "info=account" in content)): continue if item.get("filetype", "") == "file": continue mutils = MetadataUtils() media_type = mutils.detect_plugin_content(item["file"]) del mutils if media_type == "empty": continue if media_type == "folder": content = "plugin://script.skin.helper.service?action=widgets&path=%s&sublevel=%s" % ( urlencode(item["file"]), label) # add reload param for widgets if "reload=" not in content: if "movies" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-movies)]" elif "episodes" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-episodes)]" elif "tvshows" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-tvshows)]" elif "musicvideos" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-musicvideos)]" elif "albums" in content or "songs" in content or "artists" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-music)]" else: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload)]"\ "$INFO[Window(Home).Property(widgetreload2)]" content = content + reloadstr content = content.replace("&limit=100", "&limit=25") widgets.append([label, content, media_type]) if pluginpath == "script.extendedinfo" and not sublevel: # some additional entrypoints for extendedinfo... widgets += extendedinfo_youtube_widgets() return widgets
def wait_for_skinshortcuts_window(): '''wait untill skinshortcuts is active window (because of any animations that may have been applied)''' for i in range(40): if not (getCondVisibility( "Window.IsActive(DialogSelect.xml) | " "Window.IsActive(script-skin_helper_service-ColorPicker.xml) | " "Window.IsActive(DialogKeyboard.xml)")): break else: xbmc.sleep(100)
def togglekodisetting(self): '''toggle kodi setting''' settingname = self.params.get("setting", "") cur_value = getCondVisibility("system.getbool(%s)" % settingname) if cur_value: new_value = "false" else: new_value = "true" xbmc.executeJSONRPC( '{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"%s","value":%s}}' % (settingname, new_value))