mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-08 08:48:48 +01:00
Merge remote-tracking branch 'upstream/master' into search-rebased
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
@@ -946,6 +966,17 @@ public sealed partial class BaseItemRepository
|
||||
baseQuery = baseQuery.WhereHasAnyProviderIds(filter.HasAnyProviderIds);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1050,8 +1081,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -119,7 +119,6 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I
|
||||
.ToArray();
|
||||
|
||||
var toAdd = people
|
||||
.Where(e => e.Type is not PersonKind.Artist && e.Type is not PersonKind.AlbumArtist)
|
||||
.Where(e => !existingPersons.Any(f => string.Equals(f.Name, e.Name, StringComparison.OrdinalIgnoreCase) && f.PersonType == e.Type.ToString()))
|
||||
.Select(Map);
|
||||
context.Peoples.AddRange(toAdd);
|
||||
@@ -133,11 +132,6 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I
|
||||
|
||||
foreach (var person in people)
|
||||
{
|
||||
if (person.Type == PersonKind.Artist || person.Type == PersonKind.AlbumArtist)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var entityPerson = personsEntities.First(e => string.Equals(e.Name, person.Name, StringComparison.OrdinalIgnoreCase) && e.PersonType == person.Type.ToString());
|
||||
var existingMap = existingMaps.FirstOrDefault(e => string.Equals(e.People.Name, person.Name, StringComparison.OrdinalIgnoreCase) && e.People.PersonType == person.Type.ToString() && e.Role == person.Role);
|
||||
if (existingMap is null)
|
||||
|
||||
Reference in New Issue
Block a user