diff options
Diffstat (limited to 'MediaBrowser.Common.Implementations/Updates/PackageManager.cs')
| -rw-r--r-- | MediaBrowser.Common.Implementations/Updates/PackageManager.cs | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/MediaBrowser.Common.Implementations/Updates/PackageManager.cs b/MediaBrowser.Common.Implementations/Updates/PackageManager.cs index 3f09615e7..a9335dce0 100644 --- a/MediaBrowser.Common.Implementations/Updates/PackageManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/PackageManager.cs @@ -1,12 +1,16 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Updates; @@ -39,9 +43,62 @@ namespace MediaBrowser.Common.Implementations.Updates } - public Task InstallPackage(PackageVersionInfo package, CancellationToken cancellationToken) + public async Task InstallPackage(IHttpClient client, ILogger logger, ResourcePool resourcePool, IProgress<double> progress, IZipClient zipClient, IApplicationPaths appPaths, PackageVersionInfo package, CancellationToken cancellationToken) { - throw new NotImplementedException(); + // Target based on if it is an archive or single assembly + // zip archives are assumed to contain directory structures relative to our ProgramDataPath + var isArchive = string.Equals(Path.GetExtension(package.sourceUrl), ".zip", StringComparison.OrdinalIgnoreCase); + var target = isArchive ? appPaths.ProgramDataPath : Path.Combine(appPaths.PluginsPath, package.targetFilename); + + // Download to temporary file so that, if interrupted, it won't destroy the existing installation + var tempFile = await client.GetTempFile(package.sourceUrl, resourcePool.Mb, cancellationToken, progress).ConfigureAwait(false); + + cancellationToken.ThrowIfCancellationRequested(); + + // Validate with a checksum + if (package.checksum != Guid.Empty) // support for legacy uploads for now + { + using (var crypto = new MD5CryptoServiceProvider()) + using (var stream = new BufferedStream(File.OpenRead(tempFile), 100000)) + { + var check = Guid.Parse(BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", String.Empty)); + if (check != package.checksum) + { + throw new ApplicationException(string.Format("Download validation failed for {0}. Probably corrupted during transfer.", package.name)); + } + } + } + + cancellationToken.ThrowIfCancellationRequested(); + + // Success - move it to the real target based on type + if (isArchive) + { + try + { + zipClient.ExtractAll(tempFile, target, true); + } + catch (IOException e) + { + logger.ErrorException("Error attempting to extract archive from {0} to {1}", e, tempFile, target); + throw; + } + + } + else + { + try + { + File.Copy(tempFile, target, true); + File.Delete(tempFile); + } + catch (IOException e) + { + logger.ErrorException("Error attempting to move file from {0} to {1}", e, tempFile, target); + throw; + } + } + } } } |
