예제 #1
0
    def __FetchTextures(self):
        texturesToRetrieve = TextureHandler.Instance().NumberOfMissingTextures()

        if texturesToRetrieve > 0:
            w = None
            try:
                # show a blocking or background progress bar
                if texturesToRetrieve > 4:
                    w = XbmcDialogProgressWrapper(
                        "%s: %s" % (Config.appName, LanguageHelper.GetLocalizedString(LanguageHelper.InitChannelTitle)),
                        LanguageHelper.GetLocalizedString(LanguageHelper.FetchTexturesTitle),
                        # Config.TextureUrl
                    )
                else:
                    w = XbmcDialogProgressBgWrapper(
                        "%s: %s" % (Config.appName, LanguageHelper.GetLocalizedString(LanguageHelper.FetchTexturesTitle)),
                        Config.TextureUrl
                    )

                bytesTransfered = TextureHandler.Instance().FetchTextures(w.ProgressUpdate)
                if bytesTransfered > 0:
                    Statistics.RegisterCdnBytes(bytesTransfered)
            except:
                Logger.Error("Error fetching textures", exc_info=True)
            finally:
                if w is not None:
                    # always close the progress bar
                    w.Close()
        return
예제 #2
0
    def __GetApplicationKey(self):
        """ Gets the decrypted application key that is used for all the encryption

        @return: the decrypted application key that is used for all the encryption
        """

        applicationKeyEncrypted = AddonSettings.GetSetting(Vault.__APPLICATION_KEY_SETTING)
        if not applicationKeyEncrypted:
            return None

        vaultIncorrectPin = LanguageHelper.GetLocalizedString(LanguageHelper.VaultIncorrectPin)
        pin = XbmcWrapper.ShowKeyBoard(
            heading=LanguageHelper.GetLocalizedString(LanguageHelper.VaultInputPin),
            hidden=True)
        if not pin:
            XbmcWrapper.ShowNotification("", vaultIncorrectPin, XbmcWrapper.Error)
            raise RuntimeError("Incorrect Retrospect PIN specified")
        pinKey = self.__GetPBK(pin)
        applicationKey = self.__Decrypt(applicationKeyEncrypted, pinKey)
        if not applicationKey.startswith(Vault.__APPLICATION_KEY_SETTING):
            Logger.Critical("Invalid Retrospect PIN")
            XbmcWrapper.ShowNotification("", vaultIncorrectPin, XbmcWrapper.Error)
            raise RuntimeError("Incorrect Retrospect PIN specified")

        applicationKeyValue = applicationKey[len(Vault.__APPLICATION_KEY_SETTING) + 1:]
        Logger.Info("Successfully decrypted the ApplicationKey.")
        return applicationKeyValue
예제 #3
0
    def ChangePin(self, applicationKey=None):
        # type: (str) -> bool
        """ Stores an existing ApplicationKey using a new PIN

        @param applicationKey: an existing ApplicationKey that will be stored. If none specified,
                               the existing ApplicationKey of the Vault will be used.
        @return: indication of success
        """

        Logger.Info("Updating the ApplicationKey with a new PIN")

        if self.__newKeyGeneratedInConstructor:
            Logger.Info("A key was just generated, no need to change PINs.")
            return True

        if applicationKey is None:
            Logger.Debug("Using the ApplicationKey from the vault.")
            applicationKey = Vault.__Key
        else:
            Logger.Debug("Using the ApplicationKey from the input parameter.")

        if not applicationKey:
            raise ValueError("No ApplicationKey specified.")

        # Now we get a new PIN and (re)encrypt

        pin = XbmcWrapper.ShowKeyBoard(
            heading=LanguageHelper.GetLocalizedString(LanguageHelper.VaultNewPin),
            hidden=True)
        if not pin:
            XbmcWrapper.ShowNotification(
                "", LanguageHelper.GetLocalizedString(LanguageHelper.VaultNoPin),
                XbmcWrapper.Error)
            return False

        pin2 = XbmcWrapper.ShowKeyBoard(
            heading=LanguageHelper.GetLocalizedString(LanguageHelper.VaultRepeatPin),
            hidden=True)
        if pin != pin2:
            Logger.Critical("Mismatch in PINs")
            XbmcWrapper.ShowNotification(
                "",
                LanguageHelper.GetLocalizedString(LanguageHelper.VaultPinsDontMatch),
                XbmcWrapper.Error)
            return False

        encryptedKey = "%s=%s" % (self.__APPLICATION_KEY_SETTING, applicationKey)

        # let's generate a pin using the scrypt password-based key derivation
        pinKey = self.__GetPBK(pin)
        encryptedKey = self.__Encrypt(encryptedKey, pinKey)
        AddonSettings.SetSetting(Vault.__APPLICATION_KEY_SETTING, encryptedKey)
        Logger.Info("Successfully updated the Retrospect PIN")
        return True
