/// <summary> /// Sets the initial item values. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> /// <param name="fileSystem">The file system.</param> public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem) { // If the resolver didn't specify this if (string.IsNullOrEmpty(item.Path)) { item.Path = args.Path; } // If the resolver didn't specify this if (args.Parent != null) { item.Parent = args.Parent; } item.Id = item.Path.GetMBId(item.GetType()); // If the resolver didn't specify this if (string.IsNullOrEmpty(item.DisplayMediaType)) { item.DisplayMediaType = item.GetType().Name; } // Make sure the item has a name EnsureName(item, args); item.DontFetchMeta = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 || item.Parents.Any(i => i.IsLocked); // Make sure DateCreated and DateModified have values EntityResolutionHelper.EnsureDates(fileSystem, item, args, true); }
/// <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) { return entries.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; }
/// <summary> /// Sets the initial item values. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> /// <param name="fileSystem">The file system.</param> /// <param name="libraryManager">The library manager.</param> public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem, ILibraryManager libraryManager) { // If the resolver didn't specify this if (string.IsNullOrEmpty(item.Path)) { item.Path = args.Path; } // If the resolver didn't specify this if (args.Parent != null) { item.Parent = args.Parent; } item.Id = libraryManager.GetNewItemId(item.Path, item.GetType()); // Make sure the item has a name EnsureName(item, args.FileInfo); item.IsLocked = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 || item.Parents.Any(i => i.IsLocked); // Make sure DateCreated and DateModified have values EnsureDates(fileSystem, item, args, true); }
/// <summary> /// Gets the filtered file system entries. /// </summary> /// <param name="path">The path.</param> /// <param name="logger">The logger.</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> /// <param name="args">The args.</param> /// <returns>Dictionary{System.StringFileSystemInfo}.</returns> /// <exception cref="System.ArgumentNullException">path</exception> public static Dictionary<string, FileSystemInfo> GetFilteredFileSystemEntries(string path, ILogger logger, string searchPattern = "*", int flattenFolderDepth = 0, bool resolveShortcuts = true, ItemResolveArgs args = null) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } var dict = new Dictionary<string, FileSystemInfo>(StringComparer.OrdinalIgnoreCase); var entries = new DirectoryInfo(path).EnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly); foreach (var entry in entries) { var isDirectory = entry.Attributes.HasFlag(FileAttributes.Directory); if (resolveShortcuts && FileSystem.IsShortcut(entry.FullName)) { var newPath = FileSystem.ResolveShortcut(entry.FullName); if (string.IsNullOrWhiteSpace(newPath)) { //invalid shortcut - could be old or target could just be unavailable logger.Warn("Encountered invalid shortcut: " + entry.FullName); continue; } var data = FileSystem.GetFileSystemInfo(newPath); if (data.Exists) { // add to our physical locations if (args != null) { args.AddAdditionalLocation(newPath); } dict[data.FullName] = data; } else { logger.Warn("Cannot add unavailble/non-existent location {0}", data.FullName); } } else if (flattenFolderDepth > 0 && isDirectory) { foreach (var child in GetFilteredFileSystemEntries(entry.FullName, logger, flattenFolderDepth: flattenFolderDepth - 1, resolveShortcuts: resolveShortcuts)) { dict[child.Key] = child.Value; } } else { dict[entry.FullName] = entry; } } return dict; }
/// <summary> /// Ensures the name. /// </summary> /// <param name="item">The item.</param> private static void EnsureName(BaseItem item, ItemResolveArgs args) { // If the subclass didn't supply a name, add it here if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Path)) { //we use our resolve args name here to get the name of the containg folder, not actual video file item.Name = GetMBName(args.FileInfo.Name, (args.FileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory); } }
private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService) { var path = ContainingFolderPath; var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, LibraryManager, directoryService) { FileInfo = new DirectoryInfo(path), Path = path, Parent = Parent, CollectionType = CollectionType }; // Gather child folder and files if (args.IsDirectory) { var isPhysicalRoot = args.IsPhysicalRoot; // When resolving the root, we need it's grandchildren (children of user views) var flattenFolderDepth = isPhysicalRoot ? 2 : 0; var fileSystemDictionary = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, FileSystem, Logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); // Need to remove subpaths that may have been resolved from shortcuts // Example: if \\server\movies exists, then strip out \\server\movies\action if (isPhysicalRoot) { var paths = LibraryManager.NormalizeRootPathList(fileSystemDictionary.Keys); fileSystemDictionary = paths.Select(i => (FileSystemInfo)new DirectoryInfo(i)).ToDictionary(i => i.FullName); } args.FileSystemDictionary = fileSystemDictionary; } PhysicalLocationsList = args.PhysicalLocations.ToList(); return args; }
/// <summary> /// Populates the backdrops. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateBackdrops(BaseItem item, ItemResolveArgs args) { var isFileSystemItem = item.LocationType == LocationType.FileSystem; var backdropFiles = new List<string>(); PopulateBackdrops(item, args, backdropFiles, "backdrop", "backdrop"); // Support {name}-fanart.ext if (isFileSystemItem) { var name = Path.GetFileNameWithoutExtension(item.Path); if (!string.IsNullOrEmpty(name)) { var image = GetImage(item, args, name + "-fanart"); if (image != null) { backdropFiles.Add(image.FullName); } } } // Support plex/xbmc conventions PopulateBackdrops(item, args, backdropFiles, "fanart", "fanart-"); PopulateBackdrops(item, args, backdropFiles, "background", "background-"); PopulateBackdrops(item, args, backdropFiles, "art", "art-"); var season = item as Season; if (season != null && item.IndexNumber.HasValue && isFileSystemItem) { var image = GetSeasonImageFromSeriesFolder(season, "-fanart"); if (image != null) { backdropFiles.Add(image.FullName); } } if (isFileSystemItem) { PopulateBackdropsFromExtraFanart(args, backdropFiles); } if (backdropFiles.Count > 0) { item.BackdropImagePaths = backdropFiles; } }
/// <summary> /// Populates the banner. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateBanner(BaseItem item, ItemResolveArgs args) { // Banner Image var image = GetImage(item, args, "banner"); if (image == null) { var isFileSystemItem = item.LocationType == LocationType.FileSystem; // Supprt xbmc conventions var season = item as Season; if (season != null && item.IndexNumber.HasValue && isFileSystemItem) { image = GetSeasonImageFromSeriesFolder(season, "-banner"); } } if (image != null) { item.SetImagePath(ImageType.Banner, image.FullName); } }
/// <summary> /// Populates the thumb. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateThumb(BaseItem item, ItemResolveArgs args) { // Thumbnail Image var image = GetImage(item, args, "thumb") ?? GetImage(item, args, "landscape"); if (image == null) { var isFileSystemItem = item.LocationType == LocationType.FileSystem; // Supprt xbmc conventions var season = item as Season; if (season != null && item.IndexNumber.HasValue && isFileSystemItem) { image = GetSeasonImageFromSeriesFolder(season, "-landscape"); } } if (image != null) { item.SetImagePath(ImageType.Thumb, image.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) { PopulatePrimaryImage(item, args); // Logo Image var image = GetImage(item, args, "logo"); if (image != null) { item.SetImagePath(ImageType.Logo, image.FullName); } // Clearart image = GetImage(item, args, "clearart"); if (image != null) { item.SetImagePath(ImageType.Art, image.FullName); } // Disc image = GetImage(item, args, "disc") ?? GetImage(item, args, "cdart"); if (image != null) { item.SetImagePath(ImageType.Disc, image.FullName); } // Box Image image = GetImage(item, args, "box"); if (image != null) { item.SetImagePath(ImageType.Box, image.FullName); } // BoxRear Image image = GetImage(item, args, "boxrear"); if (image != null) { item.SetImagePath(ImageType.BoxRear, image.FullName); } // Thumbnail Image image = GetImage(item, args, "menu"); if (image != null) { item.SetImagePath(ImageType.Menu, image.FullName); } PopulateBanner(item, args); PopulateThumb(item, args); // Backdrop Image PopulateBackdrops(item, args); PopulateScreenshots(item, args); }
private void PopulatePrimaryImage(BaseItem item, ItemResolveArgs args) { // Primary Image var image = GetImage(item, args, "folder") ?? GetImage(item, args, "poster") ?? GetImage(item, args, "cover") ?? GetImage(item, args, "default"); // Support plex/xbmc convention if (image == null && item is Series) { image = GetImage(item, args, "show"); } var isFileSystemItem = item.LocationType == LocationType.FileSystem; // Support plex/xbmc convention if (image == null) { // Supprt xbmc conventions var season = item as Season; if (season != null && item.IndexNumber.HasValue && isFileSystemItem) { image = GetSeasonImageFromSeriesFolder(season, "-poster"); } } // Support plex/xbmc convention if (image == null && (item is Movie || item is MusicVideo || item is AdultVideo)) { image = GetImage(item, args, "movie"); } // Look for a file with the same name as the item if (image == null && isFileSystemItem) { var name = Path.GetFileNameWithoutExtension(item.Path); if (!string.IsNullOrEmpty(name)) { image = GetImage(item, args, name) ?? GetImage(item, args, name + "-poster"); } } if (image != null) { item.SetImagePath(ImageType.Primary, image.FullName); } }
/// <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; }
protected virtual string GetFullImagePath(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension, string extension) { var path = item.MetaLocation; if (item.IsInMixedFolder) { var pathFilenameWithoutExtension = Path.GetFileNameWithoutExtension(item.Path); // If the image filename and path file name match, just look for an image using the same full path as the item if (string.Equals(pathFilenameWithoutExtension, filenameWithoutExtension)) { return Path.ChangeExtension(item.Path, extension); } return Path.Combine(path, pathFilenameWithoutExtension + "-" + filenameWithoutExtension + extension); } return Path.Combine(path, filenameWithoutExtension + extension); }
/// <summary> /// Populates the backdrops from extra fanart. /// </summary> /// <param name="args">The args.</param> /// <param name="backdrops">The backdrops.</param> private void PopulateBackdropsFromExtraFanart(ItemResolveArgs args, List<string> backdrops) { if (!args.IsDirectory) { return; } if (args.ContainsFileSystemEntryByName("extrafanart")) { var path = Path.Combine(args.Path, "extrafanart"); var imageFiles = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly) .Where(i => { var extension = Path.GetExtension(i); if (string.IsNullOrEmpty(extension)) { return false; } return BaseItem.SupportedImageExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase); }) .ToList(); backdrops.AddRange(imageFiles); } }
/// <summary> /// Populates the screenshots. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateScreenshots(BaseItem item, ItemResolveArgs args) { // Screenshot Image var 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) { var hasScreenshots = item as IHasScreenshots; if (hasScreenshots != null) { hasScreenshots.ScreenshotImagePaths = screenshotFiles; } } }
/// <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"); // Support plex/xbmc convention if (image == null && item is Series) { image = GetImage(item, args, "show"); } // Support plex/xbmc convention if (image == null && item is Season && item.IndexNumber.HasValue) { var num = item.IndexNumber.Value.ToString(_usCulture); image = GetImage(item, args, string.Format("season-{0}", num)); } // Support plex/xbmc convention if (image == null && (item is Movie || item is MusicVideo || item is AdultVideo)) { image = GetImage(item, args, "movie"); } // 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"); // Support plex/xbmc convention if (image == null && item is Season && item.IndexNumber.HasValue) { var num = item.IndexNumber.Value.ToString(_usCulture); image = GetImage(item, args, string.Format("season-{0}-banner", num)); } 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") ?? GetImage(item, args, "cdart"); 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; } }
/// <summary> /// Populates the backdrops. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateBackdrops(BaseItem item, ItemResolveArgs args) { var backdropFiles = new List<string>(); PopulateBackdrops(item, args, backdropFiles, "backdrop", "backdrop"); // Support plex/xbmc conventions PopulateBackdrops(item, args, backdropFiles, "fanart", "fanart-"); PopulateBackdrops(item, args, backdropFiles, "background", "background-"); PopulateBackdrops(item, args, backdropFiles, "art", "art-"); if (backdropFiles.Count > 0) { item.BackdropImagePaths = backdropFiles; } }
/// <summary> /// Add files from the metadata folder to ResolveArgs /// </summary> /// <param name="args">The args.</param> public static void AddMetadataFiles(ItemResolveArgs args) { var folder = args.GetFileSystemEntryByName("metadata"); if (folder != null) { args.AddMetadataFiles(new DirectoryInfo(folder.FullName).EnumerateFiles()); } }
/// <summary> /// Populates the backdrops. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateBackdrops(BaseItem item, ItemResolveArgs args) { var isFileSystemItem = item.LocationType == LocationType.FileSystem; var backdropFiles = new List<string>(); PopulateBackdrops(item, args, backdropFiles, "backdrop", "backdrop"); // Support {name}-fanart.ext if (isFileSystemItem) { var name = Path.GetFileNameWithoutExtension(item.Path); if (!string.IsNullOrEmpty(name)) { var image = GetImage(item, args, name + "-fanart"); if (image != null) { backdropFiles.Add(image.FullName); } } } // Support plex/xbmc conventions PopulateBackdrops(item, args, backdropFiles, "fanart", "fanart-"); PopulateBackdrops(item, args, backdropFiles, "background", "background-"); PopulateBackdrops(item, args, backdropFiles, "art", "art-"); if (item is Season && item.IndexNumber.HasValue && isFileSystemItem) { var seasonMarker = item.IndexNumber.Value == 0 ? "-specials" : item.IndexNumber.Value.ToString("00", _usCulture); // Get this one directly from the file system since we have to go up a level var filename = "season" + seasonMarker + "-fanart"; var path = Path.GetDirectoryName(item.Path); path = Path.Combine(path, filename); var image = new FileInfo(path); if (image.Exists) { backdropFiles.Add(image.FullName); } } if (isFileSystemItem) { PopulateBackdropsFromExtraFanart(args, backdropFiles); } if (backdropFiles.Count > 0) { item.BackdropImagePaths = backdropFiles; } }
/// <summary> /// Populates the thumb. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> private void PopulateThumb(BaseItem item, ItemResolveArgs args) { // Thumbnail Image var image = GetImage(item, args, "thumb"); if (image == null) { // Supprt xbmc conventions if (item is Season && item.IndexNumber.HasValue && item.LocationType == LocationType.FileSystem) { var seasonMarker = item.IndexNumber.Value == 0 ? "-specials" : item.IndexNumber.Value.ToString("00", _usCulture); // Get this one directly from the file system since we have to go up a level var filename = "season" + seasonMarker + "-landscape"; var path = Path.GetDirectoryName(item.Path); path = Path.Combine(path, filename); image = new FileInfo(path); if (!image.Exists) { image = null; } } } if (image != null) { item.SetImage(ImageType.Thumb, image.FullName); } }
private void PopulatePrimaryImage(BaseItem item, ItemResolveArgs args) { // Primary Image var image = GetImage(item, args, "folder") ?? GetImage(item, args, "poster") ?? GetImage(item, args, "cover") ?? GetImage(item, args, "default"); // Support plex/xbmc convention if (image == null && item is Series) { image = GetImage(item, args, "show"); } var isFileSystemItem = item.LocationType == LocationType.FileSystem; // Support plex/xbmc convention if (image == null && item is Season && item.IndexNumber.HasValue && isFileSystemItem) { var seasonMarker = item.IndexNumber.Value == 0 ? "-specials" : item.IndexNumber.Value.ToString("00", _usCulture); // Get this one directly from the file system since we have to go up a level var filename = "season" + seasonMarker + "-poster"; var path = Path.GetDirectoryName(item.Path); path = Path.Combine(path, filename); image = new FileInfo(path); if (!image.Exists) { image = null; } } // Support plex/xbmc convention if (image == null && (item is Movie || item is MusicVideo || item is AdultVideo)) { image = GetImage(item, args, "movie"); } // Look for a file with the same name as the item if (image == null && isFileSystemItem) { var name = Path.GetFileNameWithoutExtension(item.Path); if (!string.IsNullOrEmpty(name)) { image = GetImage(item, args, name) ?? GetImage(item, args, name + "-poster"); } } if (image != null) { item.SetImage(ImageType.Primary, image.FullName); } }
/// <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 override FileSystemInfo GetImage(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension) { var location = GetLocation(item); return GetImageFromLocation(location, filenameWithoutExtension); }
/// <summary> /// Populates the backdrops. /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> /// <param name="backdropFiles">The backdrop files.</param> /// <param name="filename">The filename.</param> /// <param name="numberedSuffix">The numbered suffix.</param> private void PopulateBackdrops(BaseItem item, ItemResolveArgs args, List<string> backdropFiles, string filename, string numberedSuffix) { var image = GetImage(item, args, filename); if (image != null) { backdropFiles.Add(image.FullName); } var unfound = 0; for (var i = 1; i <= 20; i++) { // Backdrop Image image = GetImage(item, args, numberedSuffix + i); if (image != null) { backdropFiles.Add(image.FullName); } else { unfound++; if (unfound >= 3) { break; } } } }
protected override FileSystemInfo GetImage(BaseItem item, ItemResolveArgs args, string filenameWithoutExtension) { return item.ResolveArgs.PhysicalLocations .Select(i => GetImageFromLocation(i, filenameWithoutExtension)) .FirstOrDefault(i => i != null); }
/// <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; } // Sometimes these are marked hidden if (_fileSystem.IsRootPath(args.Path)) { return false; } return true; } if (args.IsDirectory) { // Ignore any folders in our list if (IgnoreFolders.Contains(filename, StringComparer.OrdinalIgnoreCase)) { 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(_fileSystem.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename) && _libraryManager.IsAudioFile(filename)) { return true; } } // Ignore samples var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase) .Replace("-", " ", StringComparison.OrdinalIgnoreCase) .Replace("_", " ", StringComparison.OrdinalIgnoreCase) .Replace("!", " ", StringComparison.OrdinalIgnoreCase); if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1) { return true; } } return false; }
/// <summary> /// 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; }
/// <summary> /// Ensures DateCreated and DateModified have values /// </summary> /// <param name="fileSystem">The file system.</param> /// <param name="item">The item.</param> /// <param name="args">The args.</param> /// <param name="includeCreationTime">if set to <c>true</c> [include creation time].</param> private static void EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args, bool includeCreationTime) { if (fileSystem == null) { throw new ArgumentNullException("fileSystem"); } if (item == null) { throw new ArgumentNullException("item"); } if (args == null) { throw new ArgumentNullException("args"); } // See if a different path came out of the resolver than what went in if (!string.Equals(args.Path, item.Path, StringComparison.OrdinalIgnoreCase)) { var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null; if (childData != null) { if (includeCreationTime) { SetDateCreated(item, fileSystem, childData); } item.DateModified = fileSystem.GetLastWriteTimeUtc(childData); } else { var fileData = fileSystem.GetFileSystemInfo(item.Path); if (fileData.Exists) { if (includeCreationTime) { SetDateCreated(item, fileSystem, fileData); } item.DateModified = fileSystem.GetLastWriteTimeUtc(fileData); } } } else { if (includeCreationTime) { SetDateCreated(item, fileSystem, args.FileInfo); } item.DateModified = fileSystem.GetLastWriteTimeUtc(args.FileInfo); } }
/// <summary> /// Equalses the specified args. /// </summary> /// <param name="args">The args.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> protected bool Equals(ItemResolveArgs args) { if (args != null) { if (args.Path == null && Path == null) return true; return args.Path != null && args.Path.Equals(Path, StringComparison.OrdinalIgnoreCase); } return false; }
/// <summary> /// Ensures DateCreated and DateModified have values /// </summary> /// <param name="item">The item.</param> /// <param name="args">The args.</param> public static void EnsureDates(BaseItem item, ItemResolveArgs args) { if (!Path.IsPathRooted(item.Path)) { return; } // See if a different path came out of the resolver than what went in if (!string.Equals(args.Path, item.Path, StringComparison.OrdinalIgnoreCase)) { var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null; if (childData != null) { item.DateCreated = childData.CreationTimeUtc; item.DateModified = childData.LastWriteTimeUtc; } else { var fileData = FileSystem.GetFileSystemInfo(item.Path); if (fileData.Exists) { item.DateCreated = fileData.CreationTimeUtc; item.DateModified = fileData.LastWriteTimeUtc; } } } else { item.DateCreated = args.FileInfo.CreationTimeUtc; item.DateModified = args.FileInfo.LastWriteTimeUtc; } }
/// <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); }