From 68d1b609647d0a592afc7d994fad2dedcb135f6b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti <luke.pulverenti@gmail.com> Date: Sat, 13 Aug 2016 01:49:00 -0400 Subject: [PATCH] stub out objects for per library settings --- .../Library/LibraryStructureService.cs | 7 +- .../Playback/BaseStreamingService.cs | 6 +- .../Configuration/LibraryOptions.cs | 14 ++++ .../Entities/Audio/Audio.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 6 +- MediaBrowser.Controller/Entities/Book.cs | 2 +- .../Entities/CollectionFolder.cs | 60 ++++++++++++++ MediaBrowser.Controller/Entities/Folder.cs | 4 +- MediaBrowser.Controller/Entities/Game.cs | 2 +- .../Entities/IHasMetadata.cs | 2 +- .../Entities/Movies/BoxSet.cs | 13 ++++ MediaBrowser.Controller/Entities/Photo.cs | 2 +- MediaBrowser.Controller/Entities/Video.cs | 7 +- .../Library/ILibraryManager.cs | 18 +++-- .../Library/ItemResolveArgs.cs | 8 ++ .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Controller/Playlists/Playlist.cs | 6 ++ .../Configuration/ServerConfiguration.cs | 2 - .../Manager/MetadataService.cs | 2 +- .../MediaInfo/FFProbeProvider.cs | 2 +- .../MediaInfo/VideoImageProvider.cs | 9 ++- .../Library/LibraryManager.cs | 78 ++++++++++++++----- .../Library/Resolvers/Audio/AudioResolver.cs | 6 +- .../Resolvers/Audio/MusicAlbumResolver.cs | 30 +++---- .../Resolvers/Audio/MusicArtistResolver.cs | 2 +- .../Library/Resolvers/BaseVideoResolver.cs | 2 +- .../Library/Resolvers/PhotoResolver.cs | 7 +- .../Library/Resolvers/TV/SeriesResolver.cs | 6 +- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 2 +- .../Playlists/ManualPlaylistsFolder.cs | 2 +- .../ApplicationHost.cs | 1 + 32 files changed, 234 insertions(+), 79 deletions(-) create mode 100644 MediaBrowser.Controller/Configuration/LibraryOptions.cs diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index 3cf0d5d937..3af2134937 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Api.Library { @@ -52,6 +53,8 @@ namespace MediaBrowser.Api.Library /// </summary> /// <value>The path.</value> public string[] Paths { get; set; } + + public LibraryOptions LibraryOptions { get; set; } } [Route("/Library/VirtualFolders", "DELETE")] @@ -190,7 +193,9 @@ namespace MediaBrowser.Api.Library /// <param name="request">The request.</param> public void Post(AddVirtualFolder request) { - _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, request.Paths, request.RefreshLibrary); + var libraryOptions = request.LibraryOptions ?? new LibraryOptions(); + + _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, request.Paths, libraryOptions, request.RefreshLibrary); } /// <summary> diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 59dfd87ecd..a9489cecce 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1055,14 +1055,14 @@ namespace MediaBrowser.Api.Playback var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments; Logger.Info(commandLineLogMessage); - var logFilePrefix = "transcode"; + var logFilePrefix = "ffmpeg-transcode"; if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) { - logFilePrefix = "directstream"; + logFilePrefix = "ffmpeg-directstream"; } else if (state.VideoRequest != null && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { - logFilePrefix = "remux"; + logFilePrefix = "ffmpeg-remux"; } var logFilePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.LogDirectoryPath, logFilePrefix + "-" + Guid.NewGuid() + ".txt"); diff --git a/MediaBrowser.Controller/Configuration/LibraryOptions.cs b/MediaBrowser.Controller/Configuration/LibraryOptions.cs new file mode 100644 index 0000000000..1a824c08bf --- /dev/null +++ b/MediaBrowser.Controller/Configuration/LibraryOptions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Configuration +{ + public class LibraryOptions + { + public bool EnableAudioArchiveFiles { get; set; } + public bool EnableVideoArchiveFiles { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 1897511af7..6326bbd4f4 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1d623c3acc..cc3646cdcb 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -455,7 +455,7 @@ namespace MediaBrowser.Controller.Entities public DateTime DateLastRefreshed { get; set; } [IgnoreDataMember] - public virtual bool EnableForceSaveOnDateModifiedChange + public virtual bool EnableRefreshOnDateModifiedChange { get { return false; } } @@ -951,7 +951,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase)) ); - return LibraryManager.ResolvePaths(files, directoryService, null) + return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions()) .OfType<Audio.Audio>() .Select(audio => { @@ -981,7 +981,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase)) .SelectMany(i => directoryService.GetFiles(i.FullName)); - return LibraryManager.ResolvePaths(files, directoryService, null) + return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions()) .OfType<Video>() .Select(item => { diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 59ab954378..56f9fa784a 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 8bf9919f25..68ba22356c 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -3,11 +3,14 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Serialization; using MoreLinq; namespace MediaBrowser.Controller.Entities @@ -18,6 +21,8 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class CollectionFolder : Folder, ICollectionFolder { + public static IXmlSerializer XmlSerializer { get; set; } + public CollectionFolder() { PhysicalLocationsList = new List<string>(); @@ -39,6 +44,61 @@ namespace MediaBrowser.Controller.Entities public string CollectionType { get; set; } + private readonly Dictionary<string, LibraryOptions> _libraryOptions = new Dictionary<string, LibraryOptions>(); + public LibraryOptions GetLibraryOptions() + { + lock (_libraryOptions) + { + LibraryOptions options; + if (!_libraryOptions.TryGetValue(Path, out options)) + { + options = LoadLibraryOptions(); + _libraryOptions[Path] = options; + } + + return options; + } + } + + private LibraryOptions LoadLibraryOptions() + { + try + { + var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(Path)) as LibraryOptions; + + if (result == null) + { + return new LibraryOptions(); + } + + return result; + } + catch (FileNotFoundException) + { + return new LibraryOptions(); + } + catch (DirectoryNotFoundException) + { + return new LibraryOptions(); + } + catch (Exception ex) + { + Logger.ErrorException("Error loading library options", ex); + + return new LibraryOptions(); + } + } + + private static string GetLibraryOptionsPath(string path) + { + return System.IO.Path.Combine(path, "options.xml"); + } + + public static void SaveLibraryOptions(string path, LibraryOptions options) + { + XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); + } + /// <summary> /// Allow different display preferences for each collection folder /// </summary> diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index c1728ce389..bf04c643ce 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -273,6 +273,7 @@ namespace MediaBrowser.Controller.Entities /// </summary> protected virtual IEnumerable<BaseItem> LoadChildren() { + //Logger.Debug("Loading children from {0} {1}", Id, Path); //just load our children from the repo - the library will be validated and maintained in other processes return GetCachedChildren(); } @@ -643,8 +644,9 @@ namespace MediaBrowser.Controller.Entities protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService) { var collectionType = LibraryManager.GetContentType(this); + var libraryOptions = LibraryManager.GetLibraryOptions(this); - return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, collectionType); + return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, libraryOptions, collectionType); } /// <summary> diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index 54386a1795..24910498f5 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index c7a3c7778e..d5891c6552 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities bool RequiresRefresh(); - bool EnableForceSaveOnDateModifiedChange { get; } + bool EnableRefreshOnDateModifiedChange { get; } string PresentationUniqueKey { get; set; } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 4effc162e4..ba50a1e0de 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -62,6 +62,19 @@ namespace MediaBrowser.Controller.Entities.Movies return UnratedItem.Movie; } + protected override IEnumerable<BaseItem> LoadChildren() + { + var first = LinkedChildren.FirstOrDefault(); + + if (first != null && first.Type == LinkedChildType.Shortcut) + { + return base.LoadChildren(); + } + + // Save a trip to the database + return new List<BaseItem>(); + } + [IgnoreDataMember] public override bool IsPreSorted { diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 804ea04a59..965616eb53 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { get { return true; } } diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 7110b76cc6..830747d3c9 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -55,9 +55,12 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] - public override bool EnableForceSaveOnDateModifiedChange + public override bool EnableRefreshOnDateModifiedChange { - get { return true; } + get + { + return VideoType == VideoType.VideoFile || VideoType == VideoType.Iso; + } } public int? TotalBitrate { get; set; } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index ff7f2fe678..edbacb5e70 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Dto; namespace MediaBrowser.Controller.Library @@ -32,15 +33,11 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Resolves a set of files into a list of BaseItem /// </summary> - /// <param name="files">The files.</param> - /// <param name="directoryService">The directory service.</param> - /// <param name="parent">The parent.</param> - /// <param name="collectionType">Type of the collection.</param> - /// <returns>List{``0}.</returns> IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, - Folder parent, string - collectionType = null); + Folder parent, + LibraryOptions libraryOptions, + string collectionType = null); /// <summary> /// Gets the root folder. @@ -397,6 +394,9 @@ namespace MediaBrowser.Controller.Library /// <returns><c>true</c> if [is audio file] [the specified path]; otherwise, <c>false</c>.</returns> bool IsAudioFile(string path); + bool IsAudioFile(string path, LibraryOptions libraryOptions); + bool IsVideoFile(string path, LibraryOptions libraryOptions); + /// <summary> /// Gets the season number from path. /// </summary> @@ -453,6 +453,8 @@ namespace MediaBrowser.Controller.Library /// <returns>IEnumerable<Folder>.</returns> IEnumerable<Folder> GetCollectionFolders(BaseItem item); + LibraryOptions GetLibraryOptions(BaseItem item); + /// <summary> /// Gets the people. /// </summary> @@ -551,7 +553,7 @@ namespace MediaBrowser.Controller.Library /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> bool IgnoreFile(FileSystemMetadata file, BaseItem parent); - void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, bool refreshLibrary); + void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, LibraryOptions options, bool refreshLibrary); void RemoveVirtualFolder(string name, bool refreshLibrary); void AddMediaPath(string virtualFolderName, string path); void RemoveMediaPath(string virtualFolderName, string path); diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index ea3199b318..56ec0a2138 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Controller.Library { @@ -51,6 +52,13 @@ namespace MediaBrowser.Controller.Library } } + public LibraryOptions LibraryOptions { get; set; } + + public LibraryOptions GetLibraryOptions() + { + return LibraryOptions ?? (LibraryOptions = (Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent))); + } + /// <summary> /// Gets or sets the file system dictionary. /// </summary> diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 0462117cb5..e621eafded 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -98,6 +98,7 @@ <Compile Include="Collections\CollectionCreationOptions.cs" /> <Compile Include="Collections\CollectionEvents.cs" /> <Compile Include="Collections\ICollectionManager.cs" /> + <Compile Include="Configuration\LibraryOptions.cs" /> <Compile Include="Connect\ConnectSupporterSummary.cs" /> <Compile Include="Connect\IConnectManager.cs" /> <Compile Include="Connect\UserLinkResult.cs" /> diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 5ffe3d5daf..3e706f1fa7 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -58,6 +58,12 @@ namespace MediaBrowser.Controller.Playlists return true; } + protected override IEnumerable<BaseItem> LoadChildren() + { + // Save a trip to the database + return new List<BaseItem>(); + } + public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) { return GetPlayableItems(user).Result; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 58b74ba64a..303ba1acf7 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -180,8 +180,6 @@ namespace MediaBrowser.Model.Configuration public NameValuePair[] ContentTypes { get; set; } - public bool EnableAudioArchiveFiles { get; set; } - public bool EnableVideoArchiveFiles { get; set; } public int RemoteClientBitrateLimit { get; set; } public AutoOnOff EnableLibraryMonitor { get; set; } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 0a70a2cc43..0483a74ed1 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -149,7 +149,7 @@ namespace MediaBrowser.Providers.Manager if (file != null) { var fileLastWriteTime = file.LastWriteTimeUtc; - if (item.EnableForceSaveOnDateModifiedChange && fileLastWriteTime != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange && fileLastWriteTime != item.DateModified) { Logger.Debug("Date modified for {0}. Old date {1} new date {2} Id {3}", item.Path, item.DateModified, fileLastWriteTime, item.Id); requiresRefresh = true; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index e36be54191..0df8b6c4b7 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (!string.IsNullOrWhiteSpace(item.Path)) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path)) { var file = directoryService.GetFile(item.Path); if (file != null && file.LastWriteTimeUtc != item.DateModified) diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index fb08f00c19..280e92beb9 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -194,10 +194,13 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } return false; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 055fde504b..b00303f295 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -556,7 +556,12 @@ namespace MediaBrowser.Server.Implementations.Library return ResolvePath(fileInfo, new DirectoryService(_logger, _fileSystem), null, parent); } - private BaseItem ResolvePath(FileSystemMetadata fileInfo, IDirectoryService directoryService, IItemResolver[] resolvers, Folder parent = null, string collectionType = null) + private BaseItem ResolvePath(FileSystemMetadata fileInfo, + IDirectoryService directoryService, + IItemResolver[] resolvers, + Folder parent = null, + string collectionType = null, + LibraryOptions libraryOptions = null) { if (fileInfo == null) { @@ -575,7 +580,8 @@ namespace MediaBrowser.Server.Implementations.Library Parent = parent, Path = fullPath, FileInfo = fileInfo, - CollectionType = collectionType + CollectionType = collectionType, + LibraryOptions = libraryOptions }; // Return null if ignore rules deem that we should do so @@ -653,12 +659,17 @@ namespace MediaBrowser.Server.Implementations.Library return !args.ContainsFileSystemEntryByName(".ignore"); } - public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType) + public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, string collectionType) { - return ResolvePaths(files, directoryService, parent, collectionType, EntityResolvers); + return ResolvePaths(files, directoryService, parent, libraryOptions, collectionType, EntityResolvers); } - public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers) + public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, + IDirectoryService directoryService, + Folder parent, + LibraryOptions libraryOptions, + string collectionType, + IItemResolver[] resolvers) { var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList(); @@ -679,22 +690,27 @@ namespace MediaBrowser.Server.Implementations.Library { ResolverHelper.SetInitialItemValues(item, parent, _fileSystem, this, directoryService); } - items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers)); + items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType, resolvers, libraryOptions)); return items; } } } - return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers); + return ResolveFileList(fileList, directoryService, parent, collectionType, resolvers, libraryOptions); } - private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemMetadata> fileList, IDirectoryService directoryService, Folder parent, string collectionType, IItemResolver[] resolvers) + private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemMetadata> fileList, + IDirectoryService directoryService, + Folder parent, + string collectionType, + IItemResolver[] resolvers, + LibraryOptions libraryOptions) { return fileList.Select(f => { try { - return ResolvePath(f, directoryService, resolvers, parent, collectionType); + return ResolvePath(f, directoryService, resolvers, parent, collectionType, libraryOptions); } catch (Exception ex) { @@ -1891,6 +1907,15 @@ namespace MediaBrowser.Server.Implementations.Library .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path, StringComparer.OrdinalIgnoreCase)); } + public LibraryOptions GetLibraryOptions(BaseItem item) + { + var collectionFolder = GetCollectionFolders(item) + .OfType<CollectionFolder>() + .FirstOrDefault(); + + return collectionFolder == null ? new LibraryOptions() : collectionFolder.GetLibraryOptions(); + } + public string GetContentType(BaseItem item) { string configuredContentType = GetConfiguredContentType(item, false); @@ -2242,18 +2267,28 @@ namespace MediaBrowser.Server.Implementations.Library return item; } - public bool IsVideoFile(string path) + public bool IsVideoFile(string path, LibraryOptions libraryOptions) { - var resolver = new VideoResolver(GetNamingOptions(), new PatternsLogger()); + var resolver = new VideoResolver(GetNamingOptions(libraryOptions), new PatternsLogger()); return resolver.IsVideoFile(path); } - public bool IsAudioFile(string path) + public bool IsVideoFile(string path) + { + return IsVideoFile(path, new LibraryOptions()); + } + + public bool IsAudioFile(string path, LibraryOptions libraryOptions) { - var parser = new AudioFileParser(GetNamingOptions()); + var parser = new AudioFileParser(GetNamingOptions(libraryOptions)); return parser.IsAudioFile(path); } + public bool IsAudioFile(string path) + { + return IsAudioFile(path, new LibraryOptions()); + } + public int? GetSeasonNumberFromPath(string path) { return new SeasonPathParser(GetNamingOptions(), new RegexProvider()).Parse(path, true, true).SeasonNumber; @@ -2379,6 +2414,11 @@ namespace MediaBrowser.Server.Implementations.Library } public NamingOptions GetNamingOptions() + { + return GetNamingOptions(new LibraryOptions()); + } + + public NamingOptions GetNamingOptions(LibraryOptions libraryOptions) { var options = new ExtendedNamingOptions(); @@ -2386,13 +2426,13 @@ namespace MediaBrowser.Server.Implementations.Library options.AudioFileExtensions.Remove(".m3u"); options.AudioFileExtensions.Remove(".wpl"); - if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles) + if (!libraryOptions.EnableAudioArchiveFiles) { options.AudioFileExtensions.Remove(".rar"); options.AudioFileExtensions.Remove(".zip"); } - if (!ConfigurationManager.Configuration.EnableVideoArchiveFiles) + if (!libraryOptions.EnableVideoArchiveFiles) { options.VideoFileExtensions.Remove(".rar"); options.VideoFileExtensions.Remove(".zip"); @@ -2443,7 +2483,7 @@ namespace MediaBrowser.Server.Implementations.Library new GenericVideoResolver<Trailer>(this) }; - return ResolvePaths(files, directoryService, null, null, resolvers) + return ResolvePaths(files, directoryService, null, new LibraryOptions(), null, resolvers) .OfType<Trailer>() .Select(video => { @@ -2487,7 +2527,7 @@ namespace MediaBrowser.Server.Implementations.Library files.AddRange(currentVideo.Extras.Where(i => !string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => _fileSystem.GetFileInfo(i.Path))); } - return ResolvePaths(files, directoryService, null, null) + return ResolvePaths(files, directoryService, null, new LibraryOptions(), null) .OfType<Video>() .Select(video => { @@ -2665,7 +2705,7 @@ namespace MediaBrowser.Server.Implementations.Library throw new InvalidOperationException(); } - public void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, bool refreshLibrary) + public void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, LibraryOptions options, bool refreshLibrary) { if (string.IsNullOrWhiteSpace(name)) { @@ -2708,6 +2748,8 @@ namespace MediaBrowser.Server.Implementations.Library } } + CollectionFolder.SaveLibraryOptions(virtualFolderPath, options); + if (mediaPaths != null) { foreach (var path in mediaPaths) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index b4cda39cd2..039a17100a 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -37,14 +37,16 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio if (!args.IsDirectory) { - if (_libraryManager.IsAudioFile(args.Path)) + var libraryOptions = args.GetLibraryOptions(); + + if (_libraryManager.IsAudioFile(args.Path, libraryOptions)) { var collectionType = args.GetCollectionType(); var isMixed = string.IsNullOrWhiteSpace(collectionType); // For conflicting extensions, give priority to videos - if (isMixed && _libraryManager.IsVideoFile(args.Path)) + if (isMixed && _libraryManager.IsVideoFile(args.Path, libraryOptions)) { return null; } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 9f8293cb5b..546f64d3c3 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.IO; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { @@ -72,12 +73,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// <summary> /// Determine if the supplied file data points to a music album /// </summary> - /// <param name="path">The path.</param> - /// <param name="directoryService">The directory service.</param> - /// <returns><c>true</c> if [is music album] [the specified data]; otherwise, <c>false</c>.</returns> - public bool IsMusicAlbum(string path, IDirectoryService directoryService) + public bool IsMusicAlbum(string path, IDirectoryService directoryService, LibraryOptions libraryOptions) { - return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, _libraryManager); + return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService, _logger, _fileSystem, libraryOptions, _libraryManager); } /// <summary> @@ -91,7 +89,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio if (args.IsDirectory) { //if (args.Parent is MusicArtist) return true; //saves us from testing children twice - if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, _libraryManager)) return true; + if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService, _logger, _fileSystem, args.GetLibraryOptions(), _libraryManager)) return true; } return false; @@ -100,18 +98,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// <summary> /// Determine if the supplied list contains what we should consider music /// </summary> - /// <param name="list">The list.</param> - /// <param name="allowSubfolders">if set to <c>true</c> [allow subfolders].</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 the specified list contains music; otherwise, <c>false</c>.</returns> private bool ContainsMusic(IEnumerable<FileSystemMetadata> list, bool allowSubfolders, IDirectoryService directoryService, ILogger logger, IFileSystem fileSystem, + LibraryOptions libraryOptions, ILibraryManager libraryManager) { var discSubfolderCount = 0; @@ -124,11 +116,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio if (allowSubfolders) { var path = fileSystemInfo.FullName; - var isMultiDisc = IsMultiDiscFolder(path); + var isMultiDisc = IsMultiDiscFolder(path, libraryOptions); if (isMultiDisc) { - var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager); + var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryOptions, libraryManager); if (hasMusic) { @@ -138,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio } else { - var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryManager); + var hasMusic = ContainsMusic(directoryService.GetFileSystemEntries(path), false, directoryService, logger, fileSystem, libraryOptions, libraryManager); if (hasMusic) { @@ -151,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio var fullName = fileSystemInfo.FullName; - if (libraryManager.IsAudioFile(fullName)) + if (libraryManager.IsAudioFile(fullName, libraryOptions)) { return true; } @@ -165,9 +157,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return discSubfolderCount > 0; } - private bool IsMultiDiscFolder(string path) + private bool IsMultiDiscFolder(string path, LibraryOptions libraryOptions) { - var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(libraryOptions); var parser = new AlbumParser(namingOptions, new PatternsLogger()); var result = parser.ParseMultiPart(path); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index e3c991e7ea..e819af06fd 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -72,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio 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 => albumResolver.IsMusicAlbum(i.FullName, directoryService)) ? new MusicArtist() : null; + return args.FileSystemChildren.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory).Any(i => albumResolver.IsMusicAlbum(i.FullName, directoryService, args.GetLibraryOptions())) ? new MusicArtist() : null; } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index 703a338568..d0042a9907 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers return null; } - if (LibraryManager.IsVideoFile(args.Path) || videoInfo.IsStub) + if (LibraryManager.IsVideoFile(args.Path, args.GetLibraryOptions()) || videoInfo.IsStub) { var path = args.Path; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs index 9dd30eddee..09a9a3b4e9 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -6,6 +6,7 @@ using System; using System.IO; using System.Linq; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Server.Implementations.Library.Resolvers { @@ -40,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers var filename = Path.GetFileNameWithoutExtension(args.Path); // Make sure the image doesn't belong to a video file - if (args.DirectoryService.GetFiles(Path.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(i, filename))) + if (args.DirectoryService.GetFiles(Path.GetDirectoryName(args.Path)).Any(i => IsOwnedByMedia(args.GetLibraryOptions(), i, filename))) { return null; } @@ -56,9 +57,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers return null; } - private bool IsOwnedByMedia(FileSystemMetadata file, string imageFilename) + private bool IsOwnedByMedia(LibraryOptions libraryOptions, FileSystemMetadata file, string imageFilename) { - if (_libraryManager.IsVideoFile(file.FullName) && imageFilename.StartsWith(Path.GetFileNameWithoutExtension(file.Name), StringComparison.OrdinalIgnoreCase)) + if (_libraryManager.IsVideoFile(file.FullName, libraryOptions) && imageFilename.StartsWith(Path.GetFileNameWithoutExtension(file.Name), StringComparison.OrdinalIgnoreCase)) { return true; } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 45ba2ddbb3..f1bbc1f327 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using CommonIO; +using MediaBrowser.Controller.Configuration; namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { @@ -83,7 +84,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { return null; } - if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, false)) + if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false)) { return new Series { @@ -104,6 +105,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager, + LibraryOptions libraryOptions, bool isTvContentType) { foreach (var child in fileSystemChildren) @@ -134,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV else { string fullName = child.FullName; - if (libraryManager.IsVideoFile(fullName)) + if (libraryManager.IsVideoFile(fullName, libraryOptions)) { if (isTvContentType) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index ee8ab7c254..4c9b2a4d97 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV try { - _libraryManager.AddVirtualFolder(recordingFolder.Name, recordingFolder.CollectionType, pathsToCreate.ToArray(), true); + _libraryManager.AddVirtualFolder(recordingFolder.Name, recordingFolder.CollectionType, pathsToCreate.ToArray(), new LibraryOptions(), true); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index c01261d738..bbb36b46e1 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -4041,7 +4041,7 @@ namespace MediaBrowser.Server.Implementations.Persistence ? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult) : CommandBehavior.SequentialAccess; - Logger.Debug("GetItemValues: " + cmd.CommandText); + //Logger.Debug("GetItemValues: " + cmd.CommandText); using (var reader = cmd.ExecuteReader(commandBehavior)) { diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 20324215b8..ff0e4a0e01 100644 --- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.Playlists protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) { - return GetRecursiveChildren(i => i is Playlist); + return base.GetEligibleChildrenForRecursiveChildren(user).OfType<Playlist>(); } public override bool IsHidden diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index ce99f0a240..74438abbcf 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -765,6 +765,7 @@ namespace MediaBrowser.Server.Startup.Common UserView.PlaylistManager = PlaylistManager; BaseItem.CollectionManager = CollectionManager; BaseItem.MediaSourceManager = MediaSourceManager; + CollectionFolder.XmlSerializer = XmlSerializer; } /// <summary>