예제 #4
0
    def ShowFavourites(self, channel, replaceExisting=False):
        """ Show the favourites

        Arguments:
        channel : Channel - The channel to show favourites for. Might be None to show all.

        Keyword Arguments:
        replaceExisting : boolean - if True it will replace the current list

        """
        Logger.Debug("Plugin::ShowFavourites")

        if channel is None:
            Logger.Info("Showing all favourites")
        else:
            Logger.Info("Showing favourites for: %s", channel)
        stopWatch = stopwatch.StopWatch("Plugin Favourites timer", Logger.Instance())

        try:
            ok = True
            f = Favourites(Config.favouriteDir)
            favs = f.List(channel)

            # get (actionUrl, pickle) tuples
            # favs = map(lambda (a, p): (a, Pickler.DePickleMediaItem(p)), favs)
            if len(favs) == 0:
                ok = self.__ShowEmptyInformation(favs, favs=True)

            stopWatch.Lap("Items retrieved")

            # create the XBMC items
            xbmcItems = map(lambda item: self.__ConvertMainlistItemToXbmcItem(channel, item[1],
                                                                              True, item[0]), favs)
            stopWatch.Lap("%s items for Kodi generated" % (len(xbmcItems),))

            # add them to XBMC
            ok = ok and xbmcplugin.addDirectoryItems(self.handle, xbmcItems, len(xbmcItems))
            # add sort handle, but don't use any dates as they make no sense for favourites
            self.__AddSortMethodToHandle(self.handle)

            # set the content
            xbmcplugin.setContent(handle=self.handle, content=self.contentType)
            # make sure we do not cache this one to disc!
            xbmcplugin.endOfDirectory(self.handle, succeeded=ok, updateListing=replaceExisting, cacheToDisc=False)
            stopWatch.Lap("items send to Kodi")

            Logger.Debug("Plugin::Favourites completed. Returned %s item(s)", len(favs))
            stopWatch.Stop()
        except:
            XbmcWrapper.ShowNotification(LanguageHelper.GetLocalizedString(LanguageHelper.ErrorId),
                                         LanguageHelper.GetLocalizedString(LanguageHelper.ErrorList),
                                         XbmcWrapper.Error, 4000)
            Logger.Error("Plugin::Error parsing favourites", exc_info=True)
            xbmcplugin.endOfDirectory(self.handle, False)
예제 #5
0
    def __UpdateFromUrl(self, url, zipName):
        """ Update a channel from an URL

        @param url:     The url to download
        @param zipName: The name to give the download

        """

        Logger.Info("Going to update from %s", url)
        # wrapper = XbmcDialogProgressWrapper("Updating XOT", url)
        # destFilename = UriHandler.Download(url, zipName, Config.cacheDir, wrapper.ProgressUpdate)
        destFilename = UriHandler.Download(url, zipName, Config.cacheDir,
                                           self.__RetrieveProgressDummy)
        Logger.Debug("Download succeeded: %s", destFilename)

        # we extract to the deploy folder, so with the first start of XOT, the new channel is deployed
        deployDir = os.path.abspath(os.path.join(Config.rootDir, "deploy"))
        zipFile = zipfile.ZipFile(destFilename)

        # now extract
        first = True
        Logger.Debug("Extracting %s to %s", destFilename, deployDir)
        for name in zipFile.namelist():
            if first:
                folder = os.path.split(name)[0]
                if os.path.exists(os.path.join(deployDir, folder)):
                    shutil.rmtree(os.path.join(deployDir, folder))
                first = False

            if not name.endswith("/") and not name.endswith("\\"):
                fileName = os.path.join(deployDir, name)
                path = os.path.dirname(fileName)
                if not os.path.exists(path):
                    os.makedirs(path)
                Logger.Debug("Extracting %s", fileName)
                outfile = open(fileName, 'wb')
                outfile.write(zipFile.read(name))
                outfile.close()

        zipFile.close()
        os.remove(destFilename)
        Logger.Info("Update completed and zip file (%s) removed", destFilename)

        message = LanguageHelper.GetLocalizedString(
            LanguageHelper.UpdateCompleteId,
            splitOnPipes=False) % (zipName.replace(".zip", ""), )
        message = message.split("|")
        XbmcWrapper.ShowNotification(LanguageHelper.GetLocalizedString(
            LanguageHelper.RestartId),
                                     message,
                                     displayTime=5000,
                                     logger=Logger.Instance())
예제 #6
0
    def AddCategories(self, data):
        Logger.Info("Performing Pre-Processing")
        items = []

        if self.parentItem and "code" in self.parentItem.metaData:
            self.__currentChannel = self.parentItem.metaData["code"]
            Logger.Info("Only showing items for channel: '%s'", self.__currentChannel)
            return data, items

        cat = mediaitem.MediaItem("\a.: Categoriën :.", "https://www.vrt.be/vrtnu/categorieen/")
        cat.fanart = self.fanart
        cat.thumb = self.noImage
        cat.icon = self.icon
        cat.dontGroup = True
        items.append(cat)

        live = mediaitem.MediaItem("\a.: Live Streams :.", "https://services.vrt.be/videoplayer/r/live.json")
        live.fanart = self.fanart
        live.thumb = self.noImage
        live.icon = self.icon
        live.dontGroup = True
        live.isLive = True
        items.append(live)

        channelText = LanguageHelper.GetLocalizedString(30010)
        channels = mediaitem.MediaItem(".: %s :." % (channelText, ), "#channels")
        channels.fanart = self.fanart
        channels.thumb = self.noImage
        channels.icon = self.icon
        channels.dontGroup = True
        items.append(channels)

        Logger.Debug("Pre-Processing finished")
        return data, items
예제 #7
0
    def CreateJsonPageItem(self, resultSet):
        """Creates a new MediaItem for an episode

        Arguments:
        resultSet : list[string] - the resultSet of the self.episodeItemRegex

        Returns:
        A new MediaItem of type 'folder'

        This method creates a new MediaItem from the Regular Expression
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        """
        Logger.Trace(resultSet)

        if "nextPageUrl" not in resultSet:
            return None

        title = "\b.: %s :." % (LanguageHelper.GetLocalizedString(LanguageHelper.MorePages), )
        url = "%s%s" % (self.baseUrl, resultSet["nextPageUrl"])
        item = mediaitem.MediaItem(title, url)
        item.icon = self.icon
        item.thumb = self.noImage
        item.complete = True
        return item
