handle plugin manifests automatically
This commit is contained in:
parent
76d66e0dee
commit
9caf311925
|
@ -1,12 +1,13 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Json;
|
||||
|
@ -14,6 +15,7 @@ using MediaBrowser.Common.Json.Converters;
|
|||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Updates;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
@ -332,34 +334,54 @@ namespace Emby.Server.Implementations.Plugins
|
|||
ChangePluginState(plugin, PluginStatus.Malfunctioned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the manifest back to disk.
|
||||
/// </summary>
|
||||
/// <param name="manifest">The <see cref="PluginManifest"/> to save.</param>
|
||||
/// <param name="path">The path where to save the manifest.</param>
|
||||
/// <returns>True if successful.</returns>
|
||||
/// <inheritdoc/>
|
||||
public bool SaveManifest(PluginManifest manifest, string path)
|
||||
{
|
||||
if (manifest == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var data = JsonSerializer.Serialize(manifest, _jsonOptions);
|
||||
File.WriteAllText(Path.Combine(path, "meta.json"), data);
|
||||
return true;
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception e)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
_logger.LogWarning(e, "Unable to save plugin manifest. {Path}", path);
|
||||
_logger.LogWarning(e, "Unable to save plugin manifest due to invalid value. {Path}", path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool GenerateManifest(PackageInfo packageInfo, Version version, string path)
|
||||
{
|
||||
var versionInfo = packageInfo.Versions.First(v => v.Version == version.ToString());
|
||||
var url = packageInfo.ImageUrl ?? string.Empty;
|
||||
var imageFilename = url.Substring(url.LastIndexOf('/') + 1, url.Length);
|
||||
|
||||
using (var client = new WebClient())
|
||||
{
|
||||
client.DownloadFile(url, Path.Join(path, imageFilename));
|
||||
}
|
||||
|
||||
var manifest = new PluginManifest
|
||||
{
|
||||
Category = packageInfo.Category,
|
||||
Changelog = versionInfo.Changelog ?? string.Empty,
|
||||
Description = packageInfo.Description,
|
||||
Id = new Guid(packageInfo.Id),
|
||||
Name = packageInfo.Name,
|
||||
Overview = packageInfo.Overview,
|
||||
Owner = packageInfo.Owner,
|
||||
TargetAbi = versionInfo.TargetAbi ?? string.Empty,
|
||||
Timestamp = DateTime.Parse(versionInfo.Timestamp ?? string.Empty),
|
||||
Version = versionInfo.Version,
|
||||
Status = PluginStatus.Active,
|
||||
AutoUpdate = true,
|
||||
ImagePath = Path.Join(path, imageFilename)
|
||||
};
|
||||
|
||||
return SaveManifest(manifest, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes a plugin's load status.
|
||||
/// </summary>
|
||||
|
@ -410,7 +432,7 @@ namespace Emby.Server.Implementations.Plugins
|
|||
if (plugin == null)
|
||||
{
|
||||
// Create a dummy record for the providers.
|
||||
// TODO: remove this code, if all provided have been released as separate plugins.
|
||||
// TODO: remove this code once all provided have been released as separate plugins.
|
||||
plugin = new LocalPlugin(
|
||||
instance.AssemblyFilePath,
|
||||
true,
|
||||
|
|
|
@ -192,17 +192,12 @@ namespace Emby.Server.Implementations.Updates
|
|||
var version = package.Versions[i];
|
||||
|
||||
var plugin = _pluginManager.GetPlugin(packageGuid, version.VersionNumber);
|
||||
// Update the manifests, if anything changes.
|
||||
if (plugin != null)
|
||||
{
|
||||
if (!string.Equals(plugin.Manifest.TargetAbi, version.TargetAbi, StringComparison.Ordinal))
|
||||
{
|
||||
plugin.Manifest.TargetAbi = version.TargetAbi ?? string.Empty;
|
||||
_pluginManager.SaveManifest(plugin.Manifest, plugin.Path);
|
||||
}
|
||||
_pluginManager.GenerateManifest(package, version.VersionNumber, plugin.Path);
|
||||
}
|
||||
|
||||
// Remove versions with a target abi that is greater then the current application version.
|
||||
// Remove versions with a target ABI greater then the current application version.
|
||||
if (Version.TryParse(version.TargetAbi, out var targetAbi) && _applicationHost.ApplicationVersion < targetAbi)
|
||||
{
|
||||
package.Versions.RemoveAt(i);
|
||||
|
@ -294,7 +289,8 @@ namespace Emby.Server.Implementations.Updates
|
|||
Name = package.Name,
|
||||
Version = v.VersionNumber,
|
||||
SourceUrl = v.SourceUrl,
|
||||
Checksum = v.Checksum
|
||||
Checksum = v.Checksum,
|
||||
PackageInfo = package
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -571,24 +567,16 @@ namespace Emby.Server.Implementations.Updates
|
|||
|
||||
stream.Position = 0;
|
||||
_zipClient.ExtractAllFromZip(stream, targetDir, true);
|
||||
_pluginManager.GenerateManifest(package.PackageInfo, package.Version, targetDir);
|
||||
_pluginManager.ImportPluginFrom(targetDir);
|
||||
}
|
||||
|
||||
private async Task<bool> InstallPackageInternal(InstallationInfo package, CancellationToken cancellationToken)
|
||||
{
|
||||
// Set last update time if we were installed before
|
||||
LocalPlugin? plugin = _pluginManager.Plugins.FirstOrDefault(p => p.Id.Equals(package.Id) && p.Version.Equals(package.Version))
|
||||
?? _pluginManager.Plugins.FirstOrDefault(p => p.Name.Equals(package.Name, StringComparison.OrdinalIgnoreCase) && p.Version.Equals(package.Version));
|
||||
if (plugin != null)
|
||||
{
|
||||
plugin.Manifest.Timestamp = DateTime.UtcNow;
|
||||
_pluginManager.SaveManifest(plugin.Manifest, plugin.Path);
|
||||
}
|
||||
|
||||
// Do the install
|
||||
await PerformPackageInstallation(package, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Do plugin-specific processing
|
||||
_logger.LogInformation(plugin == null ? "New plugin installed: {PluginName} {PluginVersion}" : "Plugin updated: {PluginName} {PluginVersion}", package.Name, package.Version);
|
||||
|
||||
return plugin != null;
|
||||
|
|
|
@ -4,6 +4,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Updates;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace MediaBrowser.Common.Plugins
|
||||
|
@ -44,6 +45,15 @@ namespace MediaBrowser.Common.Plugins
|
|||
/// <returns>True if successful.</returns>
|
||||
bool SaveManifest(PluginManifest manifest, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a manifest from repository data.
|
||||
/// </summary>
|
||||
/// <param name="packageInfo">The <see cref="PackageInfo"/> used to generate a manifest.</param>
|
||||
/// <param name="version">Version to be installed.</param>
|
||||
/// <param name="path">The path where to save the manifest.</param>
|
||||
/// <returns>True if successful.</returns>
|
||||
bool GenerateManifest(PackageInfo packageInfo, Version version, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Imports plugin details from a folder.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
|
@ -45,5 +46,11 @@ namespace MediaBrowser.Model.Updates
|
|||
/// </summary>
|
||||
/// <value>The checksum.</value>
|
||||
public string Checksum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets package information for the installation.
|
||||
/// </summary>
|
||||
/// <value>The package information.</value>
|
||||
public PackageInfo PackageInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user