Removed Linq usage from ItemController

This commit is contained in:
LukePulverenti Luke Pulverenti luke pulverenti 2012-08-20 21:21:03 -04:00
parent 758d18a652
commit 906ad3cb1a
8 changed files with 76 additions and 133 deletions

View file

@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Events
/// </summary> /// </summary>
public class ItemResolveEventArgs : PreBeginResolveEventArgs public class ItemResolveEventArgs : PreBeginResolveEventArgs
{ {
public IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> FileSystemChildren { get; set; } public KeyValuePair<string, WIN32_FIND_DATA>[] FileSystemChildren { get; set; }
public KeyValuePair<string, WIN32_FIND_DATA>? GetFileSystemEntry(string path, bool? isFolder) public KeyValuePair<string, WIN32_FIND_DATA>? GetFileSystemEntry(string path, bool? isFolder)
{ {

View file

@ -42,13 +42,14 @@ namespace MediaBrowser.Controller
/// Gets the list of currently registered metadata prvoiders /// Gets the list of currently registered metadata prvoiders
/// </summary> /// </summary>
[ImportMany(typeof(BaseMetadataProvider))] [ImportMany(typeof(BaseMetadataProvider))]
public BaseMetadataProvider[] MetadataProviders { get; private set; } public IEnumerable<BaseMetadataProvider> MetadataProviders { get; private set; }
/// <summary> /// <summary>
/// Gets the list of currently registered entity resolvers /// Gets the list of currently registered entity resolvers
/// </summary> /// </summary>
[ImportMany(typeof(IBaseItemResolver))] [ImportMany(typeof(IBaseItemResolver))]
public IBaseItemResolver[] EntityResolvers { get; private set; } private IEnumerable<IBaseItemResolver> EntityResolversEnumerable { get; set; }
internal IBaseItemResolver[] EntityResolvers { get; private set; }
/// <summary> /// <summary>
/// Creates a kernel based on a Data path, which is akin to our current programdata path /// Creates a kernel based on a Data path, which is akin to our current programdata path
@ -89,6 +90,12 @@ namespace MediaBrowser.Controller
// The base class will start up all the plugins // The base class will start up all the plugins
base.OnComposablePartsLoaded(); base.OnComposablePartsLoaded();
// Sort the resolvers by priority
EntityResolvers = EntityResolversEnumerable.OrderBy(e => e.Priority).ToArray();
// Sort the providers by priority
MetadataProviders = MetadataProviders.OrderBy(e => e.Priority);
// Initialize the metadata providers // Initialize the metadata providers
Parallel.ForEach(MetadataProviders, provider => Parallel.ForEach(MetadataProviders, provider =>
{ {
@ -149,7 +156,7 @@ namespace MediaBrowser.Controller
DirectoryWatchers.Stop(); DirectoryWatchers.Stop();
RootFolder = await ItemController.GetItem(null, MediaRootFolderPath).ConfigureAwait(false) as Folder; RootFolder = await ItemController.GetItem(MediaRootFolderPath).ConfigureAwait(false) as Folder;
DirectoryWatchers.Start(); DirectoryWatchers.Start();
} }
@ -178,7 +185,7 @@ namespace MediaBrowser.Controller
return; return;
} }
BaseItem newItem = await ItemController.GetItem(item.Parent, item.Path).ConfigureAwait(false); BaseItem newItem = await ItemController.GetItem(item.Path, item.Parent).ConfigureAwait(false);
List<BaseItem> children = item.Parent.Children.ToList(); List<BaseItem> children = item.Parent.Children.ToList();
@ -229,56 +236,14 @@ namespace MediaBrowser.Controller
internal async Task ExecuteMetadataProviders(BaseEntity item, ItemResolveEventArgs args) internal async Task ExecuteMetadataProviders(BaseEntity item, ItemResolveEventArgs args)
{ {
// Get all supported providers // Get all supported providers
var supportedProviders = Kernel.Instance.MetadataProviders.Where(i => i.Supports(item)); BaseMetadataProvider[] supportedProviders = Kernel.Instance.MetadataProviders.Where(i => i.Supports(item)).ToArray();
// First priority providers // Run them
var providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.First); for (int i = 0; i < supportedProviders.Length; i++)
if (providers.Any())
{ {
await Task.WhenAll( var provider = supportedProviders[i];
providers.Select(i => i.Fetch(item, args))
).ConfigureAwait(false);
}
// Second priority providers await provider.Fetch(item, args);
providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.Second);
if (providers.Any())
{
await Task.WhenAll(
providers.Select(i => i.Fetch(item, args))
).ConfigureAwait(false);
}
// Third priority providers
providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.Third);
if (providers.Any())
{
await Task.WhenAll(
providers.Select(i => i.Fetch(item, args))
).ConfigureAwait(false);
}
// Lowest priority providers
providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.Last);
if (providers.Any())
{
await Task.WhenAll(
providers.Select(i => i.Fetch(item, args))
).ConfigureAwait(false);
}
// Execute internet providers
providers = supportedProviders.Where(i => i.RequiresInternet);
if (providers.Any())
{
await Task.WhenAll(
providers.Select(i => i.Fetch(item, args))
).ConfigureAwait(false);
} }
} }

