Comments and cleanup. ALso updated ffmpeg + ffprobe

This commit is contained in:
LukePulverenti Luke Pulverenti luke pulverenti 2012-08-23 14:35:44 -04:00
parent 4068047845
commit 2454b72c93
22 changed files with 68 additions and 76 deletions

View File

@ -9,6 +9,14 @@ namespace MediaBrowser.Api
{ {
public static class ImageProcessor public static class ImageProcessor
{ {
/// <summary>
/// Resizes an image from a source stream and saves the result to an output stream
/// </summary>
/// <param name="width">Use if a fixed width is required. Aspect ratio will be preserved.</param>
/// <param name="height">Use if a fixed height is required. Aspect ratio will be preserved.</param>
/// <param name="maxWidth">Use if a max width is required. Aspect ratio will be preserved.</param>
/// <param name="maxHeight">Use if a max height is required. Aspect ratio will be preserved.</param>
/// <param name="quality">Quality level, from 0-100. Currently only applies to JPG. The default value should suffice.</param>
public static void ProcessImage(Stream sourceImageStream, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality) public static void ProcessImage(Stream sourceImageStream, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality)
{ {
Image originalImage = Image.FromStream(sourceImageStream); Image originalImage = Image.FromStream(sourceImageStream);

View File

@ -1,14 +1,13 @@
using System; using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO; using System.IO;
using System.Configuration;
using System.Reflection; using System.Reflection;
namespace MediaBrowser.Common.Configuration namespace MediaBrowser.Common.Configuration
{ {
/// <summary>
/// Provides a base class to hold common application paths used by both the UI and Server.
/// This can be subclassed to add application-specific paths.
/// </summary>
public abstract class BaseApplicationPaths public abstract class BaseApplicationPaths
{ {
private string _programDataPath; private string _programDataPath;

View File

@ -1,9 +0,0 @@
using System;
namespace MediaBrowser.Common.Events
{
public class GenericItemEventArgs<TItemType> : EventArgs
{
public TItemType Item { get; set; }
}
}

View File

@ -67,7 +67,6 @@
<Compile Include="Configuration\BaseApplicationConfiguration.cs" /> <Compile Include="Configuration\BaseApplicationConfiguration.cs" />
<Compile Include="Configuration\BaseApplicationPaths.cs" /> <Compile Include="Configuration\BaseApplicationPaths.cs" />
<Compile Include="Drawing\DrawingUtils.cs" /> <Compile Include="Drawing\DrawingUtils.cs" />
<Compile Include="Events\GenericItemEventArgs.cs" />
<Compile Include="Net\Handlers\StaticFileHandler.cs" /> <Compile Include="Net\Handlers\StaticFileHandler.cs" />
<Compile Include="Net\MimeTypes.cs" /> <Compile Include="Net\MimeTypes.cs" />
<Compile Include="Properties\Resources.Designer.cs"> <Compile Include="Properties\Resources.Designer.cs">

View File

@ -4,7 +4,7 @@ namespace MediaBrowser.Common.Serialization
{ {
/// <summary> /// <summary>
/// This adds support for ServiceStack's proprietary JSV output format. /// This adds support for ServiceStack's proprietary JSV output format.
/// It's based on Json but the serializer performs faster and output runs about 10% smaller /// It's a hybrid of Json and Csv but the serializer performs about 25% faster and output runs about 10% smaller
/// http://www.servicestack.net/benchmarks/NorthwindDatabaseRowsSerialization.100000-times.2010-08-17.html /// http://www.servicestack.net/benchmarks/NorthwindDatabaseRowsSerialization.100000-times.2010-08-17.html
/// </summary> /// </summary>
public static class JsvSerializer public static class JsvSerializer

View File

@ -3,6 +3,9 @@ using MediaBrowser.Common.Configuration;
namespace MediaBrowser.Controller.Configuration namespace MediaBrowser.Controller.Configuration
{ {
/// <summary>
/// Extends BaseApplicationPaths to add paths that are only applicable on the server
/// </summary>
public class ServerApplicationPaths : BaseApplicationPaths public class ServerApplicationPaths : BaseApplicationPaths
{ {
private string _rootFolderPath; private string _rootFolderPath;

View File

@ -1 +1 @@
faf137524dd67edb423344830e1436dcdca83daf 480bd76ce262d65df6b87802bd9bda18cf5b1c8f

View File

@ -1 +1 @@
a304265e8410291c1f696e74a4f9b84970bb5753 1f5e9773868e0f41260f64e20090803400b9a36d

View File

@ -49,6 +49,11 @@ namespace MediaBrowser.Controller
/// </summary> /// </summary>
[ImportMany(typeof(IBaseItemResolver))] [ImportMany(typeof(IBaseItemResolver))]
private IEnumerable<IBaseItemResolver> EntityResolversEnumerable { get; set; } private IEnumerable<IBaseItemResolver> EntityResolversEnumerable { get; set; }
/// <summary>
/// Once MEF has loaded the resolvers, sort them by priority and store them in this array
/// Given the sheer number of times they'll be iterated over it'll be faster to loop through an array
/// </summary>
internal IBaseItemResolver[] EntityResolvers { get; private set; } internal IBaseItemResolver[] EntityResolvers { get; private set; }
/// <summary> /// <summary>

View File

@ -76,7 +76,6 @@
<Compile Include="Resolvers\VideoResolver.cs" /> <Compile Include="Resolvers\VideoResolver.cs" />
<Compile Include="Resolvers\VirtualFolderResolver.cs" /> <Compile Include="Resolvers\VirtualFolderResolver.cs" />
<Compile Include="Xml\BaseItemXmlParser.cs" /> <Compile Include="Xml\BaseItemXmlParser.cs" />
<Compile Include="Xml\FolderXmlParser.cs" />
<Compile Include="Xml\XmlExtensions.cs" /> <Compile Include="Xml\XmlExtensions.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -20,14 +20,17 @@ namespace MediaBrowser.Controller.Providers
get { return MetadataProviderPriority.First; } get { return MetadataProviderPriority.First; }
} }
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
{
await Task.Run(() => { Fetch(item, args); }).ConfigureAwait(false);
}
private void Fetch(BaseEntity item, ItemResolveEventArgs args)
{ {
if (args.ContainsFile("folder.xml")) if (args.ContainsFile("folder.xml"))
{ {
return Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, Path.Combine(args.Path, "folder.xml")); }); new BaseItemXmlParser<Folder>().Fetch(item as Folder, Path.Combine(args.Path, "folder.xml"));
} }
return Task.FromResult<object>(null);
} }
} }
} }

View File

@ -1,12 +0,0 @@
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.Xml
{
/// <summary>
/// Fetches metadata for a folder.
/// Since folder.xml contains no folder-specific values, no overrides are needed
/// </summary>
public class FolderXmlParser : BaseItemXmlParser<Folder>
{
}
}

View File

@ -22,14 +22,17 @@ namespace MediaBrowser.Movies.Providers
get { return MetadataProviderPriority.First; } get { return MetadataProviderPriority.First; }
} }
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
{
await Task.Run(() => { Fetch(item, args); }).ConfigureAwait(false);
}
private void Fetch(BaseEntity item, ItemResolveEventArgs args)
{ {
if (args.ContainsFile("movie.xml")) if (args.ContainsFile("movie.xml"))
{ {
return Task.Run(() => { new BaseItemXmlParser<Movie>().Fetch(item as Movie, Path.Combine(args.Path, "movie.xml")); }); new BaseItemXmlParser<Movie>().Fetch(item as Movie, Path.Combine(args.Path, "movie.xml"));
} }
return Task.FromResult<object>(null);
} }
} }
} }

View File

@ -12,6 +12,10 @@ namespace MediaBrowser.Movies.Resolvers
{ {
protected override BoxSet Resolve(ItemResolveEventArgs args) protected override BoxSet Resolve(ItemResolveEventArgs args)
{ {
// It's a boxset if all of the following conditions are met:
// It's under a 'Movies' VF
// Is a Directory
// Contains [boxset] in the path
if ((args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase) && args.IsDirectory) if ((args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase) && args.IsDirectory)
{ {
if (Path.GetFileName(args.Path).IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1) if (Path.GetFileName(args.Path).IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1)

View File

@ -1,15 +1,9 @@
using System; using System;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Events; using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.IO; using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Movies.Entities; using MediaBrowser.Movies.Entities;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MediaBrowser.Movies.Resolvers namespace MediaBrowser.Movies.Resolvers
{ {
@ -18,34 +12,19 @@ namespace MediaBrowser.Movies.Resolvers
{ {
protected override Movie Resolve(ItemResolveEventArgs args) protected override Movie Resolve(ItemResolveEventArgs args)
{ {
// Must be a directory and under a 'Movies' VF
if ((args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase) && args.IsDirectory) if ((args.VirtualFolderCollectionType ?? string.Empty).Equals("Movies", StringComparison.OrdinalIgnoreCase) && args.IsDirectory)
{ {
if (args.ContainsFile("movie.xml") || Path.GetFileName(args.Path).IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1) // Return a movie if the video resolver finds something in the folder
{
return GetMovie(args) ?? new Movie();
}
// If it's not a boxset, the only other allowed parent type is Folder
if (!(args.Parent is BoxSet))
{
if (args.Parent != null && args.Parent.GetType() != typeof(Folder))
{
return null;
}
}
// There's no metadata or [tmdb in the path, now we will have to work some magic to see if this is a Movie
if (args.Parent != null)
{
return GetMovie(args); return GetMovie(args);
} }
}
return null; return null;
} }
private Movie GetMovie(ItemResolveEventArgs args) private Movie GetMovie(ItemResolveEventArgs args)
{ {
// Loop through each child file/folder and see if we find a video
for (var i = 0; i < args.FileSystemChildren.Length; i++) for (var i = 0; i < args.FileSystemChildren.Length; i++)
{ {
var child = args.FileSystemChildren[i]; var child = args.FileSystemChildren[i];

View File

@ -28,6 +28,7 @@ namespace MediaBrowser.TV
void ItemController_PreBeginResolvePath(object sender, PreBeginResolveEventArgs e) void ItemController_PreBeginResolvePath(object sender, PreBeginResolveEventArgs e)
{ {
// Don't try and resolve files with the metadata folder
if (System.IO.Path.GetFileName(e.Path).Equals("metadata", StringComparison.OrdinalIgnoreCase) && e.IsDirectory) if (System.IO.Path.GetFileName(e.Path).Equals("metadata", StringComparison.OrdinalIgnoreCase) && e.IsDirectory)
{ {
if (e.Parent is Season || e.Parent is Series) if (e.Parent is Season || e.Parent is Series)

View File

@ -40,6 +40,7 @@ namespace MediaBrowser.TV.Providers
private void SetPrimaryImagePath(Episode item, Season season, string metadataFolder, string episodeFileName) private void SetPrimaryImagePath(Episode item, Season season, string metadataFolder, string episodeFileName)
{ {
// Look for the image file in the metadata folder, and if found, set PrimaryImagePath
string[] imageFiles = new string[] { string[] imageFiles = new string[] {
Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".jpg")), Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".jpg")),
Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".png")) Path.Combine(metadataFolder, Path.ChangeExtension(episodeFileName, ".png"))
@ -49,7 +50,7 @@ namespace MediaBrowser.TV.Providers
if (season == null) if (season == null)
{ {
// Gotta do this the slow way // Epsiode directly in Series folder. Gotta do this the slow way
image = imageFiles.FirstOrDefault(f => File.Exists(f)); image = imageFiles.FirstOrDefault(f => File.Exists(f));
} }
else else

View File

@ -22,21 +22,21 @@ namespace MediaBrowser.TV.Providers
get { return MetadataProviderPriority.First; } get { return MetadataProviderPriority.First; }
} }
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
{ {
return Fetch(item, args); await Task.Run(() => { Fetch(item, args); }).ConfigureAwait(false);
} }
private Task Fetch(BaseEntity item, ItemResolveEventArgs args) private void Fetch(BaseEntity item, ItemResolveEventArgs args)
{ {
string metadataFolder = Path.Combine(args.Parent.Path, "metadata"); string metadataFolder = Path.Combine(args.Parent.Path, "metadata");
string metadataFile = Path.Combine(metadataFolder, Path.ChangeExtension(Path.GetFileName(args.Path), ".xml")); string metadataFile = Path.Combine(metadataFolder, Path.ChangeExtension(Path.GetFileName(args.Path), ".xml"));
return FetchMetadata(item as Episode, args.Parent as Season, metadataFile); FetchMetadata(item as Episode, args.Parent as Season, metadataFile);
} }
private async Task FetchMetadata(Episode item, Season season, string metadataFile) private void FetchMetadata(Episode item, Season season, string metadataFile)
{ {
if (season == null) if (season == null)
{ {
@ -55,7 +55,7 @@ namespace MediaBrowser.TV.Providers
} }
} }
await Task.Run(() => { new EpisodeXmlParser().Fetch(item, metadataFile); }).ConfigureAwait(false); new EpisodeXmlParser().Fetch(item, metadataFile);
} }
} }
} }

View File

@ -22,14 +22,17 @@ namespace MediaBrowser.TV.Providers
get { return MetadataProviderPriority.First; } get { return MetadataProviderPriority.First; }
} }
public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args)
{
await Task.Run(() => { Fetch(item, args); }).ConfigureAwait(false);
}
private void Fetch(BaseEntity item, ItemResolveEventArgs args)
{ {
if (args.ContainsFile("series.xml")) if (args.ContainsFile("series.xml"))
{ {
return Task.Run(() => { new SeriesXmlParser().Fetch(item as Series, Path.Combine(args.Path, "series.xml")); }); new SeriesXmlParser().Fetch(item as Series, Path.Combine(args.Path, "series.xml"));
} }
return Task.FromResult<object>(null);
} }
} }
} }

View File

@ -10,6 +10,7 @@ namespace MediaBrowser.TV.Resolvers
{ {
protected override Episode Resolve(ItemResolveEventArgs args) protected override Episode Resolve(ItemResolveEventArgs args)
{ {
// If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something
if (args.Parent is Season || args.Parent is Series) if (args.Parent is Season || args.Parent is Series)
{ {
return base.Resolve(args); return base.Resolve(args);

View File

@ -15,6 +15,7 @@ namespace MediaBrowser.TV.Resolvers
{ {
Season season = new Season(); Season season = new Season();
// Gather these now so that the episode provider classes can utilize them instead of having to make their own file system calls
if (args.ContainsFolder("metadata")) if (args.ContainsFolder("metadata"))
{ {
season.MetadataFiles = Directory.GetFiles(Path.Combine(args.Path, "metadata"), "*", SearchOption.TopDirectoryOnly); season.MetadataFiles = Directory.GetFiles(Path.Combine(args.Path, "metadata"), "*", SearchOption.TopDirectoryOnly);

View File

@ -20,6 +20,10 @@ namespace MediaBrowser.TV.Resolvers
return null; return null;
} }
// It's a Series if any of the following conditions are met:
// series.xml exists
// [tvdbid= is present in the path
// TVUtils.IsSeriesFolder returns true
if (args.ContainsFile("series.xml") || Path.GetFileName(args.Path).IndexOf("[tvdbid=", StringComparison.OrdinalIgnoreCase) != -1 || TVUtils.IsSeriesFolder(args.Path, args.FileSystemChildren)) if (args.ContainsFile("series.xml") || Path.GetFileName(args.Path).IndexOf("[tvdbid=", StringComparison.OrdinalIgnoreCase) != -1 || TVUtils.IsSeriesFolder(args.Path, args.FileSystemChildren))
{ {
return new Series(); return new Series();