Exemplo n.º 1
0
        private void RemoveObsoleteSeasons(Series series)
        {
            // TODO Legacy. It's not really "physical" seasons as any virtual seasons are always converted to non-virtual in FillInMissingSeasonsAsync.
            var physicalSeasonNumbers = new HashSet <int>();
            var virtualSeasons        = new List <Season>();

            foreach (var existingSeason in series.Children.OfType <Season>())
            {
                if (existingSeason.LocationType != LocationType.Virtual && existingSeason.IndexNumber.HasValue)
                {
                    physicalSeasonNumbers.Add(existingSeason.IndexNumber.Value);
                }
                else if (existingSeason.LocationType == LocationType.Virtual)
                {
                    virtualSeasons.Add(existingSeason);
                }
            }

            foreach (var virtualSeason in virtualSeasons)
            {
                var seasonNumber = virtualSeason.IndexNumber;
                // If there's a physical season with the same number or no episodes in the season, delete it
                if ((seasonNumber.HasValue && physicalSeasonNumbers.Contains(seasonNumber.Value)) ||
                    !virtualSeason.GetEpisodes().Any())
                {
                    Logger.LogInformation("Removing virtual season {SeasonNumber} in series {SeriesName}", virtualSeason.IndexNumber, series.Name);

                    LibraryManager.DeleteItem(
                        virtualSeason,
                        new DeleteOptions
                    {
                        DeleteFileLocation = true
                    },
                        false);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Validates the children internal.
        /// </summary>
        /// <param name="progress">The progress.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="recursive">if set to <c>true</c> [recursive].</param>
        /// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
        /// <param name="refreshOptions">The refresh options.</param>
        /// <param name="directoryService">The directory service.</param>
        /// <returns>Task.</returns>
        protected async virtual Task ValidateChildrenInternal(IProgress <double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
        {
            var locationType = LocationType;

            cancellationToken.ThrowIfCancellationRequested();

            var validChildren = new List <BaseItem>();

            if (locationType != LocationType.Remote && locationType != LocationType.Virtual)
            {
                IEnumerable <BaseItem> nonCachedChildren;

                try
                {
                    nonCachedChildren = GetNonCachedChildren(directoryService);
                }
                catch (IOException ex)
                {
                    nonCachedChildren = new BaseItem[] { };

                    Logger.ErrorException("Error getting file system entries for {0}", ex, Path);
                }

                if (nonCachedChildren == null)
                {
                    return;                            //nothing to validate
                }
                progress.Report(5);

                //build a dictionary of the current children we have now by Id so we can compare quickly and easily
                var currentChildren = GetActualChildrenDictionary();

                //create a list for our validated children
                var newItems = new List <BaseItem>();

                cancellationToken.ThrowIfCancellationRequested();

                foreach (var child in nonCachedChildren)
                {
                    BaseItem currentChild;

                    if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child))
                    {
                        await currentChild.UpdateIsOffline(false).ConfigureAwait(false);

                        validChildren.Add(currentChild);

                        continue;
                    }

                    // Brand new item - needs to be added
                    child.SetParent(this);
                    newItems.Add(child);
                    validChildren.Add(child);
                }

                // If any items were added or removed....
                if (newItems.Count > 0 || currentChildren.Count != validChildren.Count)
                {
                    // That's all the new and changed ones - now see if there are any that are missing
                    var itemsRemoved   = currentChildren.Values.Except(validChildren).ToList();
                    var actualRemovals = new List <BaseItem>();

                    foreach (var item in itemsRemoved)
                    {
                        var itemLocationType = item.LocationType;
                        if (itemLocationType == LocationType.Virtual ||
                            itemLocationType == LocationType.Remote)
                        {
                        }

                        else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path))
                        {
                            await item.UpdateIsOffline(true).ConfigureAwait(false);
                        }
                        else
                        {
                            actualRemovals.Add(item);
                        }
                    }

                    if (actualRemovals.Count > 0)
                    {
                        foreach (var item in actualRemovals)
                        {
                            Logger.Debug("Removed item: " + item.Path);

                            item.SetParent(null);
                            item.IsOffline = false;
                            await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false);

                            LibraryManager.ReportItemRemoved(item);
                        }
                    }

                    await LibraryManager.CreateItems(newItems, cancellationToken).ConfigureAwait(false);
                }
            }

            progress.Report(10);

            cancellationToken.ThrowIfCancellationRequested();

            if (recursive)
            {
                await ValidateSubFolders(ActualChildren.OfType <Folder>().ToList(), directoryService, progress, cancellationToken).ConfigureAwait(false);
            }

            progress.Report(20);

            if (refreshChildMetadata)
            {
                var container = this as IMetadataContainer;

                var innerProgress = new ActionableProgress <double>();

                innerProgress.RegisterAction(p => progress.Report(.80 * p + 20));

                if (container != null)
                {
                    await container.RefreshAllMetadata(refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    await RefreshMetadataRecursive(refreshOptions, recursive, innerProgress, cancellationToken);
                }
            }

            progress.Report(100);
        }