diff options
Diffstat (limited to 'Emby.Server.Implementations/Updates/InstallationManager.cs')
| -rw-r--r-- | Emby.Server.Implementations/Updates/InstallationManager.cs | 98 |
1 files changed, 84 insertions, 14 deletions
diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 851e7bd68..7a071c071 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -93,17 +93,29 @@ namespace Emby.Server.Implementations.Updates public IEnumerable<InstallationInfo> CompletedInstallations => _completedInstallationsInternal; /// <inheritdoc /> - public async Task<IReadOnlyList<PackageInfo>> GetPackages(string manifest, CancellationToken cancellationToken = default) + public async Task<IList<PackageInfo>> GetPackages(string manifestName, string manifest, CancellationToken cancellationToken = default) { try { using var response = await _httpClientFactory.CreateClient(NamedClient.Default) - .GetAsync(manifest, cancellationToken).ConfigureAwait(false); + .GetAsync(new Uri(manifest), cancellationToken).ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); try { - return await _jsonSerializer.DeserializeFromStreamAsync<IReadOnlyList<PackageInfo>>(stream).ConfigureAwait(false); + var package = await _jsonSerializer.DeserializeFromStreamAsync<IList<PackageInfo>>(stream).ConfigureAwait(false); + + // Store the repository and repository url with each version, as they may be spread apart. + foreach (var entry in package) + { + foreach (var ver in entry.versions) + { + ver.repositoryName = manifestName; + ver.repositoryUrl = manifest; + } + } + + return package; } catch (SerializationException ex) { @@ -123,17 +135,69 @@ namespace Emby.Server.Implementations.Updates } } + private static void MergeSort(IList<VersionInfo> source, IList<VersionInfo> dest) + { + int sLength = source.Count - 1; + int dLength = dest.Count; + int s = 0, d = 0; + var sourceVersion = source[0].VersionNumber; + var destVersion = dest[0].VersionNumber; + + while (d < dLength) + { + if (sourceVersion.CompareTo(destVersion) >= 0) + { + if (s < sLength) + { + sourceVersion = source[++s].VersionNumber; + } + else + { + // Append all of destination to the end of source. + while (d < dLength) + { + source.Add(dest[d++]); + } + + break; + } + } + else + { + source.Insert(s++, dest[d++]); + if (d >= dLength) + { + break; + } + + sLength++; + destVersion = dest[d].VersionNumber; + } + } + } + /// <inheritdoc /> public async Task<IReadOnlyList<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken = default) { var result = new List<PackageInfo>(); foreach (RepositoryInfo repository in _config.Configuration.PluginRepositories) { - foreach (var package in await GetPackages(repository.Url, cancellationToken).ConfigureAwait(true)) + if (repository.Enabled) { - package.repositoryName = repository.Name; - package.repositoryUrl = repository.Url; - result.Add(package); + // Where repositories have the same content, the details of the first is taken. + foreach (var package in await GetPackages(repository.Name, repository.Url, cancellationToken).ConfigureAwait(true)) + { + var existing = FilterPackages(result, package.name, Guid.Parse(package.guid)).FirstOrDefault(); + if (existing != null) + { + // Assumption is both lists are ordered, so slot these into the correct place. + MergeSort(existing.versions, package.versions); + } + else + { + result.Add(package); + } + } } } @@ -144,7 +208,8 @@ namespace Emby.Server.Implementations.Updates public IEnumerable<PackageInfo> FilterPackages( IEnumerable<PackageInfo> availablePackages, string name = null, - Guid guid = default) + Guid guid = default, + Version specificVersion = null) { if (name != null) { @@ -156,6 +221,11 @@ namespace Emby.Server.Implementations.Updates availablePackages = availablePackages.Where(x => Guid.Parse(x.guid) == guid); } + if (specificVersion != null) + { + availablePackages = availablePackages.Where(x => x.versions.Where(y => y.VersionNumber.Equals(specificVersion)).Any()); + } + return availablePackages; } @@ -167,7 +237,7 @@ namespace Emby.Server.Implementations.Updates Version minVersion = null, Version specificVersion = null) { - var package = FilterPackages(availablePackages, name, guid).FirstOrDefault(); + var package = FilterPackages(availablePackages, name, guid, specificVersion).FirstOrDefault(); // Package not found in repository if (package == null) @@ -181,21 +251,21 @@ namespace Emby.Server.Implementations.Updates if (specificVersion != null) { - availableVersions = availableVersions.Where(x => new Version(x.version) == specificVersion); + availableVersions = availableVersions.Where(x => x.VersionNumber.Equals(specificVersion)); } else if (minVersion != null) { - availableVersions = availableVersions.Where(x => new Version(x.version) >= minVersion); + availableVersions = availableVersions.Where(x => x.VersionNumber >= minVersion); } - foreach (var v in availableVersions.OrderByDescending(x => x.version)) + foreach (var v in availableVersions.OrderByDescending(x => x.VersionNumber)) { yield return new InstallationInfo { Changelog = v.changelog, Guid = new Guid(package.guid), Name = package.name, - Version = new Version(v.version), + Version = v.VersionNumber, SourceUrl = v.sourceUrl, Checksum = v.checksum }; @@ -333,7 +403,7 @@ namespace Emby.Server.Implementations.Updates string targetDir = Path.Combine(_appPaths.PluginsPath, package.Name); using var response = await _httpClientFactory.CreateClient(NamedClient.Default) - .GetAsync(package.SourceUrl, cancellationToken).ConfigureAwait(false); + .GetAsync(new Uri(package.SourceUrl), cancellationToken).ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); // CA5351: Do Not Use Broken Cryptographic Algorithms |
