aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities
diff options
context:
space:
mode:
authorMarc Brooks <IDisposable@gmail.com>2025-02-03 19:48:59 -0600
committerGitHub <noreply@github.com>2025-02-03 19:48:59 -0600
commite8cbcde02ebd930a5eeb6c95e0875a9e30acb3e8 (patch)
tree2ecd43f232012c8f037f4cd6fee4168e46d01aa3 /MediaBrowser.Controller/Entities
parent6dc61a430ba3a8480399309f277e5debfd6403ba (diff)
parentd376b5fbc7cf3ae7440a606a9e885d70605956bd (diff)
Merge branch 'master' into sort-nfo-data
Diffstat (limited to 'MediaBrowser.Controller/Entities')
-rw-r--r--MediaBrowser.Controller/Entities/AggregateFolder.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs9
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicGenre.cs3
-rw-r--r--MediaBrowser.Controller/Entities/AudioBook.cs1
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs51
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs50
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs3
-rw-r--r--MediaBrowser.Controller/Entities/IHasMediaSources.cs4
-rw-r--r--MediaBrowser.Controller/Entities/IItemByName.cs2
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs5
-rw-r--r--MediaBrowser.Controller/Entities/LinkedChild.cs7
-rw-r--r--MediaBrowser.Controller/Entities/Movies/BoxSet.cs13
-rw-r--r--MediaBrowser.Controller/Entities/PeopleHelper.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Person.cs3
-rw-r--r--MediaBrowser.Controller/Entities/PersonInfo.cs6
-rw-r--r--MediaBrowser.Controller/Entities/PhotoAlbum.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Studio.cs3
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs4
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs4
-rw-r--r--MediaBrowser.Controller/Entities/UserRootFolder.cs4
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs4
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Year.cs3
26 files changed, 103 insertions, 89 deletions
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
index 40cdd6c91..a02802f41 100644
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs
@@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class AggregateFolder : Folder
{
- private readonly object _childIdsLock = new object();
+ private readonly Lock _childIdsLock = new();
/// <summary>
/// The _virtual children.
@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Entities
return CreateResolveArgs(directoryService, true).FileSystemChildren;
}
- protected override List<BaseItem> LoadChildren()
+ protected override IReadOnlyList<BaseItem> LoadChildren()
{
lock (_childIdsLock)
{
diff --git a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
index 1625c748a..b085398c5 100644
--- a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Entities.Audio
IReadOnlyList<string> Artists { get; set; }
}
- public static class Extentions
+ public static class Extensions
{
public static IEnumerable<string> GetAllArtists<T>(this T item)
where T : IHasArtist, IHasAlbumArtist
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index a0aae8769..f3873775b 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -21,6 +21,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <summary>
/// Class MusicAlbum.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
{
public MusicAlbum()
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 1ab6c9706..ecb3ac3a6 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -21,6 +21,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <summary>
/// Class MusicArtist.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
{
[JsonIgnore]
@@ -84,7 +85,7 @@ namespace MediaBrowser.Controller.Entities.Audio
return !IsAccessedByName;
}
- public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
if (query.IncludeItemTypes.Length == 0)
{
@@ -110,15 +111,15 @@ namespace MediaBrowser.Controller.Entities.Audio
return base.IsSaveLocalMetadataEnabled();
}
- protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
+ protected override async Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
{
if (IsAccessedByName)
{
// Should never get in here anyway
- return Task.CompletedTask;
+ return;
}
- return base.ValidateChildrenInternal(progress, recursive, refreshChildMetadata, false, refreshOptions, directoryService, cancellationToken);
+ await base.ValidateChildrenInternal(progress, recursive, refreshChildMetadata, false, refreshOptions, directoryService, cancellationToken).ConfigureAwait(false);
}
public override List<string> GetUserDataKeys()
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
index 7448d02ea..65669e680 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
@@ -14,6 +14,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <summary>
/// Class MusicGenre.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class MusicGenre : BaseItem, IItemByName
{
[JsonIgnore]
@@ -64,7 +65,7 @@ namespace MediaBrowser.Controller.Entities.Audio
return true;
}
- public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.GenreIds = new[] { Id };
query.IncludeItemTypes = new[] { BaseItemKind.MusicVideo, BaseItemKind.Audio, BaseItemKind.MusicAlbum, BaseItemKind.MusicArtist };
diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs
index 782481fbc..666bf2a75 100644
--- a/MediaBrowser.Controller/Entities/AudioBook.cs
+++ b/MediaBrowser.Controller/Entities/AudioBook.cs
@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Providers;
namespace MediaBrowser.Controller.Entities
{
+ [Common.RequiresSourceSerialisation]
public class AudioBook : Audio.Audio, IHasSeries, IHasLookupInfo<SongInfo>
{
[JsonIgnore]
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 8201ae318..29b0b6861 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -16,6 +17,7 @@ using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Chapters;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities.Audio;
@@ -480,6 +482,8 @@ namespace MediaBrowser.Controller.Entities
public static IItemRepository ItemRepository { get; set; }
+ public static IChapterRepository ChapterRepository { get; set; }
+
public static IFileSystem FileSystem { get; set; }
public static IUserDataManager UserDataManager { get; set; }
@@ -1042,7 +1046,7 @@ namespace MediaBrowser.Controller.Entities
return PlayAccess.Full;
}
- public virtual List<MediaStream> GetMediaStreams()
+ public virtual IReadOnlyList<MediaStream> GetMediaStreams()
{
return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
{
@@ -1055,7 +1059,7 @@ namespace MediaBrowser.Controller.Entities
return false;
}
- public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
+ public virtual IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
{
if (SourceType == SourceType.Channel)
{
@@ -1089,7 +1093,7 @@ namespace MediaBrowser.Controller.Entities
return 1;
}).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
.ThenByDescending(i => i, new MediaSourceWidthComparator())
- .ToList();
+ .ToArray();
}
protected virtual IEnumerable<(BaseItem Item, MediaSourceType MediaSourceType)> GetAllItemsForMediaSources()
@@ -1609,7 +1613,7 @@ namespace MediaBrowser.Controller.Entities
}
var parent = GetParents().FirstOrDefault() ?? this;
- if (parent is UserRootFolder or AggregateFolder)
+ if (parent is UserRootFolder or AggregateFolder or UserView)
{
return true;
}
@@ -1781,7 +1785,7 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- Studios = [..current, name];
+ Studios = [.. current, name];
}
}
}
@@ -1795,7 +1799,7 @@ namespace MediaBrowser.Controller.Entities
/// Adds a genre to the item.
/// </summary>
/// <param name="name">The name.</param>
- /// <exception cref="ArgumentNullException">Throwns if name is null.</exception>
+ /// <exception cref="ArgumentNullException">Throws if name is null.</exception>
public void AddGenre(string name)
{
ArgumentException.ThrowIfNullOrEmpty(name);
@@ -1803,7 +1807,7 @@ namespace MediaBrowser.Controller.Entities
var genres = Genres;
if (!genres.Contains(name, StringComparison.OrdinalIgnoreCase))
{
- Genres = [..genres, name];
+ Genres = [.. genres, name];
}
}
@@ -1821,7 +1825,10 @@ namespace MediaBrowser.Controller.Entities
{
ArgumentNullException.ThrowIfNull(user);
- var data = UserDataManager.GetUserData(user, this);
+ var data = UserDataManager.GetUserData(user, this) ?? new UserItemData()
+ {
+ Key = GetUserDataKeys().First(),
+ };
if (datePlayed.HasValue)
{
@@ -1974,11 +1981,11 @@ namespace MediaBrowser.Controller.Entities
public void AddImage(ItemImageInfo image)
{
- ImageInfos = [..ImageInfos, image];
+ ImageInfos = [.. ImageInfos, image];
}
- public virtual Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
- => LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken);
+ public virtual async Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
+ => await LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken).ConfigureAwait(false);
/// <summary>
/// Validates that images within the item are still on the filesystem.
@@ -2031,7 +2038,7 @@ namespace MediaBrowser.Controller.Entities
{
if (imageType == ImageType.Chapter)
{
- var chapter = ItemRepository.GetChapter(this, imageIndex);
+ var chapter = ChapterRepository.GetChapter(this.Id, imageIndex);
if (chapter is null)
{
@@ -2081,7 +2088,7 @@ namespace MediaBrowser.Controller.Entities
if (image.Type == ImageType.Chapter)
{
- var chapters = ItemRepository.GetChapters(this);
+ var chapters = ChapterRepository.GetChapters(this.Id);
for (var i = 0; i < chapters.Count; i++)
{
if (chapters[i].ImagePath == image.Path)
@@ -2367,7 +2374,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- protected Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
+ protected async Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
var newOptions = new MetadataRefreshOptions(options)
{
@@ -2428,10 +2435,10 @@ namespace MediaBrowser.Controller.Entities
}
}
- return ownedItem.RefreshMetadata(newOptions, cancellationToken);
+ await ownedItem.RefreshMetadata(newOptions, cancellationToken).ConfigureAwait(false);
}
- protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
+ protected async Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
{
var newOptions = new MetadataRefreshOptions(options)
{
@@ -2441,9 +2448,7 @@ namespace MediaBrowser.Controller.Entities
var id = LibraryManager.GetNewItemId(path, typeof(Video));
// Try to retrieve it from the db. If we don't find it, use the resolved version
- var video = LibraryManager.GetItemById(id) as Video;
-
- if (video is null)
+ if (LibraryManager.GetItemById(id) is not Video video)
{
video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
@@ -2452,15 +2457,15 @@ namespace MediaBrowser.Controller.Entities
if (video is null)
{
- return Task.FromResult(true);
+ return;
}
if (video.OwnerId.IsEmpty())
{
- video.OwnerId = this.Id;
+ video.OwnerId = Id;
}
- return RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken);
+ await RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false);
}
public string GetEtag(User user)
@@ -2524,7 +2529,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <param name="children">Media children.</param>
/// <returns><c>true</c> if the rating was updated; otherwise <c>false</c>.</returns>
- public bool UpdateRatingToItems(IList<BaseItem> children)
+ public bool UpdateRatingToItems(IReadOnlyList<BaseItem> children)
{
var currentOfficialRating = OfficialRating;
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
index 66dea1084..518766937 100644
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -10,6 +10,7 @@ using MediaBrowser.Controller.Providers;
namespace MediaBrowser.Controller.Entities
{
+ [Common.RequiresSourceSerialisation]
public class Book : BaseItem, IHasLookupInfo<BookInfo>, IHasSeries
{
public Book()
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 83c19a54e..c110f4d9f 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Security;
@@ -11,6 +12,7 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
+using J2N.Collections.Generic.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
@@ -247,7 +249,7 @@ namespace MediaBrowser.Controller.Entities
/// We want this synchronous.
/// </summary>
/// <returns>Returns children.</returns>
- protected virtual List<BaseItem> LoadChildren()
+ protected virtual IReadOnlyList<BaseItem> LoadChildren()
{
// logger.LogDebug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
// just load our children from the repo - the library will be validated and maintained in other processes
@@ -450,7 +452,7 @@ namespace MediaBrowser.Controller.Entities
if (newItems.Count > 0)
{
- LibraryManager.CreateItems(newItems, this, cancellationToken);
+ LibraryManager.CreateOrUpdateItems(newItems, this, cancellationToken);
}
}
else
@@ -528,13 +530,13 @@ namespace MediaBrowser.Controller.Entities
}
}
- private Task RefreshMetadataRecursive(IList<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task RefreshMetadataRecursive(IList<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
{
- return RunTasks(
+ await RunTasks(
(baseItem, innerProgress) => RefreshChildMetadata(baseItem, refreshOptions, recursive && baseItem.IsFolder, innerProgress, cancellationToken),
children,
progress,
- cancellationToken);
+ cancellationToken).ConfigureAwait(false);
}
private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
@@ -575,13 +577,13 @@ namespace MediaBrowser.Controller.Entities
/// <param name="progress">The progress.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- private Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
{
- return RunTasks(
+ await RunTasks(
(folder, innerProgress) => folder.ValidateChildrenInternal(innerProgress, true, false, false, null, directoryService, cancellationToken),
children,
progress,
- cancellationToken);
+ cancellationToken).ConfigureAwait(false);
}
/// <summary>
@@ -659,7 +661,7 @@ namespace MediaBrowser.Controller.Entities
/// Get our children from the repo - stubbed for now.
/// </summary>
/// <returns>IEnumerable{BaseItem}.</returns>
- protected List<BaseItem> GetCachedChildren()
+ protected IReadOnlyList<BaseItem> GetCachedChildren()
{
return ItemRepository.GetItemList(new InternalItemsQuery
{
@@ -1240,11 +1242,6 @@ namespace MediaBrowser.Controller.Entities
return false;
}
- if (request.GenreIds.Count > 0)
- {
- return false;
- }
-
if (request.VideoTypes.Length > 0)
{
return false;
@@ -1283,14 +1280,14 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- public List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
+ public IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{
ArgumentNullException.ThrowIfNull(user);
return GetChildren(user, includeLinkedChildren, new InternalItemsQuery(user));
}
- public virtual List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
+ public virtual IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
{
ArgumentNullException.ThrowIfNull(user);
@@ -1304,7 +1301,7 @@ namespace MediaBrowser.Controller.Entities
AddChildren(user, includeLinkedChildren, result, false, query);
- return result.Values.ToList();
+ return result.Values.ToArray();
}
protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
@@ -1369,7 +1366,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
+ public virtual IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
ArgumentNullException.ThrowIfNull(user);
@@ -1377,35 +1374,35 @@ namespace MediaBrowser.Controller.Entities
AddChildren(user, true, result, true, query);
- return result.Values;
+ return result.Values.ToArray();
}
/// <summary>
/// Gets the recursive children.
/// </summary>
/// <returns>IList{BaseItem}.</returns>
- public IList<BaseItem> GetRecursiveChildren()
+ public IReadOnlyList<BaseItem> GetRecursiveChildren()
{
return GetRecursiveChildren(true);
}
- public IList<BaseItem> GetRecursiveChildren(bool includeLinkedChildren)
+ public IReadOnlyList<BaseItem> GetRecursiveChildren(bool includeLinkedChildren)
{
return GetRecursiveChildren(i => true, includeLinkedChildren);
}
- public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
+ public IReadOnlyList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
{
return GetRecursiveChildren(filter, true);
}
- public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter, bool includeLinkedChildren)
+ public IReadOnlyList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter, bool includeLinkedChildren)
{
var result = new Dictionary<Guid, BaseItem>();
AddChildrenToList(result, includeLinkedChildren, true, filter);
- return result.Values.ToList();
+ return result.Values.ToArray();
}
/// <summary>
@@ -1556,11 +1553,12 @@ namespace MediaBrowser.Controller.Entities
/// Gets the linked children.
/// </summary>
/// <returns>IEnumerable{BaseItem}.</returns>
- public IEnumerable<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
+ public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
{
return LinkedChildren
.Select(i => new Tuple<LinkedChild, BaseItem>(i, GetLinkedChild(i)))
- .Where(i => i.Item2 is not null);
+ .Where(i => i.Item2 is not null)
+ .ToArray();
}
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index ddf62dd4c..6ec78a270 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -14,6 +14,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class Genre.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class Genre : BaseItem, IItemByName
{
/// <summary>
@@ -61,7 +62,7 @@ namespace MediaBrowser.Controller.Entities
return false;
}
- public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.GenreIds = new[] { Id };
query.ExcludeItemTypes = new[]
diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
index 90d9bdd2d..ad35494c2 100644
--- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs
+++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
@@ -22,8 +22,8 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <param name="enablePathSubstitution"><c>true</c> to enable path substitution, <c>false</c> to not.</param>
/// <returns>A list of media sources.</returns>
- List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
+ IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
- List<MediaStream> GetMediaStreams();
+ IReadOnlyList<MediaStream> GetMediaStreams();
}
}
diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs
index cac8aa61a..4928bda7a 100644
--- a/MediaBrowser.Controller/Entities/IItemByName.cs
+++ b/MediaBrowser.Controller/Entities/IItemByName.cs
@@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public interface IItemByName
{
- IList<BaseItem> GetTaggedItems(InternalItemsQuery query);
+ IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query);
}
public interface IHasDualAccess : IItemByName
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index 1461a3680..43f02fb72 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -37,7 +37,6 @@ namespace MediaBrowser.Controller.Entities
IncludeItemTypes = Array.Empty<BaseItemKind>();
ItemIds = Array.Empty<Guid>();
MediaTypes = Array.Empty<MediaType>();
- MinSimilarityScore = 20;
OfficialRatings = Array.Empty<string>();
OrderBy = Array.Empty<(ItemSortBy, SortOrder)>();
PersonIds = Array.Empty<Guid>();
@@ -71,8 +70,6 @@ namespace MediaBrowser.Controller.Entities
public User? User { get; set; }
- public BaseItem? SimilarTo { get; set; }
-
public bool? IsFolder { get; set; }
public bool? IsFavorite { get; set; }
@@ -295,8 +292,6 @@ namespace MediaBrowser.Controller.Entities
public DtoOptions DtoOptions { get; set; }
- public int MinSimilarityScore { get; set; }
-
public string? HasNoAudioTrackWithLanguage { get; set; }
public string? HasNoInternalSubtitleTrackWithLanguage { get; set; }
diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs
index fd5fef3dc..98e4f525f 100644
--- a/MediaBrowser.Controller/Entities/LinkedChild.cs
+++ b/MediaBrowser.Controller/Entities/LinkedChild.cs
@@ -4,7 +4,6 @@
using System;
using System.Globalization;
-using System.Text.Json.Serialization;
namespace MediaBrowser.Controller.Entities
{
@@ -12,7 +11,6 @@ namespace MediaBrowser.Controller.Entities
{
public LinkedChild()
{
- Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
}
public string Path { get; set; }
@@ -21,9 +19,6 @@ namespace MediaBrowser.Controller.Entities
public string LibraryItemId { get; set; }
- [JsonIgnore]
- public string Id { get; set; }
-
/// <summary>
/// Gets or sets the linked item id.
/// </summary>
@@ -31,6 +26,8 @@ namespace MediaBrowser.Controller.Entities
public static LinkedChild Create(BaseItem item)
{
+ ArgumentNullException.ThrowIfNull(item);
+
var child = new LinkedChild
{
Path = item.Path,
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index a07187d2f..d0c9f049a 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Linq;
using System.Text.Json.Serialization;
using Jellyfin.Data.Entities;
@@ -91,7 +92,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return Enumerable.Empty<BaseItem>();
}
- protected override List<BaseItem> LoadChildren()
+ protected override IReadOnlyList<BaseItem> LoadChildren()
{
if (IsLegacyBoxSet)
{
@@ -99,7 +100,7 @@ namespace MediaBrowser.Controller.Entities.Movies
}
// Save a trip to the database
- return new List<BaseItem>();
+ return [];
}
public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
@@ -127,16 +128,16 @@ namespace MediaBrowser.Controller.Entities.Movies
return LibraryManager.Sort(items, user, new[] { sortBy }, SortOrder.Ascending);
}
- public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
+ public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
{
var children = base.GetChildren(user, includeLinkedChildren, query);
- return Sort(children, user).ToList();
+ return Sort(children, user).ToArray();
}
- public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
+ public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
var children = base.GetRecursiveChildren(user, query);
- return Sort(children, user).ToList();
+ return Sort(children, user).ToArray();
}
public BoxSetInfo GetLookupInfo()
diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs
index d81860436..24b1843ce 100644
--- a/MediaBrowser.Controller/Entities/PeopleHelper.cs
+++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs
@@ -10,7 +10,7 @@ namespace MediaBrowser.Controller.Entities
{
public static class PeopleHelper
{
- public static void AddPerson(List<PersonInfo> people, PersonInfo person)
+ public static void AddPerson(ICollection<PersonInfo> people, PersonInfo person)
{
ArgumentNullException.ThrowIfNull(person);
ArgumentException.ThrowIfNullOrEmpty(person.Name);
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
index 7f265084f..5cc4d322f 100644
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ b/MediaBrowser.Controller/Entities/Person.cs
@@ -14,6 +14,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// This is the full Person object that can be retrieved with all of it's data.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
{
/// <summary>
@@ -62,7 +63,7 @@ namespace MediaBrowser.Controller.Entities
return value;
}
- public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.PersonIds = new[] { Id };
diff --git a/MediaBrowser.Controller/Entities/PersonInfo.cs b/MediaBrowser.Controller/Entities/PersonInfo.cs
index 3df0b0b78..0ed870bac 100644
--- a/MediaBrowser.Controller/Entities/PersonInfo.cs
+++ b/MediaBrowser.Controller/Entities/PersonInfo.cs
@@ -17,8 +17,14 @@ namespace MediaBrowser.Controller.Entities
public PersonInfo()
{
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ Id = Guid.NewGuid();
}
+ /// <summary>
+ /// Gets or Sets the PersonId.
+ /// </summary>
+ public Guid Id { get; set; }
+
public Guid ItemId { get; set; }
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs
index a7ecb9061..5b31b4f11 100644
--- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs
+++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs
@@ -4,6 +4,7 @@ using System.Text.Json.Serialization;
namespace MediaBrowser.Controller.Entities
{
+ [Common.RequiresSourceSerialisation]
public class PhotoAlbum : Folder
{
[JsonIgnore]
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
index a3736a4bf..9103b09a9 100644
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ b/MediaBrowser.Controller/Entities/Studio.cs
@@ -13,6 +13,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class Studio.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class Studio : BaseItem, IItemByName
{
/// <summary>
@@ -63,7 +64,7 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.StudioIds = new[] { Id };
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 181b9be2b..e3fbe8e4d 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -10,6 +10,7 @@ using System.Text.Json.Serialization;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
+using MediaBrowser.Common;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Querying;
@@ -19,6 +20,7 @@ namespace MediaBrowser.Controller.Entities.TV
/// <summary>
/// Class Season.
/// </summary>
+ [RequiresSourceSerialisation]
public class Season : Folder, IHasSeries, IHasLookupInfo<SeasonInfo>
{
[JsonIgnore]
@@ -132,7 +134,7 @@ namespace MediaBrowser.Controller.Entities.TV
var series = Series;
if (series is not null)
{
- return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000", CultureInfo.InvariantCulture);
+ return series.PresentationUniqueKey + "-" + IndexNumber.Value.ToString("000", CultureInfo.InvariantCulture);
}
}
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index a324f79ef..137d91f1c 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -189,12 +189,12 @@ namespace MediaBrowser.Controller.Entities.TV
return list;
}
- public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
+ public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
{
return GetSeasons(user, new DtoOptions(true));
}
- public List<BaseItem> GetSeasons(User user, DtoOptions options)
+ public IReadOnlyList<BaseItem> GetSeasons(User user, DtoOptions options)
{
var query = new InternalItemsQuery(user)
{
diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs
index a687adedd..7ae4a4a2c 100644
--- a/MediaBrowser.Controller/Entities/UserRootFolder.cs
+++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs
@@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class UserRootFolder : Folder
{
- private readonly object _childIdsLock = new object();
+ private readonly Lock _childIdsLock = new();
private List<Guid> _childrenIds = null;
/// <summary>
@@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- protected override List<BaseItem> LoadChildren()
+ protected override IReadOnlyList<BaseItem> LoadChildren()
{
lock (_childIdsLock)
{
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index e4fb340f7..f5ca3737c 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -134,7 +134,7 @@ namespace MediaBrowser.Controller.Entities
}
/// <inheritdoc />
- public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
+ public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
query.SetUser(user);
query.Recursive = true;
@@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.Entities
}
/// <inheritdoc />
- protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
+ protected override IReadOnlyList<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
{
return GetChildren(user, false);
}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 420349f35..4ec2e4c0a 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -236,7 +236,7 @@ namespace MediaBrowser.Controller.Entities
return ConvertToResult(_libraryManager.GetItemList(query));
}
- private QueryResult<BaseItem> ConvertToResult(List<BaseItem> items)
+ private QueryResult<BaseItem> ConvertToResult(IReadOnlyList<BaseItem> items)
{
return new QueryResult<BaseItem>(items);
}
diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs
index afdaf448b..37820296c 100644
--- a/MediaBrowser.Controller/Entities/Year.cs
+++ b/MediaBrowser.Controller/Entities/Year.cs
@@ -13,6 +13,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class Year.
/// </summary>
+ [Common.RequiresSourceSerialisation]
public class Year : BaseItem, IItemByName
{
[JsonIgnore]
@@ -55,7 +56,7 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
if (!int.TryParse(Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
{