View file

@ -6,7 +6,6 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Events; using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO; using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Library namespace MediaBrowser.Controller.Library
@ -60,42 +59,9 @@ namespace MediaBrowser.Controller.Library
private BaseItem ResolveItem(ItemResolveEventArgs args) private BaseItem ResolveItem(ItemResolveEventArgs args)
{ {
// Try first priority resolvers // Try first priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.First)) for (int i = 0; i < Kernel.Instance.EntityResolvers.Length; i++)
{ {
var item = resolver.ResolvePath(args); var item = Kernel.Instance.EntityResolvers[i].ResolvePath(args);
if (item != null)
{
return item;
}
}
// Try second priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Second))
{
var item = resolver.ResolvePath(args);
if (item != null)
{
return item;
}
}
// Try third priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Third))
{
var item = resolver.ResolvePath(args);
if (item != null)
{
return item;
}
}
// Try last priority resolvers
foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Last))
{
var item = resolver.ResolvePath(args);
if (item != null) if (item != null)
{ {
@ -109,29 +75,21 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Resolves a path into a BaseItem /// Resolves a path into a BaseItem
/// </summary> /// </summary>
public async Task<BaseItem> GetItem(Folder parent, string path) public async Task<BaseItem> GetItem(string path, Folder parent = null, WIN32_FIND_DATA? fileInfo = null)
{ {
WIN32_FIND_DATA fileData = FileData.GetFileData(path); WIN32_FIND_DATA fileData = fileInfo ?? FileData.GetFileData(path);
return await GetItemInternal(parent, path, fileData).ConfigureAwait(false);
}
/// <summary>
/// Resolves a path into a BaseItem
/// </summary>
private async Task<BaseItem> GetItemInternal(Folder parent, string path, WIN32_FIND_DATA fileData)
{
if (!OnPreBeginResolvePath(parent, path, fileData)) if (!OnPreBeginResolvePath(parent, path, fileData))
{ {
return null; return null;
} }
IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren; KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren;
// Gather child folder and files // Gather child folder and files
if (fileData.IsDirectory) if (fileData.IsDirectory)
{ {
fileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, WIN32_FIND_DATA>(f, FileData.GetFileData(f))); fileSystemChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly));
bool isVirtualFolder = parent != null && parent.IsRoot; bool isVirtualFolder = parent != null && parent.IsRoot;
fileSystemChildren = FilterChildFileSystemEntries(fileSystemChildren, isVirtualFolder); fileSystemChildren = FilterChildFileSystemEntries(fileSystemChildren, isVirtualFolder);
@ -177,19 +135,17 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Finds child BaseItems for a given Folder /// Finds child BaseItems for a given Folder
/// </summary> /// </summary>
private async Task AttachChildren(Folder folder, IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren) private async Task AttachChildren(Folder folder, KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren)
{ {
KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildrenArray = fileSystemChildren.ToArray(); int count = fileSystemChildren.Length;
int count = fileSystemChildrenArray.Length;
Task<BaseItem>[] tasks = new Task<BaseItem>[count]; Task<BaseItem>[] tasks = new Task<BaseItem>[count];
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
var child = fileSystemChildrenArray[i]; var child = fileSystemChildren[i];
tasks[i] = GetItemInternal(folder, child.Key, child.Value); tasks[i] = GetItem(child.Key, folder, child.Value);
} }
BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks).ConfigureAwait(false); BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks).ConfigureAwait(false);
@ -199,25 +155,25 @@ namespace MediaBrowser.Controller.Library
{ {
return string.IsNullOrEmpty(f.SortName) ? f.Name : f.SortName; return string.IsNullOrEmpty(f.SortName) ? f.Name : f.SortName;
}).ToArray(); });
} }
/// <summary> /// <summary>
/// Transforms shortcuts into their actual paths /// Transforms shortcuts into their actual paths
/// </summary> /// </summary>
private List<KeyValuePair<string, WIN32_FIND_DATA>> FilterChildFileSystemEntries(IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren, bool flattenShortcuts) private KeyValuePair<string, WIN32_FIND_DATA>[] FilterChildFileSystemEntries(KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildren, bool flattenShortcuts)
{ {
List<KeyValuePair<string, WIN32_FIND_DATA>> returnFiles = new List<KeyValuePair<string, WIN32_FIND_DATA>>(); KeyValuePair<string, WIN32_FIND_DATA>[] returnArray = new KeyValuePair<string, WIN32_FIND_DATA>[fileSystemChildren.Length];
List<KeyValuePair<string, WIN32_FIND_DATA>> resolvedShortcuts = new List<KeyValuePair<string, WIN32_FIND_DATA>>();
// Loop through each file for (int i = 0; i < fileSystemChildren.Length; i++)
foreach (KeyValuePair<string, WIN32_FIND_DATA> file in fileSystemChildren)
{ {
// Folders KeyValuePair<string, WIN32_FIND_DATA> file = fileSystemChildren[i];
if (file.Value.IsDirectory) if (file.Value.IsDirectory)
{ {
returnFiles.Add(file); returnArray[i] = file;
} }
// If it's a shortcut, resolve it // If it's a shortcut, resolve it
else if (Shortcut.IsShortcut(file.Key)) else if (Shortcut.IsShortcut(file.Key))
{ {
@ -225,34 +181,42 @@ namespace MediaBrowser.Controller.Library
WIN32_FIND_DATA newPathData = FileData.GetFileData(newPath); WIN32_FIND_DATA newPathData = FileData.GetFileData(newPath);
// Find out if the shortcut is pointing to a directory or file // Find out if the shortcut is pointing to a directory or file
if (newPathData.IsDirectory) if (newPathData.IsDirectory)
{ {
// If we're flattening then get the shortcut's children // If we're flattening then get the shortcut's children
if (flattenShortcuts) if (flattenShortcuts)
{ {
IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> newChildren = Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, WIN32_FIND_DATA>(f, FileData.GetFileData(f))); returnArray[i] = file;
KeyValuePair<string, WIN32_FIND_DATA>[] newChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly));
returnFiles.AddRange(FilterChildFileSystemEntries(newChildren, false)); resolvedShortcuts.AddRange(FilterChildFileSystemEntries(newChildren, false));
} }
else else
{ {
returnFiles.Add(new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData)); returnArray[i] = new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData);
} }
} }
else else
{ {
returnFiles.Add(new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData)); returnArray[i] = new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData);
} }
} }
else else
{ {
returnFiles.Add(file); returnArray[i] = file;
} }
} }
return returnFiles; if (resolvedShortcuts.Count > 0)
{
resolvedShortcuts.InsertRange(0, returnArray);
return resolvedShortcuts.ToArray();
}
else
{
return returnArray;
}
} }
/// <summary> /// <summary>
@ -338,11 +302,25 @@ namespace MediaBrowser.Controller.Library
ItemResolveEventArgs args = new ItemResolveEventArgs(); ItemResolveEventArgs args = new ItemResolveEventArgs();
args.Path = path; args.Path = path;
args.FileData = FileData.GetFileData(path); args.FileData = FileData.GetFileData(path);
args.FileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, WIN32_FIND_DATA>(f, FileData.GetFileData(f))); args.FileSystemChildren = ConvertFileSystemEntries(Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly));
await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false); await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false);
return item; return item;
} }
private KeyValuePair<string, WIN32_FIND_DATA>[] ConvertFileSystemEntries(string[] files)
{
KeyValuePair<string, WIN32_FIND_DATA>[] items = new KeyValuePair<string, WIN32_FIND_DATA>[files.Length];
for (int i = 0; i < files.Length; i++)
{
string file = files[i];
items[i] = new KeyValuePair<string, WIN32_FIND_DATA>(file, FileData.GetFileData(file));
}
return items;
}
} }
} }

