aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Server.Implementations')
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStopLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Session/SessionEndedLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationFailedLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs4
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Users/UserCreatedLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Users/UserDeletedLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Users/UserLockedOutLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Events/Consumers/Users/UserPasswordChangedLogger.cs2
-rw-r--r--Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs37
-rw-r--r--Jellyfin.Server.Implementations/Item/ChapterRepository.cs19
-rw-r--r--Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs11
-rw-r--r--Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs11
21 files changed, 92 insertions, 36 deletions
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs
index 5f4864e953..cfd1cbe05b 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Library/LyricDownloadFailureLogger.cs
@@ -37,7 +37,7 @@ public class LyricDownloadFailureLogger : IEventConsumer<LyricDownloadFailureEve
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("LyricDownloadFailureFromForItem"),
+ _localizationManager.GetServerLocalizedString("LyricDownloadFailureFromForItem"),
eventArgs.Provider,
GetItemName(eventArgs.Item)),
"LyricDownloadFailure",
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs
index 8fe380e4f4..24146210c6 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Library/SubtitleDownloadFailureLogger.cs
@@ -37,7 +37,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Library
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
+ _localizationManager.GetServerLocalizedString("SubtitleDownloadFailureFromForItem"),
eventArgs.Provider,
GetItemName(eventArgs.Item)),
"SubtitleDownloadFailure",
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs
index 1a8931a6dc..df526977a2 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationFailedLogger.cs
@@ -35,7 +35,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Security
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("FailedLoginAttemptWithUserName"),
+ _localizationManager.GetServerLocalizedString("FailedLoginAttemptWithUserName"),
eventArgs.Username),
"AuthenticationFailed",
Guid.Empty)
@@ -43,7 +43,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Security
LogSeverity = LogLevel.Error,
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("LabelIpAddressValue"),
+ _localizationManager.GetServerLocalizedString("LabelIpAddressValue"),
eventArgs.RemoteEndPoint),
}).ConfigureAwait(false);
}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs
index 584d559e44..fa9ce21170 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Security/AuthenticationSucceededLogger.cs
@@ -33,14 +33,14 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Security
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("AuthenticationSucceededWithUserName"),
+ _localizationManager.GetServerLocalizedString("AuthenticationSucceededWithUserName"),
eventArgs.User.Name),
"AuthenticationSucceeded",
eventArgs.User.Id)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("LabelIpAddressValue"),
+ _localizationManager.GetServerLocalizedString("LabelIpAddressValue"),
eventArgs.SessionInfo?.RemoteEndPoint),
}).ConfigureAwait(false);
}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs
index 73323acb37..8f71966b83 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs
@@ -61,7 +61,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserStartedPlayingItemWithValues"),
+ _localizationManager.GetServerLocalizedString("UserStartedPlayingItemWithValues"),
user.Username,
GetItemName(eventArgs.MediaInfo),
eventArgs.DeviceName),
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStopLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStopLogger.cs
index b75567539c..09d68e4451 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStopLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStopLogger.cs
@@ -69,7 +69,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserStoppedPlayingItemWithValues"),
+ _localizationManager.GetServerLocalizedString("UserStoppedPlayingItemWithValues"),
user.Username,
GetItemName(item),
eventArgs.DeviceName),
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionEndedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionEndedLogger.cs
index b90708a2f2..74dfeebba6 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionEndedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionEndedLogger.cs
@@ -38,7 +38,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserOfflineFromDevice"),
+ _localizationManager.GetServerLocalizedString("UserOfflineFromDevice"),
eventArgs.Argument.UserName,
eventArgs.Argument.DeviceName),
"SessionEnded",
@@ -46,7 +46,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("LabelIpAddressValue"),
+ _localizationManager.GetServerLocalizedString("LabelIpAddressValue"),
eventArgs.Argument.RemoteEndPoint),
}).ConfigureAwait(false);
}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs
index 139c2e2acb..4028522838 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/SessionStartedLogger.cs
@@ -38,7 +38,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserOnlineFromDevice"),
+ _localizationManager.GetServerLocalizedString("UserOnlineFromDevice"),
eventArgs.Argument.UserName,
eventArgs.Argument.DeviceName),
"SessionStarted",
@@ -46,7 +46,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("LabelIpAddressValue"),
+ _localizationManager.GetServerLocalizedString("LabelIpAddressValue"),
eventArgs.Argument.RemoteEndPoint)
}).ConfigureAwait(false);
}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs
index da82a3b30f..1e3dc7c92e 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/System/TaskCompletedLogger.cs
@@ -47,7 +47,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.System
var time = result.EndTimeUtc - result.StartTimeUtc;
var runningTime = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("LabelRunningTimeValue"),
+ _localizationManager.GetServerLocalizedString("LabelRunningTimeValue"),
ToUserFriendlyString(time));
if (result.Status == TaskCompletionStatus.Failed)
@@ -65,7 +65,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.System
}
await _activityManager.CreateAsync(new ActivityLog(
- string.Format(CultureInfo.InvariantCulture, _localizationManager.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
+ string.Format(CultureInfo.InvariantCulture, _localizationManager.GetServerLocalizedString("ScheduledTaskFailedWithName"), task.Name),
NotificationType.TaskFailed.ToString(),
Guid.Empty)
{
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationFailedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationFailedLogger.cs
index 632f30c7ad..9fb007aca7 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationFailedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstallationFailedLogger.cs
@@ -35,14 +35,14 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("NameInstallFailed"),
+ _localizationManager.GetServerLocalizedString("NameInstallFailed"),
eventArgs.InstallationInfo.Name),
NotificationType.InstallationFailed.ToString(),
Guid.Empty)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("VersionNumber"),
+ _localizationManager.GetServerLocalizedString("VersionNumber"),
eventArgs.InstallationInfo.Version),
Overview = eventArgs.Exception.Message
}).ConfigureAwait(false);
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs
index 4b49b714cf..2aa738c153 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginInstalledLogger.cs
@@ -35,14 +35,14 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("PluginInstalledWithName"),
+ _localizationManager.GetServerLocalizedString("PluginInstalledWithName"),
eventArgs.Argument.Name),
NotificationType.PluginInstalled.ToString(),
Guid.Empty)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("VersionNumber"),
+ _localizationManager.GetServerLocalizedString("VersionNumber"),
eventArgs.Argument.Version)
}).ConfigureAwait(false);
}
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs
index 2d24de7fc6..f7e651173d 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUninstalledLogger.cs
@@ -35,7 +35,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("PluginUninstalledWithName"),
+ _localizationManager.GetServerLocalizedString("PluginUninstalledWithName"),
eventArgs.Argument.Name),
NotificationType.PluginUninstalled.ToString(),
Guid.Empty))
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs
index e892d3dd9a..bca9662839 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Updates/PluginUpdatedLogger.cs
@@ -35,14 +35,14 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Updates
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("PluginUpdatedWithName"),
+ _localizationManager.GetServerLocalizedString("PluginUpdatedWithName"),
eventArgs.Argument.Name),
NotificationType.PluginUpdateInstalled.ToString(),
Guid.Empty)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("VersionNumber"),
+ _localizationManager.GetServerLocalizedString("VersionNumber"),
eventArgs.Argument.Version),
Overview = eventArgs.Argument.Changelog
}).ConfigureAwait(false);
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserCreatedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserCreatedLogger.cs
index 4f063f6a1b..cf5c81b981 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserCreatedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserCreatedLogger.cs
@@ -33,7 +33,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Users
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserCreatedWithName"),
+ _localizationManager.GetServerLocalizedString("UserCreatedWithName"),
eventArgs.Argument.Username),
"UserCreated",
eventArgs.Argument.Id))
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserDeletedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserDeletedLogger.cs
index ba4a072e84..720480c28f 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserDeletedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserDeletedLogger.cs
@@ -34,7 +34,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Users
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserDeletedWithName"),
+ _localizationManager.GetServerLocalizedString("UserDeletedWithName"),
eventArgs.Argument.Username),
"UserDeleted",
Guid.Empty))
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserLockedOutLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserLockedOutLogger.cs
index bbc00567d1..efaf19397f 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserLockedOutLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserLockedOutLogger.cs
@@ -35,7 +35,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Users
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserLockedOutWithName"),
+ _localizationManager.GetServerLocalizedString("UserLockedOutWithName"),
eventArgs.Argument.Username),
NotificationType.UserLockedOut.ToString(),
eventArgs.Argument.Id)
diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserPasswordChangedLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserPasswordChangedLogger.cs
index 7219704ec6..cc9efa7061 100644
--- a/Jellyfin.Server.Implementations/Events/Consumers/Users/UserPasswordChangedLogger.cs
+++ b/Jellyfin.Server.Implementations/Events/Consumers/Users/UserPasswordChangedLogger.cs
@@ -33,7 +33,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Users
await _activityManager.CreateAsync(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
- _localizationManager.GetLocalizedString("UserPasswordChangedWithName"),
+ _localizationManager.GetServerLocalizedString("UserPasswordChangedWithName"),
eventArgs.Argument.Username),
"UserPasswordChanged",
eventArgs.Argument.Id))
diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs
index 59e61cfd65..624b1b561c 100644
--- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs
+++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs
@@ -824,6 +824,26 @@ public sealed partial class BaseItemRepository
}
}
+ if (filter.SubtitleLanguages.Count > 0)
+ {
+ var foldersWithSubtitles = DescendantQueryHelper.GetFolderIdsMatching(context, new HasMediaStreamType(MediaStreamTypeEntity.Subtitle, filter.SubtitleLanguages));
+ baseQuery = baseQuery
+ .Where(e =>
+ (!e.IsFolder && e.MediaStreams!.Any(f => f.StreamType == MediaStreamTypeEntity.Subtitle
+ && (filter.SubtitleLanguages.Contains(f.Language) || (filter.SubtitleLanguages.Contains("und") && string.IsNullOrEmpty(f.Language)))))
+ || (e.IsFolder && foldersWithSubtitles.Contains(e.Id)));
+ }
+
+ if (filter.AudioLanguages.Count > 0)
+ {
+ var foldersWithAudio = DescendantQueryHelper.GetFolderIdsMatching(context, new HasMediaStreamType(MediaStreamTypeEntity.Audio, filter.AudioLanguages));
+ baseQuery = baseQuery
+ .Where(e =>
+ (!e.IsFolder && e.MediaStreams!.Any(f => f.StreamType == MediaStreamTypeEntity.Audio
+ && (filter.AudioLanguages.Contains(f.Language) || (filter.AudioLanguages.Contains("und") && string.IsNullOrEmpty(f.Language)))))
+ || (e.IsFolder && foldersWithAudio.Contains(e.Id)));
+ }
+
if (filter.HasChapterImages.HasValue)
{
var hasChapterImages = filter.HasChapterImages.Value;
@@ -953,6 +973,17 @@ public sealed partial class BaseItemRepository
}
}
+ if (filter.HasAnyProviderIds is not null && filter.HasAnyProviderIds.Count > 0)
+ {
+ var includeAny = filter.HasAnyProviderIds
+ .SelectMany(kvp => kvp.Value.Select(v => $"{kvp.Key}:{v}"))
+ .ToArray();
+ if (includeAny.Length > 0)
+ {
+ baseQuery = baseQuery.Where(e => e.Provider!.Select(f => f.ProviderId + ":" + f.ProviderValue)!.Any(f => includeAny.Contains(f)));
+ }
+ }
+
if (filter.HasImdbId.HasValue)
{
baseQuery = filter.HasImdbId.Value
@@ -1057,8 +1088,12 @@ public sealed partial class BaseItemRepository
if (filter.VideoTypes.Length > 0)
{
+ // Dvds and Blu-rays can either be stored in a folder structure or as an iso file
+ // => to find all matches we need to check both: VideoType and IsoType
+ // alternatively, we could provide specific IsoType filters
var videoTypeBs = filter.VideoTypes.Select(vt => $"\"VideoType\":\"{vt}\"").ToArray();
- Expression<Func<BaseItemEntity, bool>> hasVideoType = e => videoTypeBs.Any(f => e.Data!.Contains(f));
+ var isoTypeBs = filter.VideoTypes.Select(vt => $"\"IsoType\":\"{vt}\"").ToArray();
+ Expression<Func<BaseItemEntity, bool>> hasVideoType = e => videoTypeBs.Any(f => e.Data!.Contains(f)) || isoTypeBs.Any(f => e.Data!.Contains(f));
baseQuery = baseQuery.WhereItemOrDescendantMatches(context, hasVideoType);
}
diff --git a/Jellyfin.Server.Implementations/Item/ChapterRepository.cs b/Jellyfin.Server.Implementations/Item/ChapterRepository.cs
index 98700f3224..f7d76517e1 100644
--- a/Jellyfin.Server.Implementations/Item/ChapterRepository.cs
+++ b/Jellyfin.Server.Implementations/Item/ChapterRepository.cs
@@ -55,6 +55,7 @@ public class ChapterRepository : IChapterRepository
{
using var context = _dbProvider.CreateDbContext();
return context.Chapters.AsNoTracking().Where(e => e.ItemId.Equals(baseItemId))
+ .OrderBy(e => e.StartPositionTicks)
.Select(e => new
{
chapter = e,
@@ -69,18 +70,16 @@ public class ChapterRepository : IChapterRepository
public void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters)
{
using var context = _dbProvider.CreateDbContext();
- using (var transaction = context.Database.BeginTransaction())
+ using var transaction = context.Database.BeginTransaction();
+ context.Chapters.Where(e => e.ItemId.Equals(itemId)).ExecuteDelete();
+ for (var i = 0; i < chapters.Count; i++)
{
- context.Chapters.Where(e => e.ItemId.Equals(itemId)).ExecuteDelete();
- for (var i = 0; i < chapters.Count; i++)
- {
- var chapter = chapters[i];
- context.Chapters.Add(Map(chapter, i, itemId));
- }
-
- context.SaveChanges();
- transaction.Commit();
+ var chapter = chapters[i];
+ context.Chapters.Add(Map(chapter, i, itemId));
}
+
+ context.SaveChanges();
+ transaction.Commit();
}
/// <inheritdoc />
diff --git a/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs b/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs
index dd0446f49a..7fa33c8639 100644
--- a/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs
+++ b/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs
@@ -55,6 +55,17 @@ public class MediaStreamRepository : IMediaStreamRepository
return TranslateQuery(context.MediaStreamInfos.AsNoTracking(), filter).AsEnumerable().Select(Map).ToArray();
}
+ /// <inheritdoc />
+ public IReadOnlyList<string> GetMediaStreamLanguages(MediaStreamType mediaStreamType)
+ {
+ using var context = _dbProvider.CreateDbContext();
+ return context.MediaStreamInfos
+ .Where(e => e.StreamType == (MediaStreamTypeEntity)mediaStreamType)
+ .Select(s => string.IsNullOrEmpty(s.Language) ? "und" : s.Language) // und = undetermined
+ .Distinct()
+ .ToArray();
+ }
+
private string? GetPathToSave(string? path)
{
if (path is null)
diff --git a/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs b/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs
index 249df476a0..be98f93dab 100644
--- a/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs
+++ b/Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs
@@ -81,6 +81,8 @@ public class MediaSegmentManager : IMediaSegmentManager
foreach (var provider in providers)
{
+ cancellationToken.ThrowIfCancellationRequested();
+
if (!await provider.Supports(baseItem).ConfigureAwait(false))
{
_logger.LogDebug("Media Segment provider {ProviderName} does not support item with path {MediaPath}", provider.Name, baseItem.Path);
@@ -146,6 +148,15 @@ public class MediaSegmentManager : IMediaSegmentManager
await CreateSegmentAsync(segment, providerId).ConfigureAwait(false);
}
}
+ catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
+ {
+ throw;
+ }
+ catch (Exception ex) when (cancellationToken.IsCancellationRequested)
+ {
+ _logger.LogDebug(ex, "Provider {ProviderName} aborted segment extraction for {MediaPath} due to shutdown", provider.Name, baseItem.Path);
+ break;
+ }
catch (Exception ex)
{
_logger.LogError(ex, "Provider {ProviderName} failed to extract segments from {MediaPath}", provider.Name, baseItem.Path);