diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs index d7d37bb61c..32938e151f 100644 --- a/Emby.Server.Implementations/Archiving/ZipClient.cs +++ b/Emby.Server.Implementations/Archiving/ZipClient.cs @@ -89,6 +89,24 @@ namespace Emby.Server.Implementations.Archiving } } + public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName) + { + using (var reader = GZipReader.Open(source)) + { + if (reader.MoveToNextEntry()) + { + var entry = reader.Entry; + + var filename = entry.Key; + if (string.IsNullOrWhiteSpace(filename)) + { + filename = defaultFileName; + } + reader.WriteEntryToFile(Path.Combine(targetPath, filename)); + } + } + } + /// /// Extracts all from7z. /// diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 95ec1dee0d..7c251e3039 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -105,31 +105,64 @@ namespace Emby.Server.Implementations.LiveTv.Listings if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase)) { - using (var stream = _fileSystem.OpenRead(file)) + try { - var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString()); - _fileSystem.CreateDirectory(tempFolder); + var tempFolder = ExtractGz(file); + return FindXmlFile(tempFolder); + } + catch (Exception ex) + { + //_logger.ErrorException("Error extracting from gz file {0}", ex, file); + } - try - { - _zipClient.ExtractAllFromGz(stream, tempFolder, true); - } - catch - { - // If the extraction fails just return the original file, it could be a gz - return file; - } - - return _fileSystem.GetFiles(tempFolder, true) - .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) - .Select(i => i.FullName) - .FirstOrDefault(); + try + { + var tempFolder = ExtractFirstFileFromGz(file); + return FindXmlFile(tempFolder); + } + catch (Exception ex) + { + //_logger.ErrorException("Error extracting from zip file {0}", ex, file); } } return file; } + private string ExtractFirstFileFromGz(string file) + { + using (var stream = _fileSystem.OpenRead(file)) + { + var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString()); + _fileSystem.CreateDirectory(tempFolder); + + _zipClient.ExtractFirstFileFromGz(stream, tempFolder, "data.xml"); + + return tempFolder; + } + } + + private string ExtractGz(string file) + { + using (var stream = _fileSystem.OpenRead(file)) + { + var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString()); + _fileSystem.CreateDirectory(tempFolder); + + _zipClient.ExtractAllFromGz(stream, tempFolder, true); + + return tempFolder; + } + } + + private string FindXmlFile(string directory) + { + return _fileSystem.GetFiles(directory, true) + .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) + .Select(i => i.FullName) + .FirstOrDefault(); + } + public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(channelId)) @@ -149,6 +182,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings _logger.Debug("Getting xmltv programs for channel {0}", channelId); var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false); + _logger.Debug("Opening XmlTvReader for {0}", path); var reader = new XmlTvReader(path, GetLanguage(info)); var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken); @@ -251,6 +285,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings { // In theory this should never be called because there is always only one lineup var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false); + _logger.Debug("Opening XmlTvReader for {0}", path); var reader = new XmlTvReader(path, GetLanguage(info)); var results = reader.GetChannels(); @@ -262,6 +297,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings { // In theory this should never be called because there is always only one lineup var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false); + _logger.Debug("Opening XmlTvReader for {0}", path); var reader = new XmlTvReader(path, GetLanguage(info)); var results = reader.GetChannels(); diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs index 2dc4880c2f..4ebcba9d89 100644 --- a/MediaBrowser.Model/IO/IZipClient.cs +++ b/MediaBrowser.Model/IO/IZipClient.cs @@ -24,6 +24,7 @@ namespace MediaBrowser.Model.IO void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles); void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles); + void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName); /// /// Extracts all from zip.