123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- using MediaBrowser.Controller.Configuration;
- using MediaBrowser.Controller.Entities.TV;
- using MediaBrowser.Controller.Library;
- using MediaBrowser.Controller.Localization;
- using MediaBrowser.Controller.Providers;
- using MediaBrowser.Model.Entities;
- using MediaBrowser.Model.Logging;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- namespace MediaBrowser.Providers.TV
- {
- class SeriesGroup : List<Series>, IGrouping<string, Series>
- {
- public string Key { get; set; }
- }
- class SeriesPostScanTask : ILibraryPostScanTask, IHasOrder
- {
- /// <summary>
- /// The _library manager
- /// </summary>
- private readonly ILibraryManager _libraryManager;
- private readonly IServerConfigurationManager _config;
- private readonly ILogger _logger;
- private readonly ILocalizationManager _localization;
- public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, ILocalizationManager localization)
- {
- _libraryManager = libraryManager;
- _logger = logger;
- _config = config;
- _localization = localization;
- }
- public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
- {
- return RunInternal(progress, cancellationToken);
- }
- private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
- {
- var seriesList = _libraryManager.RootFolder
- .RecursiveChildren
- .OfType<Series>()
- .ToList();
- var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
- await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization).Run(seriesGroups, cancellationToken).ConfigureAwait(false);
- var numComplete = 0;
- foreach (var series in seriesList)
- {
- cancellationToken.ThrowIfCancellationRequested();
- var episodes = series.RecursiveChildren
- .OfType<Episode>()
- .ToList();
- var physicalEpisodes = episodes.Where(i => i.LocationType != LocationType.Virtual)
- .ToList();
- series.SeasonCount = episodes
- .Select(i => i.ParentIndexNumber ?? 0)
- .Where(i => i != 0)
- .Distinct()
- .Count();
- series.SpecialFeatureIds = physicalEpisodes
- .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
- .Select(i => i.Id)
- .ToList();
- numComplete++;
- double percent = numComplete;
- percent /= seriesList.Count;
- percent *= 100;
- progress.Report(percent);
- }
- }
- private IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList)
- {
- var links = seriesList.ToDictionary(s => s, s => seriesList.Where(c => c != s && ShareProviderId(s, c)).ToList());
- var visited = new HashSet<Series>();
- foreach (var series in seriesList)
- {
- if (!visited.Contains(series))
- {
- var group = new SeriesGroup();
- FindAllLinked(series, visited, links, group);
- group.Key = group.Select(s => s.GetProviderId(MetadataProviders.Tvdb)).FirstOrDefault(id => !string.IsNullOrEmpty(id));
- yield return group;
- }
- }
- }
- private void FindAllLinked(Series series, HashSet<Series> visited, IDictionary<Series, List<Series>> linksMap, List<Series> results)
- {
- results.Add(series);
- visited.Add(series);
- var links = linksMap[series];
- foreach (var s in links)
- {
- if (!visited.Contains(s))
- {
- FindAllLinked(s, visited, linksMap, results);
- }
- }
- }
- private bool ShareProviderId(Series a, Series b)
- {
- return a.ProviderIds.Any(id =>
- {
- string value;
- return b.ProviderIds.TryGetValue(id.Key, out value) && id.Value == value;
- });
- }
- public int Order
- {
- get
- {
- // Run after tvdb update task
- return 1;
- }
- }
- }
- }
|