aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Library
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2015-01-10 01:59:48 -0500
committerLuke <luke.pulverenti@gmail.com>2015-01-10 01:59:48 -0500
commit18b5168f05dc325985ac6a7b2b5b390fa4b12042 (patch)
tree7e440e3267895f7ce161ac5ae3d5723e0894bd5f /MediaBrowser.Server.Implementations/Library
parente3a1c13e7cc8c49eb66b395b4810339f41fdf6b3 (diff)
parente97848289600570b489b6fdb608014b383772523 (diff)
Merge pull request #971 from MediaBrowser/dev
3.0.5482.4
Diffstat (limited to 'MediaBrowser.Server.Implementations/Library')
-rw-r--r--MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs90
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs43
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs53
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs152
-rw-r--r--MediaBrowser.Server.Implementations/Library/SearchEngine.cs7
9 files changed, 308 insertions, 70 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
index 1628ccc32..1771bbdb2 100644
--- a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
+++ b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
@@ -114,7 +115,12 @@ namespace MediaBrowser.Server.Implementations.Library
}
// Ignore samples
- if (filename.IndexOf(".sample.", StringComparison.OrdinalIgnoreCase) != -1)
+ var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase)
+ .Replace("-", " ", StringComparison.OrdinalIgnoreCase)
+ .Replace("_", " ", StringComparison.OrdinalIgnoreCase)
+ .Replace("!", " ", StringComparison.OrdinalIgnoreCase);
+
+ if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1)
{
return true;
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 37a68b52b..ab72d89fd 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -13,6 +13,7 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Naming.Audio;
@@ -200,7 +201,7 @@ namespace MediaBrowser.Server.Implementations.Library
MultiItemResolvers = EntityResolvers.OfType<IMultiItemResolver>().ToArray();
IntroProviders = introProviders.ToArray();
Comparers = itemComparers.ToArray();
-
+
PostscanTasks = postscanTasks.OrderBy(i =>
{
var hasOrder = i as IHasOrder;
@@ -578,7 +579,7 @@ namespace MediaBrowser.Server.Implementations.Library
if (string.IsNullOrWhiteSpace(collectionType))
{
- collectionType = GetConfiguredContentType(fullPath);
+ collectionType = GetContentTypeOverride(fullPath, true);
}
var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, this, directoryService)
@@ -1554,16 +1555,17 @@ namespace MediaBrowser.Server.Implementations.Library
public string GetContentType(BaseItem item)
{
- // Types cannot be overridden, so go from the top down until we find a configured content type
-
- var type = GetInheritedContentType(item);
-
- if (!string.IsNullOrWhiteSpace(type))
+ string configuredContentType = GetConfiguredContentType(item, false);
+ if (!string.IsNullOrWhiteSpace(configuredContentType))
{
- return type;
+ return configuredContentType;
}
-
- return GetConfiguredContentType(item);
+ configuredContentType = GetConfiguredContentType(item, true);
+ if (!string.IsNullOrWhiteSpace(configuredContentType))
+ {
+ return configuredContentType;
+ }
+ return GetInheritedContentType(item);
}
public string GetInheritedContentType(BaseItem item)
@@ -1580,19 +1582,36 @@ namespace MediaBrowser.Server.Implementations.Library
.LastOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
- private string GetConfiguredContentType(BaseItem item)
+ public string GetConfiguredContentType(BaseItem item)
{
- return GetConfiguredContentType(item.ContainingFolderPath);
+ return GetConfiguredContentType(item, false);
}
- private string GetConfiguredContentType(string path)
+ public string GetConfiguredContentType(string path)
{
- var type = ConfigurationManager.Configuration.ContentTypes
- .FirstOrDefault(i => string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i.Name, path));
+ return GetContentTypeOverride(path, false);
+ }
- return type == null ? null : type.Value;
+ public string GetConfiguredContentType(BaseItem item, bool inheritConfiguredPath)
+ {
+ ICollectionFolder collectionFolder = item as ICollectionFolder;
+ if (collectionFolder != null)
+ {
+ return collectionFolder.CollectionType;
+ }
+ return GetContentTypeOverride(item.ContainingFolderPath, inheritConfiguredPath);
}
+ private string GetContentTypeOverride(string path, bool inherit)
+ {
+ var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => string.Equals(i.Name, path, StringComparison.OrdinalIgnoreCase) || (inherit && _fileSystem.ContainsSubPath(i.Name, path)));
+ if (nameValuePair != null)
+ {
+ return nameValuePair.Value;
+ }
+ return null;
+ }
+
private string GetTopFolderContentType(BaseItem item)
{
while (!(item.Parent is AggregateFolder) && item.Parent != null)
@@ -1735,28 +1754,28 @@ namespace MediaBrowser.Server.Implementations.Library
public bool IsVideoFile(string path)
{
- var resolver = new VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var resolver = new VideoResolver(GetNamingOptions(), new Naming.Logging.NullLogger());
return resolver.IsVideoFile(path);
}
public bool IsAudioFile(string path)
{
- var parser = new AudioFileParser(new ExtendedNamingOptions());
+ var parser = new AudioFileParser(GetNamingOptions());
return parser.IsAudioFile(path);
}
public int? GetSeasonNumberFromPath(string path)
{
- return new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, true).SeasonNumber;
+ return new SeasonPathParser(GetNamingOptions(), new RegexProvider()).Parse(path, true, true).SeasonNumber;
}
public bool FillMissingEpisodeNumbersFromPath(Episode episode)
{
- var resolver = new EpisodeResolver(new ExtendedNamingOptions(),
+ var resolver = new EpisodeResolver(GetNamingOptions(),
new Naming.Logging.NullLogger());
- var fileType = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || episode.VideoType == VideoType.HdDvd ?
- FileInfoType.Directory :
+ var fileType = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || episode.VideoType == VideoType.HdDvd ?
+ FileInfoType.Directory :
FileInfoType.File;
var locationType = episode.LocationType;
@@ -1870,9 +1889,28 @@ namespace MediaBrowser.Server.Implementations.Library
return changed;
}
+ public NamingOptions GetNamingOptions()
+ {
+ var options = new ExtendedNamingOptions();
+
+ if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles)
+ {
+ options.AudioFileExtensions.Remove(".rar");
+ options.AudioFileExtensions.Remove(".zip");
+ }
+
+ if (!ConfigurationManager.Configuration.EnableVideoArchiveFiles)
+ {
+ options.VideoFileExtensions.Remove(".rar");
+ options.VideoFileExtensions.Remove(".zip");
+ }
+
+ return options;
+ }
+
public ItemLookupInfo ParseName(string name)
{
- var resolver = new VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var resolver = new VideoResolver(GetNamingOptions(), new Naming.Logging.NullLogger());
var result = resolver.CleanDateTime(name);
var cleanName = resolver.CleanString(result.Name);
@@ -1891,7 +1929,7 @@ namespace MediaBrowser.Server.Implementations.Library
.SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
.ToList();
- var videoListResolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var videoListResolver = new VideoListResolver(GetNamingOptions(), new Naming.Logging.NullLogger());
var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new PortableFileInfo
{
@@ -1944,7 +1982,7 @@ namespace MediaBrowser.Server.Implementations.Library
.SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
.ToList();
- var videoListResolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var videoListResolver = new VideoListResolver(GetNamingOptions(), new Naming.Logging.NullLogger());
var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new PortableFileInfo
{
@@ -1982,7 +2020,7 @@ namespace MediaBrowser.Server.Implementations.Library
private void SetExtraTypeFromFilename(Video item)
{
- var resolver = new ExtraResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger(), new RegexProvider());
+ var resolver = new ExtraResolver(GetNamingOptions(), new Naming.Logging.NullLogger(), new RegexProvider());
var result = resolver.GetExtraInfo(item.Path);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 0f703cb22..7c8ddabeb 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -1,7 +1,5 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
@@ -76,14 +74,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
/// </summary>
/// <param name="path">The path.</param>
/// <param name="directoryService">The directory service.</param>
- /// <param name="logger">The logger.</param>
- /// <param name="fileSystem">The file system.</param>
- /// <param name="libraryManager">The library manager.</param>
/// <returns><c>true</c> if [is music album] [the specified data]; otherwise, <c>false</c>.</returns>
- public static bool IsMusicAlbum(string path, IDirectoryService directoryService, ILogger logger, IFileSystem fileSystem,
- ILibraryManager libraryManager)
+ public bool IsMusicAlbum(string path, IDirectoryService directoryService)
{
- return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, logger, fileSystem, libraryManager);
+ return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, _libraryManager);
}
/// <summary>
@@ -113,7 +107,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
/// <param name="fileSystem">The file system.</param>
/// <param name="libraryManager">The library manager.</param>
/// <returns><c>true</c> if the specified list contains music; otherwise, <c>false</c>.</returns>
- private static bool ContainsMusic(IEnumerable<FileSystemInfo> list,
+ private bool ContainsMusic(IEnumerable<FileSystemInfo> list,
bool allowSubfolders,
IDirectoryService directoryService,
ILogger logger,
@@ -131,17 +125,26 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
var path = fileSystemInfo.FullName;
var isMultiDisc = IsMultiDiscFolder(path);
- var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager);
- if (isMultiDisc && hasMusic)
+ if (isMultiDisc)
{
- logger.Debug("Found multi-disc folder: " + path);
- discSubfolderCount++;
+ var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager);
+
+ if (hasMusic)
+ {
+ logger.Debug("Found multi-disc folder: " + path);
+ discSubfolderCount++;
+ }
}
- else if (hasMusic)
+ else
{
- // If there are folders underneath with music that are not multidisc, then this can't be a multi-disc album
- notMultiDisc = true;
+ var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager);
+
+ if (hasMusic)
+ {
+ // If there are folders underneath with music that are not multidisc, then this can't be a multi-disc album
+ notMultiDisc = true;
+ }
}
}
}
@@ -159,12 +162,14 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
return false;
}
- return discSubfolderCount > 0 && discSubfolderCount > 10;
+ return discSubfolderCount > 0;
}
- private static bool IsMultiDiscFolder(string path)
+ private bool IsMultiDiscFolder(string path)
{
- var parser = new AlbumParser(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
+
+ var parser = new AlbumParser(namingOptions, new Naming.Logging.NullLogger());
var result = parser.ParseMultiPart(path);
return result.IsMultiPart;
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index edbc87415..9f3f24865 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -70,9 +70,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
}
var directoryService = args.DirectoryService;
-
+
+ var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager);
+
// If we contain an album assume we are an artist folder
- return args.FileSystemChildren.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory).Any(i => MusicAlbumResolver.IsMusicAlbum(i.FullName, directoryService, _logger, _fileSystem, _libraryManager)) ? new MusicArtist() : null;
+ return args.FileSystemChildren.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService)) ? new MusicArtist() : null;
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index 8e2218b0a..1a4d35af5 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -44,8 +44,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
protected TVideoType ResolveVideo<TVideoType>(ItemResolveArgs args, bool parseName)
where TVideoType : Video, new()
{
+ var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
+
// If the path is a file check for a matching extensions
- var parser = new Naming.Video.VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var parser = new Naming.Video.VideoResolver(namingOptions, new Naming.Logging.NullLogger());
if (args.IsDirectory)
{
@@ -229,7 +231,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
protected void Set3DFormat(Video video)
{
- var resolver = new Format3DParser(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
+
+ var resolver = new Format3DParser(namingOptions, new Naming.Logging.NullLogger());
var result = resolver.Parse(video.Path);
Set3DFormat(video, result.Is3D, result.Format3D);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 441fada6a..4c0767b08 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -1,10 +1,11 @@
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Naming.Common;
using MediaBrowser.Naming.IO;
using MediaBrowser.Naming.Video;
using System;
@@ -68,12 +69,17 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return ResolveVideos<Video>(parent, files, directoryService, collectionType, false);
}
- return ResolveVideos<Video>(parent, files, directoryService, collectionType, false);
+ if (parent is Series || parent.Parents.OfType<Series>().Any())
+ {
+ return null;
+ }
+
+ return ResolveVideos<Movie>(parent, files, directoryService, collectionType, false);
}
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
{
- return ResolveVideos<Movie>(parent, files, directoryService, collectionType, false);
+ return ResolveVideos<Movie>(parent, files, directoryService, collectionType, true);
}
return null;
@@ -93,13 +99,19 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
leftOver.Add(child);
}
+ else if (IsIgnored(child.Name))
+ {
+
+ }
else
{
files.Add(child);
}
}
- var resolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
+
+ var resolver = new VideoListResolver(namingOptions, new Naming.Logging.NullLogger());
var resolverResult = resolver.Resolve(files.Select(i => new PortableFileInfo
{
FullName = i.FullName,
@@ -173,7 +185,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
}
- return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
+ if (args.HasParent<Series>())
+ {
+ return null;
+ }
+
+ return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
}
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
@@ -209,6 +226,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
else if (string.IsNullOrEmpty(collectionType))
{
+ if (args.HasParent<Series>())
+ {
+ return null;
+ }
+
item = ResolveVideo<Video>(args, false);
}
@@ -220,6 +242,22 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return item;
}
+ private bool IsIgnored(string filename)
+ {
+ // Ignore samples
+ var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase)
+ .Replace("-", " ", StringComparison.OrdinalIgnoreCase)
+ .Replace("_", " ", StringComparison.OrdinalIgnoreCase)
+ .Replace("!", " ", StringComparison.OrdinalIgnoreCase);
+
+ if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
/// <summary>
/// Sets the initial item values.
/// </summary>
@@ -397,7 +435,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return null;
}
- var resolver = new StackResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
+ var resolver = new StackResolver(namingOptions, new Naming.Logging.NullLogger());
var result = resolver.ResolveDirectories(folderPaths);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
index 80477e567..7d13b11ad 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
@@ -16,13 +16,16 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
/// </summary>
private readonly IServerConfigurationManager _config;
+ private readonly ILibraryManager _libraryManager;
+
/// <summary>
/// Initializes a new instance of the <see cref="SeasonResolver"/> class.
/// </summary>
/// <param name="config">The config.</param>
- public SeasonResolver(IServerConfigurationManager config)
+ public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager)
{
_config = config;
+ _libraryManager = libraryManager;
}
/// <summary>
@@ -34,9 +37,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
if (args.Parent is Series && args.IsDirectory)
{
+ var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
+
var season = new Season
{
- IndexNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(args.Path, true).SeasonNumber
+ IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber
};
if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0)
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 7f1416ad6..e68f005be 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -1,9 +1,17 @@
-using MediaBrowser.Controller.Entities.TV;
+using System.Collections.Generic;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
using System.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Naming.Common;
+using MediaBrowser.Naming.IO;
+using MediaBrowser.Naming.TV;
+using EpisodeInfo = MediaBrowser.Controller.Providers.EpisodeInfo;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
@@ -12,6 +20,17 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
/// </summary>
public class SeriesResolver : FolderResolver<Series>
{
+ private readonly IFileSystem _fileSystem;
+ private readonly ILogger _logger;
+ private readonly ILibraryManager _libraryManager;
+
+ public SeriesResolver(IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager)
+ {
+ _fileSystem = fileSystem;
+ _logger = logger;
+ _libraryManager = libraryManager;
+ }
+
/// <summary>
/// Gets the priority.
/// </summary>
@@ -34,26 +53,141 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
if (args.IsDirectory)
{
var collectionType = args.GetCollectionType();
-
- // If there's a collection type and it's not tv, it can't be a series
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{
if (args.HasParent<Series>())
{
return null;
- }
-
- return new Series
+ }
+
+ var configuredContentType = _libraryManager.GetConfiguredContentType(args.Path);
+ if (!string.Equals(configuredContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{
- Path = args.Path,
- Name = Path.GetFileName(args.Path)
- };
+ return new Series
+ {
+ Path = args.Path,
+ Name = Path.GetFileName(args.Path)
+ };
+ }
+ }
+ else
+ {
+ if (string.IsNullOrWhiteSpace(collectionType))
+ {
+ if (args.HasParent<Series>())
+ {
+ return null;
+ }
+
+ if (args.Parent.IsRoot)
+ {
+ return null;
+ }
+ if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, false))
+ {
+ return new Series
+ {
+ Path = args.Path,
+ Name = Path.GetFileName(args.Path)
+ };
+ }
+ }
}
}
return null;
}
+ public static bool IsSeriesFolder(string path,
+ IEnumerable<FileSystemInfo> fileSystemChildren,
+ IDirectoryService directoryService,
+ IFileSystem fileSystem,
+ ILogger logger,
+ ILibraryManager libraryManager,
+ bool isTvContentType)
+ {
+ foreach (var child in fileSystemChildren)
+ {
+ var attributes = child.Attributes;
+
+ if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ {
+ //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName);
+ continue;
+ }
+
+ // Can't enforce this because files saved by Bitcasa are always marked System
+ //if ((attributes & FileAttributes.System) == FileAttributes.System)
+ //{
+ // logger.Debug("Igoring series subfolder marked system: {0}", child.FullName);
+ // continue;
+ //}
+
+ if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
+ {
+ if (IsSeasonFolder(child.FullName, isTvContentType))
+ {
+ //logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
+ return true;
+ }
+ }
+ else
+ {
+ string fullName = child.FullName;
+ if (libraryManager.IsVideoFile(fullName))
+ {
+ if (isTvContentType)
+ {
+ return true;
+ }
+
+ var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions();
+
+ var episodeResolver = new Naming.TV.EpisodeResolver(namingOptions, new Naming.Logging.NullLogger());
+ var episodeInfo = episodeResolver.Resolve(fullName, FileInfoType.File, false);
+ if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ logger.Debug("{0} is not a series folder.", path);
+ return false;
+ }
+
+ /// <summary>
+ /// Determines whether [is place holder] [the specified path].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <returns><c>true</c> if [is place holder] [the specified path]; otherwise, <c>false</c>.</returns>
+ /// <exception cref="System.ArgumentNullException">path</exception>
+ private static bool IsVideoPlaceHolder(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
+ var extension = Path.GetExtension(path);
+
+ return string.Equals(extension, ".disc", StringComparison.OrdinalIgnoreCase);
+ }
+
+ /// <summary>
+ /// Determines whether [is season folder] [the specified path].
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="isTvContentType">if set to <c>true</c> [is tv content type].</param>
+ /// <returns><c>true</c> if [is season folder] [the specified path]; otherwise, <c>false</c>.</returns>
+ private static bool IsSeasonFolder(string path, bool isTvContentType)
+ {
+ var seasonNumber = new SeasonPathParser(new ExtendedNamingOptions(), new RegexProvider()).Parse(path, isTvContentType, isTvContentType).SeasonNumber;
+
+ return seasonNumber.HasValue;
+ }
+
/// <summary>
/// Sets the initial item values.
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
index 071031b25..1c92f6c4a 100644
--- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
+++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
@@ -97,6 +98,8 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException("searchTerm");
}
+ searchTerm = searchTerm.RemoveDiacritics();
+
var terms = GetWords(searchTerm);
var hints = new List<Tuple<BaseItem, string, int>>();
@@ -318,6 +321,8 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException("input");
}
+ input = input.RemoveDiacritics();
+
if (string.Equals(input, searchInput, StringComparison.OrdinalIgnoreCase))
{
return new Tuple<string, int>(searchInput, 0);