예제 #8
0
    def __ConvertMainlistItemToXbmcItem(self, channel, episodeItem, showFavourites, actionUrl=""):
        Logger.Trace("Converting a mainlist item to XbmcItem with:\nChannel: %s\nItem: %s\nShowFavourites: %s\n"
                     "Actionurl: %s", channel, episodeItem, showFavourites, actionUrl)

        if actionUrl == "" and showFavourites:
            raise Exception("Cannot create favourites XbmcItem without actionUrl")

        item = episodeItem.GetXBMCItem()

        # add the remove from favourites item:
        if showFavourites:
            # XBMC.Container.Refresh refreshes the container and replaces the last history
            # XBMC.Container.Update updates the container and but appends the new list to the history
            contextMenuItems = self.__GetContextMenuItems(channel, item=episodeItem, favouritesList=True)
        else:
            contextMenuItems = self.__GetContextMenuItems(channel, item=episodeItem)

            if self.FavouritesEnabled:
                # add the show favourites here
                cmdUrl = self.__CreateActionUrl(channel, action=self.actionFavourites)
                cmd = "XBMC.Container.Update(%s)" % (cmdUrl,)
                favs = LanguageHelper.GetLocalizedString(LanguageHelper.ChannelFavourites)
                contextMenuItems.append(('Retro: %s' % (favs, ), cmd))

        item.addContextMenuItems(contextMenuItems)

        if actionUrl == "":
            url = self.__CreateActionUrl(channel, self.actionListFolder, item=episodeItem)
        else:
            Logger.Trace("Using predefined actionUrl")
            url = actionUrl

        return url, item, True
예제 #9
0
    def AddPageItems(self, data):
        """ Adds page items to the main listing

        @param data:    the Parsed Data
        @return:        a tuple of data and items
        """

        Logger.Info("Performing Pre-Processing")
        items = []
        json = JsonHelper(data)
        totalResults = json.GetValue("totalResults")
        fromValue = json.GetValue("from")
        sizeValue = json.GetValue("size")

        if fromValue + sizeValue < totalResults:
            morePages = LanguageHelper.GetLocalizedString(
                LanguageHelper.MorePages)
            url = self.parentItem.url.split('?')[0]
            url = "%s?size=%s&from=%s&sort=Nieuwste" % (url, sizeValue,
                                                        fromValue + sizeValue)
            Logger.Debug("Adding next-page item from %s to %s",
                         fromValue + sizeValue,
                         fromValue + sizeValue + sizeValue)

            nextPage = mediaitem.MediaItem(morePages, url)
            nextPage.icon = self.parentItem.icon
            nextPage.fanart = self.parentItem.fanart
            nextPage.thumb = self.parentItem.thumb
            nextPage.dontGroup = True
            items.append(nextPage)

        Logger.Debug("Pre-Processing finished")
        return json, items
예제 #10
0
    def CreateMoreItem(self, resultSet):
        """Creates a MediaItem of type 'folder' using the resultSet from the regex.

        Arguments:
        resultSet : tuple(strig) - the resultSet of the self.folderItemRegex

        Returns:
        A new MediaItem of type 'folder'

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        """

        Logger.Trace(resultSet)

        if resultSet == "klipp" and self.__klippUrlIndicator not in self.parentItem.url:
            return None

        more = LanguageHelper.GetLocalizedString(LanguageHelper.MorePages)

        item = mediaitem.MediaItem(more, "%s&sida=2&embed=true" % (self.parentItem.url, ))
        item.thumb = self.parentItem.thumb
        item.icon = self.parentItem.icon
        item.type = 'folder'
        item.httpHeaders = self.httpHeaders
        item.complete = True
        return item
예제 #11
0
    def CreatePageItem(self, resultSet):
        """Creates a MediaItem of type 'page' using the resultSet from the regex.

        Arguments:
        resultSet : tuple(string) - the resultSet of the self.pageNavigationRegex

        Returns:
        A new MediaItem of type 'page'

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        """

        Logger.Trace(resultSet)
        nextPage = resultSet["next"]
        if not nextPage:
            Logger.Debug("No more items available")
            return None

        more = LanguageHelper.GetLocalizedString(LanguageHelper.MorePages)
        url = "%s=%s" % (self.parentItem.url.rsplit("=", 1)[0], nextPage)
        item = mediaitem.MediaItem(more, url)
        item.thumb = self.parentItem.thumb
        item.icon = self.icon
        item.fanart = self.parentItem.fanart
        item.complete = True
        return item
예제 #12
0
    def __ShowFirstTimeMessage(self, channelInfo):
        # type: (ChannelInfo) -> None
        """ Checks if it is the first time a channel is executed
        and if a first time message is available it will be shown

        Arguments:
        channelName : string - Name of the channelfile that is loaded
        channelPath : string - Path of the channelfile

        Shows a message dialog if the message should be shown.

        Make sure that each line fits in a single line of a XBMC Dialog box (50 chars)

        """

        hideFirstTime = AddonSettings.HideFirstTimeMessages()
        if channelInfo.firstTimeMessage:
            if not hideFirstTime:
                Logger.Info("Showing first time message '%s' for channel chn_%s.",
                            channelInfo.firstTimeMessage, channelInfo.moduleName)

                title = LanguageHelper.GetLocalizedString(LanguageHelper.ChannelMessageId)
                XbmcWrapper.ShowDialog(title, channelInfo.firstTimeMessage.split("|"))
            else:
                Logger.Debug("Not showing first time message due to add-on setting set to '%s'.",
                             hideFirstTime)
        return
