示例#1
0
 public override T Resolve(ItemResolveArgs args)
 {
     return(ResolveVideo <T>(args, false));
 }
示例#2
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Video.</returns>
        protected override Video Resolve(ItemResolveArgs args)
        {
            var collectionType = args.GetCollectionType();

            // Find movies with their own folders
            if (args.IsDirectory)
            {
                if (IsInvalid(args.Parent, collectionType))
                {
                    return(null);
                }

                var files = args.FileSystemChildren
                            .Where(i => !LibraryManager.IgnoreFile(i, args.Parent))
                            .ToList();

                if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <MusicVideo>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, false));
                }

                if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <Video>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, false));
                }

                if (string.IsNullOrEmpty(collectionType))
                {
                    // Owned items will be caught by the plain video resolver
                    if (args.Parent == null)
                    {
                        //return FindMovie<Video>(args.Path, args.Parent, files, args.DirectoryService, collectionType);
                        return(null);
                    }

                    if (args.HasParent <Series>())
                    {
                        return(null);
                    }

                    {
                        return(FindMovie <Movie>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, true));
                    }
                }

                if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <Movie>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, true));
                }

                return(null);
            }

            // Handle owned items
            if (args.Parent == null)
            {
                return(base.Resolve(args));
            }

            if (IsInvalid(args.Parent, collectionType))
            {
                return(null);
            }

            Video item = null;

            if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <MusicVideo>(args, false);
            }

            // To find a movie file, the collection type must be movies or boxsets
            else if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <Movie>(args, true);
            }

            else if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) ||
                     string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <Video>(args, false);
            }
            else if (string.IsNullOrEmpty(collectionType))
            {
                if (args.HasParent <Series>())
                {
                    return(null);
                }

                item = ResolveVideo <Video>(args, false);
            }

            if (item != null)
            {
                item.IsInMixedFolder = true;
            }

            return(item);
        }
示例#3
0
        /// <summary>
        /// Finds a movie based on a child file system entries
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Movie.</returns>
        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 <Movie>();

            // 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(ApplicationPaths)
                {
                    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);
        }
示例#4
0
        /// <summary>
        /// Resolves the video.
        /// </summary>
        /// <typeparam name="TVideoType">The type of the T video type.</typeparam>
        /// <param name="args">The args.</param>
        /// <param name="parseName">if set to <c>true</c> [parse name].</param>
        /// <returns>``0.</returns>
        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 VideoResolver(namingOptions);

            if (args.IsDirectory)
            {
                TVideoType    video     = null;
                VideoFileInfo videoInfo = null;

                // Loop through each child file/folder and see if we find a video
                foreach (var child in args.FileSystemChildren)
                {
                    var filename = child.Name;

                    if (child.IsDirectory)
                    {
                        if (IsDvdDirectory(child.FullName, filename, args.DirectoryService))
                        {
                            videoInfo = parser.ResolveDirectory(args.Path);

                            if (videoInfo == null)
                            {
                                return(null);
                            }

                            video = new TVideoType
                            {
                                Path           = args.Path,
                                VideoType      = VideoType.Dvd,
                                ProductionYear = videoInfo.Year
                            };
                            break;
                        }

                        if (IsBluRayDirectory(child.FullName, filename, args.DirectoryService))
                        {
                            videoInfo = parser.ResolveDirectory(args.Path);

                            if (videoInfo == null)
                            {
                                return(null);
                            }

                            video = new TVideoType
                            {
                                Path           = args.Path,
                                VideoType      = VideoType.BluRay,
                                ProductionYear = videoInfo.Year
                            };
                            break;
                        }
                    }
                    else if (IsDvdFile(filename))
                    {
                        videoInfo = parser.ResolveDirectory(args.Path);

                        if (videoInfo == null)
                        {
                            return(null);
                        }

                        video = new TVideoType
                        {
                            Path           = args.Path,
                            VideoType      = VideoType.Dvd,
                            ProductionYear = videoInfo.Year
                        };
                        break;
                    }
                }

                if (video != null)
                {
                    video.Name = parseName ?
                                 videoInfo.Name :
                                 Path.GetFileName(args.Path);

                    Set3DFormat(video, videoInfo);
                }

                return(video);
            }
            else
            {
                var videoInfo = parser.Resolve(args.Path, false, false);

                if (videoInfo == null)
                {
                    return(null);
                }

                if (LibraryManager.IsVideoFile(args.Path) || videoInfo.IsStub)
                {
                    var path = args.Path;

                    var video = new TVideoType
                    {
                        Path            = path,
                        IsInMixedFolder = true,
                        ProductionYear  = videoInfo.Year
                    };

                    SetVideoType(video, videoInfo);

                    video.Name = parseName ?
                                 videoInfo.Name :
                                 Path.GetFileNameWithoutExtension(args.Path);

                    Set3DFormat(video, videoInfo);

                    return(video);
                }
            }

            return(null);
        }
