From 2b7f64116309c7a33611334c1d08745c6c50d537 Mon Sep 17 00:00:00 2001 From: TheMelmacian <76712303+TheMelmacian@users.noreply.github.com> Date: Sun, 10 May 2026 11:10:56 +0200 Subject: feat: language filters for subtitles and audio --- .../DescendantQueryHelper.cs | 4 +++- .../MatchCriteria/HasMediaStreamType.cs | 23 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/DescendantQueryHelper.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/DescendantQueryHelper.cs index 43e6a8bc00..88a2c684ff 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/DescendantQueryHelper.cs +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/DescendantQueryHelper.cs @@ -111,7 +111,9 @@ public static class DescendantQueryHelper private static HashSet GetMatchingMediaStreamItemIds(JellyfinDbContext context, HasMediaStreamType criteria) { var query = context.MediaStreamInfos - .Where(ms => ms.StreamType == criteria.StreamType && ms.Language == criteria.Language); + .Where(ms => ms.StreamType == criteria.StreamType + && (criteria.Language.Contains(ms.Language) + || (criteria.Language.Contains("und") && string.IsNullOrEmpty(ms.Language)))); // und = undetermined if (criteria.IsExternal.HasValue) { diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/MatchCriteria/HasMediaStreamType.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/MatchCriteria/HasMediaStreamType.cs index 68f2ca2786..c1f6ab16a9 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/MatchCriteria/HasMediaStreamType.cs +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/MatchCriteria/HasMediaStreamType.cs @@ -1,3 +1,6 @@ +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter + +using System.Collections.Generic; using Jellyfin.Database.Implementations.Entities; namespace Jellyfin.Database.Implementations.MatchCriteria; @@ -6,9 +9,23 @@ namespace Jellyfin.Database.Implementations.MatchCriteria; /// Matches folders containing descendants with a specific media stream type and language. /// /// The type of media stream to match (Audio, Subtitle, etc.). -/// The language to match. +/// List of languages to match. /// If not null, filters by internal (false) or external (true) streams. Only applicable to subtitles. public sealed record HasMediaStreamType( MediaStreamTypeEntity StreamType, - string Language, - bool? IsExternal = null) : FolderMatchCriteria; + IReadOnlyCollection Language, + bool? IsExternal = null) : FolderMatchCriteria +{ + /// + /// Initializes a new instance of the class. + /// + /// The type of media stream to match (Audio, Subtitle, etc.). + /// The language to match. + /// If not null, filters by internal (false) or external (true) streams. Only applicable to subtitles. + public HasMediaStreamType( + MediaStreamTypeEntity StreamType, + string Language, + bool? IsExternal = null) : this(StreamType, [Language], IsExternal) + { + } +} -- cgit v1.2.3 From a47da0f1a3c68ed2a418416f24e3d7b0ed704ed0 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Tue, 12 May 2026 21:11:15 +0000 Subject: Update logging message for DbConcurrency messages --- .../Jellyfin.Database.Implementations/JellyfinDbContext.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs index f6fce7279a..83c15aa647 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs @@ -273,6 +273,11 @@ public class JellyfinDbContext(DbContextOptions options, ILog }).ConfigureAwait(false); return result; } + catch (DbUpdateConcurrencyException) + { + // a concurrency exception is supposed to be always handled by the invoker of the method, logging it here is only causing log bloat. + throw; + } catch (Exception e) { logger.LogError(e, "Error trying to save changes."); -- cgit v1.2.3 From 7a5181c3fd3aea8a9913fe07086970c39c9bc1c4 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 14 May 2026 07:46:43 +0200 Subject: Address review comments --- .../Localization/Core/en-US.json | 4 +- .../Localization/LocalizationManager.cs | 48 ++++++++++++---------- .../Channels/RefreshChannelsScheduledTask.cs | 4 +- 3 files changed, 30 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json index ff674bd0d0..856941c61a 100644 --- a/Emby.Server.Implementations/Localization/Core/en-US.json +++ b/Emby.Server.Implementations/Localization/Core/en-US.json @@ -93,8 +93,8 @@ "TaskUpdatePluginsDescription": "Downloads and installs updates for plugins that are configured to update automatically.", "TaskCleanTranscode": "Clean Transcode Directory", "TaskCleanTranscodeDescription": "Deletes transcode files more than one day old.", - "TasksRefreshChannels": "Refresh Channels", - "TasksRefreshChannelsDescription": "Refreshes internet channel information.", + "TaskRefreshChannels": "Refresh Channels", + "TaskRefreshChannelsDescription": "Refreshes internet channel information.", "TaskDownloadMissingLyrics": "Download missing lyrics", "TaskDownloadMissingLyricsDescription": "Downloads lyrics for songs", "TaskDownloadMissingSubtitles": "Download missing subtitles", diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 94aa933c92..0b0b300d30 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -77,22 +77,36 @@ namespace Emby.Server.Implementations.Localization var cultures = new List(); foreach (var option in _localizationOptions) { - // Resource files use underscores for some variants (e.g. es_419); - // CultureInfo only accepts hyphenated BCP-47 codes. - var code = option.Value.Replace('_', '-'); - try - { - cultures.Add(CultureInfo.GetCultureInfo(code)); - } - catch (CultureNotFoundException) + // Skip novelty codes (e.g. "pr" Pirate, "jbo" Lojban) that .NET cannot resolve. + if (TryGetCultureInfo(option.Value, out var cultureInfo)) { - // Skip novelty codes (e.g. "pr" Pirate, "jbo" Lojban) that .NET cannot resolve. + cultures.Add(cultureInfo); } } return cultures; } + /// + /// Resolves a Jellyfin resource culture code (which may use underscores, e.g. es_419) + /// to a . Returns for codes .NET cannot resolve. + /// + private static bool TryGetCultureInfo(string cultureCode, [NotNullWhen(true)] out CultureInfo? cultureInfo) + { + try + { + // Resource files use underscores for some variants (e.g. es_419); + // CultureInfo only accepts hyphenated BCP-47 codes. + cultureInfo = CultureInfo.GetCultureInfo(cultureCode.Replace('_', '-')); + return true; + } + catch (CultureNotFoundException) + { + cultureInfo = null; + return false; + } + } + private static void OnConfigurationUpdated(object? sender, EventArgs e) { if (sender is IServerConfigurationManager configManager) @@ -614,20 +628,10 @@ namespace Emby.Server.Implementations.Localization private static string GetDisplayName(string cultureCode) { - // Resource files use underscores for codes that .NET's CultureInfo doesn't accept directly (e.g. es_419). - var lookup = cultureCode.Contains('_', StringComparison.Ordinal) - ? cultureCode.Replace('_', '-') + // Custom/novelty codes like "pr" (Pirate) — fall back to code itself + return TryGetCultureInfo(cultureCode, out var cultureInfo) + ? cultureInfo.NativeName : cultureCode; - - try - { - return CultureInfo.GetCultureInfo(lookup).NativeName; - } - catch (CultureNotFoundException) - { - // Custom/novelty codes like "pr" (Pirate) — fall back to code itself - return cultureCode; - } } /// diff --git a/src/Jellyfin.LiveTv/Channels/RefreshChannelsScheduledTask.cs b/src/Jellyfin.LiveTv/Channels/RefreshChannelsScheduledTask.cs index 71e46764ad..bb4238a2ac 100644 --- a/src/Jellyfin.LiveTv/Channels/RefreshChannelsScheduledTask.cs +++ b/src/Jellyfin.LiveTv/Channels/RefreshChannelsScheduledTask.cs @@ -40,10 +40,10 @@ namespace Jellyfin.LiveTv.Channels } /// - public string Name => _localization.GetLocalizedString("TasksRefreshChannels"); + public string Name => _localization.GetLocalizedString("TaskRefreshChannels"); /// - public string Description => _localization.GetLocalizedString("TasksRefreshChannelsDescription"); + public string Description => _localization.GetLocalizedString("TaskRefreshChannelsDescription"); /// public string Category => _localization.GetLocalizedString("TasksChannelsCategory"); -- cgit v1.2.3 From 8ec3b5c7ac989a1f62a1764e36b5a24ffa8f5a41 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Thu, 14 May 2026 13:09:00 +0000 Subject: readded concurrency exception check --- .../Jellyfin.Database.Implementations/JellyfinDbContext.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs index 83c15aa647..b0c12bf592 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs @@ -299,6 +299,11 @@ public class JellyfinDbContext(DbContextOptions options, ILog }); return result; } + catch (DbUpdateConcurrencyException) + { + // a concurrency exception is supposed to be always handled by the invoker of the method, logging it here is only causing log bloat. + throw; + } catch (Exception e) { logger.LogError(e, "Error trying to save changes."); -- cgit v1.2.3