def __get_channel(self): channel_url_id = self.params.get(keyword.CHANNEL, None) channel_code = self.params.get(keyword.CHANNEL_CODE, None) if not channel_url_id: return None Logger.debug("Fetching channel %s - %s", channel_url_id, channel_code) channel = ChannelIndex.get_register().get_channel(channel_url_id, channel_code, info_only=True) Logger.debug("Created channel: %s", channel) return channel
def __get_channel(self): chn = self.params.get(self.keywordChannel, None) code = self.params.get(self.keywordChannelCode, None) if not chn: return None Logger.debug("Fetching channel %s - %s", chn, code) channel = ChannelIndex.get_register().get_channel(chn, code, info_only=True) Logger.debug("Created channel: %s", channel) return channel
def select_channels(self): """ Selects the channels that should be visible. @return: None """ valid_channels = ChannelIndex.get_register().get_channels( include_disabled=True) channels_to_show = [c for c in valid_channels if c.visible] # The old way # channels_to_show = filter(lambda c: c.visible, valid_channels) selected_channels = [c for c in channels_to_show if c.enabled] selected_indices = list( [channels_to_show.index(c) for c in selected_channels]) Logger.debug("Currently selected channels: %s", selected_indices) channel_to_show_names = [ HtmlEntityHelper.convert_html_entities(c.channelName) for c in channels_to_show ] # The old way # channel_to_show_names = list(map(lambda c: HtmlEntityHelper.convert_html_entities(c.channelName), channels_to_show)) dialog = xbmcgui.Dialog() heading = LanguageHelper.get_localized_string( LanguageHelper.ChannelSelection)[:-1] selected_channels = dialog.multiselect(heading, channel_to_show_names, preselect=selected_indices) if selected_channels is None: return selected_channels = list(selected_channels) Logger.debug("New selected channels: %s", selected_channels) indices_to_remove = [ i for i in selected_indices if i not in selected_channels ] indices_to_add = [ i for i in selected_channels if i not in selected_indices ] for i in indices_to_remove: Logger.info("Hiding channel: %s", channels_to_show[i]) AddonSettings.set_channel_visiblity(channels_to_show[i], False) for i in indices_to_add: Logger.info("Showing channel: %s", channels_to_show[i]) AddonSettings.set_channel_visiblity(channels_to_show[i], True) self.refresh() return
def __set_proxy(self, language, proxy_id, local_ip): """ Sets the proxy and local IP configuration for channels. :param str language: The language for what channels to update. :param int proxy_id: The proxy index to use. :param int local_ip: The local_ip index to use. If no proxy_id is specified (None) then the proxy_id will be determined based on language If no local_ip is specified (None) then the local_ip will be determined based on language """ languages = AddonSettings.get_available_countries( as_country_codes=True) if language is not None and language not in languages: Logger.warning("Missing language: %s", language) return if proxy_id is None: proxy_id = languages.index(language) else: # noinspection PyTypeChecker proxy_id = int(proxy_id) if local_ip is None: local_ip = languages.index(language) else: # noinspection PyTypeChecker local_ip = int(local_ip) channels = ChannelIndex.get_register().get_channels() Logger.info( "Setting proxy='%s' (%s) and local_ip='%s' (%s) for country '%s'", proxy_id, languages[proxy_id], local_ip, languages[local_ip], language) channels_in_country = [ c for c in channels if c.language == language or language is None ] for channel in channels_in_country: Logger.debug("Setting Proxy for: %s", channel) AddonSettings.set_proxy_id_for_channel(channel, proxy_id) if channel.localIPSupported: Logger.debug("Setting Local IP for: %s", channel) AddonSettings.set_local_ip_for_channel(channel, local_ip)
def show_categories(self): """ Displays the show_categories that are currently available in XOT as a directory listing. :return: indication if all succeeded. :rtype: bool """ Logger.info("Plugin::show_categories") channel_register = ChannelIndex.get_register() categories = channel_register.get_categories() kodi_items = [] icon = Config.icon fanart = Config.fanart for category in categories: name = LanguageHelper.get_localized_category(category) kodi_item = xbmcgui.ListItem(name, name) # set art try: kodi_item.setIconImage(icon) except: # it was deprecated pass kodi_item.setArt({'thumb': icon, 'icon': icon}) kodi_item.setProperty(self.propertyRetrospect, "true") kodi_item.setProperty(self.propertyRetrospectCategory, "true") if not AddonSettings.hide_fanart(): kodi_item.setArt({'fanart': fanart}) url = self._create_action_url(None, action=self.actionListCategory, category=category) kodi_items.append((url, kodi_item, True)) # Logger.Trace(kodi_items) ok = xbmcplugin.addDirectoryItems(self.handle, kodi_items, len(kodi_items)) xbmcplugin.addSortMethod(handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_LABEL) xbmcplugin.endOfDirectory(self.handle, ok) return ok
def __init__(self, addon_name, params, handle=0): # NOSONAR complexity """ Initialises the plugin with given arguments. :param str addon_name: The add-on name. :param str params: The input parameters from the query string. :param int handle: The Kodi directory handle. """ Logger.info("******** Starting %s add-on version %s/repo *********", Config.appName, Config.version) # noinspection PyTypeChecker super(Plugin, self).__init__(addon_name, handle, params) Logger.debug(self) # Container Properties self.propertyRetrospect = "Retrospect" self.propertyRetrospectChannel = "RetrospectChannel" self.propertyRetrospectChannelSetting = "RetrospectChannelSettings" self.propertyRetrospectFolder = "RetrospectFolder" self.propertyRetrospectVideo = "RetrospectVideo" self.propertyRetrospectCloaked = "RetrospectCloaked" self.propertyRetrospectCategory = "RetrospectCategory" self.propertyRetrospectFavorite = "RetrospectFavorite" self.propertyRetrospectAdaptive = "RetrospectAdaptive" # channel objects self.channelObject = None self.channelFile = "" self.channelCode = None self.methodContainer = dict( ) # : storage for the inspect.getmembers(channel) method. Improves performance # are we in session? session_active = SessionHelper.is_session_active(Logger.instance()) # fetch some environment settings env_ctrl = envcontroller.EnvController(Logger.instance()) if not session_active: # do add-on start stuff Logger.info("Add-On start detected. Performing startup actions.") # print the folder structure env_ctrl.print_retrospect_settings_and_folders( Config, AddonSettings) # show notification XbmcWrapper.show_notification(None, LanguageHelper.get_localized_string( LanguageHelper.StartingAddonId) % (Config.appName, ), fallback=False, logger=Logger) # check for updates. Using local import for performance from resources.lib.updater import Updater up = Updater(Config.updateUrl, Config.version, UriHandler.instance(), Logger.instance(), AddonSettings.get_release_track()) if up.is_new_version_available(): Logger.info("Found new version online: %s vs %s", up.currentVersion, up.onlineVersion) notification = LanguageHelper.get_localized_string( LanguageHelper.NewVersion2Id) notification = notification % (Config.appName, up.onlineVersion) XbmcWrapper.show_notification(None, lines=notification, display_time=20000) # check for cache folder env_ctrl.cache_check() # do some cache cleanup env_ctrl.cache_clean_up(Config.cacheDir, Config.cacheValidTime) # empty picklestore self._pickler.purge_store(Config.addonId) # create a session SessionHelper.create_session(Logger.instance()) #=============================================================================== # Start the plugin version of progwindow #=============================================================================== if len(self.params) == 0: # Show initial start if not in a session # now show the list if AddonSettings.show_categories(): self.show_categories() else: self.show_channel_list() #=============================================================================== # Start the plugin verion of the episode window #=============================================================================== else: # Determine what stage we are in. Check that there are more than 2 Parameters if len(self.params) > 1 and self.keywordChannel in self.params: # retrieve channel characteristics self.channelFile = os.path.splitext( self.params[self.keywordChannel])[0] self.channelCode = self.params[self.keywordChannelCode] Logger.debug( "Found Channel data in URL: channel='%s', code='%s'", self.channelFile, self.channelCode) # import the channel channel_register = ChannelIndex.get_register() channel = channel_register.get_channel(self.channelFile, self.channelCode) if channel is not None: self.channelObject = channel else: Logger.critical( "None or more than one channels were found, unable to continue." ) return # init the channel as plugin self.channelObject.init_channel() Logger.info("Loaded: %s", self.channelObject.channelName) elif self.keywordCategory in self.params \ or self.keywordAction in self.params and ( self.params[self.keywordAction] == self.actionAllFavourites or self.params[self.keywordAction] == self.actionRemoveFavourite): # no channel needed for these favourites actions. pass # =============================================================================== # Vault Actions # =============================================================================== elif self.keywordAction in self.params and \ self.params[self.keywordAction] in \ ( self.actionSetEncryptedValue, self.actionSetEncryptionPin, self.actionResetVault ): try: # Import vault here, as it is only used here or in a channel # that supports it from resources.lib.vault import Vault action = self.params[self.keywordAction] if action == self.actionResetVault: Vault.reset() return v = Vault() if action == self.actionSetEncryptionPin: v.change_pin() elif action == self.actionSetEncryptedValue: v.set_setting( self.params[self.keywordSettingId], self.params.get(self.keywordSettingName, ""), self.params.get(self.keywordSettingActionId, None)) finally: if self.keywordSettingTabFocus in self.params: AddonSettings.show_settings( self.params[self.keywordSettingTabFocus], self.params.get(self.keywordSettingSettingFocus, None)) return elif self.keywordAction in self.params and \ self.actionPostLog in self.params[self.keywordAction]: self.__send_log() return elif self.keywordAction in self.params and \ self.actionProxy in self.params[self.keywordAction]: # do this here to not close the busy dialog on the SetProxy when # a confirm box is shown title = LanguageHelper.get_localized_string( LanguageHelper.ProxyChangeConfirmTitle) content = LanguageHelper.get_localized_string( LanguageHelper.ProxyChangeConfirm) if not XbmcWrapper.show_yes_no(title, content): Logger.warning( "Stopping proxy update due to user intervention") return language = self.params.get(self.keywordLanguage, None) proxy_id = self.params.get(self.keywordProxy, None) local_ip = self.params.get(self.keywordLocalIP, None) self.__set_proxy(language, proxy_id, local_ip) return else: Logger.critical("Error determining Plugin action") return #=============================================================================== # See what needs to be done. #=============================================================================== if self.keywordAction not in self.params: Logger.critical( "Action parameters missing from request. Parameters=%s", self.params) return elif self.params[self.keywordAction] == self.actionListCategory: self.show_channel_list(self.params[self.keywordCategory]) elif self.params[ self.keywordAction] == self.actionConfigureChannel: self.__configure_channel(self.channelObject) elif self.params[self.keywordAction] == self.actionFavourites: # we should show the favourites self.show_favourites(self.channelObject) elif self.params[self.keywordAction] == self.actionAllFavourites: self.show_favourites(None) elif self.params[self.keywordAction] == self.actionListFolder: # channelName and URL is present, Parse the folder self.process_folder_list() elif self.params[self.keywordAction] == self.actionPlayVideo: self.play_video_item() elif not self.params[self.keywordAction] == "": self.on_action_from_context_menu( self.params[self.keywordAction]) else: Logger.warning( "Number of parameters (%s) or parameter (%s) values not implemented", len(self.params), self.params) self.__fetch_textures() return
def show_channel_list(self, category=None): """ Displays the channels that are currently available in XOT as a directory listing. :param str category: The category to show channels for """ if category: Logger.info("Plugin::show_channel_list for %s", category) else: Logger.info("Plugin::show_channel_list") try: # only display channels channel_register = ChannelIndex.get_register() channels = channel_register.get_channels() xbmc_items = [] # Should we show the "All Favourites"? if AddonSettings.show_show_favourites_in_channel_list(): icon = Config.icon fanart = Config.fanart name = LanguageHelper.get_localized_string( LanguageHelper.AllFavouritesId) kodi_item = xbmcgui.ListItem(name, name) # set art try: kodi_item.setIconImage(icon) except: # it was deprecated pass kodi_item.setArt({'thumb': icon, 'icon': icon}) kodi_item.setProperty(self.propertyRetrospect, "true") kodi_item.setProperty(self.propertyRetrospectCategory, "true") if not AddonSettings.hide_fanart(): kodi_item.setArt({'fanart': fanart}) url = self._create_action_url(None, action=self.actionAllFavourites) xbmc_items.append((url, kodi_item, True)) for channel in channels: if category and channel.category != category: Logger.debug("Skipping %s (%s) due to category filter", channel.channelName, channel.category) continue # Get the Kodi item item = channel.get_kodi_item() item.setProperty(self.propertyRetrospect, "true") item.setProperty(self.propertyRetrospectChannel, "true") if channel.settings: item.setProperty(self.propertyRetrospectChannelSetting, "true") if channel.adaptiveAddonSelectable: item.setProperty(self.propertyRetrospectAdaptive, "true") # Get the context menu items context_menu_items = self.__get_context_menu_items(channel) item.addContextMenuItems(context_menu_items) # Get the URL for the item url = self._create_action_url(channel, action=self.actionListFolder) # Append to the list of Kodi Items xbmc_items.append((url, item, True)) # Add the items ok = xbmcplugin.addDirectoryItems(self.handle, xbmc_items, len(xbmc_items)) # Just let Kodi display the order we give. xbmcplugin.addSortMethod( handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_UNSORTED) xbmcplugin.addSortMethod(handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_TITLE) xbmcplugin.addSortMethod(handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_GENRE) xbmcplugin.setContent(handle=self.handle, content="tvshows") xbmcplugin.endOfDirectory(self.handle, ok) except: xbmcplugin.endOfDirectory(self.handle, False) Logger.critical("Error fetching channels for plugin", exc_info=True)
def run(self): # NOSONAR addon_action = None channel_object = None if len(self.params) == 0: # Show initial start if not in a session now show the list if AddonSettings.show_categories(): from resources.lib.actions.categoryaction import CategoryAction addon_action = CategoryAction(self) else: from resources.lib.actions.channellistaction import ChannelListAction addon_action = ChannelListAction(self) else: # Determine what action to perform based on the parameters if keyword.CHANNEL in self.params: # retrieve channel characteristics channel_file = os.path.splitext( self.params[keyword.CHANNEL])[0] channel_code = self.params[keyword.CHANNEL_CODE] Logger.debug( "Found Channel data in URL: channel='%s', code='%s'", channel_file, channel_code) # import the channel channel_register = ChannelIndex.get_register() channel = channel_register.get_channel(channel_file, channel_code) if channel is not None: channel_object = channel else: Logger.critical( "None or more than one channels were found, unable to continue." ) return # init the channel as plugin channel_object.init_channel() Logger.info("Loaded: %s", channel_object.channelName) #=============================================================================== # See what needs to be done. #=============================================================================== # From here we need the "action" keyword to be present if keyword.ACTION not in self.params: Logger.critical( "Action parameters missing from request. Parameters=%s", self.params) return if self.params[keyword.ACTION] in \ (action.SET_ENCRYPTED_VALUE, action.SET_ENCRYPTION_PIN, action.RESET_VAULT): action_value = self.params[keyword.ACTION] from resources.lib.actions.vaultaction import VaultAction addon_action = VaultAction(self, action_value) elif self.params[keyword.ACTION] == action.POST_LOG: from resources.lib.actions.logaction import LogAction addon_action = LogAction(self) elif self.params[keyword.ACTION] == action.CLEANUP: from resources.lib.actions.cleanaction import CleanAction addon_action = CleanAction(self) elif self.params[keyword.ACTION] == action.LIST_CATEGORY: from resources.lib.actions.channellistaction import ChannelListAction addon_action = ChannelListAction(self, self.params[keyword.CATEGORY]) elif self.params[keyword.ACTION] == action.CONFIGURE_CHANNEL: from resources.lib.actions.configurechannelaction import ConfigureChannelAction addon_action = ConfigureChannelAction(self, channel_object) elif self.params[keyword.ACTION] == action.CHANNEL_FAVOURITES: # we should show the favourites from resources.lib.actions.favouritesaction import ShowFavouritesAction addon_action = ShowFavouritesAction(self, channel_object) elif self.params[keyword.ACTION] == action.ALL_FAVOURITES: from resources.lib.actions.favouritesaction import ShowFavouritesAction addon_action = ShowFavouritesAction(self, None) elif self.params[keyword.ACTION] == action.LIST_FOLDER: # channelName and U.lib.aRL is present, Parse the folder from resources.lib.actions.folderaction import FolderAction addon_action = FolderAction(self, channel_object) elif self.params[keyword.ACTION] == action.PLAY_VIDEO: from resources.lib.actions.videoaction import VideoAction addon_action = VideoAction(self, channel_object) elif not self.params[keyword.ACTION] == "": from resources.lib.actions.contextaction import ContextMenuAction addon_action = ContextMenuAction(self, channel_object, self.params[keyword.ACTION]) else: Logger.warning( "Number of parameters (%s) or parameter (%s) values not implemented", len(self.params), self.params) # Execute the action if addon_action is not None: addon_action.execute() self.__fetch_textures() return
def execute(self): if self.category: Logger.info("Plugin::show_channel_list for %s", self.category) else: Logger.info("Plugin::show_channel_list") try: # only display channels channel_register = ChannelIndex.get_register() channels = channel_register.get_channels() xbmc_items = [] # Should we show the "All Favourites"? if AddonSettings.show_show_favourites_in_channel_list(): icon = Config.icon fanart = Config.fanart poster = Config.poster name = LanguageHelper.get_localized_string( LanguageHelper.AllFavouritesId) description = LanguageHelper.get_localized_string( LanguageHelper.AllFavouritesDescriptionId) kodi_item = kodifactory.list_item(name, name) kodi_item.setInfo("video", {"Plot": description}) # set art try: kodi_item.setIconImage(icon) except: # it was deprecated pass kodi_item.setArt({ 'thumb': icon, 'icon': icon, 'poster': poster }) kodi_item.setProperty(self._propertyRetrospect, "true") kodi_item.setProperty(self._propertyRetrospectCategory, "true") if not AddonSettings.hide_fanart(): kodi_item.setArt({'fanart': fanart}) url = self.parameter_parser.create_action_url( None, action=action.ALL_FAVOURITES) xbmc_items.append((url, kodi_item, True)) for channel in channels: if self.category and channel.category != self.category: Logger.debug("Skipping %s (%s) due to category filter", channel.channelName, channel.category) continue # Get the Kodi item item = channel.get_kodi_item() item.setProperty(self._propertyRetrospect, "true") item.setProperty(self._propertyRetrospectChannel, "true") if channel.settings: item.setProperty(self._propertyRetrospectChannelSetting, "true") if channel.adaptiveAddonSelectable: item.setProperty(self._propertyRetrospectAdaptive, "true") # Get the context menu items context_menu_items = self._get_context_menu_items(channel) item.addContextMenuItems(context_menu_items) # Get the URL for the item url = self.parameter_parser.create_action_url( channel, action=action.LIST_FOLDER) # Append to the list of Kodi Items xbmc_items.append((url, item, True)) # Add the items ok = xbmcplugin.addDirectoryItems(self.handle, xbmc_items, len(xbmc_items)) # Just let Kodi display the order we give. xbmcplugin.addSortMethod( handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_UNSORTED) xbmcplugin.addSortMethod(handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_TITLE) xbmcplugin.addSortMethod(handle=self.handle, sortMethod=xbmcplugin.SORT_METHOD_GENRE) xbmcplugin.setContent(handle=self.handle, content="tvshows") xbmcplugin.endOfDirectory(self.handle, ok) except: xbmcplugin.endOfDirectory(self.handle, False) Logger.critical("Error fetching channels for plugin", exc_info=True)