mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-03 14:28:46 +01:00
Merge remote-tracking branch 'upstream/api-migration' into api-scheduled-tasks
This commit is contained in:
@@ -48,12 +48,6 @@ namespace MediaBrowser.Common
|
||||
/// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
|
||||
bool CanSelfRestart { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version class of the system.
|
||||
/// </summary>
|
||||
/// <value><see cref="PackageVersionClass.Release" /> or <see cref="PackageVersionClass.Beta" />.</value>
|
||||
PackageVersionClass SystemUpdateLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the application version.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Common.Json.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter for Dictionaries without string key.
|
||||
/// TODO This can be removed when System.Text.Json supports Dictionaries with non-string keys.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Type of key.</typeparam>
|
||||
/// <typeparam name="TValue">Type of value.</typeparam>
|
||||
internal sealed class JsonNonStringKeyDictionaryConverter<TKey, TValue> : JsonConverter<IDictionary<TKey, TValue>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Read JSON.
|
||||
/// </summary>
|
||||
/// <param name="reader">The Utf8JsonReader.</param>
|
||||
/// <param name="typeToConvert">The type to convert.</param>
|
||||
/// <param name="options">The json serializer options.</param>
|
||||
/// <returns>Typed dictionary.</returns>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public override IDictionary<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var convertedType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeToConvert.GenericTypeArguments[1]);
|
||||
var value = JsonSerializer.Deserialize(ref reader, convertedType, options);
|
||||
var instance = (Dictionary<TKey, TValue>)Activator.CreateInstance(
|
||||
typeToConvert,
|
||||
BindingFlags.Instance | BindingFlags.Public,
|
||||
null,
|
||||
null,
|
||||
CultureInfo.CurrentCulture);
|
||||
var enumerator = (IEnumerator)convertedType.GetMethod("GetEnumerator")!.Invoke(value, null);
|
||||
var parse = typeof(TKey).GetMethod(
|
||||
"Parse",
|
||||
0,
|
||||
BindingFlags.Public | BindingFlags.Static,
|
||||
null,
|
||||
CallingConventions.Any,
|
||||
new[] { typeof(string) },
|
||||
null);
|
||||
if (parse == null)
|
||||
{
|
||||
throw new NotSupportedException($"{typeof(TKey)} as TKey in IDictionary<TKey, TValue> is not supported.");
|
||||
}
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var element = (KeyValuePair<string?, TValue>)enumerator.Current;
|
||||
instance.Add((TKey)parse.Invoke(null, new[] { (object?) element.Key }), element.Value);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write dictionary as Json.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Utf8JsonWriter.</param>
|
||||
/// <param name="value">The dictionary value.</param>
|
||||
/// <param name="options">The Json serializer options.</param>
|
||||
public override void Write(Utf8JsonWriter writer, IDictionary<TKey, TValue> value, JsonSerializerOptions options)
|
||||
{
|
||||
var convertedDictionary = new Dictionary<string?, TValue>(value.Count);
|
||||
foreach (var (k, v) in value)
|
||||
{
|
||||
convertedDictionary[k?.ToString()] = v;
|
||||
}
|
||||
JsonSerializer.Serialize(writer, convertedDictionary, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Common.Json.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// https://github.com/dotnet/runtime/issues/30524#issuecomment-524619972.
|
||||
/// TODO This can be removed when System.Text.Json supports Dictionaries with non-string keys.
|
||||
/// </summary>
|
||||
internal sealed class JsonNonStringKeyDictionaryConverterFactory : JsonConverterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Only convert objects that implement IDictionary and do not have string keys.
|
||||
/// </summary>
|
||||
/// <param name="typeToConvert">Type convert.</param>
|
||||
/// <returns>Conversion ability.</returns>
|
||||
public override bool CanConvert(Type typeToConvert)
|
||||
{
|
||||
|
||||
if (!typeToConvert.IsGenericType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let built in converter handle string keys
|
||||
if (typeToConvert.GenericTypeArguments[0] == typeof(string))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only support objects that implement IDictionary
|
||||
return typeToConvert.GetInterface(nameof(IDictionary)) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create converter for generic dictionary type.
|
||||
/// </summary>
|
||||
/// <param name="typeToConvert">Type to convert.</param>
|
||||
/// <param name="options">Json serializer options.</param>
|
||||
/// <returns>JsonConverter for given type.</returns>
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var converterType = typeof(JsonNonStringKeyDictionaryConverter<,>)
|
||||
.MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1]);
|
||||
var converter = (JsonConverter)Activator.CreateInstance(
|
||||
converterType,
|
||||
BindingFlags.Instance | BindingFlags.Public,
|
||||
null,
|
||||
null,
|
||||
CultureInfo.CurrentCulture);
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,16 @@ namespace MediaBrowser.Common.Json
|
||||
/// <summary>
|
||||
/// Gets the default <see cref="JsonSerializerOptions" /> options.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When changing these options, update
|
||||
/// Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
|
||||
/// -> AddJellyfinApi
|
||||
/// -> AddJsonOptions
|
||||
/// </remarks>
|
||||
/// <returns>The default <see cref="JsonSerializerOptions" /> options.</returns>
|
||||
public static JsonSerializerOptions GetOptions()
|
||||
{
|
||||
var options = new JsonSerializerOptions()
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
ReadCommentHandling = JsonCommentHandling.Disallow,
|
||||
WriteIndented = false
|
||||
@@ -23,9 +29,35 @@ namespace MediaBrowser.Common.Json
|
||||
|
||||
options.Converters.Add(new JsonGuidConverter());
|
||||
options.Converters.Add(new JsonStringEnumConverter());
|
||||
options.Converters.Add(new JsonInt64Converter());
|
||||
options.Converters.Add(new JsonNonStringKeyDictionaryConverterFactory());
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets CamelCase json options.
|
||||
/// </summary>
|
||||
public static JsonSerializerOptions CamelCase
|
||||
{
|
||||
get
|
||||
{
|
||||
var options = GetOptions();
|
||||
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets PascalCase json options.
|
||||
/// </summary>
|
||||
public static JsonSerializerOptions PascalCase
|
||||
{
|
||||
get
|
||||
{
|
||||
var options = GetOptions();
|
||||
options.PropertyNamingPolicy = null;
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace MediaBrowser.Common.Plugins
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when just before the plugin is uninstalled from the server.
|
||||
/// Called just before the plugin is uninstalled from the server.
|
||||
/// </summary>
|
||||
public virtual void OnUninstalling()
|
||||
{
|
||||
@@ -101,7 +101,7 @@ namespace MediaBrowser.Common.Plugins
|
||||
private readonly object _configurationSyncLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// The save lock.
|
||||
/// The configuration save lock.
|
||||
/// </summary>
|
||||
private readonly object _configurationSaveLock = new object();
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace MediaBrowser.Common.Plugins
|
||||
protected string AssemblyFileName => Path.GetFileName(AssemblyFilePath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the plugin's configuration.
|
||||
/// Gets or sets the plugin configuration.
|
||||
/// </summary>
|
||||
/// <value>The configuration.</value>
|
||||
public TConfigurationType Configuration
|
||||
@@ -186,7 +186,7 @@ namespace MediaBrowser.Common.Plugins
|
||||
public string ConfigurationFilePath => Path.Combine(ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's configuration.
|
||||
/// Gets the plugin configuration.
|
||||
/// </summary>
|
||||
/// <value>The configuration.</value>
|
||||
BasePluginConfiguration IHasPluginConfiguration.Configuration => Configuration;
|
||||
|
||||
@@ -28,12 +28,12 @@ namespace MediaBrowser.Common.Updates
|
||||
/// <summary>
|
||||
/// Occurs when a plugin is updated.
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<(IPlugin, PackageVersionInfo)>> PluginUpdated;
|
||||
event EventHandler<GenericEventArgs<(IPlugin, VersionInfo)>> PluginUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a plugin is installed.
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<PackageVersionInfo>> PluginInstalled;
|
||||
event EventHandler<GenericEventArgs<VersionInfo>> PluginInstalled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the completed installations.
|
||||
@@ -64,12 +64,10 @@ namespace MediaBrowser.Common.Updates
|
||||
/// </summary>
|
||||
/// <param name="availableVersions">The available version of the plugin.</param>
|
||||
/// <param name="minVersion">The minimum required version of the plugin.</param>
|
||||
/// <param name="classification">The classification of updates.</param>
|
||||
/// <returns>All compatible versions ordered from newest to oldest.</returns>
|
||||
IEnumerable<PackageVersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<PackageVersionInfo> availableVersions,
|
||||
Version minVersion = null,
|
||||
PackageVersionClass classification = PackageVersionClass.Release);
|
||||
IEnumerable<VersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<VersionInfo> availableVersions,
|
||||
Version minVersion = null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all compatible versions ordered from newest to oldest.
|
||||
@@ -78,21 +76,19 @@ namespace MediaBrowser.Common.Updates
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="guid">The guid of the plugin.</param>
|
||||
/// <param name="minVersion">The minimum required version of the plugin.</param>
|
||||
/// <param name="classification">The classification.</param>
|
||||
/// <returns>All compatible versions ordered from newest to oldest.</returns>
|
||||
IEnumerable<PackageVersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<VersionInfo> GetCompatibleVersions(
|
||||
IEnumerable<PackageInfo> availablePackages,
|
||||
string name = null,
|
||||
Guid guid = default,
|
||||
Version minVersion = null,
|
||||
PackageVersionClass classification = PackageVersionClass.Release);
|
||||
Version minVersion = null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the available plugin updates.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The available plugin updates.</returns>
|
||||
Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<VersionInfo>> GetAvailablePluginUpdates(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Installs the package.
|
||||
@@ -100,7 +96,7 @@ namespace MediaBrowser.Common.Updates
|
||||
/// <param name="package">The package.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns><see cref="Task" />.</returns>
|
||||
Task InstallPackage(PackageVersionInfo package, CancellationToken cancellationToken = default);
|
||||
Task InstallPackage(VersionInfo package, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Uninstalls a plugin.
|
||||
|
||||
@@ -8,6 +8,6 @@ namespace MediaBrowser.Common.Updates
|
||||
{
|
||||
public InstallationInfo InstallationInfo { get; set; }
|
||||
|
||||
public PackageVersionInfo PackageVersionInfo { get; set; }
|
||||
public VersionInfo VersionInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user