Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
    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)
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
    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)
Пример #8
0
    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
Пример #9
0
    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)