From 3d4b2f840a3652490e0dbe559e5aa853a45130e2 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 4 Feb 2023 12:34:24 +0100 Subject: Fix BD and DVD folder recognition for tv episodes --- .../Library/Resolvers/BaseVideoResolver.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index e8615e7db..27062228f 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -67,11 +67,23 @@ namespace Emby.Server.Implementations.Library.Resolvers { if (IsDvdDirectory(child.FullName, filename, args.DirectoryService)) { - videoType = VideoType.Dvd; + var videoTmp = new TVideoType + { + Path = args.Path, + VideoType = VideoType.Dvd + }; + Set3DFormat(videoTmp); + return videoTmp; } else if (IsBluRayDirectory(filename)) { - videoType = VideoType.BluRay; + var videoTmp = new TVideoType + { + Path = args.Path, + VideoType = VideoType.BluRay + }; + Set3DFormat(videoTmp); + return videoTmp; } } else if (IsDvdFile(filename)) -- cgit v1.2.3 From 48263078b46aa4ef46c0fb6944665b2c317bf077 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 17 Feb 2023 15:00:06 +0100 Subject: Reduce string allocations by regex --- Emby.Naming/AudioBook/AudioBookFilePathParser.cs | 4 +-- Emby.Naming/AudioBook/AudioBookNameParser.cs | 2 +- Emby.Naming/Common/NamingOptions.cs | 32 ---------------------- Emby.Naming/TV/EpisodePathParser.cs | 14 +++++----- Emby.Naming/Video/CleanDateTimeParser.cs | 2 +- Emby.Naming/Video/ExtraRuleResolver.cs | 2 +- Emby.Naming/Video/VideoListResolver.cs | 9 +++--- .../Library/Resolvers/Movies/MovieResolver.cs | 9 ++---- .../Users/UserManager.cs | 2 +- .../Encoder/EncoderValidator.cs | 6 ++-- .../Common/NamingOptionsTest.cs | 2 -- 11 files changed, 22 insertions(+), 62 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs index 7b4429ab1..219599d56 100644 --- a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs +++ b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs @@ -40,7 +40,7 @@ namespace Emby.Naming.AudioBook var value = match.Groups["chapter"]; if (value.Success) { - if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) + if (int.TryParse(value.ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) { result.ChapterNumber = intValue; } @@ -52,7 +52,7 @@ namespace Emby.Naming.AudioBook var value = match.Groups["part"]; if (value.Success) { - if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) + if (int.TryParse(value.ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) { result.PartNumber = intValue; } diff --git a/Emby.Naming/AudioBook/AudioBookNameParser.cs b/Emby.Naming/AudioBook/AudioBookNameParser.cs index 97b34199e..f49c3f0e7 100644 --- a/Emby.Naming/AudioBook/AudioBookNameParser.cs +++ b/Emby.Naming/AudioBook/AudioBookNameParser.cs @@ -47,7 +47,7 @@ namespace Emby.Naming.AudioBook var value = match.Groups["year"]; if (value.Success) { - if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) + if (int.TryParse(value.ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) { result.Year = intValue; } diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index 54f62a157..c16a71e02 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -453,16 +453,6 @@ namespace Emby.Naming.Common }, }; - EpisodeWithoutSeasonExpressions = new[] - { - @"[/\._ \-]()([0-9]+)(-[0-9]+)?" - }; - - EpisodeMultiPartExpressions = new[] - { - @"^[-_ex]+([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)" - }; - VideoExtraRules = new[] { new ExtraRule( @@ -797,16 +787,6 @@ namespace Emby.Naming.Common /// public EpisodeExpression[] EpisodeExpressions { get; set; } - /// - /// Gets or sets list of raw episode without season regular expressions strings. - /// - public string[] EpisodeWithoutSeasonExpressions { get; set; } - - /// - /// Gets or sets list of raw multi-part episodes regular expressions strings. - /// - public string[] EpisodeMultiPartExpressions { get; set; } - /// /// Gets or sets list of video file extensions. /// @@ -877,16 +857,6 @@ namespace Emby.Naming.Common /// public Regex[] CleanStringRegexes { get; private set; } = Array.Empty(); - /// - /// Gets list of episode without season regular expressions. - /// - public Regex[] EpisodeWithoutSeasonRegexes { get; private set; } = Array.Empty(); - - /// - /// Gets list of multi-part episode regular expressions. - /// - public Regex[] EpisodeMultiPartRegexes { get; private set; } = Array.Empty(); - /// /// Compiles raw regex strings into regexes. /// @@ -894,8 +864,6 @@ namespace Emby.Naming.Common { CleanDateTimeRegexes = CleanDateTimes.Select(Compile).ToArray(); CleanStringRegexes = CleanStrings.Select(Compile).ToArray(); - EpisodeWithoutSeasonRegexes = EpisodeWithoutSeasonExpressions.Select(Compile).ToArray(); - EpisodeMultiPartRegexes = EpisodeMultiPartExpressions.Select(Compile).ToArray(); } private Regex Compile(string exp) diff --git a/Emby.Naming/TV/EpisodePathParser.cs b/Emby.Naming/TV/EpisodePathParser.cs index d706be280..8cd5a126e 100644 --- a/Emby.Naming/TV/EpisodePathParser.cs +++ b/Emby.Naming/TV/EpisodePathParser.cs @@ -113,7 +113,7 @@ namespace Emby.Naming.TV if (expression.DateTimeFormats.Length > 0) { if (DateTime.TryParseExact( - match.Groups[0].Value, + match.Groups[0].ValueSpan, expression.DateTimeFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, @@ -125,7 +125,7 @@ namespace Emby.Naming.TV result.Success = true; } } - else if (DateTime.TryParse(match.Groups[0].Value, out date)) + else if (DateTime.TryParse(match.Groups[0].ValueSpan, out date)) { result.Year = date.Year; result.Month = date.Month; @@ -138,12 +138,12 @@ namespace Emby.Naming.TV } else if (expression.IsNamed) { - if (int.TryParse(match.Groups["seasonnumber"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) + if (int.TryParse(match.Groups["seasonnumber"].ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) { result.SeasonNumber = num; } - if (int.TryParse(match.Groups["epnumber"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) + if (int.TryParse(match.Groups["epnumber"].ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) { result.EpisodeNumber = num; } @@ -158,7 +158,7 @@ namespace Emby.Naming.TV if (nextIndex >= name.Length || !"0123456789iIpP".Contains(name[nextIndex], StringComparison.Ordinal)) { - if (int.TryParse(endingNumberGroup.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) + if (int.TryParse(endingNumberGroup.ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) { result.EndingEpisodeNumber = num; } @@ -170,12 +170,12 @@ namespace Emby.Naming.TV } else { - if (int.TryParse(match.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) + if (int.TryParse(match.Groups[1].ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) { result.SeasonNumber = num; } - if (int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) + if (int.TryParse(match.Groups[2].ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) { result.EpisodeNumber = num; } diff --git a/Emby.Naming/Video/CleanDateTimeParser.cs b/Emby.Naming/Video/CleanDateTimeParser.cs index 0ee633dcc..9a6c6e978 100644 --- a/Emby.Naming/Video/CleanDateTimeParser.cs +++ b/Emby.Naming/Video/CleanDateTimeParser.cs @@ -43,7 +43,7 @@ namespace Emby.Naming.Video && match.Groups.Count == 5 && match.Groups[1].Success && match.Groups[2].Success - && int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year)) + && int.TryParse(match.Groups[2].ValueSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year)) { result = new CleanDateTimeResult(match.Groups[1].Value.TrimEnd(), year); return true; diff --git a/Emby.Naming/Video/ExtraRuleResolver.cs b/Emby.Naming/Video/ExtraRuleResolver.cs index 21d0da364..3219472ef 100644 --- a/Emby.Naming/Video/ExtraRuleResolver.cs +++ b/Emby.Naming/Video/ExtraRuleResolver.cs @@ -56,7 +56,7 @@ namespace Emby.Naming.Video } else if (rule.RuleType == ExtraRuleType.Regex) { - var filename = Path.GetFileName(path); + var filename = Path.GetFileName(path.AsSpan()); var isMatch = Regex.IsMatch(filename, rule.Token, RegexOptions.IgnoreCase | RegexOptions.Compiled); diff --git a/Emby.Naming/Video/VideoListResolver.cs b/Emby.Naming/Video/VideoListResolver.cs index 01e383d1c..8247c374d 100644 --- a/Emby.Naming/Video/VideoListResolver.cs +++ b/Emby.Naming/Video/VideoListResolver.cs @@ -176,16 +176,15 @@ namespace Emby.Naming.Video } // There are no span overloads for regex unfortunately - var tmpTestFilename = testFilename.ToString(); - if (CleanStringParser.TryClean(tmpTestFilename, namingOptions.CleanStringRegexes, out var cleanName)) + if (CleanStringParser.TryClean(testFilename.ToString(), namingOptions.CleanStringRegexes, out var cleanName)) { - tmpTestFilename = cleanName.Trim(); + testFilename = cleanName.AsSpan().Trim(); } // The CleanStringParser should have removed common keywords etc. - return string.IsNullOrEmpty(tmpTestFilename) + return testFilename.IsEmpty || testFilename[0] == '-' - || Regex.IsMatch(tmpTestFilename, @"^\[([^]]*)\]", RegexOptions.Compiled); + || Regex.IsMatch(testFilename, @"^\[([^]]*)\]", RegexOptions.Compiled); } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 1522cd3ae..ef4fa1fd2 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -313,13 +313,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies return result; } - private static bool IsIgnored(string filename) - { - // Ignore samples - Match m = Regex.Match(filename, @"\bsample\b", RegexOptions.IgnoreCase | RegexOptions.Compiled); - - return m.Success; - } + private static bool IsIgnored(ReadOnlySpan filename) + => Regex.IsMatch(filename, @"\bsample\b", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static bool ContainsFile(IReadOnlyList result, FileSystemMetadata file) { diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 92384986a..c4756433e 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -740,7 +740,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", nameof(name)); } - private static bool IsValidUsername(string name) + private static bool IsValidUsername(ReadOnlySpan name) { // This is some regex that matches only on unicode "word" characters, as well as -, _ and @ // In theory this will cut out most if not all 'control' characters which should help minimize any weirdness diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 9e6134b52..540d50bf1 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -277,7 +277,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (match.Success) { - if (Version.TryParse(match.Groups[1].Value, out var result)) + if (Version.TryParse(match.Groups[1].ValueSpan, out var result)) { return result; } @@ -327,8 +327,8 @@ namespace MediaBrowser.MediaEncoding.Encoder RegexOptions.Multiline)) { var version = new Version( - int.Parse(match.Groups["major"].Value, CultureInfo.InvariantCulture), - int.Parse(match.Groups["minor"].Value, CultureInfo.InvariantCulture)); + int.Parse(match.Groups["major"].ValueSpan, CultureInfo.InvariantCulture), + int.Parse(match.Groups["minor"].ValueSpan, CultureInfo.InvariantCulture)); map.Add(match.Groups["name"].Value, version); } diff --git a/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs b/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs index 58aaed023..c49663248 100644 --- a/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs +++ b/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs @@ -12,8 +12,6 @@ namespace Jellyfin.Naming.Tests.Common Assert.NotEmpty(options.CleanDateTimeRegexes); Assert.NotEmpty(options.CleanStringRegexes); - Assert.NotEmpty(options.EpisodeWithoutSeasonRegexes); - Assert.NotEmpty(options.EpisodeMultiPartRegexes); } [Fact] -- cgit v1.2.3 From 4b01aaa0f7c52557d1500daaae2bc457a56dbffe Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 1 Mar 2023 00:44:57 +0100 Subject: Allocate less Lists --- .../ConnectionManagerXmlBuilder.cs | 4 +-- .../ContentDirectory/ContentDirectoryXmlBuilder.cs | 4 +-- Emby.Naming/AudioBook/AudioBookListResolver.cs | 20 ++++++------- .../Channels/ChannelManager.cs | 2 +- .../Collections/CollectionManager.cs | 18 +++++++----- .../Data/SqliteItemRepository.cs | 10 ++++--- Emby.Server.Implementations/Dto/DtoService.cs | 12 ++++---- .../Library/LibraryManager.cs | 33 ++++++++++------------ .../Library/Resolvers/Audio/AudioResolver.cs | 3 +- .../Library/UserViewManager.cs | 2 +- .../Persistence/IItemRepository.cs | 2 +- MediaBrowser.Providers/Manager/ProviderManager.cs | 4 +-- .../Playlists/PlaylistItemsProvider.cs | 2 +- .../Plugins/AudioDb/AudioDbArtistImageProvider.cs | 5 ++-- .../MusicBrainz/MusicBrainzAlbumProvider.cs | 10 +++---- .../Plugins/Omdb/OmdbImageProvider.cs | 5 +--- .../Tmdb/BoxSets/TmdbBoxSetImageProvider.cs | 2 +- .../Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs | 4 +-- .../Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs | 2 +- .../Plugins/Tmdb/People/TmdbPersonImageProvider.cs | 5 +--- .../Plugins/Tmdb/People/TmdbPersonProvider.cs | 4 +-- .../Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs | 5 +--- .../Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs | 5 +--- .../Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs | 2 +- 24 files changed, 76 insertions(+), 89 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs b/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs index c484dac54..db1190ae7 100644 --- a/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs +++ b/Emby.Dlna/ConnectionManager/ConnectionManagerXmlBuilder.cs @@ -27,7 +27,7 @@ namespace Emby.Dlna.ConnectionManager /// The . private static IEnumerable GetStateVariables() { - var list = new List + return new StateVariable[] { new StateVariable { @@ -114,8 +114,6 @@ namespace Emby.Dlna.ConnectionManager SendsEvents = false } }; - - return list; } } } diff --git a/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs b/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs index 3edaabb70..9af28aa7c 100644 --- a/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs +++ b/Emby.Dlna/ContentDirectory/ContentDirectoryXmlBuilder.cs @@ -27,7 +27,7 @@ namespace Emby.Dlna.ContentDirectory /// The . private static IEnumerable GetStateVariables() { - var list = new List + return new StateVariable[] { new StateVariable { @@ -154,8 +154,6 @@ namespace Emby.Dlna.ContentDirectory SendsEvents = false } }; - - return list; } } } diff --git a/Emby.Naming/AudioBook/AudioBookListResolver.cs b/Emby.Naming/AudioBook/AudioBookListResolver.cs index bdae20b6b..ca304102f 100644 --- a/Emby.Naming/AudioBook/AudioBookListResolver.cs +++ b/Emby.Naming/AudioBook/AudioBookListResolver.cs @@ -79,25 +79,25 @@ namespace Emby.Naming.AudioBook { if (group.Count() > 1 || haveChaptersOrPages) { - var ex = new List(); - var alt = new List(); + List? ex = null; + List? alt = null; foreach (var audioFile in group) { - var name = Path.GetFileNameWithoutExtension(audioFile.Path); - if (name.Equals("audiobook", StringComparison.OrdinalIgnoreCase) || - name.Contains(nameParserResult.Name, StringComparison.OrdinalIgnoreCase) || - name.Contains(nameWithReplacedDots, StringComparison.OrdinalIgnoreCase)) + var name = Path.GetFileNameWithoutExtension(audioFile.Path.AsSpan()); + if (name.Equals("audiobook", StringComparison.OrdinalIgnoreCase) + || name.Contains(nameParserResult.Name, StringComparison.OrdinalIgnoreCase) + || name.Contains(nameWithReplacedDots, StringComparison.OrdinalIgnoreCase)) { - alt.Add(audioFile); + (alt ??= new()).Add(audioFile); } else { - ex.Add(audioFile); + (ex ??= new()).Add(audioFile); } } - if (ex.Count > 0) + if (ex is not null) { var extra = ex .OrderBy(x => x.Container) @@ -108,7 +108,7 @@ namespace Emby.Naming.AudioBook extras.AddRange(extra); } - if (alt.Count > 0) + if (alt is not null) { var alternatives = alt .OrderBy(x => x.Container) diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 84ba19464..1e3c4dea1 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -401,7 +401,7 @@ namespace Emby.Server.Implementations.Channels } else { - results = new List(); + results = Enumerable.Empty(); } return results diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index b53c8ca51..179683055 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -206,8 +206,7 @@ namespace Emby.Server.Implementations.Collections throw new ArgumentException("No collection exists with the supplied Id"); } - var list = new List(); - var itemList = new List(); + List? itemList = null; var linkedChildrenList = collection.GetLinkedChildren(); var currentLinkedChildrenIds = linkedChildrenList.Select(i => i.Id).ToList(); @@ -223,18 +222,23 @@ namespace Emby.Server.Implementations.Collections if (!currentLinkedChildrenIds.Contains(id)) { - itemList.Add(item); + (itemList ??= new()).Add(item); - list.Add(LinkedChild.Create(item)); linkedChildrenList.Add(item); } } - if (list.Count > 0) + if (itemList is not null) { - LinkedChild[] newChildren = new LinkedChild[collection.LinkedChildren.Length + list.Count]; + var originalLen = collection.LinkedChildren.Length; + var newItemCount = itemList.Count; + LinkedChild[] newChildren = new LinkedChild[originalLen + newItemCount]; collection.LinkedChildren.CopyTo(newChildren, 0); - list.CopyTo(newChildren, collection.LinkedChildren.Length); + for (int i = 0; i < newItemCount; i++) + { + newChildren[originalLen + i] = LinkedChild.Create(itemList[i]); + } + collection.LinkedChildren = newChildren; collection.UpdateRatingToItems(linkedChildrenList); diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 0aa943270..3bf4d07c5 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -586,7 +586,7 @@ namespace Emby.Server.Implementations.Data /// /// or is null. /// - public void SaveItems(IEnumerable items, CancellationToken cancellationToken) + public void SaveItems(IReadOnlyList items, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(items); @@ -594,9 +594,11 @@ namespace Emby.Server.Implementations.Data CheckDisposed(); - var tuples = new List<(BaseItem, List, BaseItem, string, List)>(); - foreach (var item in items) + var itemsLen = items.Count; + var tuples = new ValueTuple, BaseItem, string, List>[itemsLen]; + for (int i = 0; i < itemsLen; i++) { + var item = items[i]; var ancestorIds = item.SupportsAncestors ? item.GetAncestorIds().Distinct().ToList() : null; @@ -606,7 +608,7 @@ namespace Emby.Server.Implementations.Data var userdataKey = item.GetUserDataKeys().FirstOrDefault(); var inheritedTags = item.GetInheritedTags(); - tuples.Add((item, ancestorIds, topParent, userdataKey, inheritedTags)); + tuples[i] = (item, ancestorIds, topParent, userdataKey, inheritedTags); } using (var connection = GetConnection()) diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index e928f1ff3..45270de89 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -85,8 +85,8 @@ namespace Emby.Server.Implementations.Dto { var accessibleItems = user is null ? items : items.Where(x => x.IsVisible(user)).ToList(); var returnItems = new BaseItemDto[accessibleItems.Count]; - var programTuples = new List<(BaseItem, BaseItemDto)>(); - var channelTuples = new List<(BaseItemDto, LiveTvChannel)>(); + List<(BaseItem, BaseItemDto)> programTuples = null; + List<(BaseItemDto, LiveTvChannel)> channelTuples = null; for (int index = 0; index < accessibleItems.Count; index++) { @@ -95,11 +95,11 @@ namespace Emby.Server.Implementations.Dto if (item is LiveTvChannel tvChannel) { - channelTuples.Add((dto, tvChannel)); + (channelTuples ??= new()).Add((dto, tvChannel)); } else if (item is LiveTvProgram) { - programTuples.Add((item, dto)); + (programTuples ??= new()).Add((item, dto)); } if (item is IItemByName byName) @@ -122,12 +122,12 @@ namespace Emby.Server.Implementations.Dto returnItems[index] = dto; } - if (programTuples.Count > 0) + if (programTuples is not null) { LivetvManager.AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult(); } - if (channelTuples.Count > 0) + if (channelTuples is not null) { LivetvManager.AddChannelInfo(channelTuples, options, user); } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index a3c66dc79..66bd68ddd 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -356,8 +356,8 @@ namespace Emby.Server.Implementations.Library } var children = item.IsFolder - ? ((Folder)item).GetRecursiveChildren(false).ToList() - : new List(); + ? ((Folder)item).GetRecursiveChildren(false) + : Enumerable.Empty(); foreach (var metadataPath in GetMetadataPaths(item, children)) { @@ -1253,7 +1253,7 @@ namespace Emby.Server.Implementations.Library var parent = GetItemById(query.ParentId); if (parent is not null) { - SetTopParentIdsOrAncestors(query, new List { parent }); + SetTopParentIdsOrAncestors(query, new[] { parent }); } } @@ -1277,7 +1277,7 @@ namespace Emby.Server.Implementations.Library var parent = GetItemById(query.ParentId); if (parent is not null) { - SetTopParentIdsOrAncestors(query, new List { parent }); + SetTopParentIdsOrAncestors(query, new[] { parent }); } } @@ -1435,7 +1435,7 @@ namespace Emby.Server.Implementations.Library var parent = GetItemById(query.ParentId); if (parent is not null) { - SetTopParentIdsOrAncestors(query, new List { parent }); + SetTopParentIdsOrAncestors(query, new[] { parent }); } } @@ -1455,7 +1455,7 @@ namespace Emby.Server.Implementations.Library _itemRepository.GetItemList(query)); } - private void SetTopParentIdsOrAncestors(InternalItemsQuery query, List parents) + private void SetTopParentIdsOrAncestors(InternalItemsQuery query, IReadOnlyCollection parents) { if (parents.All(i => i is ICollectionFolder || i is UserView)) { @@ -1602,7 +1602,7 @@ namespace Emby.Server.Implementations.Library { _logger.LogError(ex, "Error getting intros"); - return new List(); + return Enumerable.Empty(); } } @@ -2876,7 +2876,7 @@ namespace Emby.Server.Implementations.Library private async Task SavePeopleMetadataAsync(IEnumerable people, CancellationToken cancellationToken) { - var personsToSave = new List(); + List personsToSave = null; foreach (var person in people) { @@ -2918,12 +2918,12 @@ namespace Emby.Server.Implementations.Library if (saveEntity) { - personsToSave.Add(personEntity); + (personsToSave ??= new()).Add(personEntity); await RunMetadataSavers(personEntity, itemUpdateType).ConfigureAwait(false); } } - if (personsToSave.Count > 0) + if (personsToSave is not null) { CreateItems(personsToSave, null, CancellationToken.None); } @@ -3085,22 +3085,19 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(path)); } - var removeList = new List(); + List removeList = null; foreach (var contentType in _configurationManager.Configuration.ContentTypes) { - if (string.IsNullOrWhiteSpace(contentType.Name)) - { - removeList.Add(contentType); - } - else if (_fileSystem.AreEqual(path, contentType.Name) + if (string.IsNullOrWhiteSpace(contentType.Name) + || _fileSystem.AreEqual(path, contentType.Name) || _fileSystem.ContainsSubPath(path, contentType.Name)) { - removeList.Add(contentType); + (removeList ??= new()).Add(contentType); } } - if (removeList.Count > 0) + if (removeList is not null) { _configurationManager.Configuration.ContentTypes = _configurationManager.Configuration.ContentTypes .Except(removeList) diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index 06621700a..69e905798 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -158,7 +158,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio private MultiItemResolverResult ResolveMultipleAudio(Folder parent, IEnumerable fileSystemEntries, bool parseName) { var files = new List(); - var items = new List(); var leftOver = new List(); // Loop through each child file/folder and see if we find a video @@ -180,7 +179,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio var result = new MultiItemResolverResult { ExtraFiles = leftOver, - Items = items + Items = new List() }; var isInMixedFolder = resolverResult.Count > 1 || (parent is not null && parent.IsTopParent); diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index 1137625f4..0e2d34d39 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -286,7 +286,7 @@ namespace Emby.Server.Implementations.Library if (parents.Count == 0) { - return new List(); + return Array.Empty(); } if (includeItemTypes.Length == 0) diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 24f7b5cd3..2c52b2b45 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Persistence /// /// The items. /// The cancellation token. - void SaveItems(IEnumerable items, CancellationToken cancellationToken); + void SaveItems(IReadOnlyList items, CancellationToken cancellationToken); void SaveImages(BaseItem item); diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index c07839ff2..81ccd8653 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -284,12 +284,12 @@ namespace MediaBrowser.Providers.Manager } catch (OperationCanceledException) { - return new List(); + return Enumerable.Empty(); } catch (Exception ex) { _logger.LogError(ex, "{ProviderName} failed in GetImageInfos for type {ItemType} at {ItemPath}", provider.GetType().Name, item.GetType().Name, item.Path); - return new List(); + return Enumerable.Empty(); } } diff --git a/MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs b/MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs index db4c5f436..9bd36f25c 100644 --- a/MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs +++ b/MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs @@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Playlists return GetPlsItems(stream); } - return new List(); + return Enumerable.Empty(); } private IEnumerable GetPlsItems(Stream stream) diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs index b1a285a96..2232dfa0d 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net.Http; using System.Text.Json; using System.Threading; @@ -42,7 +43,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List + return new ImageType[] { ImageType.Primary, ImageType.Logo, @@ -74,7 +75,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb } } - return new List(); + return Enumerable.Empty(); } private IEnumerable GetImages(AudioDbArtistProvider.Artist item) diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 4aa426989..d0bd7d609 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -157,10 +157,10 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider 0) { - var artistResults = new List(); - - foreach (var artist in artists) + var artistResults = new RemoteSearchResult[artists.Count]; + for (int i = 0; i < artists.Count; i++) { + var artist = artists[i]; var artistResult = new RemoteSearchResult { Name = artist.Name @@ -171,11 +171,11 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider GetSupportedImages(BaseItem item) { - return new List - { - ImageType.Primary - }; + yield return ImageType.Primary; } public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs index ef32b0a07..a4c6cb47d 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetImageProvider.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List + return new ImageType[] { ImageType.Primary, ImageType.Backdrop diff --git a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs index e6c7dba25..c2018d820 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/BoxSets/TmdbBoxSetProvider.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets var collectionSearchResults = await _tmdbClientManager.SearchCollectionAsync(searchInfo.Name, language, cancellationToken).ConfigureAwait(false); - var collections = new List(); + var collections = new RemoteSearchResult[collectionSearchResults.Count]; for (var i = 0; i < collectionSearchResults.Count; i++) { var collection = new RemoteSearchResult @@ -82,7 +82,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.BoxSets }; collection.SetProviderId(MetadataProvider.Tmdb, collectionSearchResults[i].Id.ToString(CultureInfo.InvariantCulture)); - collections.Add(collection); + collections[i] = collection; } return collections; diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs index 655fa5a16..bfec48e7c 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieImageProvider.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List + return new ImageType[] { ImageType.Primary, ImageType.Backdrop, diff --git a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs index bc959ee2b..9e5404b32 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonImageProvider.cs @@ -46,10 +46,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List - { - ImageType.Primary - }; + yield return ImageType.Primary; } /// diff --git a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs index c03a1ca3b..5c6e71fd8 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People var personSearchResult = await _tmdbClientManager.SearchPersonAsync(searchInfo.Name, cancellationToken).ConfigureAwait(false); - var remoteSearchResults = new List(); + var remoteSearchResults = new RemoteSearchResult[personSearchResult.Count]; for (var i = 0; i < personSearchResult.Count; i++) { var person = personSearchResult[i]; @@ -79,7 +79,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.People }; remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture)); - remoteSearchResults.Add(remoteSearchResult); + remoteSearchResults[i] = remoteSearchResult; } return remoteSearchResults; diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs index abef732bb..d1fec7cb1 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeImageProvider.cs @@ -47,10 +47,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List - { - ImageType.Primary - }; + yield return ImageType.Primary; } /// diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs index b8d1460db..a743601ed 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeasonImageProvider.cs @@ -48,10 +48,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List - { - ImageType.Primary - }; + yield return ImageType.Primary; } /// diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs index 79cb6e86d..192fb052d 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbSeriesImageProvider.cs @@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.TV /// public IEnumerable GetSupportedImages(BaseItem item) { - return new List + return new ImageType[] { ImageType.Primary, ImageType.Backdrop, -- cgit v1.2.3 From 160baa02fd9a2e7b4e2b3dcc28769274d0588413 Mon Sep 17 00:00:00 2001 From: Joe Rogers <1337joe@gmail.com> Date: Mon, 6 Mar 2023 22:18:26 -0500 Subject: Remove some BaseItem references to make ItemResolveArgs more usable for testing. --- Emby.Server.Implementations/Library/LibraryManager.cs | 2 +- MediaBrowser.Controller/Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/CollectionFolder.cs | 2 +- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 17 +++++++---------- .../Library/EpisodeResolverTest.cs | 6 ++++-- .../Library/MovieResolverTests.cs | 3 ++- 6 files changed, 16 insertions(+), 16 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 66bd68ddd..9fa4d3599 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -537,7 +537,7 @@ namespace Emby.Server.Implementations.Library collectionType = GetContentTypeOverride(fullPath, true); } - var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService, this) { Parent = parent, FileInfo = fileInfo, diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 08c622cde..aacb38607 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -120,7 +120,7 @@ namespace MediaBrowser.Controller.Entities var path = ContainingFolderPath; - var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService, LibraryManager) { FileInfo = FileSystem.GetDirectoryInfo(path) }; diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 5ac619d8f..ff1779717 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -288,7 +288,7 @@ namespace MediaBrowser.Controller.Entities { var path = ContainingFolderPath; - var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService, LibraryManager) { FileInfo = FileSystem.GetDirectoryInfo(path), Parent = GetParent() as Folder, diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index 01986d303..730d89356 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -23,6 +23,7 @@ namespace MediaBrowser.Controller.Library /// private readonly IServerApplicationPaths _appPaths; + private readonly ILibraryManager _libraryManager; private LibraryOptions _libraryOptions; /// @@ -30,10 +31,12 @@ namespace MediaBrowser.Controller.Library /// /// The app paths. /// The directory service. - public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService) + /// The library manager. + public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService, ILibraryManager libraryManager) { _appPaths = appPaths; DirectoryService = directoryService; + _libraryManager = libraryManager; } // TODO remove dependencies as properties, they should be injected where it makes sense @@ -47,7 +50,7 @@ namespace MediaBrowser.Controller.Library public LibraryOptions LibraryOptions { - get => _libraryOptions ??= Parent is null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent); + get => _libraryOptions ??= Parent is null ? new LibraryOptions() : _libraryManager.GetLibraryOptions(Parent); set => _libraryOptions = value; } @@ -231,21 +234,15 @@ namespace MediaBrowser.Controller.Library /// /// Gets the configured content type for the path. /// - /// - /// This is subject to future refactoring as it relies on a static property in BaseItem. - /// /// The configured content type. public string GetConfiguredContentType() { - return BaseItem.LibraryManager.GetConfiguredContentType(Path); + return _libraryManager.GetConfiguredContentType(Path); } /// /// Gets the file system children that do not hit the ignore file check. /// - /// - /// This is subject to future refactoring as it relies on a static property in BaseItem. - /// /// The file system children that are not ignored. public IEnumerable GetActualFileSystemChildren() { @@ -253,7 +250,7 @@ namespace MediaBrowser.Controller.Library for (var i = 0; i < numberOfChildren; i++) { var child = FileSystemChildren[i]; - if (BaseItem.LibraryManager.IgnoreFile(child, Parent)) + if (_libraryManager.IgnoreFile(child, Parent)) { continue; } diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs index 286ba0405..65f19a051 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs @@ -25,7 +25,8 @@ namespace Jellyfin.Server.Implementations.Tests.Library var episodeResolver = new EpisodeResolver(Mock.Of>(), _namingOptions); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of()) + Mock.Of(), + null) { Parent = parent, CollectionType = CollectionType.TvShows, @@ -48,7 +49,8 @@ namespace Jellyfin.Server.Implementations.Tests.Library var episodeResolver = new EpisodeResolverMock(Mock.Of>(), _namingOptions); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of()) + Mock.Of(), + null) { Parent = series, CollectionType = CollectionType.TvShows, diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs index efc3ac0c2..f96bd6138 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs @@ -21,7 +21,8 @@ public class MovieResolverTests var movieResolver = new MovieResolver(Mock.Of(), Mock.Of>(), _namingOptions); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of()) + Mock.Of(), + null) { Parent = null, FileInfo = new FileSystemMetadata -- cgit v1.2.3 From 1c3a97bf6adadf4e3b22177e1e965691637d0426 Mon Sep 17 00:00:00 2001 From: Joe Rogers <1337joe@gmail.com> Date: Mon, 6 Mar 2023 23:00:55 -0500 Subject: Inject IDirectoryService where needed instead of passing it through ItemResolveArgs --- Emby.Server.Implementations/Library/LibraryManager.cs | 8 +++++--- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 7 +++++-- .../Library/Resolvers/Audio/MusicArtistResolver.cs | 15 +++++++++------ .../Library/Resolvers/BaseVideoResolver.cs | 7 +++++-- .../Library/Resolvers/ExtraResolver.cs | 8 +++++--- .../Library/Resolvers/GenericVideoResolver.cs | 6 ++++-- .../Library/Resolvers/Movies/MovieResolver.cs | 13 +++++++------ .../Library/Resolvers/PhotoResolver.cs | 18 ++++++++++++++---- .../Library/Resolvers/TV/EpisodeResolver.cs | 6 ++++-- MediaBrowser.Controller/Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/CollectionFolder.cs | 2 +- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 10 ++-------- .../Library/EpisodeResolverTest.cs | 8 +++----- .../Library/MovieResolverTests.cs | 3 +-- 14 files changed, 66 insertions(+), 47 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 9fa4d3599..e5c520ca2 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -113,6 +113,7 @@ namespace Emby.Server.Implementations.Library /// The image processor. /// The memory cache. /// The naming options. + /// The directory service. public LibraryManager( IServerApplicationHost appHost, ILoggerFactory loggerFactory, @@ -128,7 +129,8 @@ namespace Emby.Server.Implementations.Library IItemRepository itemRepository, IImageProcessor imageProcessor, IMemoryCache memoryCache, - NamingOptions namingOptions) + NamingOptions namingOptions, + IDirectoryService directoryService) { _appHost = appHost; _logger = loggerFactory.CreateLogger(); @@ -146,7 +148,7 @@ namespace Emby.Server.Implementations.Library _memoryCache = memoryCache; _namingOptions = namingOptions; - _extraResolver = new ExtraResolver(loggerFactory.CreateLogger(), namingOptions); + _extraResolver = new ExtraResolver(loggerFactory.CreateLogger(), namingOptions, directoryService); _configurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -537,7 +539,7 @@ namespace Emby.Server.Implementations.Library collectionType = GetContentTypeOverride(fullPath, true); } - var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService, this) + var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, this) { Parent = parent, FileInfo = fileInfo, diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index a922e3685..bbc70701c 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -25,16 +25,19 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio { private readonly ILogger _logger; private readonly NamingOptions _namingOptions; + private readonly IDirectoryService _directoryService; /// /// Initializes a new instance of the class. /// /// The logger. /// The naming options. - public MusicAlbumResolver(ILogger logger, NamingOptions namingOptions) + /// The directory service. + public MusicAlbumResolver(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) { _logger = logger; _namingOptions = namingOptions; + _directoryService = directoryService; } /// @@ -109,7 +112,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio } // If args contains music it's a music album - if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService)) + if (ContainsMusic(args.FileSystemChildren, true, _directoryService)) { return true; } diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index 2538c2b5b..c858dc53d 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Emby.Naming.Common; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using Microsoft.Extensions.Logging; @@ -18,19 +19,23 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio public class MusicArtistResolver : ItemResolver { private readonly ILogger _logger; - private NamingOptions _namingOptions; + private readonly NamingOptions _namingOptions; + private readonly IDirectoryService _directoryService; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// The . + /// The directory service. public MusicArtistResolver( ILogger logger, - NamingOptions namingOptions) + NamingOptions namingOptions, + IDirectoryService directoryService) { _logger = logger; _namingOptions = namingOptions; + _directoryService = directoryService; } /// @@ -78,9 +83,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio return null; } - var directoryService = args.DirectoryService; - - var albumResolver = new MusicAlbumResolver(_logger, _namingOptions); + var albumResolver = new MusicAlbumResolver(_logger, _namingOptions, _directoryService); var directories = args.FileSystemChildren.Where(i => i.IsDirectory); @@ -97,7 +100,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio } // If we contain a music album assume we are an artist folder - if (albumResolver.IsMusicAlbum(fileSystemInfo.FullName, directoryService)) + if (albumResolver.IsMusicAlbum(fileSystemInfo.FullName, _directoryService)) { // Stop once we see a music album state.Stop(); diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index e8615e7db..9b133bef4 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -25,14 +25,17 @@ namespace Emby.Server.Implementations.Library.Resolvers { private readonly ILogger _logger; - protected BaseVideoResolver(ILogger logger, NamingOptions namingOptions) + protected BaseVideoResolver(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) { _logger = logger; NamingOptions = namingOptions; + DirectoryService = directoryService; } protected NamingOptions NamingOptions { get; } + protected IDirectoryService DirectoryService { get; } + /// /// Resolves the specified args. /// @@ -65,7 +68,7 @@ namespace Emby.Server.Implementations.Library.Resolvers var filename = child.Name; if (child.IsDirectory) { - if (IsDvdDirectory(child.FullName, filename, args.DirectoryService)) + if (IsDvdDirectory(child.FullName, filename, DirectoryService)) { videoType = VideoType.Dvd; } diff --git a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs index 30c52e19d..0b255f673 100644 --- a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs @@ -4,6 +4,7 @@ using System.IO; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using Microsoft.Extensions.Logging; @@ -25,11 +26,12 @@ namespace Emby.Server.Implementations.Library.Resolvers /// /// The logger. /// An instance of . - public ExtraResolver(ILogger logger, NamingOptions namingOptions) + /// The directory service. + public ExtraResolver(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) { _namingOptions = namingOptions; - _trailerResolvers = new IItemResolver[] { new GenericVideoResolver(logger, namingOptions) }; - _videoResolvers = new IItemResolver[] { new GenericVideoResolver /// The app paths. - /// The directory service. /// The library manager. - public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService, ILibraryManager libraryManager) + public ItemResolveArgs(IServerApplicationPaths appPaths, ILibraryManager libraryManager) { _appPaths = appPaths; - DirectoryService = directoryService; _libraryManager = libraryManager; } - // TODO remove dependencies as properties, they should be injected where it makes sense - public IDirectoryService DirectoryService { get; } - /// /// Gets or sets the file system children. /// diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs index 65f19a051..6d0ed7bbb 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs @@ -22,10 +22,9 @@ namespace Jellyfin.Server.Implementations.Tests.Library { var parent = new Folder { Name = "extras" }; - var episodeResolver = new EpisodeResolver(Mock.Of>(), _namingOptions); + var episodeResolver = new EpisodeResolver(Mock.Of>(), _namingOptions, Mock.Of()); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of(), null) { Parent = parent, @@ -46,10 +45,9 @@ namespace Jellyfin.Server.Implementations.Tests.Library // Have to create a mock because of moq proxies not being castable to a concrete implementation // https://github.com/jellyfin/jellyfin/blob/ab0cff8556403e123642dc9717ba778329554634/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs#L48 - var episodeResolver = new EpisodeResolverMock(Mock.Of>(), _namingOptions); + var episodeResolver = new EpisodeResolverMock(Mock.Of>(), _namingOptions, Mock.Of()); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of(), null) { Parent = series, @@ -64,7 +62,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library private sealed class EpisodeResolverMock : EpisodeResolver { - public EpisodeResolverMock(ILogger logger, NamingOptions namingOptions) : base(logger, namingOptions) + public EpisodeResolverMock(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) : base(logger, namingOptions, directoryService) { } diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs index f96bd6138..aed584355 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs @@ -18,10 +18,9 @@ public class MovieResolverTests [Fact] public void Resolve_GivenLocalAlternateVersion_ResolvesToVideo() { - var movieResolver = new MovieResolver(Mock.Of(), Mock.Of>(), _namingOptions); + var movieResolver = new MovieResolver(Mock.Of(), Mock.Of>(), _namingOptions, Mock.Of()); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of(), null) { Parent = null, -- cgit v1.2.3 From 361fff3a0c1b2e5c14e991d53f5736e909b889b6 Mon Sep 17 00:00:00 2001 From: Joe Rogers <1337joe@gmail.com> Date: Mon, 6 Mar 2023 23:27:21 -0500 Subject: Fix cases where multiple files are resolved as a single book --- Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs | 3 ++- .../Library/AudioResolverTests.cs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index 69e905798..a74f82475 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -192,7 +192,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio continue; } - if (resolvedItem.Files.Count == 0) + // Until multi-part books are handled letting files stack hides them from browsing in the client + if (resolvedItem.Files.Count == 0 || resolvedItem.Extras.Count > 0 || resolvedItem.AlternateVersions.Count > 0) { continue; } diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs index ca5829f10..d136c1bc6 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs @@ -40,6 +40,9 @@ public class AudioResolverTests [InlineData("chapter 01 part 01.mp3", "chapter 01 part 02.mp3")] /* Mismatched chapters, parts, and named files. */ [InlineData("chapter 01.mp3", "part 2.mp3")] + [InlineData("book title.mp3", "chapter name.mp3")] // "book title" resolves as alternate version of book based on directory name + [InlineData("01 Content.mp3", "01 Credits.mp3")] // resolves as alternate versions of chapter 1 + [InlineData("Chapter Name.mp3", "Part 1.mp3")] public void Resolve_AudiobookDirectory_NoResult(params string[] children) { var resolved = TestResolveChildren("/parent/book title", children); -- cgit v1.2.3 From b96420b7865538439c6a96305d70fa4f16dfd591 Mon Sep 17 00:00:00 2001 From: SenorSmartyPants Date: Sun, 26 Feb 2023 13:32:46 -0600 Subject: Clean Extra Names - Adds regular expression to CleanStrings to remove suffix style extra naming from the name presented in JF. - Override Resolve for Extras to enable parsename - remove exclusion on parsename of extratypes --- Emby.Naming/Common/NamingOptions.cs | 3 ++- Emby.Naming/Video/VideoResolver.cs | 3 +-- .../Library/Resolvers/ExtraResolver.cs | 11 +++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index e9161a6b7..1406c6443 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -157,7 +157,8 @@ namespace Emby.Naming.Common @"^(?.+?)(\[.*\])", @"^\s*(?.+?)\WE[0-9]+(-|~)E?[0-9]+(\W|$)", @"^\s*\[[^\]]+\](?!\.\w+$)\s*(?.+)", - @"^\s*(?.+?)\s+-\s+[0-9]+\s*$" + @"^\s*(?.+?)\s+-\s+[0-9]+\s*$", + @"^\s*(?.+?)(([-._ ](trailer|sample))|-(scene|clip|behindthescenes|deleted|deletedscene|featurette|short|interview|other|extra))$" }; SubtitleFileExtensions = new[] diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs index 858e9dd2f..db5bfdbf9 100644 --- a/Emby.Naming/Video/VideoResolver.cs +++ b/Emby.Naming/Video/VideoResolver.cs @@ -87,8 +87,7 @@ namespace Emby.Naming.Video name = cleanDateTimeResult.Name; year = cleanDateTimeResult.Year; - if (extraResult.ExtraType is null - && TryCleanString(name, namingOptions, out var newName)) + if (TryCleanString(name, namingOptions, out var newName)) { name = newName; } diff --git a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs index 0b255f673..b4791b945 100644 --- a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs @@ -4,6 +4,7 @@ using System.IO; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; @@ -15,7 +16,7 @@ namespace Emby.Server.Implementations.Library.Resolvers /// /// Resolves a Path into a Video or Video subclass. /// - internal class ExtraResolver + internal class ExtraResolver : BaseVideoResolver