diff options
Diffstat (limited to 'MediaBrowser.Controller')
12 files changed, 128 insertions, 69 deletions
diff --git a/MediaBrowser.Controller/IO/DirectoryWatchers.cs b/MediaBrowser.Controller/IO/DirectoryWatchers.cs index 1ca9cf0c8..e4eadbbd0 100644 --- a/MediaBrowser.Controller/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Controller/IO/DirectoryWatchers.cs @@ -75,7 +75,7 @@ namespace MediaBrowser.Controller.IO }
}
- private void TimerStopped(object stateInfo)
+ private async void TimerStopped(object stateInfo)
{
updateTimer.Dispose();
updateTimer = null;
@@ -83,7 +83,7 @@ namespace MediaBrowser.Controller.IO List<string> paths = affectedPaths;
affectedPaths = new List<string>();
- //ProcessPathChanges(paths);
+ await ProcessPathChanges(paths);
}
private async Task ProcessPathChanges(IEnumerable<string> paths)
@@ -109,10 +109,7 @@ namespace MediaBrowser.Controller.IO }
else
{
- /*Parallel.For(0, itemsToRefresh.Count, i =>
- {
- Kernel.Instance.ReloadItem(itemsToRefresh[i]);
- });*/
+ await Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i)));
}
}
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index b696abef5..57e30479b 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -248,5 +248,47 @@ namespace MediaBrowser.Controller return list;
}
+
+ internal async Task ExecuteMetadataProviders(BaseEntity item, ItemResolveEventArgs args)
+ {
+ var supportedProviders = Kernel.Instance.MetadataProviders.Where(i => i.Supports(item));
+
+ // Start with non-internet providers. Run them sequentially
+ foreach (BaseMetadataProvider provider in supportedProviders.Where(i => !i.RequiresInternet))
+ {
+ await provider.Fetch(item, args);
+ }
+
+ var internetProviders = supportedProviders.Where(i => i.RequiresInternet);
+
+ if (internetProviders.Any())
+ {
+ // Now execute internet providers in parallel
+ await Task.WhenAll(
+ internetProviders.Select(i => i.Fetch(item, args))
+ );
+ }
+ }
+
+ protected override void DisposeComposableParts()
+ {
+ base.DisposeComposableParts();
+
+ DisposeProviders();
+ }
+
+ /// <summary>
+ /// Disposes all providers
+ /// </summary>
+ private void DisposeProviders()
+ {
+ if (MetadataProviders != null)
+ {
+ foreach (var provider in MetadataProviders)
+ {
+ provider.Dispose();
+ }
+ }
+ }
}
}
diff --git a/MediaBrowser.Controller/Library/ItemController.cs b/MediaBrowser.Controller/Library/ItemController.cs index 4b0d9a983..bc5cea79b 100644 --- a/MediaBrowser.Controller/Library/ItemController.cs +++ b/MediaBrowser.Controller/Library/ItemController.cs @@ -1,4 +1,5 @@ using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -217,49 +218,49 @@ namespace MediaBrowser.Controller.Library /// <summary>
/// Gets a Person
/// </summary>
- public Person GetPerson(string name)
+ public async Task<Person> GetPerson(string name)
{
string path = Path.Combine(Kernel.Instance.ApplicationPaths.PeoplePath, name);
- return GetImagesByNameItem<Person>(path, name);
+ return await GetImagesByNameItem<Person>(path, name);
}
/// <summary>
/// Gets a Studio
/// </summary>
- public Studio GetStudio(string name)
+ public async Task<Studio> GetStudio(string name)
{
string path = Path.Combine(Kernel.Instance.ApplicationPaths.StudioPath, name);
- return GetImagesByNameItem<Studio>(path, name);
+ return await GetImagesByNameItem<Studio>(path, name);
}
/// <summary>
/// Gets a Genre
/// </summary>
- public Genre GetGenre(string name)
+ public async Task<Genre> GetGenre(string name)
{
string path = Path.Combine(Kernel.Instance.ApplicationPaths.GenrePath, name);
- return GetImagesByNameItem<Genre>(path, name);
+ return await GetImagesByNameItem<Genre>(path, name);
}
/// <summary>
/// Gets a Year
/// </summary>
- public Year GetYear(int value)
+ public async Task<Year> GetYear(int value)
{
string path = Path.Combine(Kernel.Instance.ApplicationPaths.YearPath, value.ToString());
- return GetImagesByNameItem<Year>(path, value.ToString());
+ return await GetImagesByNameItem<Year>(path, value.ToString());
}
- private Dictionary<string, object> ImagesByNameItemCache = new Dictionary<string, object>();
+ private ConcurrentDictionary<string, object> ImagesByNameItemCache = new ConcurrentDictionary<string, object>();
/// <summary>
/// Generically retrieves an IBN item
/// </summary>
- private T GetImagesByNameItem<T>(string path, string name)
+ private async Task<T> GetImagesByNameItem<T>(string path, string name)
where T : BaseEntity, new()
{
string key = path.ToLower();
@@ -267,7 +268,9 @@ namespace MediaBrowser.Controller.Library // Look for it in the cache, if it's not there, create it
if (!ImagesByNameItemCache.ContainsKey(key))
{
- ImagesByNameItemCache[key] = CreateImagesByNameItem<T>(path, name);
+ T obj = await CreateImagesByNameItem<T>(path, name);
+ ImagesByNameItemCache[key] = obj;
+ return obj;
}
return ImagesByNameItemCache[key] as T;
@@ -276,7 +279,7 @@ namespace MediaBrowser.Controller.Library /// <summary>
/// Creates an IBN item based on a given path
/// </summary>
- private T CreateImagesByNameItem<T>(string path, string name)
+ private async Task<T> CreateImagesByNameItem<T>(string path, string name)
where T : BaseEntity, new()
{
T item = new T();
@@ -284,25 +287,28 @@ namespace MediaBrowser.Controller.Library item.Name = name;
item.Id = Kernel.GetMD5(path);
- if (Directory.Exists(path))
+ if (!Directory.Exists(path))
{
- item.DateCreated = Directory.GetCreationTime(path);
- item.DateModified = Directory.GetLastAccessTime(path);
- if (File.Exists(Path.Combine(path, "folder.jpg")))
- {
- item.PrimaryImagePath = Path.Combine(path, "folder.jpg");
- }
- else if (File.Exists(Path.Combine(path, "folder.png")))
- {
- item.PrimaryImagePath = Path.Combine(path, "folder.png");
- }
+ Directory.CreateDirectory(path);
}
- else
+
+ item.DateCreated = Directory.GetCreationTime(path);
+ item.DateModified = Directory.GetLastAccessTime(path);
+
+ if (File.Exists(Path.Combine(path, "folder.jpg")))
+ {
+ item.PrimaryImagePath = Path.Combine(path, "folder.jpg");
+ }
+ else if (File.Exists(Path.Combine(path, "folder.png")))
{
- DateTime now = DateTime.Now;
+ item.PrimaryImagePath = Path.Combine(path, "folder.png");
+ }
+
+ var b = false;
- item.DateCreated = now;
- item.DateModified = now;
+ if (b)
+ {
+ await Kernel.Instance.ExecuteMetadataProviders(item, null);
}
return item;
diff --git a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs index 934f082d5..70adb688f 100644 --- a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs +++ b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs @@ -12,12 +12,12 @@ namespace MediaBrowser.Controller.Providers [Export(typeof(BaseMetadataProvider))]
public class AudioInfoProvider : BaseMetadataProvider
{
- public override bool Supports(BaseItem item)
+ public override bool Supports(BaseEntity item)
{
return item is Audio;
}
- public async override Task Fetch(BaseItem item, ItemResolveEventArgs args)
+ public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
{
Audio audio = item as Audio;
@@ -62,6 +62,7 @@ namespace MediaBrowser.Controller.Providers {
base.Init();
+ // Do this now so that we don't have to do this on every operation, which would require us to create a lock in order to maintain thread-safety
for (int i = 0; i <= 9; i++)
{
EnsureDirectory(Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, i.ToString()));
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index 93d9ef10e..e40d30372 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -1,10 +1,11 @@ -using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
using MediaBrowser.Controller.Events;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Providers
{
- public abstract class BaseMetadataProvider
+ public abstract class BaseMetadataProvider : IDisposable
{
/// <summary>
/// If the provider needs any startup routines, add them here
@@ -13,11 +14,23 @@ namespace MediaBrowser.Controller.Providers {
}
- public virtual bool Supports(BaseItem item)
+ /// <summary>
+ /// Disposes anything created during Init
+ /// </summary>
+ public virtual void Dispose()
+ {
+ }
+
+ public abstract bool Supports(BaseEntity item);
+
+ public virtual bool RequiresInternet
{
- return true;
+ get
+ {
+ return false;
+ }
}
- public abstract Task Fetch(BaseItem item, ItemResolveEventArgs args);
+ public abstract Task Fetch(BaseEntity item, ItemResolveEventArgs args);
}
}
diff --git a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs index 14067dd20..2ef214237 100644 --- a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs @@ -9,12 +9,12 @@ namespace MediaBrowser.Controller.Providers [Export(typeof(BaseMetadataProvider))]
public class FolderProviderFromXml : BaseMetadataProvider
{
- public override bool Supports(BaseItem item)
+ public override bool Supports(BaseEntity item)
{
return item is Folder;
}
- public async override Task Fetch(BaseItem item, ItemResolveEventArgs args)
+ public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
{
var metadataFile = args.GetFileByName("folder.xml");
diff --git a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs index 2df07251a..5b086f795 100644 --- a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs @@ -12,13 +12,18 @@ namespace MediaBrowser.Controller.Providers [Export(typeof(BaseMetadataProvider))]
public class ImageFromMediaLocationProvider : BaseMetadataProvider
{
- public override Task Fetch(BaseItem item, ItemResolveEventArgs args)
+ public override bool Supports(BaseEntity item)
+ {
+ return item is BaseItem;
+ }
+
+ public override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
{
return Task.Run(() =>
{
if (args.IsFolder)
{
- PopulateImages(item, args);
+ PopulateImages(item as BaseItem, args);
}
});
}
diff --git a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs index 027c2f75d..9d909934d 100644 --- a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs +++ b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs @@ -10,8 +10,15 @@ namespace MediaBrowser.Controller.Providers [Export(typeof(BaseMetadataProvider))]
public class LocalTrailerProvider : BaseMetadataProvider
{
- public async override Task Fetch(BaseItem item, ItemResolveEventArgs args)
+ public override bool Supports(BaseEntity item)
{
+ return item is BaseItem;
+ }
+
+ public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
+ {
+ BaseItem baseItem = item as BaseItem;
+
var trailerPath = args.GetFolderByName("trailers");
if (trailerPath.HasValue)
@@ -32,7 +39,7 @@ namespace MediaBrowser.Controller.Providers }
}
- item.LocalTrailers = localTrailers;
+ baseItem.LocalTrailers = localTrailers;
}
}
}
diff --git a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs index 75e516487..d8f6b61ce 100644 --- a/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs +++ b/MediaBrowser.Controller/Resolvers/BaseItemResolver.cs @@ -2,13 +2,12 @@ using System.IO;
using System.Threading.Tasks;
using MediaBrowser.Controller.Events;
-using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Resolvers
{
public abstract class BaseItemResolver<T> : IBaseItemResolver
- where T : BaseItem, new ()
+ where T : BaseItem, new()
{
protected virtual T Resolve(ItemResolveEventArgs args)
{
@@ -18,7 +17,7 @@ namespace MediaBrowser.Controller.Resolvers /// <summary>
/// Sets initial values on the newly resolved item
/// </summary>
- protected virtual void SetItemValues(T item, ItemResolveEventArgs args)
+ protected virtual void SetInitialItemValues(T item, ItemResolveEventArgs args)
{
// If the subclass didn't specify this
if (string.IsNullOrEmpty(item.Path))
@@ -38,35 +37,24 @@ namespace MediaBrowser.Controller.Resolvers public async Task<BaseItem> ResolvePath(ItemResolveEventArgs args)
{
T item = Resolve(args);
-
+
if (item != null)
{
// Set initial values on the newly resolved item
- SetItemValues(item, args);
+ SetInitialItemValues(item, args);
// Make sure the item has a name
EnsureName(item);
// Make sure DateCreated and DateModified have values
EnsureDates(item);
-
- await FetchMetadataFromProviders(item, args);
+
+ await Kernel.Instance.ExecuteMetadataProviders(item, args);
}
return item;
}
- private async Task FetchMetadataFromProviders(T item, ItemResolveEventArgs args)
- {
- foreach (BaseMetadataProvider provider in Kernel.Instance.MetadataProviders)
- {
- if (provider.Supports(item))
- {
- await provider.Fetch(item, args);
- }
- }
- }
-
private void EnsureName(T item)
{
// If the subclass didn't supply a name, add it here
diff --git a/MediaBrowser.Controller/Resolvers/FolderResolver.cs b/MediaBrowser.Controller/Resolvers/FolderResolver.cs index ff326669f..858b3bcd8 100644 --- a/MediaBrowser.Controller/Resolvers/FolderResolver.cs +++ b/MediaBrowser.Controller/Resolvers/FolderResolver.cs @@ -21,9 +21,9 @@ namespace MediaBrowser.Controller.Resolvers public abstract class BaseFolderResolver<TItemType> : BaseItemResolver<TItemType>
where TItemType : Folder, new()
{
- protected override void SetItemValues(TItemType item, ItemResolveEventArgs args)
+ protected override void SetInitialItemValues(TItemType item, ItemResolveEventArgs args)
{
- base.SetItemValues(item, args);
+ base.SetInitialItemValues(item, args);
item.IsRoot = args.Parent == null;
}
diff --git a/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs b/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs index 51478fd02..c81cb204a 100644 --- a/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs +++ b/MediaBrowser.Controller/Resolvers/VirtualFolderResolver.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Controller.Resolvers return null;
}
- protected override void SetItemValues(VirtualFolder item, ItemResolveEventArgs args)
+ protected override void SetInitialItemValues(VirtualFolder item, ItemResolveEventArgs args)
{
// Set the name initially by stripping off the [CollectionType=...]
// The name can always be overridden later by folder.xml
@@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Resolvers item.CollectionType = pathName.Substring(index + srch.Length).TrimEnd(']');
}
- base.SetItemValues(item, args);
+ base.SetInitialItemValues(item, args);
}
}
diff --git a/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs b/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs index 0e514b8b2..6c7a265fa 100644 --- a/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs @@ -2,9 +2,9 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using System.Xml;
using MediaBrowser.Model.Entities;
-using System.Threading.Tasks;
namespace MediaBrowser.Controller.Xml
{
|