예제 #13
0
    def CreatePageItem(self, resultSet):
        """Creates a MediaItem of type 'page' using the resultSet from the regex.

        Arguments:
        resultSet : tuple(string) - the resultSet of the self.pageNavigationRegex

        Returns:
        A new MediaItem of type 'page'

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        """

        Logger.Debug("Starting CreatePageItem")

        # current page?
        baseUrl, page = self.parentItem.url.rsplit("=", 1)
        page = int(page)
        maxPages = resultSet.get("total_pages", 0)
        Logger.Trace("Current Page: %d of %d (%s)", page, maxPages, baseUrl)
        if page + 1 >= maxPages:
            return None

        title = LanguageHelper.GetLocalizedString(LanguageHelper.MorePages)
        url = "%s=%s" % (baseUrl, page + 1)
        item = mediaitem.MediaItem(title, url)
        item.fanart = self.parentItem.fanart
        item.thumb = self.parentItem.thumb
        return item
예제 #14
0
    def AddClips(self, data):
        Logger.Info("Adding Clips Pre-Processing")
        items = []

        # if the main list was retrieve using json, are the current data is json, just determine
        # the clip URL
        clipUrl = None
        if data.lstrip().startswith("{"):
            if self.parentItem.url.endswith("type=program"):
                # http://playapi.mtgx.tv/v3/videos?format=6723&order=-airdate&type=program
                # http://playapi.mtgx.tv/v3/videos?format=6723&order=-updated&type=clip" % (dataId,)
                clipUrl = self.parentItem.url.replace("type=program",
                                                      "type=clip")
        else:
            # now we determine the ID and load the json data
            dataId = Regexer.DoRegex('data-format-id="(\d+)"', data)[-1]
            Logger.Debug("Found FormatId = %s", dataId)
            programUrl = "http://playapi.mtgx.tv/v3/videos?format=%s&order=-airdate&type=program" % (
                dataId, )
            data = UriHandler.Open(programUrl, proxy=self.proxy)
            clipUrl = "http://playapi.mtgx.tv/v3/videos?format=%s&order=-updated&type=clip" % (
                dataId, )

        if clipUrl is not None:
            clipTitle = LanguageHelper.GetLocalizedString(LanguageHelper.Clips)
            clipItem = mediaitem.MediaItem("\a.: %s :." % (clipTitle, ),
                                           clipUrl)
            clipItem.thumb = self.noImage
            items.append(clipItem)

        Logger.Debug("Pre-Processing finished")
        return data, items
예제 #15
0
    def __ShowEmptyInformation(self, items, favs=False):
        """ Adds an empty item to a list or just shows a message.
        @type favs: boolean indicating that we are dealing with favourites
        @param items: the list of items

        @rtype : boolean indicating succes or not

        """

        if self.channelObject:
            Statistics.RegisterError(self.channelObject)

        if favs:
            title = LanguageHelper.GetLocalizedString(LanguageHelper.NoFavsId)
        else:
            title = LanguageHelper.GetLocalizedString(LanguageHelper.ErrorNoEpisodes)

        behaviour = AddonSettings.GetEmptyListBehaviour()

        Logger.Debug("Showing empty info for mode (favs=%s): [%s]", favs, behaviour)
        if behaviour == "error":
            # show error
            ok = False
        elif behaviour == "dummy" and not favs:
            # We should add a dummy items, but not for favs
            emptyListItem = MediaItem("- %s -" % (title.strip("."), ), "", type='video')
            emptyListItem.icon = self.channelObject.icon
            emptyListItem.thumb = self.channelObject.noImage
            emptyListItem.fanart = self.channelObject.fanart
            emptyListItem.dontGroup = True
            emptyListItem.description = "This listing was left empty intentionally."
            emptyListItem.complete = True
            emptyListItem.fanart = self.channelObject.fanart
            # add funny stream here?
            # part = emptyListItem.CreateNewEmptyMediaPart()
            # for s, b in YouTube.GetStreamsFromYouTube("", self.channelObject.proxy):
            #     part.AppendMediaStream(s, b)

            # if we add one, set OK to True
            ok = True
            items.append(emptyListItem)
        else:
            ok = True

        XbmcWrapper.ShowNotification(LanguageHelper.GetLocalizedString(LanguageHelper.ErrorId),
                                     title, XbmcWrapper.Error, 2500)
        return ok
