< Summary - Jellyfin

Information
Class: Emby.Server.Implementations.Library.Validators.CollectionPostScanTask
Assembly: Emby.Server.Implementations
File(s): /srv/git/jellyfin/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs
Line coverage
100%
Covered lines: 4
Uncovered lines: 0
Coverable lines: 4
Total lines: 156
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

/srv/git/jellyfin/Emby.Server.Implementations/Library/Validators/CollectionPostScanTask.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Threading;
 5using System.Threading.Tasks;
 6using Jellyfin.Data.Enums;
 7using MediaBrowser.Controller.Collections;
 8using MediaBrowser.Controller.Entities;
 9using MediaBrowser.Controller.Entities.Movies;
 10using MediaBrowser.Controller.Library;
 11using MediaBrowser.Model.Entities;
 12using MediaBrowser.Model.Querying;
 13using Microsoft.Extensions.Logging;
 14
 15namespace Emby.Server.Implementations.Library.Validators
 16{
 17    /// <summary>
 18    /// Class CollectionPostScanTask.
 19    /// </summary>
 20    public class CollectionPostScanTask : ILibraryPostScanTask
 21    {
 22        private readonly ILibraryManager _libraryManager;
 23        private readonly ICollectionManager _collectionManager;
 24        private readonly ILogger<CollectionPostScanTask> _logger;
 25
 26        /// <summary>
 27        /// Initializes a new instance of the <see cref="CollectionPostScanTask" /> class.
 28        /// </summary>
 29        /// <param name="libraryManager">The library manager.</param>
 30        /// <param name="collectionManager">The collection manager.</param>
 31        /// <param name="logger">The logger.</param>
 32        public CollectionPostScanTask(
 33            ILibraryManager libraryManager,
 34            ICollectionManager collectionManager,
 35            ILogger<CollectionPostScanTask> logger)
 36        {
 2237            _libraryManager = libraryManager;
 2238            _collectionManager = collectionManager;
 2239            _logger = logger;
 2240        }
 41
 42        /// <summary>
 43        /// Runs the specified progress.
 44        /// </summary>
 45        /// <param name="progress">The progress.</param>
 46        /// <param name="cancellationToken">The cancellation token.</param>
 47        /// <returns>Task.</returns>
 48        public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
 49        {
 50            var collectionNameMoviesMap = new Dictionary<string, HashSet<Guid>>();
 51
 52            foreach (var library in _libraryManager.RootFolder.Children)
 53            {
 54                if (!_libraryManager.GetLibraryOptions(library).AutomaticallyAddToCollection)
 55                {
 56                    continue;
 57                }
 58
 59                var startIndex = 0;
 60                var pagesize = 1000;
 61
 62                while (true)
 63                {
 64                    var movies = _libraryManager.GetItemList(new InternalItemsQuery
 65                    {
 66                        MediaTypes = new[] { MediaType.Video },
 67                        IncludeItemTypes = new[] { BaseItemKind.Movie },
 68                        IsVirtualItem = false,
 69                        OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
 70                        Parent = library,
 71                        StartIndex = startIndex,
 72                        Limit = pagesize,
 73                        Recursive = true
 74                    });
 75
 76                    foreach (var m in movies)
 77                    {
 78                        if (m is Movie movie && !string.IsNullOrEmpty(movie.CollectionName))
 79                        {
 80                            if (collectionNameMoviesMap.TryGetValue(movie.CollectionName, out var movieList))
 81                            {
 82                                movieList.Add(movie.Id);
 83                            }
 84                            else
 85                            {
 86                                collectionNameMoviesMap[movie.CollectionName] = new HashSet<Guid> { movie.Id };
 87                            }
 88                        }
 89                    }
 90
 91                    if (movies.Count < pagesize)
 92                    {
 93                        break;
 94                    }
 95
 96                    startIndex += pagesize;
 97                }
 98            }
 99
 100            var numComplete = 0;
 101            var count = collectionNameMoviesMap.Count;
 102
 103            if (count == 0)
 104            {
 105                progress.Report(100);
 106                return;
 107            }
 108
 109            var boxSets = _libraryManager.GetItemList(new InternalItemsQuery
 110            {
 111                IncludeItemTypes = new[] { BaseItemKind.BoxSet },
 112                CollapseBoxSetItems = false,
 113                Recursive = true
 114            });
 115
 116            foreach (var (collectionName, movieIds) in collectionNameMoviesMap)
 117            {
 118                try
 119                {
 120                    var boxSet = boxSets.FirstOrDefault(b => b?.Name == collectionName) as BoxSet;
 121                    if (boxSet is null)
 122                    {
 123                        // won't automatically create collection if only one movie in it
 124                        if (movieIds.Count >= 2)
 125                        {
 126                            boxSet = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions
 127                            {
 128                                Name = collectionName,
 129                                IsLocked = true
 130                            });
 131
 132                            await _collectionManager.AddToCollectionAsync(boxSet.Id, movieIds);
 133                        }
 134                    }
 135                    else
 136                    {
 137                        await _collectionManager.AddToCollectionAsync(boxSet.Id, movieIds);
 138                    }
 139
 140                    numComplete++;
 141                    double percent = numComplete;
 142                    percent /= count;
 143                    percent *= 100;
 144
 145                    progress.Report(percent);
 146                }
 147                catch (Exception ex)
 148                {
 149                    _logger.LogError(ex, "Error refreshing {CollectionName} with {@MovieIds}", collectionName, movieIds)
 150                }
 151            }
 152
 153            progress.Report(100);
 154        }
 155    }
 156}