Beispiel #1
0
    def DownloadVideoItem(self, item):
        """Downloads an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that should be downloaded.

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

        Used to download an <item>. If the item is not complete, the self.UpdateVideoItem
        method is called to update the item. The method downloads only the MediaStream
        with the bitrate that was set in the addon settings.

        After downloading the self.downloaded property is set.

        """

        if not item.IsPlayable():
            Logger.Error("Cannot download a folder item.")
            return item

        if item.IsPlayable():
            if not item.complete:
                Logger.Info("Fetching MediaUrl for PlayableItem[%s]", item.type)
                item = self.ProcessVideoItem(item)

            if not item.complete or not item.HasMediaItemParts():
                Logger.Error("Cannot download incomplete item or item without MediaItemParts")
                return item

            i = 1
            bitrate = AddonSettings.GetMaxStreamBitrate()
            for mediaItemPart in item.MediaItemParts:
                Logger.Info("Trying to download %s", mediaItemPart)
                stream = mediaItemPart.GetMediaStreamForBitrate(bitrate)
                downloadUrl = stream.Url
                extension = UriHandler.GetExtensionFromUrl(downloadUrl)
                if len(item.MediaItemParts) > 1:
                    saveFileName = "%s-Part_%s.%s" % (item.name, i, extension)
                else:
                    saveFileName = "%s.%s" % (item.name, extension)
                Logger.Debug(saveFileName)

                # headers = item.HttpHeaders + mediaItemPart.HttpHeaders
                headers = item.HttpHeaders.copy()
                headers.update(mediaItemPart.HttpHeaders)

                progressDialog = XbmcDialogProgressWrapper("Downloading Item", item.name, stream.Url)
                folderName = XbmcWrapper.ShowFolderSelection('Select download destination for "%s"' % (saveFileName, ))
                UriHandler.Download(downloadUrl, saveFileName, folderName, progressDialog, proxy=self.proxy,
                                    additionalHeaders=headers)
                i += 1

            item.downloaded = True

        return item
    def __init__(self, channelInfo):
        """Initialisation of the class.

        Arguments:
        channelInfo: ChannelInfo - The channel info object to base this channel on.

        All class variables should be instantiated here and this method should not
        be overridden by any derived classes.

        """

        chn_class.Channel.__init__(self, channelInfo)

        self.mainListUri = "#mainlist"
        self._AddDataParser(url="#mainlist", preprocessor=self.ParseRadioList)
        self._AddDataParser(url="*", preprocessor=self.ParseSubList)

        # ============== Actual channel setup STARTS here and should be overwritten from derived classes ===============
        self.noImage = "radionlimage.png"

        #===============================================================================================================
        # non standard items

        # download the stream data
        dataPath = os.path.join(self.path, "data")
        Logger.Debug("Checking '%s' for data", dataPath)
        if not os.path.isdir(dataPath):
            Logger.Info("No data found at '%s', downloading stream data",
                        dataPath)
            url = "http://www.rieter.net/net.rieter.xot.repository/net.rieter.xot.channel.streams/" \
                  "net.rieter.xot.channel.streams.radionl.data.zip"

            # give the user feedback
            progressDialog = XbmcDialogProgressWrapper(
                "Downloading Data",
                "net.rieter.xot.channel.streams.radionl.data.zip", url)

            # download the zipfile
            zipFile = UriHandler.Download(
                url, "net.rieter.xot.channel.streams.radionl.data.zip",
                self.GetDefaultCachePath(), progressDialog)

            # and unzip it
            ZipHelper.Unzip(zipFile, dataPath)

            if os.path.isdir(dataPath):
                Logger.Info("Data successfully downloaded to: %s", dataPath)

        #===============================================================================================================
        # Test cases:

        # ====================================== Actual channel setup STOPS here =======================================
        return
Beispiel #3
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())
Beispiel #4
0
    def PlayVideoItem(self, item, bitrate=None):
        """Starts the playback of the <item> with the specific <bitrate> in the selected <player>.

        Arguments:
        item    : MediaItem - The item to start playing

        Keyword Arguments:
        bitrate : [opt] integer - The requested bitrate in Kbps or None.
        plugin  : [opt] boolean - Indication whether we are in plugin mode. If True, there
                                  will not actually be playback, rather a tuple with info.

        Returns:
        The updated <item>.

        Starts the playback of the selected MediaItem <item>. Before playback is started
        the item is check for completion (item.complete), if not completed, the self.UpdateVideoItem
        method is called to update the item.

        After updating the requested bitrate playlist is selected, if bitrate was set to None
        the bitrate is retrieved from the addon settings. The playlist is then played using the
        requested player.

        """

        if bitrate is None:
            # use the bitrate from the xbmc settings if bitrate was not specified and the item is MultiBitrate
            bitrate = AddonSettings.GetMaxStreamBitrate()

        # should we download items?
        Logger.Debug("Checking for not streamable parts")
        # We need to substract the download time from processing time
        downloadStart = datetime.now()
        for part in item.MediaItemParts:
            if not part.CanStream:
                stream = part.GetMediaStreamForBitrate(bitrate)
                if not stream.Downloaded:
                    Logger.Debug("Downloading not streamable part: %s\nDownloading Stream: %s", part, stream)

                    # we need a unique filename
                    fileName = encodinghelper.EncodingHelper.EncodeMD5(stream.Url)
                    extension = UriHandler.GetExtensionFromUrl(stream.Url)

                    # now we force the busy dialog to close, else we cannot cancel the download
                    # setResolved will not work.
                    xbmc.executebuiltin("Dialog.Close(busydialog)")

                    # headers = item.HttpHeaders + part.HttpHeaders
                    headers = item.HttpHeaders.copy()
                    headers.update(part.HttpHeaders)

                    Logger.Error(headers)
                    streamFilename = "xot.%s.%skbps-%s.%s" % (fileName, stream.Bitrate, item.name, extension)
                    progressDialog = XbmcDialogProgressWrapper("Downloading Item", item.name, stream.Url)
                    cacheFile = UriHandler.Download(stream.Url, streamFilename, self.GetDefaultCachePath(),
                                                    progressDialog.ProgressUpdate, proxy=self.proxy,
                                                    additionalHeaders=headers)

                    if cacheFile == "":
                        Logger.Error("Cannot download stream %s \nFrom: %s", stream, part)
                        return

                    if cacheFile.startswith("\\\\"):
                        cacheFile = cacheFile.replace("\\", "/")
                        stream.Url = "file:///%s" % (cacheFile,)
                    else:
                        stream.Url = "file://%s" % (cacheFile,)
                        # stream.Url = cacheFile
                    stream.Downloaded = True

        # We need to substract the download time from processing time
        downloadTime = datetime.now() - downloadStart
        downloadDuration = 1000 * downloadTime.seconds + downloadTime.microseconds / 1000

        # Set item as downloaded
        item.downloaded = True

        # get the playlist
        (playList, srt) = item.GetXBMCPlayList(bitrate, updateItemUrls=True, proxy=self.proxy)

        # call for statistics with timing
        Statistics.RegisterPlayback(self, item, Initializer.StartTime, -downloadDuration)

        # if the item urls have been updated, don't start playback, but return
        return playList, srt