aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs')
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs107
1 files changed, 30 insertions, 77 deletions
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index bd1cd1e1d..10f7e5cc8 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -6,9 +6,9 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.IO.Compression;
using System.Linq;
using System.Net.Http;
-using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Extensions;
@@ -33,20 +33,17 @@ namespace Emby.Server.Implementations.LiveTv.Listings
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<XmlTvListingsProvider> _logger;
private readonly IFileSystem _fileSystem;
- private readonly IZipClient _zipClient;
public XmlTvListingsProvider(
IServerConfigurationManager config,
IHttpClientFactory httpClientFactory,
ILogger<XmlTvListingsProvider> logger,
- IFileSystem fileSystem,
- IZipClient zipClient)
+ IFileSystem fileSystem)
{
_config = config;
_httpClientFactory = httpClientFactory;
_logger = logger;
_fileSystem = fileSystem;
- _zipClient = zipClient;
}
public string Name => "XmlTV";
@@ -67,16 +64,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
_logger.LogInformation("xmltv path: {Path}", info.Path);
- if (!info.Path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
- {
- return UnzipIfNeeded(info.Path, info.Path);
- }
-
string cacheFilename = info.Id + ".xml";
string cacheFile = Path.Combine(_config.ApplicationPaths.CachePath, "xmltv", cacheFilename);
+
if (File.Exists(cacheFile) && File.GetLastWriteTimeUtc(cacheFile) >= DateTime.UtcNow.Subtract(_maxCacheAge))
{
- return UnzipIfNeeded(info.Path, cacheFile);
+ return cacheFile;
}
// Must check if file exists as parent directory may not exist.
@@ -84,93 +77,53 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
File.Delete(cacheFile);
}
+ else
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(cacheFile));
+ }
- _logger.LogInformation("Downloading xmltv listings from {Path}", info.Path);
+ if (info.Path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ _logger.LogInformation("Downloading xmltv listings from {Path}", info.Path);
- Directory.CreateDirectory(Path.GetDirectoryName(cacheFile));
+ using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(info.Path, cancellationToken).ConfigureAwait(false);
+ await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(info.Path, cancellationToken).ConfigureAwait(false);
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- await using (var fileStream = new FileStream(cacheFile, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.CopyToBufferSize, FileOptions.Asynchronous))
- {
- await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
+ return await UnzipIfNeededAndCopy(info.Path, stream, cacheFile, cancellationToken).ConfigureAwait(false);
}
+ else
+ {
+ await using var stream = new FileStream(info.Path, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
- return UnzipIfNeeded(info.Path, cacheFile);
+ return await UnzipIfNeededAndCopy(info.Path, stream, cacheFile, cancellationToken).ConfigureAwait(false);
+ }
}
- private string UnzipIfNeeded(ReadOnlySpan<char> originalUrl, string file)
+ private async Task<string> UnzipIfNeededAndCopy(string originalUrl, Stream stream, string file, CancellationToken cancellationToken)
{
- ReadOnlySpan<char> ext = Path.GetExtension(originalUrl.LeftPart('?'));
+ int index = originalUrl.IndexOf('?', StringComparison.CurrentCulture);
+ string ext = Path.GetExtension(index > -1 ? originalUrl.Remove(index) : originalUrl);
if (ext.Equals(".gz", StringComparison.OrdinalIgnoreCase))
{
try
{
- string tempFolder = ExtractGz(file);
- return FindXmlFile(tempFolder);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error extracting from gz file {File}", file);
- }
-
- try
- {
- string tempFolder = ExtractFirstFileFromGz(file);
- return FindXmlFile(tempFolder);
+ using var reader = new GZipStream(stream, CompressionMode.Decompress);
+ await using var writer = File.Create(file);
+ await reader.CopyToAsync(writer, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
- _logger.LogError(ex, "Error extracting from zip file {File}", file);
+ _logger.LogError(ex, "Error extracting from gz file {File}", originalUrl);
}
}
-
- return file;
- }
-
- private string ExtractFirstFileFromGz(string file)
- {
- using (var stream = File.OpenRead(file))
- {
- string tempFolder = GetTempFolderPath(stream);
- Directory.CreateDirectory(tempFolder);
-
- _zipClient.ExtractFirstFileFromGz(stream, tempFolder, "data.xml");
-
- return tempFolder;
- }
- }
-
- private string ExtractGz(string file)
- {
- using (var stream = File.OpenRead(file))
+ else
{
- string tempFolder = GetTempFolderPath(stream);
- Directory.CreateDirectory(tempFolder);
-
- _zipClient.ExtractAllFromGz(stream, tempFolder, true);
-
- return tempFolder;
+ await using var fileStream = new FileStream(file, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.CopyToBufferSize, FileOptions.Asynchronous);
+ await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
}
- }
- private string GetTempFolderPath(Stream stream)
- {
-#pragma warning disable CA5351
- using var md5 = MD5.Create();
-#pragma warning restore CA5351
- var checksum = Convert.ToHexString(md5.ComputeHash(stream));
- stream.Position = 0;
- return Path.Combine(_config.ApplicationPaths.TempDirectory, checksum);
- }
-
- private string FindXmlFile(string directory)
- {
- return _fileSystem.GetFiles(directory, true)
- .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
- .Select(i => i.FullName)
- .FirstOrDefault();
+ return file;
}
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)