예제 #16
0
    def __GetAvailableUpdates(self):
        """ Opens the addon.xml and fetches all updates. Compares them with the installed versions and returns a list
        of URL's to download

        @return: a list of URLs
        """

        data = UriHandler.Open(Config.UpdateUrl.replace(".md5", ""))
        channels = Regexer.DoRegex(
            '<addon\W+id="(net.rieter.xot(?:.channel.[^"]+|))\W+version="([^"]+)"',
            data)
        updates = []

        for channel in channels:
            addonId = channel[0]
            addonVersion = channel[1]
            if addonId == Config.addonId:
                Logger.Debug("Found main Retrospect version: %s", addonVersion)
                # the main XOT add-on
                if Version(version=addonVersion) != Config.version:
                    Logger.Warning(
                        "Not deploying new channels because Retrospect versions do not match: "
                        "Installed %s vs Online %s", Config.version,
                        addonVersion)
                    message = LanguageHelper.GetLocalizedString(
                        LanguageHelper.NewVersion2Id, splitOnPipes=False)
                    message = message % (Config.appName, addonVersion)
                    XbmcWrapper.ShowDialog(
                        LanguageHelper.GetLocalizedString(
                            LanguageHelper.NewVersionId), message.split("|"))
                    return []
            else:
                # set the zipfile name here, but check in the next loop!
                channelId = "%s-%s" % (addonId, addonVersion)
                if self.__IsVersionInstalled(addonId, addonVersion):
                    # already installed, continue as if
                    Logger.Info("Update already installed: %s", channelId)
                    continue
                else:
                    url = "http://www.rieter.net/net.rieter.xot.repository/%s/%s-%s.zip" % (
                        addonId, addonId, addonVersion)
                    filename = "%s-%s.zip" % (addonId, addonVersion)
                    Logger.Info("New update found: %s @ %s", channelId, url)
                    updates.append((url, filename))
        return updates
예제 #17
0
    def Reset():
        """ Resets the Vault and Retrospect Machine key, making all encrypted values
        useless.

        """

        ok = XbmcWrapper.ShowYesNo(LanguageHelper.GetLocalizedString(LanguageHelper.VaultReset),
                                   LanguageHelper.GetLocalizedString(LanguageHelper.VaultResetConfirm))
        if not ok:
            Logger.Debug("Aborting Reset Vault")
            return

        Logger.Info("Resetting the vault to a new initial state.")
        AddonSettings.SetSetting(Vault.__APPLICATION_KEY_SETTING, "")

        # create a vault instance so we initialize a new one with a new PIN.
        Vault()
        return
예제 #18
0
    def CtMnTestProxy(self, item):  # :@UnusedVariable
        """ Checks if the proxy is OK"""

        if not self.proxy:
            message = "Proxy not configured: %s" % (self.proxy,)
        else:
            url = Config.UpdateUrl + "proxy"
            data = UriHandler.Open(url, proxy=self.proxy)
            # Logger.Trace(data)
            if data == "1":
                message = LanguageHelper.GetLocalizedString(LanguageHelper.ProxyOkId) % (self.proxy,)
            else:
                message = LanguageHelper.GetLocalizedString(LanguageHelper.ProxyNokId) % (self.proxy,)

        Logger.Debug(message)

        XbmcWrapper.ShowDialog("", message)
        pass
예제 #19
0
    def CreatePageItem(self, resultSet):
        items = []
        if 'next' in resultSet:
            title = LanguageHelper.GetLocalizedString(LanguageHelper.MorePages)
            url = resultSet['next']
            item = mediaitem.MediaItem(title, url)
            item.fanart = self.parentItem.fanart
            item.thumb = self.parentItem.thumb
            items.append(item)

        return items
예제 #20
0
    def CreatePageItem(self, resultSet):
        """Creates a MediaItem of type 'page' using the resultSet from the regex.

        Arguments:
        resultSet : tuple(string) - the resultSet of the self.pageNavigationRegex

        Returns:
        A new MediaItem of type 'page'

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        """

        if "totalPages" not in resultSet:
            return None

        Logger.Debug("Starting CreatePageItem")

        # current page?
        pageUriPart = "page%5Bnumber%5D="
        if pageUriPart not in self.parentItem.url:
            page = 1
            urlFormat = "{0}&page%5Bnumber%5D={{0:d}}".format(
                self.parentItem.url)
        else:
            baseUrl, pagePart = self.parentItem.url.rsplit(pageUriPart, 1)
            nextPart = pagePart.find("&")
            if nextPart < 0:
                # end
                page = int(pagePart)
                urlFormat = "{0}&page%5Bnumber%5D={{0:d}}".format(baseUrl)
            else:
                page = int(pagePart[0:nextPart])
                urlFormat = "{0}&page%5Bnumber%5D={{0:d}}&{1}".format(
                    baseUrl, pagePart[nextPart:])

        maxPages = resultSet.get("totalPages", 0)
        Logger.Trace("Current Page: %d of %d (%s)", page, maxPages,
                     self.parentItem.url)

        if page + 1 > maxPages:
            return None

        title = LanguageHelper.GetLocalizedString(LanguageHelper.MorePages)
        url = urlFormat.format(page + 1)
        item = mediaitem.MediaItem(title, url)
        item.fanart = self.parentItem.fanart
        item.thumb = self.parentItem.thumb
        return item
예제 #21
0
    def IsInstallMethodValid(self, config):
        """ Validates that Retrospect is installed using the repository. If not
        it will popup a dialog box.

        Arguments:
        config : Config - The Retrospect config object.

        """

        repoAvailable = self.__IsRepoAvailable(config)

        if not repoAvailable:
            # show alert
            if self.logger:
                self.logger.Warning(
                    "No Respository installed. Reminding user to install it.")

            XbmcWrapper.ShowDialog(
                LanguageHelper.GetLocalizedString(
                    LanguageHelper.RepoWarningId),
                LanguageHelper.GetLocalizedString(
                    LanguageHelper.RepoWarningDetailId))

        return repoAvailable
