Switched to low-level io methods for better performance
This commit is contained in:
parent
6fbeee841f
commit
758d18a652
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Events
|
namespace MediaBrowser.Controller.Events
|
||||||
{
|
{
|
||||||
|
@ -10,18 +11,25 @@ namespace MediaBrowser.Controller.Events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ItemResolveEventArgs : PreBeginResolveEventArgs
|
public class ItemResolveEventArgs : PreBeginResolveEventArgs
|
||||||
{
|
{
|
||||||
public IEnumerable<KeyValuePair<string, FileAttributes>> FileSystemChildren { get; set; }
|
public IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> FileSystemChildren { get; set; }
|
||||||
|
|
||||||
public KeyValuePair<string, FileAttributes>? GetFolderByName(string name)
|
public KeyValuePair<string, WIN32_FIND_DATA>? GetFileSystemEntry(string path, bool? isFolder)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, FileAttributes> entry in FileSystemChildren)
|
foreach (KeyValuePair<string, WIN32_FIND_DATA> entry in FileSystemChildren)
|
||||||
{
|
{
|
||||||
if (!entry.Value.HasFlag(FileAttributes.Directory))
|
if (isFolder.HasValue)
|
||||||
{
|
{
|
||||||
continue;
|
if (isFolder.Value && entry.Value.IsDirectory)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!isFolder.Value && !entry.Value.IsDirectory)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.IO.Path.GetFileName(entry.Key).Equals(name, StringComparison.OrdinalIgnoreCase))
|
if (entry.Key.Equals(path, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -29,14 +37,21 @@ namespace MediaBrowser.Controller.Events
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValuePair<string, FileAttributes>? GetFileByName(string name)
|
public KeyValuePair<string, WIN32_FIND_DATA>? GetFileSystemEntryByName(string name, bool? isFolder)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, FileAttributes> entry in FileSystemChildren)
|
foreach (KeyValuePair<string, WIN32_FIND_DATA> entry in FileSystemChildren)
|
||||||
{
|
{
|
||||||
if (entry.Value.HasFlag(FileAttributes.Directory))
|
if (isFolder.HasValue)
|
||||||
{
|
{
|
||||||
continue;
|
if (isFolder.Value && entry.Value.IsDirectory)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!isFolder.Value && !entry.Value.IsDirectory)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.IO.Path.GetFileName(entry.Key).Equals(name, StringComparison.OrdinalIgnoreCase))
|
if (System.IO.Path.GetFileName(entry.Key).Equals(name, StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -50,12 +65,12 @@ namespace MediaBrowser.Controller.Events
|
||||||
|
|
||||||
public bool ContainsFile(string name)
|
public bool ContainsFile(string name)
|
||||||
{
|
{
|
||||||
return GetFileByName(name) != null;
|
return GetFileSystemEntryByName(name, false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ContainsFolder(string name)
|
public bool ContainsFolder(string name)
|
||||||
{
|
{
|
||||||
return GetFolderByName(name) != null;
|
return GetFileSystemEntryByName(name, true) != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +86,8 @@ namespace MediaBrowser.Controller.Events
|
||||||
|
|
||||||
public bool Cancel { get; set; }
|
public bool Cancel { get; set; }
|
||||||
|
|
||||||
public FileAttributes FileAttributes { get; set; }
|
public FileAttributes FileAttributes { get { return FileData.dwFileAttributes; } }
|
||||||
|
public WIN32_FIND_DATA FileData { get; set; }
|
||||||
|
|
||||||
public bool IsFolder
|
public bool IsFolder
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace MediaBrowser.Controller.IO
|
||||||
List<string> paths = affectedPaths;
|
List<string> paths = affectedPaths;
|
||||||
affectedPaths = new List<string>();
|
affectedPaths = new List<string>();
|
||||||
|
|
||||||
await ProcessPathChanges(paths);
|
await ProcessPathChanges(paths).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessPathChanges(IEnumerable<string> paths)
|
private async Task ProcessPathChanges(IEnumerable<string> paths)
|
||||||
|
@ -105,11 +105,11 @@ namespace MediaBrowser.Controller.IO
|
||||||
return folder != null && folder.IsRoot;
|
return folder != null && folder.IsRoot;
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
await Kernel.Instance.ReloadRoot();
|
await Kernel.Instance.ReloadRoot().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i)));
|
await Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i))).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
96
MediaBrowser.Controller/IO/FileData.cs
Normal file
96
MediaBrowser.Controller/IO/FileData.cs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.IO
|
||||||
|
{
|
||||||
|
public static class FileData
|
||||||
|
{
|
||||||
|
public const int MAX_PATH = 260;
|
||||||
|
public const int MAX_ALTERNATE = 14;
|
||||||
|
|
||||||
|
public static WIN32_FIND_DATA GetFileData(string fileName)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATA data;
|
||||||
|
IntPtr handle = FindFirstFile(fileName, out data);
|
||||||
|
if (handle == IntPtr.Zero)
|
||||||
|
throw new IOException("FindFirstFile failed");
|
||||||
|
FindClose(handle);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern IntPtr FindFirstFile(string fileName, out WIN32_FIND_DATA data);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern bool FindClose(IntPtr hFindFile);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct FILETIME
|
||||||
|
{
|
||||||
|
public uint dwLowDateTime;
|
||||||
|
public uint dwHighDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||||
|
public struct WIN32_FIND_DATA
|
||||||
|
{
|
||||||
|
public FileAttributes dwFileAttributes;
|
||||||
|
public FILETIME ftCreationTime;
|
||||||
|
public FILETIME ftLastAccessTime;
|
||||||
|
public FILETIME ftLastWriteTime;
|
||||||
|
public int nFileSizeHigh;
|
||||||
|
public int nFileSizeLow;
|
||||||
|
public int dwReserved0;
|
||||||
|
public int dwReserved1;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FileData.MAX_PATH)]
|
||||||
|
public string cFileName;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = FileData.MAX_ALTERNATE)]
|
||||||
|
public string cAlternate;
|
||||||
|
|
||||||
|
public bool IsDirectory
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return dwFileAttributes.HasFlag(FileAttributes.Directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime CreationTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ParseFileTime(ftCreationTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime LastAccessTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ParseFileTime(ftLastAccessTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime LastWriteTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ParseFileTime(ftLastWriteTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime ParseFileTime(FILETIME filetime)
|
||||||
|
{
|
||||||
|
long highBits = filetime.dwHighDateTime;
|
||||||
|
highBits = highBits << 32;
|
||||||
|
return DateTime.FromFileTime(highBits + (long)filetime.dwLowDateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,13 +20,13 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// This gives listeners a chance to cancel the operation and cause the path to be ignored.
|
/// This gives listeners a chance to cancel the operation and cause the path to be ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<PreBeginResolveEventArgs> PreBeginResolvePath;
|
public event EventHandler<PreBeginResolveEventArgs> PreBeginResolvePath;
|
||||||
private bool OnPreBeginResolvePath(Folder parent, string path, FileAttributes attributes)
|
private bool OnPreBeginResolvePath(Folder parent, string path, WIN32_FIND_DATA fileData)
|
||||||
{
|
{
|
||||||
PreBeginResolveEventArgs args = new PreBeginResolveEventArgs()
|
PreBeginResolveEventArgs args = new PreBeginResolveEventArgs()
|
||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
Parent = parent,
|
Parent = parent,
|
||||||
FileAttributes = attributes,
|
FileData = fileData,
|
||||||
Cancel = false
|
Cancel = false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,39 +111,41 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<BaseItem> GetItem(Folder parent, string path)
|
public async Task<BaseItem> GetItem(Folder parent, string path)
|
||||||
{
|
{
|
||||||
return await GetItemInternal(parent, path, File.GetAttributes(path)).ConfigureAwait(false);
|
WIN32_FIND_DATA fileData = FileData.GetFileData(path);
|
||||||
|
|
||||||
|
return await GetItemInternal(parent, path, fileData).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves a path into a BaseItem
|
/// Resolves a path into a BaseItem
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<BaseItem> GetItemInternal(Folder parent, string path, FileAttributes attributes)
|
private async Task<BaseItem> GetItemInternal(Folder parent, string path, WIN32_FIND_DATA fileData)
|
||||||
{
|
{
|
||||||
if (!OnPreBeginResolvePath(parent, path, attributes))
|
if (!OnPreBeginResolvePath(parent, path, fileData))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<KeyValuePair<string, FileAttributes>> fileSystemChildren;
|
IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren;
|
||||||
|
|
||||||
// Gather child folder and files
|
// Gather child folder and files
|
||||||
if (attributes.HasFlag(FileAttributes.Directory))
|
if (fileData.IsDirectory)
|
||||||
{
|
{
|
||||||
fileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, FileAttributes>(f, File.GetAttributes(f)));
|
fileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, WIN32_FIND_DATA>(f, FileData.GetFileData(f)));
|
||||||
|
|
||||||
bool isVirtualFolder = parent != null && parent.IsRoot;
|
bool isVirtualFolder = parent != null && parent.IsRoot;
|
||||||
fileSystemChildren = FilterChildFileSystemEntries(fileSystemChildren, isVirtualFolder);
|
fileSystemChildren = FilterChildFileSystemEntries(fileSystemChildren, isVirtualFolder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileSystemChildren = new KeyValuePair<string, FileAttributes>[] { };
|
fileSystemChildren = new KeyValuePair<string, WIN32_FIND_DATA>[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemResolveEventArgs args = new ItemResolveEventArgs()
|
ItemResolveEventArgs args = new ItemResolveEventArgs()
|
||||||
{
|
{
|
||||||
Path = path,
|
Path = path,
|
||||||
FileAttributes = attributes,
|
|
||||||
FileSystemChildren = fileSystemChildren,
|
FileSystemChildren = fileSystemChildren,
|
||||||
|
FileData = fileData,
|
||||||
Parent = parent,
|
Parent = parent,
|
||||||
Cancel = false
|
Cancel = false
|
||||||
};
|
};
|
||||||
|
@ -175,9 +177,9 @@ 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, FileAttributes>> fileSystemChildren)
|
private async Task AttachChildren(Folder folder, IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren)
|
||||||
{
|
{
|
||||||
KeyValuePair<string, FileAttributes>[] fileSystemChildrenArray = fileSystemChildren.ToArray();
|
KeyValuePair<string, WIN32_FIND_DATA>[] fileSystemChildrenArray = fileSystemChildren.ToArray();
|
||||||
|
|
||||||
int count = fileSystemChildrenArray.Length;
|
int count = fileSystemChildrenArray.Length;
|
||||||
|
|
||||||
|
@ -203,15 +205,15 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Transforms shortcuts into their actual paths
|
/// Transforms shortcuts into their actual paths
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<KeyValuePair<string, FileAttributes>> FilterChildFileSystemEntries(IEnumerable<KeyValuePair<string, FileAttributes>> fileSystemChildren, bool flattenShortcuts)
|
private List<KeyValuePair<string, WIN32_FIND_DATA>> FilterChildFileSystemEntries(IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren, bool flattenShortcuts)
|
||||||
{
|
{
|
||||||
List<KeyValuePair<string, FileAttributes>> returnFiles = new List<KeyValuePair<string, FileAttributes>>();
|
List<KeyValuePair<string, WIN32_FIND_DATA>> returnFiles = new List<KeyValuePair<string, WIN32_FIND_DATA>>();
|
||||||
|
|
||||||
// Loop through each file
|
// Loop through each file
|
||||||
foreach (KeyValuePair<string, FileAttributes> file in fileSystemChildren)
|
foreach (KeyValuePair<string, WIN32_FIND_DATA> file in fileSystemChildren)
|
||||||
{
|
{
|
||||||
// Folders
|
// Folders
|
||||||
if (file.Value.HasFlag(FileAttributes.Directory))
|
if (file.Value.IsDirectory)
|
||||||
{
|
{
|
||||||
returnFiles.Add(file);
|
returnFiles.Add(file);
|
||||||
}
|
}
|
||||||
|
@ -220,28 +222,28 @@ namespace MediaBrowser.Controller.Library
|
||||||
else if (Shortcut.IsShortcut(file.Key))
|
else if (Shortcut.IsShortcut(file.Key))
|
||||||
{
|
{
|
||||||
string newPath = Shortcut.ResolveShortcut(file.Key);
|
string newPath = Shortcut.ResolveShortcut(file.Key);
|
||||||
FileAttributes newPathAttributes = File.GetAttributes(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 (newPathAttributes.HasFlag(FileAttributes.Directory))
|
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, FileAttributes>> newChildren = Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, FileAttributes>(f, File.GetAttributes(f)));
|
IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> newChildren = Directory.GetFileSystemEntries(newPath, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, WIN32_FIND_DATA>(f, FileData.GetFileData(f)));
|
||||||
|
|
||||||
returnFiles.AddRange(FilterChildFileSystemEntries(newChildren, false));
|
returnFiles.AddRange(FilterChildFileSystemEntries(newChildren, false));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
returnFiles.Add(new KeyValuePair<string, FileAttributes>(newPath, newPathAttributes));
|
returnFiles.Add(new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
returnFiles.Add(new KeyValuePair<string, FileAttributes>(newPath, newPathAttributes));
|
returnFiles.Add(new KeyValuePair<string, WIN32_FIND_DATA>(newPath, newPathData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -335,8 +337,8 @@ namespace MediaBrowser.Controller.Library
|
||||||
|
|
||||||
ItemResolveEventArgs args = new ItemResolveEventArgs();
|
ItemResolveEventArgs args = new ItemResolveEventArgs();
|
||||||
args.Path = path;
|
args.Path = path;
|
||||||
args.FileAttributes = File.GetAttributes(path);
|
args.FileData = FileData.GetFileData(path);
|
||||||
args.FileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, FileAttributes>(f, File.GetAttributes(f)));
|
args.FileSystemChildren = Directory.GetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly).Select(f => new KeyValuePair<string, WIN32_FIND_DATA>(f, FileData.GetFileData(f)));
|
||||||
|
|
||||||
await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false);
|
await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
<Compile Include="FFMpeg\FFProbe.cs" />
|
<Compile Include="FFMpeg\FFProbe.cs" />
|
||||||
<Compile Include="FFMpeg\FFProbeResult.cs" />
|
<Compile Include="FFMpeg\FFProbeResult.cs" />
|
||||||
<Compile Include="IO\DirectoryWatchers.cs" />
|
<Compile Include="IO\DirectoryWatchers.cs" />
|
||||||
|
<Compile Include="IO\FileData.cs" />
|
||||||
<Compile Include="IO\Shortcut.cs" />
|
<Compile Include="IO\Shortcut.cs" />
|
||||||
<Compile Include="Library\ItemController.cs" />
|
<Compile Include="Library\ItemController.cs" />
|
||||||
<Compile Include="Kernel.cs" />
|
<Compile Include="Kernel.cs" />
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -6,7 +7,6 @@ using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
using MediaBrowser.Controller.FFMpeg;
|
using MediaBrowser.Controller.FFMpeg;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Providers
|
namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var metadataFile = args.GetFileByName("folder.xml");
|
var metadataFile = args.GetFileSystemEntryByName("folder.xml", false);
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Providers
|
namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
|
@ -47,9 +48,9 @@ namespace MediaBrowser.Controller.Providers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void PopulateImages(BaseEntity item, ItemResolveEventArgs args)
|
private void PopulateImages(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, FileAttributes> file in args.FileSystemChildren)
|
foreach (KeyValuePair<string, WIN32_FIND_DATA> file in args.FileSystemChildren)
|
||||||
{
|
{
|
||||||
if (file.Value.HasFlag(FileAttributes.Directory))
|
if (file.Value.IsDirectory)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -80,9 +81,9 @@ namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
List<string> backdropFiles = new List<string>();
|
List<string> backdropFiles = new List<string>();
|
||||||
|
|
||||||
foreach (KeyValuePair<string, FileAttributes> file in args.FileSystemChildren)
|
foreach (KeyValuePair<string, WIN32_FIND_DATA> file in args.FileSystemChildren)
|
||||||
{
|
{
|
||||||
if (file.Value.HasFlag(FileAttributes.Directory))
|
if (file.Value.IsDirectory)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
BaseItem baseItem = item as BaseItem;
|
BaseItem baseItem = item as BaseItem;
|
||||||
|
|
||||||
var trailerPath = args.GetFolderByName("trailers");
|
var trailerPath = args.GetFileSystemEntryByName("trailers", true);
|
||||||
|
|
||||||
if (trailerPath.HasValue)
|
if (trailerPath.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,12 +66,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(video.FrameRate))
|
if (video.FrameRate == 0 || video.Height == 0 || video.Width == 0 || video.BitRate == 0)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video.Height == 0 || video.Width == 0 || video.BitRate == 0)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Resolvers
|
namespace MediaBrowser.Controller.Resolvers
|
||||||
{
|
{
|
||||||
|
@ -55,7 +57,7 @@ namespace MediaBrowser.Controller.Resolvers
|
||||||
EnsureName(item);
|
EnsureName(item);
|
||||||
|
|
||||||
// Make sure DateCreated and DateModified have values
|
// Make sure DateCreated and DateModified have values
|
||||||
EnsureDates(item);
|
EnsureDates(item, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
@ -74,18 +76,33 @@ namespace MediaBrowser.Controller.Resolvers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensures DateCreated and DateModified have values
|
/// Ensures DateCreated and DateModified have values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void EnsureDates(T item)
|
private void EnsureDates(T item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
// If the subclass didn't supply dates, add them here
|
if (!Path.IsPathRooted(item.Path))
|
||||||
if (item.DateCreated == DateTime.MinValue)
|
|
||||||
{
|
{
|
||||||
item.DateCreated = Path.IsPathRooted(item.Path) ? File.GetCreationTime(item.Path) : DateTime.Now;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.DateModified == DateTime.MinValue)
|
WIN32_FIND_DATA fileData = args.FileData;
|
||||||
|
|
||||||
|
// See if a different path came out of the resolver than what went in
|
||||||
|
if (!args.Path.Equals(item.Path, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
item.DateModified = Path.IsPathRooted(item.Path) ? File.GetLastWriteTime(item.Path) : DateTime.Now;
|
KeyValuePair<string, WIN32_FIND_DATA>? childData = args.GetFileSystemEntry(item.Path, null);
|
||||||
|
|
||||||
|
if (childData != null)
|
||||||
|
{
|
||||||
|
fileData = childData.Value.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileData = FileData.GetFileData(item.Path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.DateCreated = fileData.CreationTime;
|
||||||
|
|
||||||
|
item.DateModified = fileData.LastWriteTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Resolvers
|
namespace MediaBrowser.Controller.Resolvers
|
||||||
|
@ -50,9 +51,9 @@ namespace MediaBrowser.Controller.Resolvers
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check the subfolders for bluray or dvd
|
// Also check the subfolders for bluray or dvd
|
||||||
foreach (KeyValuePair<string, FileAttributes> folder in args.FileSystemChildren)
|
foreach (KeyValuePair<string, WIN32_FIND_DATA> folder in args.FileSystemChildren)
|
||||||
{
|
{
|
||||||
if (!folder.Value.HasFlag(FileAttributes.Directory))
|
if (!folder.Value.IsDirectory)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,17 +33,6 @@ namespace MediaBrowser.Controller.Xml
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If dates weren't supplied in metadata, use values from the xml file
|
|
||||||
if (item.DateCreated == DateTime.MinValue)
|
|
||||||
{
|
|
||||||
item.DateCreated = File.GetCreationTime(metadataFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.DateModified == DateTime.MinValue)
|
|
||||||
{
|
|
||||||
item.DateModified = File.GetLastWriteTime(metadataFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -414,7 +403,7 @@ namespace MediaBrowser.Controller.Xml
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "FrameRate":
|
case "FrameRate":
|
||||||
item.FrameRate = reader.ReadElementContentAsString();
|
item.FrameRate = reader.ReadFloatSafe();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ScanType":
|
case "ScanType":
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Entities
|
||||||
public int Height { get; set; }
|
public int Height { get; set; }
|
||||||
public int Width { get; set; }
|
public int Width { get; set; }
|
||||||
public string ScanType { get; set; }
|
public string ScanType { get; set; }
|
||||||
public string FrameRate { get; set; }
|
public float FrameRate { get; set; }
|
||||||
public int BitRate { get; set; }
|
public int BitRate { get; set; }
|
||||||
public string Codec { get; set; }
|
public string Codec { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MediaBrowser.Movies.Providers
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var metadataFile = args.GetFileByName("movie.xml");
|
var metadataFile = args.GetFileSystemEntryByName("movie.xml", false);
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Controller.Resolvers;
|
using MediaBrowser.Controller.Resolvers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Movies.Entities;
|
using MediaBrowser.Movies.Entities;
|
||||||
|
@ -24,7 +25,7 @@ namespace MediaBrowser.Movies.Resolvers
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadataFile = args.GetFileByName("movie.xml");
|
var metadataFile = args.GetFileSystemEntryByName("movie.xml", false);
|
||||||
|
|
||||||
if (metadataFile.HasValue || Path.GetFileName(args.Path).IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1)
|
if (metadataFile.HasValue || Path.GetFileName(args.Path).IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
{
|
{
|
||||||
|
@ -57,8 +58,8 @@ namespace MediaBrowser.Movies.Resolvers
|
||||||
ItemResolveEventArgs childArgs = new ItemResolveEventArgs()
|
ItemResolveEventArgs childArgs = new ItemResolveEventArgs()
|
||||||
{
|
{
|
||||||
Path = child.Key,
|
Path = child.Key,
|
||||||
FileAttributes = child.Value,
|
FileData = child.Value,
|
||||||
FileSystemChildren = new KeyValuePair<string, FileAttributes>[] { }
|
FileSystemChildren = new KeyValuePair<string, WIN32_FIND_DATA>[] { }
|
||||||
};
|
};
|
||||||
|
|
||||||
var item = base.Resolve(childArgs);
|
var item = base.Resolve(childArgs);
|
||||||
|
@ -78,7 +79,7 @@ namespace MediaBrowser.Movies.Resolvers
|
||||||
|
|
||||||
private void PopulateBonusFeatures(Movie item, ItemResolveEventArgs args)
|
private void PopulateBonusFeatures(Movie item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var trailerPath = args.GetFolderByName("specials");
|
var trailerPath = args.GetFileSystemEntryByName("specials", true);
|
||||||
|
|
||||||
if (trailerPath.HasValue)
|
if (trailerPath.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MediaBrowser.TV.Providers
|
||||||
|
|
||||||
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var metadataFile = args.GetFileByName("series.xml");
|
var metadataFile = args.GetFileSystemEntryByName("series.xml", false);
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace MediaBrowser.TV.Resolvers
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadataFile = args.GetFileByName("series.xml");
|
var metadataFile = args.GetFileSystemEntryByName("series.xml", false);
|
||||||
|
|
||||||
if (metadataFile.HasValue || Path.GetFileName(args.Path).IndexOf("[tvdbid=", StringComparison.OrdinalIgnoreCase) != -1 || TVUtils.IsSeriesFolder(args.Path, args.FileSystemChildren))
|
if (metadataFile.HasValue || Path.GetFileName(args.Path).IndexOf("[tvdbid=", StringComparison.OrdinalIgnoreCase) != -1 || TVUtils.IsSeriesFolder(args.Path, args.FileSystemChildren))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using MediaBrowser.Controller.IO;
|
||||||
|
|
||||||
namespace MediaBrowser.TV
|
namespace MediaBrowser.TV
|
||||||
{
|
{
|
||||||
|
@ -52,11 +53,11 @@ namespace MediaBrowser.TV
|
||||||
return seasonPathExpressions.Any(r => r.IsMatch(path));
|
return seasonPathExpressions.Any(r => r.IsMatch(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsSeriesFolder(string path, IEnumerable<KeyValuePair<string, FileAttributes>> fileSystemChildren)
|
public static bool IsSeriesFolder(string path, IEnumerable<KeyValuePair<string, WIN32_FIND_DATA>> fileSystemChildren)
|
||||||
{
|
{
|
||||||
foreach (var child in fileSystemChildren)
|
foreach (var child in fileSystemChildren)
|
||||||
{
|
{
|
||||||
if (child.Value.HasFlag(FileAttributes.Directory))
|
if (child.Value.IsDirectory)
|
||||||
{
|
{
|
||||||
if (IsSeasonFolder(child.Key))
|
if (IsSeasonFolder(child.Key))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user