Merge pull request #2696 from mark-monteiro/fix-extras

Display Extras With Unknown Types
pull/2808/head
Vasily 5 years ago committed by GitHub
commit 5b59cd2eb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -505,7 +505,63 @@ namespace Emby.Naming.Common
RuleType = ExtraRuleType.Suffix, RuleType = ExtraRuleType.Suffix,
Token = "-short", Token = "-short",
MediaType = MediaType.Video MediaType = MediaType.Video
} },
new ExtraRule
{
ExtraType = ExtraType.BehindTheScenes,
RuleType = ExtraRuleType.DirectoryName,
Token = "behind the scenes",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.DeletedScene,
RuleType = ExtraRuleType.DirectoryName,
Token = "deleted scenes",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.Interview,
RuleType = ExtraRuleType.DirectoryName,
Token = "interviews",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.Scene,
RuleType = ExtraRuleType.DirectoryName,
Token = "scenes",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.Sample,
RuleType = ExtraRuleType.DirectoryName,
Token = "samples",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.Clip,
RuleType = ExtraRuleType.DirectoryName,
Token = "shorts",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.Clip,
RuleType = ExtraRuleType.DirectoryName,
Token = "featurettes",
MediaType = MediaType.Video,
},
new ExtraRule
{
ExtraType = ExtraType.Unknown,
RuleType = ExtraRuleType.DirectoryName,
Token = "extras",
MediaType = MediaType.Video,
},
}; };
Format3DRules = new[] Format3DRules = new[]

@ -80,6 +80,15 @@ namespace Emby.Naming.Video
result.Rule = rule; result.Rule = rule;
} }
} }
else if (rule.RuleType == ExtraRuleType.DirectoryName)
{
var directoryName = Path.GetFileName(Path.GetDirectoryName(path));
if (string.Equals(directoryName, rule.Token, StringComparison.OrdinalIgnoreCase))
{
result.ExtraType = rule.ExtraType;
result.Rule = rule;
}
}
return result; return result;
} }

@ -5,30 +5,29 @@ using MediaType = Emby.Naming.Common.MediaType;
namespace Emby.Naming.Video namespace Emby.Naming.Video
{ {
/// <summary>
/// A rule used to match a file path with an <see cref="MediaBrowser.Model.Entities.ExtraType"/>.
/// </summary>
public class ExtraRule public class ExtraRule
{ {
/// <summary> /// <summary>
/// Gets or sets the token. /// Gets or sets the token to use for matching against the file path.
/// </summary> /// </summary>
/// <value>The token.</value>
public string Token { get; set; } public string Token { get; set; }
/// <summary> /// <summary>
/// Gets or sets the type of the extra. /// Gets or sets the type of the extra to return when matched.
/// </summary> /// </summary>
/// <value>The type of the extra.</value>
public ExtraType ExtraType { get; set; } public ExtraType ExtraType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the type of the rule. /// Gets or sets the type of the rule.
/// </summary> /// </summary>
/// <value>The type of the rule.</value>
public ExtraRuleType RuleType { get; set; } public ExtraRuleType RuleType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the type of the media. /// Gets or sets the type of the media to return when matched.
/// </summary> /// </summary>
/// <value>The type of the media.</value>
public MediaType MediaType { get; set; } public MediaType MediaType { get; set; }
} }
} }

@ -5,18 +5,23 @@ namespace Emby.Naming.Video
public enum ExtraRuleType public enum ExtraRuleType
{ {
/// <summary> /// <summary>
/// The suffix /// Match <see cref="ExtraRule.Token"/> against a suffix in the file name.
/// </summary> /// </summary>
Suffix = 0, Suffix = 0,
/// <summary> /// <summary>
/// The filename /// Match <see cref="ExtraRule.Token"/> against the file name, excluding the file extension.
/// </summary> /// </summary>
Filename = 1, Filename = 1,
/// <summary> /// <summary>
/// The regex /// Match <see cref="ExtraRule.Token"/> against the file name, including the file extension.
/// </summary> /// </summary>
Regex = 2 Regex = 2,
/// <summary>
/// Match <see cref="ExtraRule.Token"/> against the name of the directory containing the file.
/// </summary>
DirectoryName = 3,
} }
} }

@ -1056,30 +1056,19 @@ namespace Emby.Server.Implementations.Dto
if (options.ContainsField(ItemFields.SpecialFeatureCount)) if (options.ContainsField(ItemFields.SpecialFeatureCount))
{ {
if (allExtras == null) allExtras = item.GetExtras().ToArray();
{
allExtras = item.GetExtras().ToArray();
}
dto.SpecialFeatureCount = allExtras.Count(i => i.ExtraType.HasValue && BaseItem.DisplayExtraTypes.Contains(i.ExtraType.Value)); dto.SpecialFeatureCount = allExtras.Count(i => i.ExtraType.HasValue && BaseItem.DisplayExtraTypes.Contains(i.ExtraType.Value));
} }
if (options.ContainsField(ItemFields.LocalTrailerCount)) if (options.ContainsField(ItemFields.LocalTrailerCount))
{ {
int trailerCount = 0; allExtras ??= item.GetExtras().ToArray();
if (allExtras == null) dto.LocalTrailerCount = allExtras.Count(i => i.ExtraType == ExtraType.Trailer);
{
allExtras = item.GetExtras().ToArray();
}
trailerCount += allExtras.Count(i => i.ExtraType.HasValue && i.ExtraType.Value == ExtraType.Trailer);
if (item is IHasTrailers hasTrailers) if (item is IHasTrailers hasTrailers)
{ {
trailerCount += hasTrailers.GetTrailerCount(); dto.LocalTrailerCount += hasTrailers.GetTrailerCount();
} }
dto.LocalTrailerCount = trailerCount;
} }
// Add EpisodeInfo // Add EpisodeInfo