예제 #22
0
    def LogOn(self):
        signatureSettings = "mediaan_signature"
        signatureSetting = AddonSettings.GetSetting(signatureSettings)
        # apiKey = "3_HZ0FtkMW_gOyKlqQzW5_0FHRC7Nd5XpXJZcDdXY4pk5eES2ZWmejRW5egwVm4ug-"  # from VTM
        apiKey = "3_OEz9nzakKMkhPdUnz41EqSRfhJg5z9JXvS4wUORkqNf2M2c1wS81ilBgCewkot97"  # from Stievie
        if signatureSetting and "|" not in signatureSetting:
            url = "https://accounts.eu1.gigya.com/accounts.getAccountInfo"
            data = "APIKey=%s" \
                   "&sdk=js_7.4.30" \
                   "&login_token=%s" % (apiKey, signatureSetting, )
            logonData = UriHandler.Open(url,
                                        params=data,
                                        proxy=self.proxy,
                                        noCache=True)
            if self.__ExtractSessionData(logonData, signatureSettings):
                return True
            Logger.Warning("Failed to extend the VTM.be session.")

        Logger.Info("Logging onto VTM.be")
        v = Vault()
        password = v.GetSetting("mediaan_password")
        username = AddonSettings.GetSetting("mediaan_username")
        if not username or not password:
            XbmcWrapper.ShowDialog(
                title=None,
                lines=LanguageHelper.GetLocalizedString(
                    LanguageHelper.MissingCredentials),
                # notificationType=XbmcWrapper.Error,
                # displayTime=5000
            )
            return False

        Logger.Debug("Using: %s / %s", username, "*" * len(password))
        url = "https://accounts.eu1.gigya.com/accounts.login"
        data = "loginID=%s" \
               "&password=%s" \
               "&targetEnv=jssdk" \
               "&APIKey=%s" \
               "&includeSSOToken=true" \
               "&authMode=cookie" % \
               (HtmlEntityHelper.UrlEncode(username), HtmlEntityHelper.UrlEncode(password), apiKey)

        logonData = UriHandler.Open(url,
                                    params=data,
                                    proxy=self.proxy,
                                    noCache=True)
        return self.__ExtractSessionData(logonData, signatureSettings)
예제 #23
0
    def CreateFolderItem(self, resultSet):
        """Creates a MediaItem of type 'folder' using the resultSet from the regex.

        Arguments:
        resultSet : tuple(strig) - the resultSet of the self.folderItemRegex

        Returns:
        A new MediaItem of type 'folder'

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        """

        Logger.Trace(resultSet)

        resultSet["title"] = LanguageHelper.GetLocalizedString(
            LanguageHelper.MorePages)
        return chn_class.Channel.CreateFolderItem(self, resultSet)
예제 #24
0
    def AddVideoPageItemsJson(self, data):
        items = []
        json = JsonHelper(data)
        currentOffset = json.GetValue("request", "offset") or 0
        itemsOnThisPage = len(json.GetValue("response", "items") or [])
        totalItems = json.GetValue("response", "total")

        if totalItems > currentOffset + itemsOnThisPage:
            # add next page items
            newOffset = currentOffset + itemsOnThisPage
            seriesId = json.GetValue("request", "parentSeriesOID")[0]
            url = "https://vod.medialaan.io/api/1.0/list?app_id=%s&parentSeriesOID=%s&offset=%s" % (self.__app, seriesId, newOffset)
            more = LanguageHelper.GetLocalizedString(LanguageHelper.MorePages)
            item = MediaItem(more, url)
            item.thumb = self.noImage
            item.icon = self.icon
            item.fanart = self.parentItem.fanart
            item.complete = True
            items.append(item)

        return json, items
예제 #25
0
    def LogOn(self):
        if self.__idToken:
            return True

        # check if there is a refresh token
        # refresh token: viervijfzes_refresh_token
        refreshToken = AddonSettings.GetSetting("viervijfzes_refresh_token")
        client = AwsIdp("eu-west-1_dViSsKM5Y",
                        "6s1h851s8uplco5h6mqh1jac8m",
                        proxy=self.proxy,
                        logger=Logger.Instance())
        if refreshToken:
            idToken = client.RenewToken(refreshToken)
            if idToken:
                self.__idToken = idToken
                return True
            else:
                Logger.Info("Extending token for VierVijfZes failed.")

        # username: viervijfzes_username
        username = AddonSettings.GetSetting("viervijfzes_username")
        # password: viervijfzes_password
        v = Vault()
        password = v.GetSetting("viervijfzes_password")
        if not username or not password:
            XbmcWrapper.ShowDialog(
                title=None,
                lines=LanguageHelper.GetLocalizedString(
                    LanguageHelper.MissingCredentials),
            )
            return False

        idToken, refreshToken = client.Authenticate(username, password)
        if not idToken or not refreshToken:
            Logger.Error("Error getting a new token. Wrong password?")
            return False

        self.__idToken = idToken
        AddonSettings.SetSetting("viervijfzes_refresh_token", refreshToken)
        return True