View file

@ -42,15 +42,15 @@ namespace MediaBrowser.Controller.Providers
public enum MetadataProviderPriority public enum MetadataProviderPriority
{ {
// Run this provider at the beginning // Run this provider at the beginning
First, First = 1,
// Run this provider after all first priority providers // Run this provider after all first priority providers
Second, Second = 2,
// Run this provider after all second priority providers // Run this provider after all second priority providers
Third, Third = 3,
// Run this provider last // Run this provider last
Last Last = 4
} }
} }

View file

@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Providers
foreach (string file in allFiles) foreach (string file in allFiles)
{ {
BaseItem child = await Kernel.Instance.ItemController.GetItem(null, file).ConfigureAwait(false); BaseItem child = await Kernel.Instance.ItemController.GetItem(file).ConfigureAwait(false);
Video video = child as Video; Video video = child as Video;

View file

@ -117,9 +117,9 @@ namespace MediaBrowser.Controller.Resolvers
public enum ResolverPriority public enum ResolverPriority
{ {
First, First = 1,
Second, Second = 2,
Third, Third = 3,
Last Last = 4
} }
} }

View file

@ -16,7 +16,7 @@ namespace MediaBrowser.Model.Entities
public bool IsRoot { get; set; } public bool IsRoot { get; set; }
public BaseItem[] Children { get; set; } public IEnumerable<BaseItem> Children { get; set; }
/// <summary> /// <summary>
/// Gets allowed children of an item /// Gets allowed children of an item

View file

@ -85,7 +85,7 @@ namespace MediaBrowser.Movies.Resolvers
{ {
string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Key, "*", SearchOption.TopDirectoryOnly); string[] allFiles = Directory.GetFileSystemEntries(trailerPath.Value.Key, "*", SearchOption.TopDirectoryOnly);
item.SpecialFeatures = allFiles.Select(f => Kernel.Instance.ItemController.GetItem(null, f)).OfType<Video>(); item.SpecialFeatures = allFiles.Select(f => Kernel.Instance.ItemController.GetItem(f)).OfType<Video>();
} }
} }