using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers.Movies;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
namespace MediaBrowser.Controller.Resolvers.Movies
{
///
/// Class MovieResolver
///
[Export(typeof(IBaseItemResolver))]
public class MovieResolver : BaseVideoResolver
{
///
/// Gets the priority.
///
/// The priority.
public override ResolverPriority Priority
{
get
{
// Give plugins a chance to catch iso's first
// Also since we have to loop through child files looking for videos,
// see if we can avoid some of that by letting other resolvers claim folders first
return ResolverPriority.Second;
}
}
///
/// Resolves the specified args.
///
/// The args.
/// Movie.
protected override Movie Resolve(ItemResolveArgs args)
{
// Must be a directory and under a 'Movies' VF
if (args.IsDirectory)
{
// Avoid expensive tests against VF's and all their children by not allowing this
if (args.Parent == null || args.Parent.IsRoot)
{
return null;
}
// If the parent is not a boxset, the only other allowed parent type is Folder
if (!(args.Parent is BoxSet))
{
if (args.Parent.GetType() != typeof(Folder))
{
return null;
}
}
// Optimization to avoid running all these tests against Top folders
if (args.Parent != null && args.Parent.IsRoot)
{
return null;
}
// The movie must be a video file
return FindMovie(args);
}
return null;
}
///
/// Sets the initial item values.
///
/// The item.
/// The args.
protected override void SetInitialItemValues(Movie item, ItemResolveArgs args)
{
base.SetInitialItemValues(item, args);
SetProviderIdFromPath(item);
}
///
/// Sets the provider id from path.
///
/// The item.
private void SetProviderIdFromPath(Movie item)
{
//we need to only look at the name of this actual item (not parents)
var justName = item.Path.Substring(item.Path.LastIndexOf(Path.DirectorySeparatorChar));
var id = justName.GetAttributeValue("tmdbid");
if (!string.IsNullOrEmpty(id))
{
item.SetProviderId(MetadataProviders.Tmdb, id);
}
}
///
/// Finds a movie based on a child file system entries
///
/// The args.
/// Movie.
private Movie FindMovie(ItemResolveArgs args)
{
// Since the looping is expensive, this is an optimization to help us avoid it
if (args.ContainsMetaFileByName("series.xml") || args.Path.IndexOf("[tvdbid", StringComparison.OrdinalIgnoreCase) != -1)
{
return null;
}
// Optimization to avoid having to resolve every file
bool? isKnownMovie = null;
var movies = new List();
// Loop through each child file/folder and see if we find a video
foreach (var child in args.FileSystemChildren)
{
if (child.IsDirectory)
{
if (IsDvdDirectory(child.cFileName))
{
return new Movie
{
Path = args.Path,
VideoType = VideoType.Dvd
};
}
if (IsBluRayDirectory(child.cFileName))
{
return new Movie
{
Path = args.Path,
VideoType = VideoType.BluRay
};
}
if (IsHdDvdDirectory(child.cFileName))
{
return new Movie
{
Path = args.Path,
VideoType = VideoType.HdDvd
};
}
continue;
}
var childArgs = new ItemResolveArgs
{
FileInfo = child,
Path = child.Path
};
var item = base.Resolve(childArgs);
if (item != null)
{
// If we already know it's a movie, we can stop looping
if (!isKnownMovie.HasValue)
{
isKnownMovie = args.ContainsMetaFileByName("movie.xml") || args.ContainsMetaFileByName(MovieDbProvider.LOCAL_META_FILE_NAME) || args.Path.IndexOf("[tmdbid", StringComparison.OrdinalIgnoreCase) != -1;
}
if (isKnownMovie.Value)
{
return item;
}
movies.Add(item);
}
}
// If there are multiple video files, return null, and let the VideoResolver catch them later as plain videos
return movies.Count == 1 ? movies[0] : null;
}
///
/// Determines whether [is DVD directory] [the specified directory name].
///
/// Name of the directory.
/// true if [is DVD directory] [the specified directory name]; otherwise, false.
private bool IsDvdDirectory(string directoryName)
{
return directoryName.Equals("video_ts", StringComparison.OrdinalIgnoreCase);
}
///
/// Determines whether [is hd DVD directory] [the specified directory name].
///
/// Name of the directory.
/// true if [is hd DVD directory] [the specified directory name]; otherwise, false.
private bool IsHdDvdDirectory(string directoryName)
{
return directoryName.Equals("hvdvd_ts", StringComparison.OrdinalIgnoreCase);
}
///
/// Determines whether [is blu ray directory] [the specified directory name].
///
/// Name of the directory.
/// true if [is blu ray directory] [the specified directory name]; otherwise, false.
private bool IsBluRayDirectory(string directoryName)
{
return directoryName.Equals("bdmv", StringComparison.OrdinalIgnoreCase);
}
}
}