diff options
| author | Petrus.Z <silencly07@gmail.com> | 2021-11-15 22:26:42 +0800 |
|---|---|---|
| committer | Petrus.Z <silencly07@gmail.com> | 2021-11-16 00:17:14 +0800 |
| commit | 5eb1fde88cb32e05ea51f26e1577b20bb4c60bd6 (patch) | |
| tree | 93e71b5db7c09005b3009d01a77e4aa57ea1c01e | |
| parent | 9c74103fbe151cad7ec0c2ddf4061afc9378b203 (diff) | |
Add Collection Validator, create collection based on nfo
Based on nfo's set element, automatically add movie to collection.
Signed-off-by: Petrus.Z <silencly07@gmail.com>
| -rw-r--r-- | Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs | 50 | ||||
| -rw-r--r-- | Emby.Server.Implementations/Library/Validators/CollectionValidator.cs | 166 |
2 files changed, 216 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs b/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs new file mode 100644 index 000000000..bc204b788 --- /dev/null +++ b/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Collections; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; +using Microsoft.Extensions.Logging; + +namespace Emby.Server.Implementations.Library.Validators +{ + /// <summary> + /// Class CollectionPostScanTask. + /// </summary> + public class CollectionPostScanTask : ILibraryPostScanTask + { + /// <summary> + /// The _library manager. + /// </summary> + private readonly ILibraryManager _libraryManager; + private readonly ICollectionManager _collectionManager; + private readonly ILogger<CollectionValidator> _logger; + + /// <summary> + /// Initializes a new instance of the <see cref="CollectionPostScanTask" /> class. + /// </summary> + /// <param name="libraryManager">The library manager.</param> + /// <param name="collectionManager">The collection manager.</param> + /// <param name="logger">The logger.</param> + public CollectionPostScanTask( + ILibraryManager libraryManager, + ILogger<CollectionValidator> logger, + ICollectionManager collectionManager) + { + _libraryManager = libraryManager; + _collectionManager = collectionManager; + _logger = logger; + } + + /// <summary> + /// Runs the specified progress. + /// </summary> + /// <param name="progress">The progress.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + public Task Run(IProgress<double> progress, CancellationToken cancellationToken) + { + return new CollectionValidator(_libraryManager, _collectionManager, _logger).Run(progress, cancellationToken); + } + } +} diff --git a/Emby.Server.Implementations/Library/Validators/CollectionValidator.cs b/Emby.Server.Implementations/Library/Validators/CollectionValidator.cs new file mode 100644 index 000000000..439fc1da1 --- /dev/null +++ b/Emby.Server.Implementations/Library/Validators/CollectionValidator.cs @@ -0,0 +1,166 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; +using MediaBrowser.Controller.Collections; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Querying; +using Microsoft.Extensions.Logging; +using Jellyfin.Data.Enums; + +namespace Emby.Server.Implementations.Library.Validators +{ + /// <summary> + /// Class CollectionValidator. + /// </summary> + public class CollectionValidator + { + /// <summary> + /// The library manager. + /// </summary> + private readonly ILibraryManager _libraryManager; + + /// <summary> + /// The collection manager. + /// </summary> + private readonly ICollectionManager _collectionManager; + + /// <summary> + /// The logger. + /// </summary> + private readonly ILogger<CollectionValidator> _logger; + + /// <summary> + /// Initializes a new instance of the <see cref="CollectionValidator" /> class. + /// </summary> + /// <param name="libraryManager">The library manager.</param> + /// <param name="collectionManager">The collection manager.</param> + /// <param name="logger">The logger.</param> + public CollectionValidator(ILibraryManager libraryManager, ICollectionManager collectionManager, ILogger<CollectionValidator> logger) + { + _libraryManager = libraryManager; + _collectionManager = collectionManager; + _logger = logger; + } + + /// <summary> + /// Runs the specified progress. + /// </summary> + /// <param name="progress">The progress.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) + { + var movies = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { nameof(Movie) }, + IsVirtualItem = false, + OrderBy = new List<ValueTuple<string, SortOrder>> + { + new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) + }, + Recursive = true + }).Select(m => m as Movie).ToList(); + + var boxSets = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { nameof(BoxSet) }, + CollapseBoxSetItems = false, + Recursive = true + }).Select(b => b as BoxSet).ToList(); + + var numComplete = 0; + var count = movies.Count; + + var map = new Dictionary<string, List<Movie>>(); + foreach (var movie in movies) + { + if (movie != null && movie.CollectionName != null) + { + var movieList = new List<Movie>(); + if (map.TryGetValue(movie.CollectionName, out movieList)) + { + if (!movieList.Where(m => m.Id == movie.Id).Any()) + { + movieList.Add(movie); + map[movie.CollectionName] = movieList; + } + } + else + { + map[movie.CollectionName] = new List<Movie> { movie }; + } + + } + + numComplete++; + double percent = numComplete; + percent /= count * 2; + percent *= 100; + + progress.Report(percent); + } + + foreach (var pair in map) + { + try + { + var collectionName = pair.Key; + var movieList = pair.Value; + + var boxSet = boxSets.FirstOrDefault(b => b != null ? b.Name == collectionName : false); + if (boxSet == null) + { + // won't automatically create collection if only one movie in it + if (movieList.Count >= 2) + { + boxSet = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions + { + Name = collectionName, + IsLocked = true + }); + + AddMovieToCollection(boxSet.Id, boxSet, movieList); + } + } + else + { + AddMovieToCollection(boxSet.Id, boxSet, movieList); + } + + numComplete++; + double percent = numComplete; + percent /= count * 2; + percent *= 100; + + progress.Report(percent); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error refreshing {0}, {1}", pair.Key, pair.Value.ToString()); + } + } + + progress.Report(100); + } + + private async void AddMovieToCollection(Guid boxSetId, BoxSet boxSet, List<Movie> movieList) + { + + var movieIds = new List<Guid>(); + foreach (var movie in movieList) + { + if (!boxSet.ContainsLinkedChildByItemId(movie.Id)) + { + movieIds.Add(movie.Id); + } + } + if (movieIds.Any()) { + await _collectionManager.AddToCollectionAsync(boxSetId, movieIds); + } + } + } +} |