예제 #26
0
    def AlphaListing(self, data):
        """Performs pre-process actions for data processing

        Arguments:
        data : string - the retrieve data that was loaded for the current item and URL.

        Returns:
        A tuple of the data and a list of MediaItems that were generated.


        Accepts an data from the ProcessFolderList method, BEFORE the items are
        processed. Allows setting of parameters (like title etc) for the channel.
        Inside this method the <data> could be changed and additional items can
        be created.

        The return values should always be instantiated in at least ("", []).

        """

        Logger.Info("Generating an Alpha list for NPO")

        items = []
        # https://www.npo.nl/media/series?page=1&dateFrom=2014-01-01&tilemapping=normal&tiletype=teaser
        # https://www.npo.nl/media/series?page=2&dateFrom=2014-01-01&az=A&tilemapping=normal&tiletype=teaser
        # https://www.npo.nl/media/series?page=2&dateFrom=2014-01-01&az=0-9&tilemapping=normal&tiletype=teaser

        titleFormat = LanguageHelper.GetLocalizedString(LanguageHelper.StartWith)
        urlFormat = "https://www.npo.nl/media/series?page=1&dateFrom=2014-01-01&az=%s&tilemapping=normal&tiletype=teaser&pageType=catalogue"
        for char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0":
            if char == "0":
                char = "0-9"
            subItem = mediaitem.MediaItem(titleFormat % (char,), urlFormat % (char, ))
            subItem.complete = True
            subItem.icon = self.icon
            subItem.thumb = self.noImage
            subItem.dontGroup = True
            subItem.HttpHeaders = {"X-Requested-With": "XMLHttpRequest"}
            items.append(subItem)
        return data, items
예제 #27
0
    def AddPages(self, data):
        """Performs pre-process actions for data processing

        Arguments:
        data : string - the retrieve data that was loaded for the current item and URL.

        Returns:
        A tuple of the data and a list of MediaItems that were generated.


        Accepts an data from the ProcessFolderList method, BEFORE the items are
        processed. Allows setting of parameters (like title etc) for the channel.
        Inside this method the <data> could be changed and additional items can
        be created.

        The return values should always be instantiated in at least ("", []).

        """

        Logger.Info("Adding pages")

        # extract the current page from:
        # http://www.foxsports.nl/video/filter/fragments/1/alle/tennis/
        currentPages = Regexer.DoRegex('(.+filter/fragments)/(\d+)/(.+)', self.parentItem.url)
        if not currentPages:
            return data, []

        currentPage = currentPages[0]
        items = []

        url = "%s/%s/%s" % (currentPage[0], int(currentPage[1]) + 1, currentPage[2])
        pageItem = mediaitem.MediaItem(LanguageHelper.GetLocalizedString(LanguageHelper.MorePages), url)
        pageItem.fanart = self.parentItem.fanart
        pageItem.thumb = self.parentItem.thumb
        pageItem.dontGroup = True
        items.append(pageItem)

        return data, items
예제 #28
0
    def AlphaListing(self, data):
        """Performs pre-process actions for data processing

        Arguments:
        data : string - the retrieve data that was loaded for the current item and URL.

        Returns:
        A tuple of the data and a list of MediaItems that were generated.


        Accepts an data from the ProcessFolderList method, BEFORE the items are
        processed. Allows setting of parameters (like title etc) for the channel.
        Inside this method the <data> could be changed and additional items can
        be created.

        The return values should always be instantiated in at least ("", []).

        """

        Logger.Info("Generating an Alpha list for NPO")

        items = []
        titleFormat = LanguageHelper.GetLocalizedString(LanguageHelper.StartWith)
        for char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0":
            if char == "0":
                char = "0-9"
                subItem = mediaitem.MediaItem(titleFormat % (char,), "http://www.npo.nl/a-z?page=1")
            else:
                subItem = mediaitem.MediaItem(titleFormat % (char,),
                                              "http://www.npo.nl/a-z/%s?page=1" % (char.lower(),))
            subItem.complete = True
            subItem.icon = self.icon
            subItem.thumb = self.noImage
            subItem.dontGroup = True
            items.append(subItem)
        return data, items
예제 #29
0
    def SetSetting(self, settingId, settingName=None, settingActionId=None):
        # type: (str, str) -> None
        """ Reads a value for a setting from the keyboard and encryptes it in the Kodi
        Add-on settings

        @param settingId:   the ID for the Kodi Add-on setting to set
        @param settingName: the name to display in the keyboard
        @param settingActionId: the name of the action that was called.

        The setttingActionId defaults to <settingId>_set

        """

        Logger.Info("Encrypting value for setting '%s'", settingId)
        inputValue = XbmcWrapper.ShowKeyBoard(
            "",
            LanguageHelper.GetLocalizedString(LanguageHelper.VaultSpecifySetting) % (settingName or settingId, ))

        if inputValue is None:
            Logger.Debug("Setting of encrypted value cancelled.")
            return

        value = "%s=%s" % (settingId, inputValue)
        encryptedValue = self.__Encrypt(value, Vault.__Key)

        if settingActionId is None:
            settingActionId = "%s_set" % (settingId,)

        Logger.Debug("Updating '%s' and '%s'", settingId, settingActionId)
        AddonSettings.SetSetting(settingId, encryptedValue)
        if inputValue:
            AddonSettings.SetSetting(settingActionId, "******")
        else:
            AddonSettings.SetSetting(settingActionId, "")
        Logger.Info("Successfully encrypted value for setting '%s'", settingId)
        return