示例#5
0
 /// <summary>
 /// Sets initial values on the newly resolved item.
 /// </summary>
 /// <param name="item">The item.</param>
 /// <param name="args">The args.</param>
 protected virtual void SetInitialItemValues(T item, ItemResolveArgs args)
 {
 }
 /// <summary>
 /// Gets the image.
 /// </summary>
 /// <param name="item">The item.</param>
 /// <param name="args">The args.</param>
 /// <param name="filenameWithoutExtension">The filename without extension.</param>
 /// <returns>FileSystemInfo.</returns>
 protected virtual FileSystemInfo GetImage(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension)
 {
     return(BaseItem.SupportedImageExtensions
            .Select(i => args.GetMetaFileByPath(GetFullImagePath(item, args, filenameWithoutExtension, i)))
            .FirstOrDefault(i => i != null));
 }
示例#7
0
        /// <summary>
        /// Gets the filtered file system entries.
        /// </summary>
        /// <param name="directoryService">The directory service.</param>
        /// <param name="path">The path.</param>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="logger">The logger.</param>
        /// <param name="args">The args.</param>
        /// <param name="flattenFolderDepth">The flatten folder depth.</param>
        /// <param name="resolveShortcuts">if set to <c>true</c> [resolve shortcuts].</param>
        /// <returns>Dictionary{System.StringFileSystemInfo}.</returns>
        /// <exception cref="System.ArgumentNullException">path</exception>
        public static Dictionary <string, FileSystemMetadata> GetFilteredFileSystemEntries(IDirectoryService directoryService,
                                                                                           string path,
                                                                                           IFileSystem fileSystem,
                                                                                           ILogger logger,
                                                                                           ItemResolveArgs args,
                                                                                           int flattenFolderDepth = 0,
                                                                                           bool resolveShortcuts  = true)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            if (!resolveShortcuts && flattenFolderDepth == 0)
            {
                return(directoryService.GetFileSystemDictionary(path));
            }

            var entries = directoryService.GetFileSystemEntries(path);

            var dict = new Dictionary <string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);

            foreach (var entry in entries)
            {
                var isDirectory = entry.IsDirectory;

                var fullName = entry.FullName;

                if (resolveShortcuts && fileSystem.IsShortcut(fullName))
                {
                    try
                    {
                        var newPath = fileSystem.ResolveShortcut(fullName);

                        if (string.IsNullOrWhiteSpace(newPath))
                        {
                            //invalid shortcut - could be old or target could just be unavailable
                            logger.Warn("Encountered invalid shortcut: " + fullName);
                            continue;
                        }

                        // Don't check if it exists here because that could return false for network shares.
                        var data = fileSystem.GetDirectoryInfo(newPath);

                        // add to our physical locations
                        args.AddAdditionalLocation(newPath);

                        dict[newPath] = data;
                    }
                    catch (Exception ex)
                    {
                        logger.ErrorException("Error resolving shortcut from {0}", ex, fullName);
                    }
                }
                else if (flattenFolderDepth > 0 && isDirectory)
                {
                    foreach (var child in GetFilteredFileSystemEntries(directoryService, fullName, fileSystem, logger, args, flattenFolderDepth: flattenFolderDepth - 1, resolveShortcuts: resolveShortcuts))
                    {
                        dict[child.Key] = child.Value;
                    }
                }
                else
                {
                    dict[fullName] = entry;
                }
            }

            return(dict);
        }
 protected override FileSystemInfo GetImage(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension)
 {
     return(item.ResolveArgs.PhysicalLocations
            .Select(i => GetImageFromLocation(i, filenameWithoutExtension))
            .FirstOrDefault(i => i != null));
 }
