Some directory-watcher rework - still not working properly
This commit is contained in:
parent
6edc836ce5
commit
4e3ce41880
|
@ -2,6 +2,7 @@
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
@ -179,5 +180,14 @@ namespace MediaBrowser.Controller.Entities
|
||||||
data.PlaybackPositionTicks = 0;
|
data.PlaybackPositionTicks = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do whatever refreshing is necessary when the filesystem pertaining to this item has changed.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual Task ChangedExternally()
|
||||||
|
{
|
||||||
|
return Task.Run(() => RefreshMetadata());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds child BaseItems for a given Folder
|
/// Finds child BaseItems for us
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Task<BaseItem>[] GetChildren(WIN32_FIND_DATA[] fileSystemChildren)
|
protected Task<BaseItem>[] GetChildren(WIN32_FIND_DATA[] fileSystemChildren)
|
||||||
{
|
{
|
||||||
|
@ -328,6 +328,26 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Folders need to validate and refresh
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override Task ChangedExternally()
|
||||||
|
{
|
||||||
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
|
if (this.IsRoot)
|
||||||
|
{
|
||||||
|
Kernel.Instance.ReloadRoot().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RefreshMetadata();
|
||||||
|
ValidateChildren();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Since it can be slow to make all of these calculations at once, this method will provide a way to get them all back together
|
/// Since it can be slow to make all of these calculations at once, this method will provide a way to get them all back together
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -578,17 +598,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (BaseItem item in ActualChildren)
|
//this should be functionally equivilent to what was here since it is IEnum and works on a thread-safe copy
|
||||||
{
|
return RecursiveChildren.FirstOrDefault(i => i.Id == id);
|
||||||
result = item.FindItemById(id);
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -596,31 +607,13 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseItem FindByPath(string path)
|
public BaseItem FindByPath(string path)
|
||||||
{
|
{
|
||||||
if (Path.Equals(path, StringComparison.OrdinalIgnoreCase))
|
if (PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (BaseItem item in ActualChildren)
|
//this should be functionally equivilent to what was here since it is IEnum and works on a thread-safe copy
|
||||||
{
|
return RecursiveChildren.FirstOrDefault(i => i.Path.Equals(path, StringComparison.OrdinalIgnoreCase));
|
||||||
var folder = item as Folder;
|
|
||||||
|
|
||||||
if (folder != null)
|
|
||||||
{
|
|
||||||
var foundItem = folder.FindByPath(path);
|
|
||||||
|
|
||||||
if (foundItem != null)
|
|
||||||
{
|
|
||||||
return foundItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (item.Path.Equals(path, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.IO
|
||||||
private Timer updateTimer;
|
private Timer updateTimer;
|
||||||
private List<string> affectedPaths = new List<string>();
|
private List<string> affectedPaths = new List<string>();
|
||||||
|
|
||||||
private const int TimerDelayInSeconds = 5;
|
private const int TimerDelayInSeconds = 30;
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
@ -44,12 +44,13 @@ namespace MediaBrowser.Controller.IO
|
||||||
var watcher = new FileSystemWatcher(path, "*") { };
|
var watcher = new FileSystemWatcher(path, "*") { };
|
||||||
watcher.IncludeSubdirectories = true;
|
watcher.IncludeSubdirectories = true;
|
||||||
|
|
||||||
watcher.Changed += watcher_Changed;
|
//watcher.Changed += watcher_Changed;
|
||||||
|
|
||||||
// All the others seem to trigger change events on the parent, so let's keep it simple for now.
|
// All the others seem to trigger change events on the parent, so let's keep it simple for now.
|
||||||
//watcher.Created += watcher_Changed;
|
// Actually, we really need to only watch created, deleted and renamed as changed fires too much -ebr
|
||||||
//watcher.Deleted += watcher_Changed;
|
watcher.Created += watcher_Changed;
|
||||||
//watcher.Renamed += watcher_Changed;
|
watcher.Deleted += watcher_Changed;
|
||||||
|
watcher.Renamed += watcher_Changed;
|
||||||
|
|
||||||
watcher.EnableRaisingEvents = true;
|
watcher.EnableRaisingEvents = true;
|
||||||
FileSystemWatchers.Add(watcher);
|
FileSystemWatchers.Add(watcher);
|
||||||
|
@ -57,11 +58,25 @@ namespace MediaBrowser.Controller.IO
|
||||||
}
|
}
|
||||||
|
|
||||||
void watcher_Changed(object sender, FileSystemEventArgs e)
|
void watcher_Changed(object sender, FileSystemEventArgs e)
|
||||||
|
{
|
||||||
|
Logger.LogDebugInfo("****** Watcher sees change of type " + e.ChangeType.ToString() + " to " + e.FullPath);
|
||||||
|
lock (affectedPaths)
|
||||||
{
|
{
|
||||||
if (!affectedPaths.Contains(e.FullPath))
|
if (!affectedPaths.Contains(e.FullPath))
|
||||||
{
|
{
|
||||||
|
Logger.LogDebugInfo("****** Adding " + e.FullPath + " to affected paths.");
|
||||||
affectedPaths.Add(e.FullPath);
|
affectedPaths.Add(e.FullPath);
|
||||||
}
|
}
|
||||||
|
if (e.ChangeType == WatcherChangeTypes.Renamed)
|
||||||
|
{
|
||||||
|
var renamedArgs = e as RenamedEventArgs;
|
||||||
|
if (affectedPaths.Contains(renamedArgs.OldFullPath))
|
||||||
|
{
|
||||||
|
Logger.LogDebugInfo("****** Removing " + renamedArgs.OldFullPath + " from affected paths.");
|
||||||
|
affectedPaths.Remove(renamedArgs.OldFullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (updateTimer == null)
|
if (updateTimer == null)
|
||||||
{
|
{
|
||||||
|
@ -77,9 +92,12 @@ namespace MediaBrowser.Controller.IO
|
||||||
{
|
{
|
||||||
updateTimer.Dispose();
|
updateTimer.Dispose();
|
||||||
updateTimer = null;
|
updateTimer = null;
|
||||||
|
List<string> paths;
|
||||||
List<string> paths = affectedPaths;
|
lock (affectedPaths)
|
||||||
|
{
|
||||||
|
paths = affectedPaths;
|
||||||
affectedPaths = new List<string>();
|
affectedPaths = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
await ProcessPathChanges(paths).ConfigureAwait(false);
|
await ProcessPathChanges(paths).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -106,14 +124,16 @@ namespace MediaBrowser.Controller.IO
|
||||||
return Kernel.Instance.ReloadRoot();
|
return Kernel.Instance.ReloadRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i)));
|
foreach (var p in paths) Logger.LogDebugInfo("********* "+ p + " reports change.");
|
||||||
|
foreach (var i in itemsToRefresh) Logger.LogDebugInfo("********* "+i.Name + " will be refreshed.");
|
||||||
|
return Task.WhenAll(itemsToRefresh.Select(i => i.ChangedExternally()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseItem GetAffectedBaseItem(string path)
|
private BaseItem GetAffectedBaseItem(string path)
|
||||||
{
|
{
|
||||||
BaseItem item = null;
|
BaseItem item = null;
|
||||||
|
|
||||||
while (item == null)
|
while (item == null && !string.IsNullOrEmpty(path))
|
||||||
{
|
{
|
||||||
item = Kernel.Instance.RootFolder.FindByPath(path);
|
item = Kernel.Instance.RootFolder.FindByPath(path);
|
||||||
|
|
||||||
|
|
|
@ -201,10 +201,10 @@ namespace MediaBrowser.Controller
|
||||||
//Task.Delay(30000); //let's wait and see if more data gets filled in...
|
//Task.Delay(30000); //let's wait and see if more data gets filled in...
|
||||||
var allChildren = RootFolder.RecursiveChildren;
|
var allChildren = RootFolder.RecursiveChildren;
|
||||||
Logger.LogDebugInfo(string.Format("Loading complete. Movies: {0} Episodes: {1} Folders: {2}", allChildren.OfType<Entities.Movies.Movie>().Count(), allChildren.OfType<Entities.TV.Episode>().Count(), allChildren.Where(i => i is Folder && !(i is Series || i is Season)).Count()));
|
Logger.LogDebugInfo(string.Format("Loading complete. Movies: {0} Episodes: {1} Folders: {2}", allChildren.OfType<Entities.Movies.Movie>().Count(), allChildren.OfType<Entities.TV.Episode>().Count(), allChildren.Where(i => i is Folder && !(i is Series || i is Season)).Count()));
|
||||||
foreach (var child in allChildren)
|
//foreach (var child in allChildren)
|
||||||
{
|
//{
|
||||||
Logger.LogDebugInfo("(" + child.GetType().Name + ") " + child.Name + " (" + child.Path + ")");
|
// Logger.LogDebugInfo("(" + child.GetType().Name + ") " + child.Name + " (" + child.Path + ")");
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -257,36 +257,6 @@ namespace MediaBrowser.Controller
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReloadItem(BaseItem item)
|
|
||||||
{
|
|
||||||
var folder = item as Folder;
|
|
||||||
|
|
||||||
if (folder != null && folder.IsRoot)
|
|
||||||
{
|
|
||||||
await ReloadRoot().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(item.Path) && !File.Exists(item.Path))
|
|
||||||
{
|
|
||||||
await ReloadItem(item.Parent).ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseItem newItem = await ItemController.GetItem(item.Path, item.Parent).ConfigureAwait(false);
|
|
||||||
|
|
||||||
List<BaseItem> children = item.Parent.Children.ToList();
|
|
||||||
|
|
||||||
int index = children.IndexOf(item);
|
|
||||||
|
|
||||||
children.RemoveAt(index);
|
|
||||||
|
|
||||||
children.Insert(index, newItem);
|
|
||||||
|
|
||||||
//item.Parent.ActualChildren = children.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds a library item by Id
|
/// Finds a library item by Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -13,21 +13,6 @@ namespace MediaBrowser.Controller.Library
|
||||||
{
|
{
|
||||||
public class ItemController
|
public class ItemController
|
||||||
{
|
{
|
||||||
//private BaseItem ResolveItem(ItemResolveEventArgs args)
|
|
||||||
//{
|
|
||||||
// // Try first priority resolvers
|
|
||||||
// for (int i = 0; i < Kernel.Instance.EntityResolvers.Length; i++)
|
|
||||||
// {
|
|
||||||
// var item = Kernel.Instance.EntityResolvers[i].ResolvePath(args);
|
|
||||||
|
|
||||||
// if (item != null)
|
|
||||||
// {
|
|
||||||
// return item;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return null;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves a path into a BaseItem
|
/// Resolves a path into a BaseItem
|
||||||
|
@ -56,7 +41,7 @@ namespace MediaBrowser.Controller.Library
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fire BeginResolvePath to see if anyone wants to cancel this operation
|
// Check to see if we should resolve based on our contents
|
||||||
if (!EntityResolutionHelper.ShouldResolvePathContents(args))
|
if (!EntityResolutionHelper.ShouldResolvePathContents(args))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -67,80 +52,6 @@ namespace MediaBrowser.Controller.Library
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Finds child BaseItems for a given Folder
|
|
||||||
///// </summary>
|
|
||||||
//private Task<BaseItem>[] GetChildren(Folder folder, WIN32_FIND_DATA[] fileSystemChildren, bool allowInternetProviders)
|
|
||||||
//{
|
|
||||||
// Task<BaseItem>[] tasks = new Task<BaseItem>[fileSystemChildren.Length];
|
|
||||||
|
|
||||||
// for (int i = 0; i < fileSystemChildren.Length; i++)
|
|
||||||
// {
|
|
||||||
// var child = fileSystemChildren[i];
|
|
||||||
|
|
||||||
// tasks[i] = GetItem(child.Path, folder, child, allowInternetProviders: allowInternetProviders);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return tasks;
|
|
||||||
//}
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Transforms shortcuts into their actual paths
|
|
||||||
///// </summary>
|
|
||||||
//private WIN32_FIND_DATA[] FilterChildFileSystemEntries(WIN32_FIND_DATA[] fileSystemChildren, bool flattenShortcuts)
|
|
||||||
//{
|
|
||||||
// WIN32_FIND_DATA[] returnArray = new WIN32_FIND_DATA[fileSystemChildren.Length];
|
|
||||||
// List<WIN32_FIND_DATA> resolvedShortcuts = new List<WIN32_FIND_DATA>();
|
|
||||||
|
|
||||||
// for (int i = 0; i < fileSystemChildren.Length; i++)
|
|
||||||
// {
|
|
||||||
// WIN32_FIND_DATA file = fileSystemChildren[i];
|
|
||||||
|
|
||||||
// // If it's a shortcut, resolve it
|
|
||||||
// if (Shortcut.IsShortcut(file.Path))
|
|
||||||
// {
|
|
||||||
// string newPath = Shortcut.ResolveShortcut(file.Path);
|
|
||||||
// WIN32_FIND_DATA newPathData = FileData.GetFileData(newPath);
|
|
||||||
|
|
||||||
// // Find out if the shortcut is pointing to a directory or file
|
|
||||||
// if (newPathData.IsDirectory)
|
|
||||||
// {
|
|
||||||
// // If we're flattening then get the shortcut's children
|
|
||||||
|
|
||||||
// if (flattenShortcuts)
|
|
||||||
// {
|
|
||||||
// returnArray[i] = file;
|
|
||||||
// WIN32_FIND_DATA[] newChildren = FileData.GetFileSystemEntries(newPath, "*").ToArray();
|
|
||||||
|
|
||||||
// resolvedShortcuts.AddRange(FilterChildFileSystemEntries(newChildren, false));
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// returnArray[i] = newPathData;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// returnArray[i] = newPathData;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// returnArray[i] = file;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (resolvedShortcuts.Count > 0)
|
|
||||||
// {
|
|
||||||
// resolvedShortcuts.InsertRange(0, returnArray);
|
|
||||||
// return resolvedShortcuts.ToArray();
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// return returnArray;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Person
|
/// Gets a Person
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user