aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMBR-0001 <55142207+MBR-0001@users.noreply.github.com>2026-03-01 05:57:22 -0500
committerBond_009 <bond.009@outlook.com>2026-03-01 05:57:22 -0500
commitd2f733f9a4d91a09ab887d410b2778a916f27c7d (patch)
treebdc9361df6307eb3062b82003f74b91d810e8152
parentd55f082579933cad112a6fed6caa6130bf0d838c (diff)
Backport pull request #16204 from jellyfin/release-10.11.z
Fix broken library subtitle download settings Original-merge: ca57166e95858f9c767b6279df6e5abfe9212700 Merged-by: Bond-009 <bond.009@outlook.com> Backported-by: Bond_009 <bond.009@outlook.com>
-rw-r--r--Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs106
1 files changed, 106 insertions, 0 deletions
diff --git a/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs b/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs
new file mode 100644
index 0000000000..e82123e5ac
--- /dev/null
+++ b/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Server.ServerSetupApp;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Globalization;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Server.Migrations.Routines;
+
+/// <summary>
+/// Migration to fix broken library subtitle download languages.
+/// </summary>
+[JellyfinMigration("2026-02-06T20:00:00", nameof(FixLibrarySubtitleDownloadLanguages))]
+internal class FixLibrarySubtitleDownloadLanguages : IAsyncMigrationRoutine
+{
+ private readonly ILocalizationManager _localizationManager;
+ private readonly ILibraryManager _libraryManager;
+ private readonly ILogger _logger;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FixLibrarySubtitleDownloadLanguages"/> class.
+ /// </summary>
+ /// <param name="localizationManager">The Localization manager.</param>
+ /// <param name="startupLogger">The startup logger for Startup UI integration.</param>
+ /// <param name="libraryManager">The Library manager.</param>
+ /// <param name="logger">The logger.</param>
+ public FixLibrarySubtitleDownloadLanguages(
+ ILocalizationManager localizationManager,
+ IStartupLogger<FixLibrarySubtitleDownloadLanguages> startupLogger,
+ ILibraryManager libraryManager,
+ ILogger<FixLibrarySubtitleDownloadLanguages> logger)
+ {
+ _localizationManager = localizationManager;
+ _libraryManager = libraryManager;
+ _logger = startupLogger.With(logger);
+ }
+
+ /// <inheritdoc />
+ public Task PerformAsync(CancellationToken cancellationToken)
+ {
+ _logger.LogInformation("Starting to fix library subtitle download languages.");
+
+ var virtualFolders = _libraryManager.GetVirtualFolders(false);
+
+ foreach (var virtualFolder in virtualFolders)
+ {
+ var options = virtualFolder.LibraryOptions;
+ if (options.SubtitleDownloadLanguages is null || options.SubtitleDownloadLanguages.Length == 0)
+ {
+ continue;
+ }
+
+ // Some virtual folders don't have a proper item id.
+ if (!Guid.TryParse(virtualFolder.ItemId, out var folderId))
+ {
+ continue;
+ }
+
+ var collectionFolder = _libraryManager.GetItemById<CollectionFolder>(folderId);
+ if (collectionFolder is null)
+ {
+ _logger.LogWarning("Could not find collection folder for virtual folder '{LibraryName}' with id '{FolderId}'. Skipping.", virtualFolder.Name, folderId);
+ continue;
+ }
+
+ var fixedLanguages = new List<string>();
+
+ foreach (var language in options.SubtitleDownloadLanguages)
+ {
+ var foundLanguage = _localizationManager.FindLanguageInfo(language)?.ThreeLetterISOLanguageName;
+ if (foundLanguage is not null)
+ {
+ // Converted ISO 639-2/B to T (ger to deu)
+ if (!string.Equals(foundLanguage, language, StringComparison.OrdinalIgnoreCase))
+ {
+ _logger.LogInformation("Converted '{Language}' to '{ResolvedLanguage}' in library '{LibraryName}'.", language, foundLanguage, virtualFolder.Name);
+ }
+
+ if (fixedLanguages.Contains(foundLanguage, StringComparer.OrdinalIgnoreCase))
+ {
+ _logger.LogInformation("Language '{Language}' already exists for library '{LibraryName}'. Skipping duplicate.", foundLanguage, virtualFolder.Name);
+ continue;
+ }
+
+ fixedLanguages.Add(foundLanguage);
+ }
+ else
+ {
+ _logger.LogInformation("Could not resolve language '{Language}' in library '{LibraryName}'. Skipping.", language, virtualFolder.Name);
+ }
+ }
+
+ options.SubtitleDownloadLanguages = [.. fixedLanguages];
+ collectionFolder.UpdateLibraryOptions(options);
+ }
+
+ _logger.LogInformation("Library subtitle download languages fixed.");
+
+ return Task.CompletedTask;
+ }
+}