aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/Folder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities/Folder.cs')
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs196
1 files changed, 124 insertions, 72 deletions
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 727b7dbeb..34b33fde0 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -271,6 +271,11 @@ namespace MediaBrowser.Controller.Entities
return GetCachedChildren();
}
+ public override double? GetRefreshProgress()
+ {
+ return ProviderManager.GetRefreshProgress(Id);
+ }
+
public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken)
{
return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)));
@@ -318,6 +323,14 @@ namespace MediaBrowser.Controller.Entities
return current.IsValidFromResolver(newItem);
}
+ protected override void TriggerOnRefreshStart()
+ {
+ }
+
+ protected override void TriggerOnRefreshComplete()
+ {
+ }
+
/// <summary>
/// Validates the children internal.
/// </summary>
@@ -328,7 +341,27 @@ namespace MediaBrowser.Controller.Entities
/// <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)
+ protected virtual async Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
+ {
+ if (recursive)
+ {
+ ProviderManager.OnRefreshStart(this);
+ }
+
+ try
+ {
+ await ValidateChildrenInternal2(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService).ConfigureAwait(false);
+ }
+ finally
+ {
+ if (recursive)
+ {
+ ProviderManager.OnRefreshComplete(this);
+ }
+ }
+ }
+
+ private async Task ValidateChildrenInternal2(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
{
var locationType = LocationType;
@@ -360,6 +393,11 @@ namespace MediaBrowser.Controller.Entities
progress.Report(5);
+ if (recursive)
+ {
+ ProviderManager.OnRefreshProgress(this, 5);
+ }
+
//build a dictionary of the current children we have now by Id so we can compare quickly and easily
var currentChildren = GetActualChildrenDictionary();
@@ -424,76 +462,99 @@ namespace MediaBrowser.Controller.Entities
await LibraryManager.CreateItems(newItems, cancellationToken).ConfigureAwait(false);
}
}
+ else
+ {
+ if (recursive || refreshChildMetadata)
+ {
+ // used below
+ validChildren = Children.ToList();
+ }
+ }
progress.Report(10);
- cancellationToken.ThrowIfCancellationRequested();
-
if (recursive)
{
- await ValidateSubFolders(Children.ToList().OfType<Folder>().ToList(), directoryService, progress, cancellationToken).ConfigureAwait(false);
+ ProviderManager.OnRefreshProgress(this, 10);
}
- progress.Report(20);
+ cancellationToken.ThrowIfCancellationRequested();
- if (refreshChildMetadata)
+ if (recursive)
{
- var container = this as IMetadataContainer;
+ using (var innerProgress = new ActionableProgress<double>())
+ {
+ var folder = this;
+ innerProgress.RegisterAction(p =>
+ {
+ double newPct = .70 * p + 10;
+ progress.Report(newPct);
+ ProviderManager.OnRefreshProgress(folder, newPct);
+ });
- var innerProgress = new ActionableProgress<double>();
+ await ValidateSubFolders(validChildren.OfType<Folder>().ToList(), directoryService, innerProgress, cancellationToken).ConfigureAwait(false);
+ }
+ }
- innerProgress.RegisterAction(p => progress.Report(.80 * p + 20));
+ if (refreshChildMetadata)
+ {
+ progress.Report(80);
- if (container != null)
+ if (recursive)
{
- await container.RefreshAllMetadata(refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false);
+ ProviderManager.OnRefreshProgress(this, 80);
}
- else
+
+ var container = this as IMetadataContainer;
+
+ using (var innerProgress = new ActionableProgress<double>())
{
- await RefreshMetadataRecursive(refreshOptions, recursive, innerProgress, cancellationToken);
+ var folder = this;
+ innerProgress.RegisterAction(p =>
+ {
+ double newPct = .20 * p + 80;
+ progress.Report(newPct);
+ if (recursive)
+ {
+ ProviderManager.OnRefreshProgress(folder, newPct);
+ }
+ });
+
+ if (container != null)
+ {
+ await container.RefreshAllMetadata(refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken);
+ }
}
}
-
- progress.Report(100);
}
- private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task RefreshMetadataRecursive(List<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
{
- var children = Children.ToList();
-
- var percentages = new Dictionary<Guid, double>(children.Count);
var numComplete = 0;
var count = children.Count;
+ double currentPercent = 0;
foreach (var child in children)
{
cancellationToken.ThrowIfCancellationRequested();
- if (child.IsFolder)
+ using (var innerProgress = new ActionableProgress<double>())
{
- var innerProgress = new ActionableProgress<double>();
-
// Avoid implicitly captured closure
- var currentChild = child;
+ var currentInnerPercent = currentPercent;
+
innerProgress.RegisterAction(p =>
{
- lock (percentages)
- {
- percentages[currentChild.Id] = p / 100;
-
- var innerPercent = percentages.Values.Sum();
- innerPercent /= count;
- innerPercent *= 100;
- progress.Report(innerPercent);
- }
+ double innerPercent = currentInnerPercent;
+ innerPercent += p / (count);
+ progress.Report(innerPercent);
});
- await RefreshChildMetadata(child, refreshOptions, recursive, innerProgress, cancellationToken)
- .ConfigureAwait(false);
- }
- else
- {
- await RefreshChildMetadata(child, refreshOptions, false, new Progress<double>(), cancellationToken)
+ await RefreshChildMetadata(child, refreshOptions, recursive && child.IsFolder, innerProgress, cancellationToken)
.ConfigureAwait(false);
}
@@ -501,11 +562,10 @@ namespace MediaBrowser.Controller.Entities
double percent = numComplete;
percent /= count;
percent *= 100;
+ currentPercent = percent;
progress.Report(percent);
}
-
- progress.Report(100);
}
private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
@@ -526,11 +586,10 @@ namespace MediaBrowser.Controller.Entities
if (folder != null)
{
- await folder.RefreshMetadataRecursive(refreshOptions, true, progress, cancellationToken);
+ await folder.RefreshMetadataRecursive(folder.Children.ToList(), refreshOptions, true, progress, cancellationToken);
}
}
}
- progress.Report(100);
}
/// <summary>
@@ -543,47 +602,40 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns>
private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
{
- var list = children;
- var childCount = list.Count;
-
- var percentages = new Dictionary<Guid, double>(list.Count);
+ var numComplete = 0;
+ var count = children.Count;
+ double currentPercent = 0;
- foreach (var item in list)
+ foreach (var child in children)
{
cancellationToken.ThrowIfCancellationRequested();
- var child = item;
-
- var innerProgress = new ActionableProgress<double>();
-
- innerProgress.RegisterAction(p =>
+ using (var innerProgress = new ActionableProgress<double>())
{
- lock (percentages)
+ // Avoid implicitly captured closure
+ var currentInnerPercent = currentPercent;
+
+ innerProgress.RegisterAction(p =>
{
- percentages[child.Id] = p / 100;
+ double innerPercent = currentInnerPercent;
+ innerPercent += p / (count);
+ progress.Report(innerPercent);
+ });
- var percent = percentages.Values.Sum();
- percent /= childCount;
+ await child.ValidateChildrenInternal(innerProgress, cancellationToken, true, false, null, directoryService)
+ .ConfigureAwait(false);
+ }
- progress.Report(10 * percent + 10);
- }
- });
+ numComplete++;
+ double percent = numComplete;
+ percent /= count;
+ percent *= 100;
+ currentPercent = percent;
- await child.ValidateChildrenInternal(innerProgress, cancellationToken, true, false, null, directoryService)
- .ConfigureAwait(false);
+ progress.Report(percent);
}
}
- /// <summary>
- /// Determines whether the specified path is offline.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns><c>true</c> if the specified path is offline; otherwise, <c>false</c>.</returns>
- public static bool IsPathOffline(string path)
- {
- return IsPathOffline(path, LibraryManager.GetVirtualFolders().SelectMany(i => i.Locations).ToList());
- }
-
public static bool IsPathOffline(string path, List<string> allLibraryPaths)
{
if (FileSystem.FileExists(path))
@@ -926,7 +978,7 @@ namespace MediaBrowser.Controller.Entities
SortBy = query.SortBy,
SortOrder = query.SortOrder
- }, new Progress<double>(), CancellationToken.None).Result;
+ }, new SimpleProgress<double>(), CancellationToken.None).Result;
}
catch
{