@ -2609,14 +2609,12 @@ namespace Emby.Server.Implementations.Library
}).OrderBy(i => i.Path); }).OrderBy(i => i.Path);
} }
private static readonly string[] ExtrasSubfolderNames = new[] { "extras", "specials", "shorts", "scenes", "featurettes", "behind the scenes", "deleted scenes", "interviews" };
public IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) public IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{ {
var namingOptions = GetNamingOptions(); var namingOptions = GetNamingOptions();
var files = owner.IsInMixedFolder ? new List<FileSystemMetadata>() : fileSystemChildren.Where(i => i.IsDirectory) var files = owner.IsInMixedFolder ? new List<FileSystemMetadata>() : fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => ExtrasSubfolderNames.Contains(i.Name ?? string.Empty, StringComparer.OrdinalIgnoreCase)) .Where(i => BaseItem.AllExtrasTypesFolderNames.Contains(i.Name ?? string.Empty, StringComparer.OrdinalIgnoreCase))
.SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false)) .SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false))
.ToList(); .ToList();

@ -361,7 +361,8 @@ namespace MediaBrowser.Api.UserLibrary
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
var dtos = item.GetDisplayExtras() var dtos = item
.GetExtras(BaseItem.DisplayExtraTypes)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
return dtos.ToArray(); return dtos.ToArray();

@ -1326,8 +1326,9 @@ namespace MediaBrowser.Controller.Entities
} }
// Use some hackery to get the extra type based on foldername // Use some hackery to get the extra type based on foldername
Enum.TryParse(extraFolderName.Replace(" ", ""), true, out ExtraType extraType); item.ExtraType = Enum.TryParse(extraFolderName.Replace(" ", string.Empty), true, out ExtraType extraType)
item.ExtraType = extraType; ? extraType
: Model.Entities.ExtraType.Unknown;
return item; return item;
@ -2877,14 +2878,29 @@ namespace MediaBrowser.Controller.Entities
/// <value>The remote trailers.</value> /// <value>The remote trailers.</value>
public IReadOnlyList<MediaUrl> RemoteTrailers { get; set; } public IReadOnlyList<MediaUrl> RemoteTrailers { get; set; }
/// <summary>
/// Get all extras associated with this item, sorted by <see cref="SortName"/>.
/// </summary>
/// <returns>An enumerable containing the items.</returns>
public IEnumerable<BaseItem> GetExtras() public IEnumerable<BaseItem> GetExtras()
{ {
return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i != null).OrderBy(i => i.SortName); return ExtraIds
.Select(LibraryManager.GetItemById)
.Where(i => i != null)
.OrderBy(i => i.SortName);
} }
/// <summary>
/// Get all extras with specific types that are associated with this item.
/// </summary>
/// <param name="extraTypes">The types of extras to retrieve.</param>
/// <returns>An enumerable containing the extras.</returns>
public IEnumerable<BaseItem> GetExtras(IReadOnlyCollection<ExtraType> extraTypes) public IEnumerable<BaseItem> GetExtras(IReadOnlyCollection<ExtraType> extraTypes)
{ {
return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i?.ExtraType != null && extraTypes.Contains(i.ExtraType.Value)); return ExtraIds
.Select(LibraryManager.GetItemById)
.Where(i => i != null)
.Where(i => i.ExtraType.HasValue && extraTypes.Contains(i.ExtraType.Value));
} }
public IEnumerable<BaseItem> GetTrailers() public IEnumerable<BaseItem> GetTrailers()
@ -2895,11 +2911,6 @@ namespace MediaBrowser.Controller.Entities
return Array.Empty<BaseItem>(); return Array.Empty<BaseItem>();
} }
public IEnumerable<BaseItem> GetDisplayExtras()
{
return GetExtras(DisplayExtraTypes);
}
public virtual bool IsHD => Height >= 720; public virtual bool IsHD => Height >= 720;
public bool IsShortcut { get; set; } public bool IsShortcut { get; set; }
@ -2917,8 +2928,19 @@ namespace MediaBrowser.Controller.Entities
return RunTimeTicks ?? 0; return RunTimeTicks ?? 0;
} }
// Possible types of extra videos /// <summary>
public static readonly IReadOnlyCollection<ExtraType> DisplayExtraTypes = new[] { Model.Entities.ExtraType.BehindTheScenes, Model.Entities.ExtraType.Clip, Model.Entities.ExtraType.DeletedScene, Model.Entities.ExtraType.Interview, Model.Entities.ExtraType.Sample, Model.Entities.ExtraType.Scene }; /// Extra types that should be counted and displayed as "Special Features" in the UI.
/// </summary>
public static readonly IReadOnlyCollection<ExtraType> DisplayExtraTypes = new HashSet<ExtraType>
{
Model.Entities.ExtraType.Unknown,
Model.Entities.ExtraType.BehindTheScenes,
Model.Entities.ExtraType.Clip,
Model.Entities.ExtraType.DeletedScene,
Model.Entities.ExtraType.Interview,
Model.Entities.ExtraType.Sample,
Model.Entities.ExtraType.Scene
};
public virtual bool SupportsExternalTransfer => false; public virtual bool SupportsExternalTransfer => false;

@ -4,6 +4,7 @@ namespace MediaBrowser.Model.Entities
{ {
public enum ExtraType public enum ExtraType
{ {
Unknown = 0,
Clip = 1, Clip = 1,
Trailer = 2, Trailer = 2,
BehindTheScenes = 3, BehindTheScenes = 3,

Loading…
Cancel
Save