瀏覽代碼

Use System.IO.Compression instead of SharpCompress for gzips

adrez99 3 年之前
父節點
當前提交
72893da4d8

+ 0 - 3
Emby.Server.Implementations/ApplicationHost.cs

@@ -22,7 +22,6 @@ using Emby.Drawing;
 using Emby.Naming.Common;
 using Emby.Notifications;
 using Emby.Photos;
-using Emby.Server.Implementations.Archiving;
 using Emby.Server.Implementations.Channels;
 using Emby.Server.Implementations.Collections;
 using Emby.Server.Implementations.Configuration;
@@ -558,8 +557,6 @@ namespace Emby.Server.Implementations
 
             serviceCollection.AddSingleton<IInstallationManager, InstallationManager>();
 
-            serviceCollection.AddSingleton<IZipClient, ZipClient>();
-
             serviceCollection.AddSingleton<IServerApplicationHost>(this);
             serviceCollection.AddSingleton(ApplicationPaths);
 

+ 0 - 46
Emby.Server.Implementations/Archiving/ZipClient.cs

@@ -1,46 +0,0 @@
-using System.IO;
-using MediaBrowser.Model.IO;
-using SharpCompress.Common;
-using SharpCompress.Readers;
-using SharpCompress.Readers.GZip;
-
-namespace Emby.Server.Implementations.Archiving
-{
-    /// <summary>
-    /// Class DotNetZipClient.
-    /// </summary>
-    public class ZipClient : IZipClient
-    {
-        /// <inheritdoc />
-        public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
-        {
-            using var reader = GZipReader.Open(source);
-            var options = new ExtractionOptions
-            {
-                ExtractFullPath = true,
-                Overwrite = overwriteExistingFiles
-            };
-
-            Directory.CreateDirectory(targetPath);
-            reader.WriteAllToDirectory(targetPath, options);
-        }
-
-        /// <inheritdoc />
-        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));
-            }
-        }
-    }
-}

+ 0 - 1
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -32,7 +32,6 @@
     <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.5" />
     <PackageReference Include="Mono.Nat" Version="3.0.3" />
     <PackageReference Include="prometheus-net.DotNetRuntime" Version="4.2.4" />
-    <PackageReference Include="sharpcompress" Version="0.31.0" />
     <PackageReference Include="SQLitePCL.pretty.netstandard" Version="3.1.0" />
     <PackageReference Include="DotNet.Glob" Version="3.1.3" />
   </ItemGroup>

+ 30 - 77
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)

+ 0 - 16
MediaBrowser.Model/IO/IZipClient.cs

@@ -1,16 +0,0 @@
-#pragma warning disable CS1591
-
-using System.IO;
-
-namespace MediaBrowser.Model.IO
-{
-    /// <summary>
-    /// Interface IZipClient.
-    /// </summary>
-    public interface IZipClient
-    {
-        void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles);
-
-        void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName);
-    }
-}