aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs5
-rw-r--r--Emby.Server.Implementations/Localization/Core/bg-BG.json22
-rw-r--r--Jellyfin.Api/Attributes/AcceptsFileAttribute.cs28
-rw-r--r--Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs18
-rw-r--r--Jellyfin.Api/Controllers/ImageController.cs4
-rw-r--r--Jellyfin.Api/Controllers/PluginsController.cs4
-rw-r--r--Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs1
-rw-r--r--Jellyfin.Server/Filters/FileRequestFilter.cs43
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs7
9 files changed, 106 insertions, 26 deletions
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index e9e688fa6..60f82806f 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -79,11 +79,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
return new MusicArtist();
}
- if (_config.Configuration.EnableSimpleArtistDetection)
- {
- return null;
- }
-
// Avoid mis-identifying top folders
if (args.Parent.IsRoot)
{
diff --git a/Emby.Server.Implementations/Localization/Core/bg-BG.json b/Emby.Server.Implementations/Localization/Core/bg-BG.json
index 7ff30df71..9db3b50d9 100644
--- a/Emby.Server.Implementations/Localization/Core/bg-BG.json
+++ b/Emby.Server.Implementations/Localization/Core/bg-BG.json
@@ -55,26 +55,26 @@
"NotificationOptionPluginInstalled": "Приставката е инсталирана",
"NotificationOptionPluginUninstalled": "Приставката е деинсталирана",
"NotificationOptionPluginUpdateInstalled": "Обновлението на приставката е инсталирано",
- "NotificationOptionServerRestartRequired": "Нужно е повторно пускане на сървъра",
+ "NotificationOptionServerRestartRequired": "Сървърът трябва да се рестартира",
"NotificationOptionTaskFailed": "Грешка в планирана задача",
- "NotificationOptionUserLockedOut": "Потребителя е заключен",
+ "NotificationOptionUserLockedOut": "Потребителят е заключен",
"NotificationOptionVideoPlayback": "Възпроизвеждането на видео започна",
"NotificationOptionVideoPlaybackStopped": "Възпроизвеждането на видео е спряно",
"Photos": "Снимки",
"Playlists": "Списъци",
"Plugin": "Приставка",
- "PluginInstalledWithName": "{0} е инсталирано",
- "PluginUninstalledWithName": "{0} е деинсталирано",
- "PluginUpdatedWithName": "{0} е обновено",
+ "PluginInstalledWithName": "{0} е инсталиранa",
+ "PluginUninstalledWithName": "{0} е деинсталиранa",
+ "PluginUpdatedWithName": "{0} е обновенa",
"ProviderValue": "Доставчик: {0}",
"ScheduledTaskFailedWithName": "{0} се провали",
"ScheduledTaskStartedWithName": "{0} започна",
- "ServerNameNeedsToBeRestarted": "{0} е нужно да се рестартира",
+ "ServerNameNeedsToBeRestarted": "{0} трябва да се рестартира",
"Shows": "Сериали",
"Songs": "Песни",
"StartupEmbyServerIsLoading": "Сървърът зарежда. Моля, опитайте отново след малко.",
"SubtitleDownloadFailureForItem": "Неуспешно изтегляне на субтитри за {0}",
- "SubtitleDownloadFailureFromForItem": "Поднадписите за {1} от {0} не можаха да се изтеглят",
+ "SubtitleDownloadFailureFromForItem": "Субтитрите за {1} от {0} не можаха да бъдат изтеглени",
"Sync": "Синхронизиране",
"System": "Система",
"TvShows": "Телевизионни сериали",
@@ -92,12 +92,12 @@
"ValueHasBeenAddedToLibrary": "{0} беше добавен във Вашата библиотека",
"ValueSpecialEpisodeName": "Специални - {0}",
"VersionNumber": "Версия {0}",
- "TaskDownloadMissingSubtitlesDescription": "Търси Интернет за липсващи поднадписи, на база конфигурацията за мета-данни.",
- "TaskDownloadMissingSubtitles": "Изтегляне на липсващи поднадписи",
+ "TaskDownloadMissingSubtitlesDescription": "Търси Интернет за липсващи субтитри, на база конфигурацията за мета-данни.",
+ "TaskDownloadMissingSubtitles": "Изтегляне на липсващи субтитри",
"TaskRefreshChannelsDescription": "Обновява информацията за интернет канала.",
"TaskRefreshChannels": "Обновяване на Канали",
- "TaskCleanTranscodeDescription": "Изтрива прекодирани файлове по-стари от един ден.",
- "TaskCleanTranscode": "Изчиства директорията за прекодиране",
+ "TaskCleanTranscodeDescription": "Изтрива транскодирани файлове по-стари от един ден.",
+ "TaskCleanTranscode": "Изчиства директорията за транскодиране",
"TaskUpdatePluginsDescription": "Изтегля и инсталира актуализации за добавките, които са настроени за автоматична актуализация.",
"TaskUpdatePlugins": "Актуализира добавките",
"TaskRefreshPeopleDescription": "Актуализира мета-данните за артистите и режисьорите за Вашата медийна библиотека.",
diff --git a/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs b/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
new file mode 100644
index 000000000..49b6689cd
--- /dev/null
+++ b/Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Jellyfin.Api.Attributes
+{
+ /// <summary>
+ /// Internal produces image attribute.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method)]
+ public class AcceptsFileAttribute : Attribute
+ {
+ private readonly string[] _contentTypes;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AcceptsFileAttribute"/> class.
+ /// </summary>
+ /// <param name="contentTypes">Content types this endpoint produces.</param>
+ public AcceptsFileAttribute(params string[] contentTypes)
+ {
+ _contentTypes = contentTypes;
+ }
+
+ /// <summary>
+ /// Gets the configured content types.
+ /// </summary>
+ /// <returns>the configured content types.</returns>
+ public string[] GetContentTypes() => _contentTypes;
+ }
+}
diff --git a/Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs b/Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs
new file mode 100644
index 000000000..001f27409
--- /dev/null
+++ b/Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs
@@ -0,0 +1,18 @@
+namespace Jellyfin.Api.Attributes
+{
+ /// <summary>
+ /// Produces file attribute of "image/*".
+ /// </summary>
+ public class AcceptsImageFileAttribute : AcceptsFileAttribute
+ {
+ private const string ContentType = "image/*";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AcceptsImageFileAttribute"/> class.
+ /// </summary>
+ public AcceptsImageFileAttribute()
+ : base(ContentType)
+ {
+ }
+ }
+}
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index c606d327c..dc3634970 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -87,6 +87,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("Users/{userId}/Images/{imageType}")]
[Authorize(Policy = Policies.DefaultAuthorization)]
+ [AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
@@ -133,6 +134,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("Users/{userId}/Images/{imageType}/{index}")]
[Authorize(Policy = Policies.DefaultAuthorization)]
+ [AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
@@ -312,6 +314,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
[HttpPost("Items/{itemId}/Images/{imageType}")]
[Authorize(Policy = Policies.RequiresElevation)]
+ [AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
@@ -346,6 +349,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
[HttpPost("Items/{itemId}/Images/{imageType}/{imageIndex}")]
[Authorize(Policy = Policies.RequiresElevation)]
+ [AcceptsImageFile]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs
index b2e8bee91..a5aa9bfca 100644
--- a/Jellyfin.Api/Controllers/PluginsController.cs
+++ b/Jellyfin.Api/Controllers/PluginsController.cs
@@ -298,9 +298,7 @@ namespace Jellyfin.Api.Controllers
}
var imagePath = Path.Combine(plugin.Path, plugin.Manifest.ImagePath ?? string.Empty);
- if (((ServerConfiguration)_config.CommonConfiguration).DisablePluginImages
- || plugin.Manifest.ImagePath == null
- || !System.IO.File.Exists(imagePath))
+ if (plugin.Manifest.ImagePath == null || !System.IO.File.Exists(imagePath))
{
return NotFound();
}
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index da4cc267b..545937207 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -316,6 +316,7 @@ namespace Jellyfin.Server.Extensions
c.OperationFilter<SecurityRequirementsOperationFilter>();
c.OperationFilter<FileResponseFilter>();
+ c.OperationFilter<FileRequestFilter>();
c.OperationFilter<ParameterObsoleteFilter>();
c.DocumentFilter<WebsocketModelFilter>();
});
diff --git a/Jellyfin.Server/Filters/FileRequestFilter.cs b/Jellyfin.Server/Filters/FileRequestFilter.cs
new file mode 100644
index 000000000..69e10994f
--- /dev/null
+++ b/Jellyfin.Server/Filters/FileRequestFilter.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using Jellyfin.Api.Attributes;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+
+namespace Jellyfin.Server.Filters
+{
+ /// <inheritdoc />
+ public class FileRequestFilter : IOperationFilter
+ {
+ /// <inheritdoc />
+ public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ {
+ foreach (var attribute in context.ApiDescription.ActionDescriptor.EndpointMetadata)
+ {
+ if (attribute is AcceptsFileAttribute acceptsFileAttribute)
+ {
+ operation.RequestBody = GetRequestBody(acceptsFileAttribute.GetContentTypes());
+ break;
+ }
+ }
+ }
+
+ private static OpenApiRequestBody GetRequestBody(IEnumerable<string> contentTypes)
+ {
+ var body = new OpenApiRequestBody();
+ var mediaType = new OpenApiMediaType
+ {
+ Schema = new OpenApiSchema
+ {
+ Type = "string",
+ Format = "binary"
+ }
+ };
+ foreach (var contentType in contentTypes)
+ {
+ body.Content.Add(contentType, mediaType);
+ }
+
+ return body;
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 0f0ad0f9a..ba55a2ace 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -418,8 +418,6 @@ namespace MediaBrowser.Model.Configuration
public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>();
- public bool EnableSimpleArtistDetection { get; set; } = false;
-
public string[] UninstalledPlugins { get; set; } = Array.Empty<string>();
/// <summary>
@@ -461,10 +459,5 @@ namespace MediaBrowser.Model.Configuration
/// Gets or sets a value indicating whether older plugins should automatically be deleted from the plugin folder.
/// </summary>
public bool RemoveOldPlugins { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether plugin image should be disabled.
- /// </summary>
- public bool DisablePluginImages { get; set; }
}
}