2
0
Greenback 4 жил өмнө
parent
commit
18855a7884

+ 5 - 0
Emby.Server.Implementations/Plugins/PluginManifest.cs

@@ -56,5 +56,10 @@ namespace Emby.Server.Implementations.Plugins
         /// Gets or sets the Version number of the plugin.
         /// </summary>
         public string Version { get; set; }
+
+        /// <summary>
+        /// Gets or sets the Repository where the plugin originated.
+        /// </summary>
+        public string Repository { get; set; }
     }
 }

+ 84 - 14
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
                 };
@@ -322,7 +392,7 @@ namespace Emby.Server.Implementations.Updates
 
         private async Task PerformPackageInstallation(InstallationInfo package, CancellationToken cancellationToken)
         {
-            var extension = Path.GetExtension(package.SourceUrl);
+            var extension = Path.GetExtension(package.SourceUrl.ToString());
             if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase))
             {
                 _logger.LogError("Only zip packages are supported. {SourceUrl} is not a zip archive.", package.SourceUrl);

+ 1 - 1
Jellyfin.Api/Controllers/PackageController.cs

@@ -99,7 +99,7 @@ namespace Jellyfin.Api.Controllers
             var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false);
             if (!string.IsNullOrEmpty(repositoryUrl))
             {
-                packages = packages.Where(p => p.repositoryUrl.Equals(repositoryUrl, StringComparison.OrdinalIgnoreCase))
+                packages = packages.Where(p => p.versions.Where(q => q.repositoryUrl.Equals(repositoryUrl, StringComparison.OrdinalIgnoreCase)).Any())
                     .ToList();
             }
 

+ 3 - 3
Jellyfin.Server/Migrations/Routines/ReaddDefaultPluginRepository.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Model.Updates;
 
@@ -14,7 +14,7 @@ namespace Jellyfin.Server.Migrations.Routines
         private readonly RepositoryInfo _defaultRepositoryInfo = new RepositoryInfo
         {
             Name = "Jellyfin Stable",
-            Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json"
+            Url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json",
         };
 
         /// <summary>
@@ -46,4 +46,4 @@ namespace Jellyfin.Server.Migrations.Routines
             }
         }
     }
-}
+}

+ 5 - 2
MediaBrowser.Common/Updates/IInstallationManager.cs

@@ -19,10 +19,11 @@ namespace MediaBrowser.Common.Updates
         /// <summary>
         /// Parses a plugin manifest at the supplied URL.
         /// </summary>
+        /// <param name="manifestName">Name of the repository.</param>
         /// <param name="manifest">The URL to query.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{IReadOnlyList{PackageInfo}}.</returns>
-        Task<IReadOnlyList<PackageInfo>> GetPackages(string manifest, CancellationToken cancellationToken = default);
+        Task<IList<PackageInfo>> GetPackages(string manifestName, string manifest, CancellationToken cancellationToken = default);
 
         /// <summary>
         /// Gets all available packages.
@@ -37,11 +38,13 @@ namespace MediaBrowser.Common.Updates
         /// <param name="availablePackages">The available packages.</param>
         /// <param name="name">The name of the plugin.</param>
         /// <param name="guid">The id of the plugin.</param>
+        /// <param name="specificVersion">The version of the plugin.</param>
         /// <returns>All plugins matching the requirements.</returns>
         IEnumerable<PackageInfo> FilterPackages(
             IEnumerable<PackageInfo> availablePackages,
             string name = null,
-            Guid guid = default);
+            Guid guid = default,
+            Version specificVersion = null);
 
         /// <summary>
         /// Returns all compatible versions ordered from newest to oldest.

+ 1 - 11
MediaBrowser.Model/Updates/PackageInfo.cs

@@ -50,17 +50,7 @@ namespace MediaBrowser.Model.Updates
         /// Gets or sets the versions.
         /// </summary>
         /// <value>The versions.</value>
-        public IReadOnlyList<VersionInfo> versions { get; set; }
-
-        /// <summary>
-        /// Gets or sets the repository name.
-        /// </summary>
-        public string repositoryName { get; set; }
-
-        /// <summary>
-        /// Gets or sets the repository url.
-        /// </summary>
-        public string repositoryUrl { get; set; }
+        public IList<VersionInfo> versions { get; set; }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="PackageInfo"/> class.

+ 6 - 0
MediaBrowser.Model/Updates/RepositoryInfo.cs

@@ -16,5 +16,11 @@ namespace MediaBrowser.Model.Updates
         /// </summary>
         /// <value>The URL.</value>
         public string? Url { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the repository is enabled.
+        /// </summary>
+        /// <value><c>true</c> if enabled.</value>
+        public bool Enabled { get; set; } = true;
     }
 }

+ 29 - 1
MediaBrowser.Model/Updates/VersionInfo.cs

@@ -9,11 +9,29 @@ namespace MediaBrowser.Model.Updates
     /// </summary>
     public class VersionInfo
     {
+        private Version _version;
+
         /// <summary>
         /// Gets or sets the version.
         /// </summary>
         /// <value>The version.</value>
-        public string version { get; set; }
+        public string version
+        {
+            get
+            {
+                return _version == null ? string.Empty : _version.ToString();
+            }
+
+            set
+            {
+                _version = Version.Parse(value);
+            }
+        }
+
+        /// <summary>
+        /// Gets the version as a <see cref="Version"/>.
+        /// </summary>
+        public Version VersionNumber => _version;
 
         /// <summary>
         /// Gets or sets the changelog for this version.
@@ -44,5 +62,15 @@ namespace MediaBrowser.Model.Updates
         /// </summary>
         /// <value>The timestamp.</value>
         public string timestamp { get; set; }
+
+        /// <summary>
+        /// Gets or sets the repository name.
+        /// </summary>
+        public string repositoryName { get; set; }
+
+        /// <summary>
+        /// Gets or sets the repository url.
+        /// </summary>
+        public string repositoryUrl { get; set; }
     }
 }