示例#9
0
        protected override MediaBrowser.Controller.Entities.Audio.Audio Resolve(ItemResolveArgs args)
        {
            // Return audio if the path is a file and has a matching extension

            var collectionType = args.GetCollectionType();

            var isBooksCollectionType = string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase);

            if (args.IsDirectory)
            {
                if (!isBooksCollectionType)
                {
                    return(null);
                }

                return(FindAudioBook(args, false));
            }

            if (AudioFileParser.IsAudioFile(args.Path, _namingOptions))
            {
                var extension = Path.GetExtension(args.Path);

                if (string.Equals(extension, ".cue", StringComparison.OrdinalIgnoreCase))
                {
                    // if audio file exists of same name, return null
                    return(null);
                }

                var isMixedCollectionType = string.IsNullOrEmpty(collectionType);

                // For conflicting extensions, give priority to videos
                if (isMixedCollectionType && VideoResolver.IsVideoFile(args.Path, _namingOptions))
                {
                    return(null);
                }

                MediaBrowser.Controller.Entities.Audio.Audio item = null;

                var isMusicCollectionType = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase);

                // Use regular audio type for mixed libraries, owned items and music
                if (isMixedCollectionType ||
                    args.Parent == null ||
                    isMusicCollectionType)
                {
                    item = new MediaBrowser.Controller.Entities.Audio.Audio();
                }
                else if (isBooksCollectionType)
                {
                    item = new AudioBook();
                }

                if (item != null)
                {
                    item.IsShortcut = string.Equals(extension, ".strm", StringComparison.OrdinalIgnoreCase);

                    item.IsInMixedFolder = true;
                }

                return(item);
            }

            return(null);
        }
示例#10
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Entities.Audio.Audio.</returns>
        protected override MediaBrowser.Controller.Entities.Audio.Audio Resolve(ItemResolveArgs args)
        {
            // Return audio if the path is a file and has a matching extension

            var libraryOptions = args.GetLibraryOptions();
            var collectionType = args.GetCollectionType();

            var isBooksCollectionType = string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase);

            if (args.IsDirectory)
            {
                if (!isBooksCollectionType)
                {
                    return(null);
                }

                var files = args.FileSystemChildren
                            .Where(i => !LibraryManager.IgnoreFile(i, args.Parent))
                            .ToList();

                if (isBooksCollectionType)
                {
                    return(FindAudio <AudioBook>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, false));
                }

                return(null);
            }

            if (LibraryManager.IsAudioFile(args.Path, libraryOptions))
            {
                if (string.Equals(Path.GetExtension(args.Path), ".cue", StringComparison.OrdinalIgnoreCase))
                {
                    // if audio file exists of same name, return null
                    return(null);
                }

                var isMixedCollectionType = string.IsNullOrWhiteSpace(collectionType);

                // For conflicting extensions, give priority to videos
                if (isMixedCollectionType && LibraryManager.IsVideoFile(args.Path, libraryOptions))
                {
                    return(null);
                }

                MediaBrowser.Controller.Entities.Audio.Audio item = null;

                var isMusicCollectionType = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase);

                // Use regular audio type for mixed libraries, owned items and music
                if (isMixedCollectionType ||
                    args.Parent == null ||
                    isMusicCollectionType)
                {
                    item = new MediaBrowser.Controller.Entities.Audio.Audio();
                }

                else if (isBooksCollectionType)
                {
                    item = new AudioBook();
                }

                if (item != null)
                {
                    item.IsInMixedFolder = true;
                }

                return(item);
            }

            return(null);
        }
示例#11
0
 /// <summary>
 /// Determines whether a path should be ignored based on its contents - called after the contents have been read
 /// </summary>
 /// <param name="args">The args.</param>
 /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
 private static bool ShouldResolvePathContents(ItemResolveArgs args)
 {
     // Ignore any folders containing a file called .ignore
     return(!args.ContainsFileSystemEntryByName(".ignore"));
 }
示例#12
0
        /// <summary>
        /// Sets the initial item values.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="args">The args.</param>
        protected override void SetInitialItemValues(Season item, ItemResolveArgs args)
        {
            base.SetInitialItemValues(item, args);

            Season.AddMetadataFiles(args);
        }