예제 #30
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        Used to update none complete MediaItems (self.complete = False). This
        could include opening the item's URL to fetch more data and then process that
        data or retrieve it's real media-URL.

        The method should at least:
        * cache the thumbnail to disk (use self.noImage if no thumb is available).
        * set at least one MediaItemPart with a single MediaStream.
        * set self.complete = True.

        if the returned item does not have a MediaItemPart then the self.complete flag
        will automatically be set back to False.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)

        data = UriHandler.Open(item.url, proxy=self.proxy)
        Logger.Trace(data)

        if 'livestart":-' in data:
            Logger.Debug("Live item that has not yet begun.")
            json = JsonHelper(data, Logger.Instance())
            secondsToStart = json.GetValue("video", "livestart")
            if secondsToStart:
                secondsToStart = -int(secondsToStart)
                Logger.Debug("Seconds till livestream: %s", secondsToStart)
                timeLeft = "%s:%02d:%02d" % (secondsToStart / 3600, (secondsToStart % 3600) / 60, secondsToStart % 60)
                Logger.Debug("Live items starts at %s", timeLeft)
                lines = list(LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamId))
                lines[-1] = "%s ETA: %s" % (lines[-1], timeLeft)
                XbmcWrapper.ShowDialog(LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamTitleId),
                                       lines)
            else:
                XbmcWrapper.ShowDialog(LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamTitleId),
                                       LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamId))
            return item

        item.MediaItemParts = []
        mediaPart = item.CreateNewEmptyMediaPart()
        spoofIp = self._GetSetting("spoof_ip", "0.0.0.0")
        if spoofIp is not None:
            mediaPart.HttpHeaders["X-Forwarded-For"] = spoofIp

        # mediaPart.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0"

        # isLive = False
        if '"live":true' in data or "/live/" in item.url:
            mediaPart.AddProperty("IsLive", "true")
            Logger.Debug("Live video item found.")
            # isLive = True
        else:
            Logger.Debug("Normal (not live, or possible was live) video item found")

        # replace items
        #videos = map(lambda v: self.__ReplaceClist(v), videos)

        jsonVideoData = JsonHelper(data)
        videos = jsonVideoData.GetValue("video", "videoReferences")
        # videos = Regexer.DoRegex(self.mediaUrlRegex, data)
        for video in videos:
            playerType = video.get("playerType", "")
            if "dash" in playerType:
                continue

            if video["url"].startswith("rtmp"):
                # just replace some data in the URL
                mediaPart.AppendMediaStream(self.GetVerifiableVideoUrl(video["url"]).replace("_definst_", "?slist="),
                                            video[1])

            elif "m3u8" in video["url"]:
                Logger.Info("SVTPlay.se m3u8 stream found: %s", video["url"])

                # apparently the m3u8 do not work well for server www0.c91001.dna.qbrick.com
                if "www0.c91001.dna.qbrick.com" in video["url"]:
                    continue

                # m3u8 we need to parse. Get more streams from this file.
                videoUrl = video["url"]
                altIndex = videoUrl.find("m3u8?")
                # altIndex = videoUrl.find("~uri")
                if altIndex > 0:
                    videoUrl = videoUrl[0:altIndex + 4]
                for s, b in M3u8.GetStreamsFromM3u8(videoUrl, self.proxy, headers=mediaPart.HttpHeaders):
                    item.complete = True
                    mediaPart.AppendMediaStream(s, b)

            elif "f4m" in video["url"]:
                Logger.Info("SVTPlay.se manifest.f4m stream found: %s", video["url"])

                #if "manifest.f4m?start=" in video["url"]:
                #    # this was a live stream, convert it to M3u8
                #    # http://svt06-lh.akamaihd.net/z/svt06_0@77501/manifest.f4m?start=1386566700&end=1386579600
                #    # to
                #    # http://svt06hls-lh.akamaihd.net/i/svt06_0@77501/master.m3u8?__b__=563&start=1386566700&end=1386579600
                #    m3u8Url = video["url"].replace("-lh.akamaihd.net/z", "hls-lh.akamaihd.net/i").replace("manifest.f4m?", "master.m3u8?__b__=563&")
                #    Logger.Info("Found f4m stream for an old Live stream. Converting to M3U8:\n%s -to -\n%s", video["url"], m3u8Url)
                #    videos.append((m3u8Url, 0))
                #    continue

                # for now we skip these as they do not yet work with XBMC
                continue
                # http://svtplay8m-f.akamaihd.net/z/se/krypterat/20120830/254218/LILYHAMMER-003A-mp4-,c,d,b,e,-v1-4bc7ecc090b19c82.mp4.csmil/manifest.f4m?hdcore=2.8.0&g=TZOMVRTEILSE
                #videoDataUrl = video["url"]
                # videoUrl = "%s?hdcore=2.8.0&g=TZOMVRTEILSE" % (videoDataUrl,)
                #videoUrl = "%s?hdcore=2.10.3&g=IJGTWSVWPPKH" % (videoDataUrl,)

                # metaData = UriHandler.Open(videoUrl, proxy=self.proxy, referer=self.swfUrl)
                # Logger.Debug(metaData)

                # The referer seems to be unimportant
                # header = "referer=%s" % (urllib.quote(self.swfUrl),)
                # videoUrl = "%s|%s" % (videoUrl, header)
                #mediaPart.AppendMediaStream(videoUrl, video[1])

            else:
                Logger.Info("SVTPlay.se standard HTTP stream found.")
                # else just use the URL
                mediaPart.AppendMediaStream(video["url"], video["bitrate"])

        subtitle = Regexer.DoRegex('"url":"([^"]+.wsrt)"|"url":"(http://media.svt.se/download/[^"]+.m3u8)', data)
        for sub in subtitle:
            if sub[-1]:
                Logger.Info("Found M3u8 subtitle, replacing with WSRT")
                start, name, index = sub[-1].rsplit("/", 2)
                subUrl = "%s/%s/%s.wsrt" % (start, name, name)
            else:
                subUrl = sub[0]
            mediaPart.Subtitle = subtitlehelper.SubtitleHelper.DownloadSubtitle(subUrl, format="srt", proxy=self.proxy)

        item.complete = True
        return item