diff options
50 files changed, 211 insertions, 162 deletions
diff --git a/.editorconfig b/.editorconfig index b84e563ef..147b76c14 100644 --- a/.editorconfig +++ b/.editorconfig @@ -192,3 +192,6 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false # Wrapping preferences csharp_preserve_single_line_statements = true csharp_preserve_single_line_blocks = true + +# CA1826: Do not use Enumerable methods on indexable collections +dotnet_diagnostic.CA1826.severity = suggestion diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 0c0ba7453..356d1e437 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -10,6 +10,7 @@ using Jellyfin.Data.Enums; using Jellyfin.Extensions; using MediaBrowser.Common; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; @@ -51,6 +52,7 @@ namespace Emby.Server.Implementations.Dto private readonly Lazy<ILiveTvManager> _livetvManagerFactory; private readonly ITrickplayManager _trickplayManager; + private readonly IChapterRepository _chapterRepository; public DtoService( ILogger<DtoService> logger, @@ -63,7 +65,8 @@ namespace Emby.Server.Implementations.Dto IApplicationHost appHost, IMediaSourceManager mediaSourceManager, Lazy<ILiveTvManager> livetvManagerFactory, - ITrickplayManager trickplayManager) + ITrickplayManager trickplayManager, + IChapterRepository chapterRepository) { _logger = logger; _libraryManager = libraryManager; @@ -76,6 +79,7 @@ namespace Emby.Server.Implementations.Dto _mediaSourceManager = mediaSourceManager; _livetvManagerFactory = livetvManagerFactory; _trickplayManager = trickplayManager; + _chapterRepository = chapterRepository; } private ILiveTvManager LivetvManager => _livetvManagerFactory.Value; @@ -165,7 +169,7 @@ namespace Emby.Server.Implementations.Dto return dto; } - private static IList<BaseItem> GetTaggedItems(IItemByName byName, User? user, DtoOptions options) + private static IReadOnlyList<BaseItem> GetTaggedItems(IItemByName byName, User? user, DtoOptions options) { return byName.GetTaggedItems( new InternalItemsQuery(user) @@ -327,7 +331,7 @@ namespace Emby.Server.Implementations.Dto return dto; } - private static void SetItemByNameInfo(BaseItem item, BaseItemDto dto, IList<BaseItem> taggedItems) + private static void SetItemByNameInfo(BaseItem item, BaseItemDto dto, IReadOnlyList<BaseItem> taggedItems) { if (item is MusicArtist) { @@ -1060,7 +1064,7 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.Chapters)) { - dto.Chapters = _itemRepo.GetChapters(item); + dto.Chapters = _chapterRepository.GetChapters(item.Id).ToList(); } if (options.ContainsField(ItemFields.Trickplay)) diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 28f7ed659..0a98d5435 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -76,6 +76,7 @@ namespace Emby.Server.Implementations.Library private readonly IItemRepository _itemRepository; private readonly IImageProcessor _imageProcessor; private readonly NamingOptions _namingOptions; + private readonly IPeopleRepository _peopleRepository; private readonly ExtraResolver _extraResolver; /// <summary> @@ -112,6 +113,7 @@ namespace Emby.Server.Implementations.Library /// <param name="imageProcessor">The image processor.</param> /// <param name="namingOptions">The naming options.</param> /// <param name="directoryService">The directory service.</param> + /// <param name="peopleRepository">The People Repository.</param> public LibraryManager( IServerApplicationHost appHost, ILoggerFactory loggerFactory, @@ -127,7 +129,8 @@ namespace Emby.Server.Implementations.Library IItemRepository itemRepository, IImageProcessor imageProcessor, NamingOptions namingOptions, - IDirectoryService directoryService) + IDirectoryService directoryService, + IPeopleRepository peopleRepository) { _appHost = appHost; _logger = loggerFactory.CreateLogger<LibraryManager>(); @@ -144,7 +147,7 @@ namespace Emby.Server.Implementations.Library _imageProcessor = imageProcessor; _cache = new ConcurrentDictionary<Guid, BaseItem>(); _namingOptions = namingOptions; - + _peopleRepository = peopleRepository; _extraResolver = new ExtraResolver(loggerFactory.CreateLogger<ExtraResolver>(), namingOptions, directoryService); _configurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -1274,7 +1277,7 @@ namespace Emby.Server.Implementations.Library return ItemIsVisible(item, user) ? item : null; } - public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent) + public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent) { if (query.Recursive && !query.ParentId.IsEmpty()) { @@ -1300,7 +1303,7 @@ namespace Emby.Server.Implementations.Library return itemList; } - public List<BaseItem> GetItemList(InternalItemsQuery query) + public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query) { return GetItemList(query, true); } @@ -1324,7 +1327,7 @@ namespace Emby.Server.Implementations.Library return _itemRepository.GetCount(query); } - public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents) + public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents) { SetTopParentIdsOrAncestors(query, parents); @@ -1357,7 +1360,7 @@ namespace Emby.Server.Implementations.Library _itemRepository.GetItemList(query)); } - public List<Guid> GetItemIds(InternalItemsQuery query) + public IReadOnlyList<Guid> GetItemIds(InternalItemsQuery query) { if (query.User is not null) { @@ -2736,12 +2739,12 @@ namespace Emby.Server.Implementations.Library return path; } - public List<PersonInfo> GetPeople(InternalPeopleQuery query) + public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery query) { - return _itemRepository.GetPeople(query); + return _peopleRepository.GetPeople(query); } - public List<PersonInfo> GetPeople(BaseItem item) + public IReadOnlyList<PersonInfo> GetPeople(BaseItem item) { if (item.SupportsPeople) { @@ -2756,12 +2759,12 @@ namespace Emby.Server.Implementations.Library } } - return new List<PersonInfo>(); + return []; } - public List<Person> GetPeopleItems(InternalPeopleQuery query) + public IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query) { - return _itemRepository.GetPeopleNames(query) + return _peopleRepository.GetPeopleNames(query) .Select(i => { try @@ -2779,9 +2782,9 @@ namespace Emby.Server.Implementations.Library .ToList()!; // null values are filtered out } - public List<string> GetPeopleNames(InternalPeopleQuery query) + public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query) { - return _itemRepository.GetPeopleNames(query); + return _peopleRepository.GetPeopleNames(query); } public void UpdatePeople(BaseItem item, List<PersonInfo> people) @@ -2790,14 +2793,14 @@ namespace Emby.Server.Implementations.Library } /// <inheritdoc /> - public async Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken) + public async Task UpdatePeopleAsync(BaseItem item, IReadOnlyList<PersonInfo> people, CancellationToken cancellationToken) { if (!item.SupportsPeople) { return; } - _itemRepository.UpdatePeople(item.Id, people); + _peopleRepository.UpdatePeople(item.Id, people); if (people is not null) { await SavePeopleMetadataAsync(people, cancellationToken).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 90a01c052..a5a715721 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -51,7 +51,8 @@ namespace Emby.Server.Implementations.Library private readonly ILocalizationManager _localizationManager; private readonly IApplicationPaths _appPaths; private readonly IDirectoryService _directoryService; - + private readonly IMediaStreamRepository _mediaStreamRepository; + private readonly IMediaAttachmentRepository _mediaAttachmentRepository; private readonly ConcurrentDictionary<string, ILiveStream> _openStreams = new ConcurrentDictionary<string, ILiveStream>(StringComparer.OrdinalIgnoreCase); private readonly AsyncNonKeyedLocker _liveStreamLocker = new(1); private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options; @@ -69,7 +70,9 @@ namespace Emby.Server.Implementations.Library IFileSystem fileSystem, IUserDataManager userDataManager, IMediaEncoder mediaEncoder, - IDirectoryService directoryService) + IDirectoryService directoryService, + IMediaStreamRepository mediaStreamRepository, + IMediaAttachmentRepository mediaAttachmentRepository) { _appHost = appHost; _itemRepo = itemRepo; @@ -82,6 +85,8 @@ namespace Emby.Server.Implementations.Library _localizationManager = localizationManager; _appPaths = applicationPaths; _directoryService = directoryService; + _mediaStreamRepository = mediaStreamRepository; + _mediaAttachmentRepository = mediaAttachmentRepository; } public void AddParts(IEnumerable<IMediaSourceProvider> providers) @@ -89,9 +94,9 @@ namespace Emby.Server.Implementations.Library _providers = providers.ToArray(); } - public List<MediaStream> GetMediaStreams(MediaStreamQuery query) + public IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery query) { - var list = _itemRepo.GetMediaStreams(query); + var list = _mediaStreamRepository.GetMediaStreams(query); foreach (var stream in list) { @@ -121,7 +126,7 @@ namespace Emby.Server.Implementations.Library return false; } - public List<MediaStream> GetMediaStreams(Guid itemId) + public IReadOnlyList<MediaStream> GetMediaStreams(Guid itemId) { var list = GetMediaStreams(new MediaStreamQuery { @@ -131,7 +136,7 @@ namespace Emby.Server.Implementations.Library return GetMediaStreamsForItem(list); } - private List<MediaStream> GetMediaStreamsForItem(List<MediaStream> streams) + private IReadOnlyList<MediaStream> GetMediaStreamsForItem(IReadOnlyList<MediaStream> streams) { foreach (var stream in streams) { @@ -145,13 +150,13 @@ namespace Emby.Server.Implementations.Library } /// <inheritdoc /> - public List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query) + public IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query) { - return _itemRepo.GetMediaAttachments(query); + return _mediaAttachmentRepository.GetMediaAttachments(query); } /// <inheritdoc /> - public List<MediaAttachment> GetMediaAttachments(Guid itemId) + public IReadOnlyList<MediaAttachment> GetMediaAttachments(Guid itemId) { return GetMediaAttachments(new MediaAttachmentQuery { @@ -332,7 +337,7 @@ namespace Emby.Server.Implementations.Library return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase)); } - public List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null) + public IReadOnlyList<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null) { ArgumentNullException.ThrowIfNull(item); diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs index a69a0f33f..c83737cec 100644 --- a/Emby.Server.Implementations/Library/MusicManager.cs +++ b/Emby.Server.Implementations/Library/MusicManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; @@ -24,7 +25,7 @@ namespace Emby.Server.Implementations.Library _libraryManager = libraryManager; } - public List<BaseItem> GetInstantMixFromSong(Audio item, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromSong(Audio item, User? user, DtoOptions dtoOptions) { var list = new List<BaseItem> { @@ -33,21 +34,21 @@ namespace Emby.Server.Implementations.Library list.AddRange(GetInstantMixFromGenres(item.Genres, user, dtoOptions)); - return list; + return list.ToImmutableList(); } /// <inheritdoc /> - public List<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(artist.Genres, user, dtoOptions); } - public List<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromAlbum(MusicAlbum item, User? user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public List<BaseItem> GetInstantMixFromFolder(Folder item, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromFolder(Folder item, User? user, DtoOptions dtoOptions) { var genres = item .GetRecursiveChildren(user, new InternalItemsQuery(user) @@ -63,12 +64,12 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromGenres(genres, user, dtoOptions); } - public List<BaseItem> GetInstantMixFromPlaylist(Playlist item, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromPlaylist(Playlist item, User? user, DtoOptions dtoOptions) { return GetInstantMixFromGenres(item.Genres, user, dtoOptions); } - public List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions) { var genreIds = genres.DistinctNames().Select(i => { @@ -85,7 +86,7 @@ namespace Emby.Server.Implementations.Library return GetInstantMixFromGenreIds(genreIds, user, dtoOptions); } - public List<BaseItem> GetInstantMixFromGenreIds(Guid[] genreIds, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromGenreIds(Guid[] genreIds, User? user, DtoOptions dtoOptions) { return _libraryManager.GetItemList(new InternalItemsQuery(user) { @@ -97,7 +98,7 @@ namespace Emby.Server.Implementations.Library }); } - public List<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions) + public IReadOnlyList<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions) { if (item is MusicGenre) { diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index 7f3f8615e..3ac1d0219 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -171,7 +171,7 @@ namespace Emby.Server.Implementations.Library } }; - List<BaseItem> mediaItems; + IReadOnlyList<BaseItem> mediaItems; if (searchQuery.IncludeItemTypes.Length == 1 && searchQuery.IncludeItemTypes[0] == BaseItemKind.MusicArtist) { diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs index cb3f5b836..c0ab535a3 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Jellyfin.Data.Enums; using Jellyfin.Extensions; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -32,6 +33,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks private readonly IEncodingManager _encodingManager; private readonly IFileSystem _fileSystem; private readonly ILocalizationManager _localization; + private readonly IChapterRepository _chapterRepository; /// <summary> /// Initializes a new instance of the <see cref="ChapterImagesTask" /> class. @@ -43,6 +45,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks /// <param name="encodingManager">Instance of the <see cref="IEncodingManager"/> interface.</param> /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param> + /// <param name="chapterRepository">Instance of the <see cref="IChapterRepository"/> interface.</param> public ChapterImagesTask( ILogger<ChapterImagesTask> logger, ILibraryManager libraryManager, @@ -50,7 +53,8 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks IApplicationPaths appPaths, IEncodingManager encodingManager, IFileSystem fileSystem, - ILocalizationManager localization) + ILocalizationManager localization, + IChapterRepository chapterRepository) { _logger = logger; _libraryManager = libraryManager; @@ -59,6 +63,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks _encodingManager = encodingManager; _fileSystem = fileSystem; _localization = localization; + _chapterRepository = chapterRepository; } /// <inheritdoc /> @@ -141,7 +146,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks try { - var chapters = _itemRepo.GetChapters(video); + var chapters = _chapterRepository.GetChapters(video.Id); var success = await _encodingManager.RefreshChapterImages(video, directoryService, chapters, extract, true, cancellationToken).ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index afc93c3a8..b2d75d5a3 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -793,7 +793,7 @@ public class LibraryController : BaseJellyfinApiController query.ExcludeArtistIds = excludeArtistIds; } - List<BaseItem> itemsResult = _libraryManager.GetItemList(query); + var itemsResult = _libraryManager.GetItemList(query); var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user); diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs index 471bcd096..11559419c 100644 --- a/Jellyfin.Api/Controllers/MoviesController.cs +++ b/Jellyfin.Api/Controllers/MoviesController.cs @@ -97,7 +97,7 @@ public class MoviesController : BaseJellyfinApiController DtoOptions = dtoOptions }; - var recentlyPlayedMovies = _libraryManager.GetItemList(query); + var recentlyPlayedMovies = _libraryManager.GetItemList(query)!; var itemTypes = new List<BaseItemKind> { BaseItemKind.Movie }; if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions) @@ -120,7 +120,7 @@ public class MoviesController : BaseJellyfinApiController DtoOptions = dtoOptions }); - var mostRecentMovies = recentlyPlayedMovies.GetRange(0, Math.Min(recentlyPlayedMovies.Count, 6)); + var mostRecentMovies = recentlyPlayedMovies.Take(Math.Min(recentlyPlayedMovies.Count, 6)); // Get recently played directors var recentDirectors = GetDirectors(mostRecentMovies) .ToList(); diff --git a/Jellyfin.Api/Controllers/YearsController.cs b/Jellyfin.Api/Controllers/YearsController.cs index e4aa0ea42..ffc34a5d9 100644 --- a/Jellyfin.Api/Controllers/YearsController.cs +++ b/Jellyfin.Api/Controllers/YearsController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; using System.Linq; using Jellyfin.Api.Extensions; @@ -105,18 +106,18 @@ public class YearsController : BaseJellyfinApiController bool Filter(BaseItem i) => FilterItem(i, excludeItemTypes, includeItemTypes, mediaTypes); - IList<BaseItem> items; + IReadOnlyList<BaseItem> items; if (parentItem.IsFolder) { var folder = (Folder)parentItem; if (userId.IsNullOrEmpty()) { - items = recursive ? folder.GetRecursiveChildren(Filter) : folder.Children.Where(Filter).ToList(); + items = recursive ? folder.GetRecursiveChildren(Filter) : folder.Children.Where(Filter).ToImmutableList(); } else { - items = recursive ? folder.GetRecursiveChildren(user, query).ToList() : folder.GetChildren(user, true).Where(Filter).ToList(); + items = recursive ? folder.GetRecursiveChildren(user, query) : folder.GetChildren(user, true).Where(Filter).ToImmutableList(); } } else diff --git a/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs b/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs index f7b714c29..f44ead6e0 100644 --- a/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs +++ b/Jellyfin.Server.Implementations/Item/MediaStreamRepository.cs @@ -174,7 +174,7 @@ public class MediaStreamRepository(IDbContextFactory<JellyfinDbContext> dbProvid Level = (float)dto.Level.GetValueOrDefault(), PixelFormat = dto.PixelFormat, BitDepth = dto.BitDepth.GetValueOrDefault(0), - IsAnamorphic = dto.IsAnamorphic.GetValueOrDefault(0), + IsAnamorphic = dto.IsAnamorphic.GetValueOrDefault(), RefFrames = dto.RefFrames.GetValueOrDefault(0), CodecTag = dto.CodecTag, Comment = dto.Comment, diff --git a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs index 3ced6e24e..584dbd1b6 100644 --- a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs +++ b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs @@ -89,7 +89,9 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider) : Name = people.Name, Role = people.Role, SortOrder = people.SortOrder, - PersonType = people.Type.ToString() + PersonType = people.Type.ToString(), + Item = null!, + ListOrder = people.SortOrder }; return personInfo; diff --git a/Jellyfin.Server.Implementations/ModelConfiguration/ChapterConfiguration.cs b/Jellyfin.Server.Implementations/ModelConfiguration/ChapterConfiguration.cs index 0e7c88931..464fbfb01 100644 --- a/Jellyfin.Server.Implementations/ModelConfiguration/ChapterConfiguration.cs +++ b/Jellyfin.Server.Implementations/ModelConfiguration/ChapterConfiguration.cs @@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Jellyfin.Server.Implementations.ModelConfiguration; - /// <summary> /// Chapter configuration. /// </summary> diff --git a/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs b/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs index f6c48498c..9fe3ee010 100644 --- a/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs +++ b/Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs @@ -179,7 +179,7 @@ public class TrickplayManager : ITrickplayManager { // Extract images // Note: Media sources under parent items exist as their own video/item as well. Only use this video stream for trickplay. - var mediaSource = video.GetMediaSources(false).Find(source => Guid.Parse(source.Id).Equals(video.Id)); + var mediaSource = video.GetMediaSources(false).FirstOrDefault(source => Guid.Parse(source.Id).Equals(video.Id)); if (mediaSource is null) { diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 40cdd6c91..00b06dc79 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -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/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 1ab6c9706..6d3249399 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -84,7 +84,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) { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 7448d02ea..80f3902be 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -64,7 +64,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/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index a4764dd33..054c71db7 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; @@ -1044,7 +1045,7 @@ namespace MediaBrowser.Controller.Entities return PlayAccess.Full; } - public virtual List<MediaStream> GetMediaStreams() + public virtual IReadOnlyList<MediaStream> GetMediaStreams() { return MediaSourceManager.GetMediaStreams(new MediaStreamQuery { @@ -1057,7 +1058,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) { @@ -1091,7 +1092,7 @@ namespace MediaBrowser.Controller.Entities return 1; }).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0) .ThenByDescending(i => i, new MediaSourceWidthComparator()) - .ToList(); + .ToImmutableList(); } protected virtual IEnumerable<(BaseItem Item, MediaSourceType MediaSourceType)> GetAllItemsForMediaSources() @@ -2527,7 +2528,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/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 83c19a54e..1bec66f95 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 @@ -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 { @@ -1283,14 +1285,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 +1306,7 @@ namespace MediaBrowser.Controller.Entities AddChildren(user, includeLinkedChildren, result, false, query); - return result.Values.ToList(); + return result.Values.ToImmutableList(); } protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) @@ -1369,7 +1371,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 +1379,35 @@ namespace MediaBrowser.Controller.Entities AddChildren(user, true, result, true, query); - return result.Values; + return result.Values.ToImmutableList(); } /// <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.ToImmutableList(); } /// <summary> @@ -1556,11 +1558,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) + .ToImmutableList(); } 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..e5353d7bd 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -61,7 +61,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/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index a07187d2f..4cddc9125 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).ToImmutableList(); } - 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).ToImmutableList(); } public BoxSetInfo GetLookupInfo() diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs index 5292bd772..4141b1712 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..b0933d23f 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -62,7 +62,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/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index a3736a4bf..b46a3d1bc 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -63,7 +63,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/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..7cf447fb8 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -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..587d7ce7e 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -55,7 +55,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)) { diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index b802b7e6e..47b1cb16e 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -483,21 +483,21 @@ namespace MediaBrowser.Controller.Library /// </summary> /// <param name="item">The item.</param> /// <returns>List<PersonInfo>.</returns> - List<PersonInfo> GetPeople(BaseItem item); + IReadOnlyList<PersonInfo> GetPeople(BaseItem item); /// <summary> /// Gets the people. /// </summary> /// <param name="query">The query.</param> /// <returns>List<PersonInfo>.</returns> - List<PersonInfo> GetPeople(InternalPeopleQuery query); + IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery query); /// <summary> /// Gets the people items. /// </summary> /// <param name="query">The query.</param> /// <returns>List<Person>.</returns> - List<Person> GetPeopleItems(InternalPeopleQuery query); + IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query); /// <summary> /// Updates the people. @@ -513,21 +513,21 @@ namespace MediaBrowser.Controller.Library /// <param name="people">The people.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The async task.</returns> - Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken); + Task UpdatePeopleAsync(BaseItem item, IReadOnlyList<PersonInfo> people, CancellationToken cancellationToken); /// <summary> /// Gets the item ids. /// </summary> /// <param name="query">The query.</param> /// <returns>List<Guid>.</returns> - List<Guid> GetItemIds(InternalItemsQuery query); + IReadOnlyList<Guid> GetItemIds(InternalItemsQuery query); /// <summary> /// Gets the people names. /// </summary> /// <param name="query">The query.</param> /// <returns>List<System.String>.</returns> - List<string> GetPeopleNames(InternalPeopleQuery query); + IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query); /// <summary> /// Queries the items. @@ -553,9 +553,9 @@ namespace MediaBrowser.Controller.Library /// </summary> /// <param name="query">The query.</param> /// <returns>QueryResult<BaseItem>.</returns> - List<BaseItem> GetItemList(InternalItemsQuery query); + IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query); - List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent); + IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent); /// <summary> /// Gets the items. @@ -563,7 +563,7 @@ namespace MediaBrowser.Controller.Library /// <param name="query">The query to use.</param> /// <param name="parents">Items to use for query.</param> /// <returns>List of items.</returns> - List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents); + IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents); /// <summary> /// Gets the items result. diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index 44a1a85e3..5ed3a49c3 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -29,28 +29,28 @@ namespace MediaBrowser.Controller.Library /// </summary> /// <param name="itemId">The item identifier.</param> /// <returns>IEnumerable<MediaStream>.</returns> - List<MediaStream> GetMediaStreams(Guid itemId); + IReadOnlyList<MediaStream> GetMediaStreams(Guid itemId); /// <summary> /// Gets the media streams. /// </summary> /// <param name="query">The query.</param> /// <returns>IEnumerable<MediaStream>.</returns> - List<MediaStream> GetMediaStreams(MediaStreamQuery query); + IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery query); /// <summary> /// Gets the media attachments. /// </summary> /// <param name="itemId">The item identifier.</param> /// <returns>IEnumerable<MediaAttachment>.</returns> - List<MediaAttachment> GetMediaAttachments(Guid itemId); + IReadOnlyList<MediaAttachment> GetMediaAttachments(Guid itemId); /// <summary> /// Gets the media attachments. /// </summary> /// <param name="query">The query.</param> /// <returns>IEnumerable<MediaAttachment>.</returns> - List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query); + IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query); /// <summary> /// Gets the playack media sources. diff --git a/MediaBrowser.Controller/Library/IMusicManager.cs b/MediaBrowser.Controller/Library/IMusicManager.cs index 93073cc79..7ba8fc20c 100644 --- a/MediaBrowser.Controller/Library/IMusicManager.cs +++ b/MediaBrowser.Controller/Library/IMusicManager.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Library /// <param name="user">The user to use.</param> /// <param name="dtoOptions">The options to use.</param> /// <returns>List of items.</returns> - List<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions); + IReadOnlyList<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions); /// <summary> /// Gets the instant mix from artist. @@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Library /// <param name="user">The user to use.</param> /// <param name="dtoOptions">The options to use.</param> /// <returns>List of items.</returns> - List<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions); + IReadOnlyList<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions); /// <summary> /// Gets the instant mix from genre. @@ -35,6 +35,6 @@ namespace MediaBrowser.Controller.Library /// <param name="user">The user to use.</param> /// <param name="dtoOptions">The options to use.</param> /// <returns>List of items.</returns> - List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions); + IReadOnlyList<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions); } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 3c2cf8e3d..64d49d8c4 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.Linq; using System.Text.Json.Serialization; @@ -122,7 +123,7 @@ namespace MediaBrowser.Controller.LiveTv public IEnumerable<BaseItem> GetTaggedItems() => Enumerable.Empty<BaseItem>(); - public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution) + public override IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution) { var list = new List<MediaSourceInfo>(); @@ -140,12 +141,12 @@ namespace MediaBrowser.Controller.LiveTv list.Add(info); - return list; + return list.ToImmutableList(); } - public override List<MediaStream> GetMediaStreams() + public override IReadOnlyList<MediaStream> GetMediaStreams() { - return new List<MediaStream>(); + return []; } protected override string GetInternalMetadataPath(string basePath) diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 45aefacf6..bf6871a74 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -137,27 +137,27 @@ namespace MediaBrowser.Controller.Playlists return Task.CompletedTask; } - public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query) + public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query) { return GetPlayableItems(user, query); } - protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService) + protected override IReadOnlyList<BaseItem> GetNonCachedChildren(IDirectoryService directoryService) { return []; } - public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query) + public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query) { return GetPlayableItems(user, query); } - public IEnumerable<Tuple<LinkedChild, BaseItem>> GetManageableItems() + public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetManageableItems() { return GetLinkedChildrenInfos(); } - private List<BaseItem> GetPlayableItems(User user, InternalItemsQuery query) + private IReadOnlyList<BaseItem> GetPlayableItems(User user, InternalItemsQuery query) { query ??= new InternalItemsQuery(user); diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs index cfff3eb14..eabbe73cd 100644 --- a/MediaBrowser.Controller/Providers/MetadataResult.cs +++ b/MediaBrowser.Controller/Providers/MetadataResult.cs @@ -3,6 +3,7 @@ #pragma warning disable CA1002, CA2227, CS1591 using System.Collections.Generic; +using System.Linq; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Entities; @@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Providers // Images aren't always used so the allocation is a waste a lot of the time private List<LocalImageInfo> _images; private List<(string Url, ImageType Type)> _remoteImages; + private List<PersonInfo> _people; public MetadataResult() { @@ -21,17 +23,21 @@ namespace MediaBrowser.Controller.Providers public List<LocalImageInfo> Images { - get => _images ??= new List<LocalImageInfo>(); + get => _images ??= []; set => _images = value; } public List<(string Url, ImageType Type)> RemoteImages { - get => _remoteImages ??= new List<(string Url, ImageType Type)>(); + get => _remoteImages ??= []; set => _remoteImages = value; } - public List<PersonInfo> People { get; set; } + public IReadOnlyList<PersonInfo> People + { + get => _people; + set => _people = value.ToList(); + } public bool HasMetadata { get; set; } @@ -47,7 +53,7 @@ namespace MediaBrowser.Controller.Providers { People ??= new List<PersonInfo>(); - PeopleHelper.AddPerson(People, p); + PeopleHelper.AddPerson(_people, p); } /// <summary> @@ -61,7 +67,7 @@ namespace MediaBrowser.Controller.Providers } else { - People.Clear(); + _people.Clear(); } } } diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 32ab7716f..b51ab4c08 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -39,7 +39,7 @@ namespace MediaBrowser.Providers.BoxSets protected override bool EnableUpdatingPremiereDateFromChildren => true; /// <inheritdoc /> - protected override IList<BaseItem> GetChildrenForMetadataUpdates(BoxSet item) + protected override IReadOnlyList<BaseItem> GetChildrenForMetadataUpdates(BoxSet item) { return item.GetLinkedChildren(); } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 7203bf115..4c9d162c4 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -322,17 +322,17 @@ namespace MediaBrowser.Providers.Manager return false; } - protected virtual IList<BaseItem> GetChildrenForMetadataUpdates(TItemType item) + protected virtual IReadOnlyList<BaseItem> GetChildrenForMetadataUpdates(TItemType item) { if (item is Folder folder) { return folder.GetRecursiveChildren(); } - return Array.Empty<BaseItem>(); + return []; } - protected virtual ItemUpdateType UpdateMetadataFromChildren(TItemType item, IList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected virtual ItemUpdateType UpdateMetadataFromChildren(TItemType item, IReadOnlyList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType) { var updateType = ItemUpdateType.None; @@ -371,7 +371,7 @@ namespace MediaBrowser.Providers.Manager return updateType; } - private ItemUpdateType UpdateCumulativeRunTimeTicks(TItemType item, IList<BaseItem> children) + private ItemUpdateType UpdateCumulativeRunTimeTicks(TItemType item, IReadOnlyList<BaseItem> children) { if (item is Folder folder && folder.SupportsCumulativeRunTimeTicks) { @@ -395,7 +395,7 @@ namespace MediaBrowser.Providers.Manager return ItemUpdateType.None; } - private ItemUpdateType UpdateDateLastMediaAdded(TItemType item, IList<BaseItem> children) + private ItemUpdateType UpdateDateLastMediaAdded(TItemType item, IReadOnlyList<BaseItem> children) { var updateType = ItemUpdateType.None; @@ -429,7 +429,7 @@ namespace MediaBrowser.Providers.Manager return updateType; } - private ItemUpdateType UpdatePremiereDate(TItemType item, IList<BaseItem> children) + private ItemUpdateType UpdatePremiereDate(TItemType item, IReadOnlyList<BaseItem> children) { var updateType = ItemUpdateType.None; @@ -467,7 +467,7 @@ namespace MediaBrowser.Providers.Manager return updateType; } - private ItemUpdateType UpdateGenres(TItemType item, IList<BaseItem> children) + private ItemUpdateType UpdateGenres(TItemType item, IReadOnlyList<BaseItem> children) { var updateType = ItemUpdateType.None; @@ -488,7 +488,7 @@ namespace MediaBrowser.Providers.Manager return updateType; } - private ItemUpdateType UpdateStudios(TItemType item, IList<BaseItem> children) + private ItemUpdateType UpdateStudios(TItemType item, IReadOnlyList<BaseItem> children) { var updateType = ItemUpdateType.None; @@ -509,7 +509,7 @@ namespace MediaBrowser.Providers.Manager return updateType; } - private ItemUpdateType UpdateOfficialRating(TItemType item, IList<BaseItem> children) + private ItemUpdateType UpdateOfficialRating(TItemType item, IReadOnlyList<BaseItem> children) { var updateType = ItemUpdateType.None; @@ -1142,13 +1142,8 @@ namespace MediaBrowser.Providers.Manager } } - private static void MergePeople(List<PersonInfo> source, List<PersonInfo> target) + private static void MergePeople(IReadOnlyList<PersonInfo> source, IReadOnlyList<PersonInfo> target) { - if (target is null) - { - target = new List<PersonInfo>(); - } - foreach (var person in target) { var normalizedName = person.Name.RemoveDiacritics(); diff --git a/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs b/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs index 27f6d120f..3add439f9 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs @@ -36,6 +36,7 @@ namespace MediaBrowser.Providers.MediaInfo private readonly IMediaSourceManager _mediaSourceManager; private readonly LyricResolver _lyricResolver; private readonly ILyricManager _lyricManager; + private readonly IMediaStreamRepository _mediaStreamRepository; /// <summary> /// Initializes a new instance of the <see cref="AudioFileProber"/> class. @@ -47,6 +48,7 @@ namespace MediaBrowser.Providers.MediaInfo /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param> /// <param name="lyricResolver">Instance of the <see cref="LyricResolver"/> interface.</param> /// <param name="lyricManager">Instance of the <see cref="ILyricManager"/> interface.</param> + /// <param name="mediaStreamRepository">Instance of the <see cref="IMediaStreamRepository"/>.</param> public AudioFileProber( ILogger<AudioFileProber> logger, IMediaSourceManager mediaSourceManager, @@ -54,7 +56,8 @@ namespace MediaBrowser.Providers.MediaInfo IItemRepository itemRepo, ILibraryManager libraryManager, LyricResolver lyricResolver, - ILyricManager lyricManager) + ILyricManager lyricManager, + IMediaStreamRepository mediaStreamRepository) { _mediaEncoder = mediaEncoder; _itemRepo = itemRepo; @@ -63,6 +66,7 @@ namespace MediaBrowser.Providers.MediaInfo _mediaSourceManager = mediaSourceManager; _lyricResolver = lyricResolver; _lyricManager = lyricManager; + _mediaStreamRepository = mediaStreamRepository; ATL.Settings.DisplayValueSeparator = InternalValueSeparator; ATL.Settings.UseFileNameWhenNoTitle = false; ATL.Settings.ID3v2_separatev2v3Values = false; @@ -149,7 +153,7 @@ namespace MediaBrowser.Providers.MediaInfo audio.HasLyrics = mediaStreams.Any(s => s.Type == MediaStreamType.Lyric); - _itemRepo.SaveMediaStreams(audio.Id, mediaStreams, cancellationToken); + _mediaStreamRepository.SaveMediaStreams(audio.Id, mediaStreams, cancellationToken); } /// <summary> diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index d1c0ddb37..bfe4f3300 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Providers.MediaInfo return GetImage((Audio)item, imageStreams, cancellationToken); } - private async Task<DynamicImageResponse> GetImage(Audio item, List<MediaStream> imageStreams, CancellationToken cancellationToken) + private async Task<DynamicImageResponse> GetImage(Audio item, IReadOnlyList<MediaStream> imageStreams, CancellationToken cancellationToken) { var path = GetAudioImagePath(item); diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 62c590944..301555eef 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -31,6 +31,7 @@ namespace MediaBrowser.Providers.MediaInfo public class FFProbeVideoInfo { private readonly ILogger<FFProbeVideoInfo> _logger; + private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaEncoder _mediaEncoder; private readonly IItemRepository _itemRepo; private readonly IBlurayExaminer _blurayExaminer; @@ -42,7 +43,8 @@ namespace MediaBrowser.Providers.MediaInfo private readonly ILibraryManager _libraryManager; private readonly AudioResolver _audioResolver; private readonly SubtitleResolver _subtitleResolver; - private readonly IMediaSourceManager _mediaSourceManager; + private readonly IMediaAttachmentRepository _mediaAttachmentRepository; + private readonly IMediaStreamRepository _mediaStreamRepository; public FFProbeVideoInfo( ILogger<FFProbeVideoInfo> logger, @@ -57,7 +59,9 @@ namespace MediaBrowser.Providers.MediaInfo IChapterRepository chapterManager, ILibraryManager libraryManager, AudioResolver audioResolver, - SubtitleResolver subtitleResolver) + SubtitleResolver subtitleResolver, + IMediaAttachmentRepository mediaAttachmentRepository, + IMediaStreamRepository mediaStreamRepository) { _logger = logger; _mediaSourceManager = mediaSourceManager; @@ -72,6 +76,9 @@ namespace MediaBrowser.Providers.MediaInfo _libraryManager = libraryManager; _audioResolver = audioResolver; _subtitleResolver = subtitleResolver; + _mediaAttachmentRepository = mediaAttachmentRepository; + _mediaStreamRepository = mediaStreamRepository; + _mediaStreamRepository = mediaStreamRepository; } public async Task<ItemUpdateType> ProbeVideo<T>( @@ -267,11 +274,11 @@ namespace MediaBrowser.Providers.MediaInfo video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle); - _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken); + _mediaStreamRepository.SaveMediaStreams(video.Id, mediaStreams, cancellationToken); if (mediaAttachments.Any()) { - _itemRepo.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken); + _mediaAttachmentRepository.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken); } if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh diff --git a/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs index f5e9dddcf..1c2f8b913 100644 --- a/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs @@ -67,6 +67,8 @@ namespace MediaBrowser.Providers.MediaInfo /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param> /// <param name="namingOptions">The <see cref="NamingOptions"/>.</param> /// <param name="lyricManager">Instance of the <see cref="ILyricManager"/> interface.</param> + /// <param name="mediaAttachmentRepository">Instance of the <see cref="IMediaAttachmentRepository"/> interface.</param> + /// <param name="mediaStreamRepository">Instance of the <see cref="IMediaStreamRepository"/> interface.</param> public ProbeProvider( IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, @@ -81,7 +83,9 @@ namespace MediaBrowser.Providers.MediaInfo IFileSystem fileSystem, ILoggerFactory loggerFactory, NamingOptions namingOptions, - ILyricManager lyricManager) + ILyricManager lyricManager, + IMediaAttachmentRepository mediaAttachmentRepository, + IMediaStreamRepository mediaStreamRepository) { _logger = loggerFactory.CreateLogger<ProbeProvider>(); _audioResolver = new AudioResolver(loggerFactory.CreateLogger<AudioResolver>(), localization, mediaEncoder, fileSystem, namingOptions); @@ -101,7 +105,9 @@ namespace MediaBrowser.Providers.MediaInfo chapterManager, libraryManager, _audioResolver, - _subtitleResolver); + _subtitleResolver, + mediaAttachmentRepository, + mediaStreamRepository); _audioProber = new AudioFileProber( loggerFactory.CreateLogger<AudioFileProber>(), @@ -110,7 +116,8 @@ namespace MediaBrowser.Providers.MediaInfo itemRepo, libraryManager, _lyricResolver, - lyricManager); + lyricManager, + mediaStreamRepository); } /// <inheritdoc /> diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs index 20fb4dab9..227f31025 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleDownloader.cs @@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.MediaInfo public async Task<List<string>> DownloadSubtitles( Video video, - List<MediaStream> mediaStreams, + IReadOnlyList<MediaStream> mediaStreams, bool skipIfEmbeddedSubtitlesPresent, bool skipIfAudioTrackMatches, bool requirePerfectMatch, @@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.MediaInfo public Task<bool> DownloadSubtitles( Video video, - List<MediaStream> mediaStreams, + IReadOnlyList<MediaStream> mediaStreams, bool skipIfEmbeddedSubtitlesPresent, bool skipIfAudioTrackMatches, bool requirePerfectMatch, @@ -120,7 +120,7 @@ namespace MediaBrowser.Providers.MediaInfo private async Task<bool> DownloadSubtitles( Video video, - List<MediaStream> mediaStreams, + IReadOnlyList<MediaStream> mediaStreams, bool skipIfEmbeddedSubtitlesPresent, bool skipIfAudioTrackMatches, bool requirePerfectMatch, diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index a39bd16ce..25698d8cb 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -47,11 +47,11 @@ namespace MediaBrowser.Providers.Music protected override bool EnableUpdatingStudiosFromChildren => true; /// <inheritdoc /> - protected override IList<BaseItem> GetChildrenForMetadataUpdates(MusicAlbum item) + protected override IReadOnlyList<BaseItem> GetChildrenForMetadataUpdates(MusicAlbum item) => item.GetRecursiveChildren(i => i is Audio); /// <inheritdoc /> - protected override ItemUpdateType UpdateMetadataFromChildren(MusicAlbum item, IList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected override ItemUpdateType UpdateMetadataFromChildren(MusicAlbum item, IReadOnlyList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType) { var updateType = base.UpdateMetadataFromChildren(item, children, isFullRefresh, currentUpdateType); diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index 1f342c0db..8af6de925 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System.Collections.Generic; +using System.Collections.Immutable; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -28,7 +29,7 @@ namespace MediaBrowser.Providers.Music protected override bool EnableUpdatingGenresFromChildren => true; /// <inheritdoc /> - protected override IList<BaseItem> GetChildrenForMetadataUpdates(MusicArtist item) + protected override IReadOnlyList<BaseItem> GetChildrenForMetadataUpdates(MusicArtist item) { return item.IsAccessedByName ? item.GetTaggedItems(new InternalItemsQuery @@ -36,7 +37,7 @@ namespace MediaBrowser.Providers.Music Recursive = true, IsFolder = false }) - : item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder); + : item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToImmutableArray(); } } } diff --git a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs index 43889bfbf..7be54453f 100644 --- a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs +++ b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Playlists protected override bool EnableUpdatingStudiosFromChildren => true; /// <inheritdoc /> - protected override IList<BaseItem> GetChildrenForMetadataUpdates(Playlist item) + protected override IReadOnlyList<BaseItem> GetChildrenForMetadataUpdates(Playlist item) => item.GetLinkedChildren(); /// <inheritdoc /> diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index 8b690193e..b27ccaa6a 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -80,11 +80,11 @@ namespace MediaBrowser.Providers.TV } /// <inheritdoc /> - protected override IList<BaseItem> GetChildrenForMetadataUpdates(Season item) + protected override IReadOnlyList<BaseItem> GetChildrenForMetadataUpdates(Season item) => item.GetEpisodes(); /// <inheritdoc /> - protected override ItemUpdateType UpdateMetadataFromChildren(Season item, IList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected override ItemUpdateType UpdateMetadataFromChildren(Season item, IReadOnlyList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType) { var updateType = base.UpdateMetadataFromChildren(item, children, isFullRefresh, currentUpdateType); @@ -96,7 +96,7 @@ namespace MediaBrowser.Providers.TV return updateType; } - private ItemUpdateType SaveIsVirtualItem(Season item, IList<BaseItem> episodes) + private ItemUpdateType SaveIsVirtualItem(Season item, IReadOnlyList<BaseItem> episodes) { var isVirtualItem = item.LocationType == LocationType.Virtual && (episodes.Count == 0 || episodes.All(i => i.LocationType == LocationType.Virtual)); diff --git a/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs index 813d75f6c..4cd676be1 100644 --- a/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.XbmcMetadata.Savers AddAlbums(albums, writer); } - private void AddAlbums(IList<BaseItem> albums, XmlWriter writer) + private void AddAlbums(IReadOnlyList<BaseItem> albums, XmlWriter writer) { foreach (var album in albums) { diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 79e9e7503..51c5a2080 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -914,7 +914,7 @@ namespace MediaBrowser.XbmcMetadata.Savers writer.WriteEndElement(); } - private void AddActors(List<PersonInfo> people, XmlWriter writer, ILibraryManager libraryManager, bool saveImagePath) + private void AddActors(IReadOnlyList<PersonInfo> people, XmlWriter writer, ILibraryManager libraryManager, bool saveImagePath) { foreach (var person in people) { |