示例#13
0
        public override Video Resolve(ItemResolveArgs args)
        {
            var collectionType = args.GetCollectionType();

            // Find movies with their own folders
            if (args.IsDirectory)
            {
                if (IsInvalid(args.Parent, collectionType))
                {
                    return(null);
                }

                Video movie = null;
                var   files = args.GetActualFileSystemChildren().ToList();

                if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
                {
                    movie = FindMovie <MusicVideo>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, false);
                }

                if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
                {
                    movie = FindMovie <Video>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, false);
                }

                if (string.IsNullOrEmpty(collectionType))
                {
                    // Owned items will be caught by the video extra resolver
                    if (args.Parent == null)
                    {
                        return(null);
                    }

                    if (args.HasParent <Series>())
                    {
                        return(null);
                    }

                    movie = FindMovie <Movie>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, true);
                }

                if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
                {
                    movie = FindMovie <Movie>(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, true);
                }

                // ignore extras
                return(movie?.ExtraType == null ? movie : null);
            }

            if (args.Parent == null)
            {
                return(base.Resolve(args));
            }

            if (IsInvalid(args.Parent, collectionType))
            {
                return(null);
            }

            Video item = null;

            if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <MusicVideo>(args, false);
            }

            // To find a movie file, the collection type must be movies or boxsets
            else if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <Movie>(args, true);
            }
            else if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) ||
                     string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <Video>(args, false);
            }
            else if (string.IsNullOrEmpty(collectionType))
            {
                if (args.HasParent <Series>())
                {
                    return(null);
                }

                item = ResolveVideo <Video>(args, false);
            }

            // Ignore extras
            if (item?.ExtraType != null)
            {
                return(null);
            }

            if (item != null)
            {
                item.IsInMixedFolder = true;
            }

            return(item);
        }
示例#14
0
        protected virtual TVideoType ResolveVideo <TVideoType>(ItemResolveArgs args, bool parseName)
            where TVideoType : Video, new()
        {
            VideoFileInfo videoInfo = null;
            VideoType?    videoType = null;

            // If the path is a file check for a matching extensions
            if (args.IsDirectory)
            {
                // Loop through each child file/folder and see if we find a video
                foreach (var child in args.FileSystemChildren)
                {
                    var filename = child.Name;
                    if (child.IsDirectory)
                    {
                        if (IsDvdDirectory(child.FullName, filename, args.DirectoryService))
                        {
                            videoType = VideoType.Dvd;
                        }
                        else if (IsBluRayDirectory(filename))
                        {
                            videoType = VideoType.BluRay;
                        }
                    }
                    else if (IsDvdFile(filename))
                    {
                        videoType = VideoType.Dvd;
                    }

                    if (videoType == null)
                    {
                        continue;
                    }

                    videoInfo = VideoResolver.ResolveDirectory(args.Path, NamingOptions, parseName);
                    break;
                }
            }
            else
            {
                videoInfo = VideoResolver.Resolve(args.Path, false, NamingOptions, parseName);
            }

            if (videoInfo == null || (!videoInfo.IsStub && !VideoResolver.IsVideoFile(args.Path, NamingOptions)))
            {
                return(null);
            }

            var video = new TVideoType
            {
                Name           = videoInfo.Name,
                Path           = args.Path,
                ProductionYear = videoInfo.Year,
                ExtraType      = videoInfo.ExtraType
            };

            if (videoType.HasValue)
            {
                video.VideoType = videoType.Value;
            }
            else
            {
                SetVideoType(video, videoInfo);
            }

            Set3DFormat(video, videoInfo);

            return(video);
        }
示例#15
0
 private bool HasPhotos(ItemResolveArgs args)
 {
     return(args.FileSystemChildren.Any(i => (!i.IsDirectory) && PhotoResolver.IsImageFile(i.FullName, _imageProcessor)));
 }
示例#16
0
 /// <summary>
 /// Resolves the specified args.
 /// </summary>
 /// <param name="args">The args.</param>
 /// <returns>`0.</returns>
 protected virtual T Resolve(ItemResolveArgs args)
 {
     return(null);
 }
示例#17
0
        /// <summary>
        /// Shoulds the ignore.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        public bool ShouldIgnore(ItemResolveArgs args)
        {
            var filename = args.FileInfo.Name;

            // Handle mac .DS_Store
            // https://github.com/MediaBrowser/MediaBrowser/issues/427
            if (filename.IndexOf("._", StringComparison.OrdinalIgnoreCase) == 0)
            {
                return(true);
            }

            // Ignore hidden files and folders
            if (args.IsHidden)
            {
                var parentFolderName = Path.GetFileName(Path.GetDirectoryName(args.Path));

                if (string.Equals(parentFolderName, BaseItem.ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
                {
                    return(false);
                }
                if (string.Equals(parentFolderName, BaseItem.ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
                {
                    return(false);
                }

                // Drives will sometimes be hidden
                if (args.Path.EndsWith(Path.VolumeSeparatorChar + "\\", StringComparison.OrdinalIgnoreCase))
                {
                    return(false);
                }

                // Shares will sometimes be hidden
                if (args.Path.StartsWith("\\", StringComparison.OrdinalIgnoreCase))
                {
                    // Look for a share, e.g. \\server\movies
                    // Is there a better way to detect if a path is a share without using native code?
                    if (args.Path.Substring(2).Split(Path.DirectorySeparatorChar).Length == 2)
                    {
                        return(false);
                    }
                }

                return(true);
            }

            if (args.IsDirectory)
            {
                // Ignore any folders in our list
                if (IgnoreFolders.ContainsKey(filename))
                {
                    return(true);
                }

                // Ignore trailer folders but allow it at the collection level
                if (string.Equals(filename, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase) &&
                    !(args.Parent is AggregateFolder) && !(args.Parent is UserRootFolder))
                {
                    return(true);
                }

                if (string.Equals(filename, BaseItem.ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
                {
                    return(true);
                }

                if (string.Equals(filename, BaseItem.ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
                {
                    return(true);
                }
            }
            else
            {
                if (args.Parent != null)
                {
                    // Don't resolve these into audio files
                    if (string.Equals(Path.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename) && EntityResolutionHelper.IsAudioFile(filename))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#18
0
 private static bool HasPhotos(ItemResolveArgs args)
 {
     return(args.FileSystemChildren.Any(i => ((i.Attributes & FileAttributes.Directory) != FileAttributes.Directory) && PhotoResolver.IsImageFile(i.FullName)));
 }
        /// <summary>
        /// Fills in image paths based on files win the folder
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="args">The args.</param>
        private void PopulateBaseItemImages(BaseItem item, ItemResolveArgs args)
        {
            // Primary Image
            var image = GetImage(item, args, "folder") ??
                        GetImage(item, args, "poster") ??
                        GetImage(item, args, "cover") ??
                        GetImage(item, args, "default");

            // Look for a file with the same name as the item
            if (image == null)
            {
                var name = Path.GetFileNameWithoutExtension(item.Path);

                if (!string.IsNullOrEmpty(name))
                {
                    image = GetImage(item, args, name);
                }
            }

            if (image != null)
            {
                item.SetImage(ImageType.Primary, image.FullName);
            }

            // Logo Image
            image = GetImage(item, args, "logo");

            if (image != null)
            {
                item.SetImage(ImageType.Logo, image.FullName);
            }

            // Banner Image
            image = GetImage(item, args, "banner");

            if (image != null)
            {
                item.SetImage(ImageType.Banner, image.FullName);
            }

            // Clearart
            image = GetImage(item, args, "clearart");

            if (image != null)
            {
                item.SetImage(ImageType.Art, image.FullName);
            }

            // Disc
            image = GetImage(item, args, "disc");

            if (image != null)
            {
                item.SetImage(ImageType.Disc, image.FullName);
            }

            // Thumbnail Image
            image = GetImage(item, args, "thumb");

            if (image != null)
            {
                item.SetImage(ImageType.Thumb, image.FullName);
            }

            // Box Image
            image = GetImage(item, args, "box");

            if (image != null)
            {
                item.SetImage(ImageType.Box, image.FullName);
            }

            // BoxRear Image
            image = GetImage(item, args, "boxrear");

            if (image != null)
            {
                item.SetImage(ImageType.BoxRear, image.FullName);
            }

            // Thumbnail Image
            image = GetImage(item, args, "menu");

            if (image != null)
            {
                item.SetImage(ImageType.Menu, image.FullName);
            }

            // Backdrop Image
            PopulateBackdrops(item, args);

            // Screenshot Image
            image = GetImage(item, args, "screenshot");

            var screenshotFiles = new List <string>();

            if (image != null)
            {
                screenshotFiles.Add(image.FullName);
            }

            var unfound = 0;

            for (var i = 1; i <= 20; i++)
            {
                // Screenshot Image
                image = GetImage(item, args, "screenshot" + i);

                if (image != null)
                {
                    screenshotFiles.Add(image.FullName);
                }
                else
                {
                    unfound++;

                    if (unfound >= 3)
                    {
                        break;
                    }
                }
            }

            if (screenshotFiles.Count > 0)
            {
                item.ScreenshotImagePaths = screenshotFiles;
            }
        }
示例#20
0
 protected override TVideoType ResolveVideo <TVideoType>(ItemResolveArgs args, bool parseName) => new ();
示例#21
0
 /// <summary>
 /// Resolves the specified args.
 /// </summary>
 /// <param name="args">The args.</param>
 /// <returns>`0.</returns>
 protected override T Resolve(ItemResolveArgs args)
 {
     return(ResolveVideo <T>(args, false));
 }
示例#22
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Episode.</returns>
        protected override Episode Resolve(ItemResolveArgs args)
        {
            var parent = args.Parent;

            if (parent == null)
            {
                return(null);
            }

            var season = parent as Season;

            // Just in case the user decided to nest episodes.
            // Not officially supported but in some cases we can handle it.
            if (season == null)
            {
                season = parent.Parents.OfType <Season>().FirstOrDefault();
            }

            // If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something
            if (season != null || parent is Series || parent.Parents.OfType <Series>().Any())
            {
                Episode episode = null;

                if (args.IsDirectory)
                {
                    if (args.ContainsFileSystemEntryByName("video_ts"))
                    {
                        episode = new Episode
                        {
                            Path      = args.Path,
                            VideoType = VideoType.Dvd
                        };
                    }
                    if (args.ContainsFileSystemEntryByName("bdmv"))
                    {
                        episode = new Episode
                        {
                            Path      = args.Path,
                            VideoType = VideoType.BluRay
                        };
                    }
                }

                if (episode == null)
                {
                    episode = base.Resolve(args);
                }

                if (episode != null)
                {
                    // The base video resolver is going to fill these in, so null them out
                    episode.ProductionYear = null;
                    episode.Name           = null;

                    if (season != null)
                    {
                        episode.ParentIndexNumber = season.IndexNumber;
                    }

                    if (episode.ParentIndexNumber == null)
                    {
                        episode.ParentIndexNumber = SeriesResolver.GetSeasonNumberFromEpisodeFile(args.Path);
                    }
                }

                return(episode);
            }

            return(null);
        }
示例#23
0
 /// <summary>
 /// Resolves the specified args.
 /// </summary>
 /// <param name="args">The args.</param>
 /// <returns>`0.</returns>
 public virtual T Resolve(ItemResolveArgs args)
 {
     return(null);
 }
示例#24
0
        /// <summary>
        /// Gets the filtered file system entries.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="logger">The logger.</param>
        /// <param name="args">The args.</param>
        /// <param name="searchPattern">The search pattern.</param>
        /// <param name="flattenFolderDepth">The flatten folder depth.</param>
        /// <param name="resolveShortcuts">if set to <c>true</c> [resolve shortcuts].</param>
        /// <returns>Dictionary{System.StringFileSystemInfo}.</returns>
        /// <exception cref="System.ArgumentNullException">path</exception>
        public static Dictionary <string, FileSystemInfo> GetFilteredFileSystemEntries(string path, ILogger logger, ItemResolveArgs args, string searchPattern = "*", int flattenFolderDepth = 0, bool resolveShortcuts = true)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            var entries = new DirectoryInfo(path).EnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);

            if (!resolveShortcuts && flattenFolderDepth == 0)
            {
                // Seeing dupes on some users file system for some reason
                return(entries
                       .DistinctBy(i => i.FullName, StringComparer.OrdinalIgnoreCase)
                       .ToDictionary(i => i.FullName, StringComparer.OrdinalIgnoreCase));
            }

            var dict = new Dictionary <string, FileSystemInfo>(StringComparer.OrdinalIgnoreCase);

            foreach (var entry in entries)
            {
                var isDirectory = (entry.Attributes & FileAttributes.Directory) == FileAttributes.Directory;

                var fullName = entry.FullName;

                if (resolveShortcuts && FileSystem.IsShortcut(fullName))
                {
                    var newPath = FileSystem.ResolveShortcut(fullName);

                    if (string.IsNullOrWhiteSpace(newPath))
                    {
                        //invalid shortcut - could be old or target could just be unavailable
                        logger.Warn("Encountered invalid shortcut: " + fullName);
                        continue;
                    }

                    // Don't check if it exists here because that could return false for network shares.
                    var data = new DirectoryInfo(newPath);

                    // add to our physical locations
                    args.AddAdditionalLocation(newPath);

                    dict[newPath] = data;
                }
                else if (flattenFolderDepth > 0 && isDirectory)
                {
                    foreach (var child in GetFilteredFileSystemEntries(fullName, logger, args, flattenFolderDepth: flattenFolderDepth - 1, resolveShortcuts: resolveShortcuts))
                    {
                        dict[child.Key] = child.Value;
                    }
                }
                else
                {
                    dict[fullName] = entry;
                }
            }

            return(dict);
        }
示例#25
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Series.</returns>
        protected override Series Resolve(ItemResolveArgs args)
        {
            if (args.IsDirectory)
            {
                if (args.HasParent <Series>() || args.HasParent <Season>())
                {
                    return(null);
                }

                var collectionType = args.GetCollectionType();
                if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
                {
                    //if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
                    //{
                    //    return new Series
                    //    {
                    //        Path = args.Path,
                    //        Name = Path.GetFileName(args.Path)
                    //    };
                    //}

                    var configuredContentType = _libraryManager.GetConfiguredContentType(args.Path);
                    if (!string.Equals(configuredContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
                    {
                        return(new Series
                        {
                            Path = args.Path,
                            Name = Path.GetFileName(args.Path)
                        });
                    }
                }
                else if (string.IsNullOrEmpty(collectionType))
                {
                    if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
                    {
                        if (args.Parent != null && args.Parent.IsRoot)
                        {
                            // For now, return null, but if we want to allow this in the future then add some additional checks to guard against a misplaced tvshow.nfo
                            return(null);
                        }

                        return(new Series
                        {
                            Path = args.Path,
                            Name = Path.GetFileName(args.Path)
                        });
                    }

                    if (args.Parent != null && 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);
        }
示例#26
0
        /// <summary>
        /// Finds a movie based on a child file system entries
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path">The path.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="fileSystemEntries">The file system entries.</param>
        /// <param name="directoryService">The directory service.</param>
        /// <param name="supportMultiFileItems">if set to <c>true</c> [support multi file items].</param>
        /// <returns>Movie.</returns>
        private T FindMovie <T>(string path, Folder parent, IEnumerable <FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, bool supportMultiFileItems, bool supportsMultipleSources)
            where T : Video, new()
        {
            var movies = new List <T>();

            var multiDiscFolders = new List <FileSystemInfo>();

            // Loop through each child file/folder and see if we find a video
            foreach (var child in fileSystemEntries)
            {
                var filename = child.Name;

                if ((child.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    if (IsDvdDirectory(filename))
                    {
                        return(new T
                        {
                            Path = path,
                            VideoType = VideoType.Dvd
                        });
                    }
                    if (IsBluRayDirectory(filename))
                    {
                        return(new T
                        {
                            Path = path,
                            VideoType = VideoType.BluRay
                        });
                    }

                    if (EntityResolutionHelper.IsMultiPartFolder(filename))
                    {
                        multiDiscFolders.Add(child);
                    }

                    continue;
                }

                // Don't misidentify xbmc trailers as a movie
                if (filename.IndexOf(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) != -1)
                {
                    continue;
                }

                var childArgs = new ItemResolveArgs(_applicationPaths, _libraryManager, directoryService)
                {
                    FileInfo = child,
                    Path     = child.FullName,
                    Parent   = parent
                };

                var item = ResolveVideo <T>(childArgs);

                if (item != null)
                {
                    item.IsInMixedFolder = false;
                    movies.Add(item);
                }
            }

            if (movies.Count > 1)
            {
                if (supportMultiFileItems)
                {
                    var result = GetMultiFileMovie(movies);

                    if (result != null)
                    {
                        return(result);
                    }
                }
                if (supportsMultipleSources)
                {
                    var result = GetMovieWithMultipleSources(movies);

                    if (result != null)
                    {
                        return(result);
                    }
                }
                return(null);
            }

            if (movies.Count == 1)
            {
                return(movies[0]);
            }

            if (multiDiscFolders.Count > 0)
            {
                var folders = fileSystemEntries.Where(child => (child.Attributes & FileAttributes.Directory) == FileAttributes.Directory);

                return(GetMultiDiscMovie <T>(multiDiscFolders, folders));
            }

            return(null);
        }
示例#27
0
        /// <summary>
        /// Finds a movie based on a child file system entries
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns>Movie.</returns>
        private T FindMovie <T>(ItemResolveArgs args, string path, Folder parent, List <FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, string collectionType, bool parseName)
            where T : Video, new()
        {
            var multiDiscFolders = new List <FileSystemMetadata>();

            var libraryOptions = args.GetLibraryOptions();
            var supportPhotos  = string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) && libraryOptions.EnablePhotos;
            var photos         = new List <FileSystemMetadata>();

            // Search for a folder rip
            foreach (var child in fileSystemEntries)
            {
                var filename = child.Name;

                if (child.IsDirectory)
                {
                    if (IsDvdDirectory(child.FullName, filename, directoryService))
                    {
                        var movie = new T
                        {
                            Path      = path,
                            VideoType = VideoType.Dvd
                        };
                        Set3DFormat(movie);
                        return(movie);
                    }
                    if (IsBluRayDirectory(child.FullName, filename, directoryService))
                    {
                        var movie = new T
                        {
                            Path      = path,
                            VideoType = VideoType.BluRay
                        };
                        Set3DFormat(movie);
                        return(movie);
                    }

                    multiDiscFolders.Add(child);
                }
                else if (IsDvdFile(filename))
                {
                    var movie = new T
                    {
                        Path      = path,
                        VideoType = VideoType.Dvd
                    };
                    Set3DFormat(movie);
                    return(movie);
                }
                else if (supportPhotos && PhotoResolver.IsImageFile(child.FullName, _imageProcessor))
                {
                    photos.Add(child);
                }
            }

            // TODO: Allow GetMultiDiscMovie in here
            var supportsMultiVersion = true;

            var result = ResolveVideos <T>(parent, fileSystemEntries, directoryService, supportsMultiVersion, collectionType, parseName) ??
                         new MultiItemResolverResult();

            if (result.Items.Count == 1)
            {
                var videoPath = result.Items[0].Path;
                var hasPhotos = photos.Any(i => !PhotoResolver.IsOwnedByResolvedMedia(LibraryManager, libraryOptions, videoPath, i.Name));

                if (!hasPhotos)
                {
                    var movie = (T)result.Items[0];
                    movie.IsInMixedFolder = false;
                    movie.Name            = Path.GetFileName(movie.ContainingFolderPath);
                    return(movie);
                }
            }

            if (result.Items.Count == 0 && multiDiscFolders.Count > 0)
            {
                return(GetMultiDiscMovie <T>(multiDiscFolders, directoryService));
            }

            return(null);
        }
示例#28
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Video.</returns>
        protected override Video Resolve(ItemResolveArgs args)
        {
            // Avoid expensive tests against VF's and all their children by not allowing this
            if (args.Parent != null)
            {
                if (args.Parent.IsRoot)
                {
                    return(null);
                }
            }

            var isDirectory = args.IsDirectory;

            if (isDirectory)
            {
                // Since the looping is expensive, this is an optimization to help us avoid it
                if (args.ContainsMetaFileByName("series.xml"))
                {
                    return(null);
                }
            }

            var collectionType = args.GetCollectionType();

            // Find movies with their own folders
            if (isDirectory)
            {
                if (string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <Trailer>(args.Path, args.Parent, args.FileSystemChildren, args.DirectoryService, false, false));
                }

                if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <MusicVideo>(args.Path, args.Parent, args.FileSystemChildren, args.DirectoryService, false, false));
                }

                if (string.Equals(collectionType, CollectionType.AdultVideos, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <AdultVideo>(args.Path, args.Parent, args.FileSystemChildren, args.DirectoryService, true, false));
                }

                if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <Video>(args.Path, args.Parent, args.FileSystemChildren, args.DirectoryService, true, false));
                }

                if (string.IsNullOrEmpty(collectionType) ||
                    string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
                {
                    return(FindMovie <Movie>(args.Path, args.Parent, args.FileSystemChildren, args.DirectoryService, true, true));
                }

                return(null);
            }

            var filename = Path.GetFileName(args.Path);

            // Don't misidentify xbmc trailers as a movie
            if (filename.IndexOf(BaseItem.XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) != -1)
            {
                return(null);
            }

            // Find movies that are mixed in the same folder
            if (string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase))
            {
                return(ResolveVideo <Trailer>(args));
            }

            Video item = null;

            if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <MusicVideo>(args);
            }

            if (string.Equals(collectionType, CollectionType.AdultVideos, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <AdultVideo>(args);
            }

            // To find a movie file, the collection type must be movies or boxsets
            // Otherwise we'll consider it a plain video and let the video resolver handle it
            if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
                string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
            {
                item = ResolveVideo <Movie>(args);
            }

            if (item != null)
            {
                item.IsInMixedFolder = true;
            }

            return(item);
        }
示例#29
0
        /// <summary>
        /// Sets the initial item values.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="args">The args.</param>
        protected override void SetInitialItemValues(Movie item, ItemResolveArgs args)
        {
            base.SetInitialItemValues(item, args);

            SetProviderIdFromPath(item);
        }
示例#30
0
 /// <summary>
 /// Resolves the specified args.
 /// </summary>
 /// <param name="args">The args.</param>
 /// <returns>Game.</returns>
 protected override Game Resolve(ItemResolveArgs args)
 {
     return(null);
 }