aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/BaseItem.cs
diff options
context:
space:
mode:
authorcvium <clausvium@gmail.com>2021-11-08 10:38:08 +0100
committercvium <clausvium@gmail.com>2021-11-08 10:38:08 +0100
commitf03e77a4d5fa0ca81ecb11f0ffc4c14706a6dd7d (patch)
tree06ae22d6e13ac26ab9dcb97e54591ad55654d3e1 /MediaBrowser.Controller/Entities/BaseItem.cs
parent153e9202397f236a4a415bd033c3b398b6e6573c (diff)
parent83859a1e6d96cbb60a3b43f7537c0ab0fbdff510 (diff)
Merge branch 'master' into TVFix
Diffstat (limited to 'MediaBrowser.Controller/Entities/BaseItem.cs')
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs218
1 files changed, 80 insertions, 138 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 3b182f7c9..63749b1f3 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
+using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
@@ -43,18 +44,10 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// The trailer folder name.
/// </summary>
- public const string TrailerFolderName = "trailers";
+ public const string TrailersFolderName = "trailers";
public const string ThemeSongsFolderName = "theme-music";
- public const string ThemeSongFilename = "theme";
+ public const string ThemeSongFileName = "theme";
public const string ThemeVideosFolderName = "backdrops";
- public const string ExtrasFolderName = "extras";
- public const string BehindTheScenesFolderName = "behind the scenes";
- public const string DeletedScenesFolderName = "deleted scenes";
- public const string InterviewFolderName = "interviews";
- public const string SceneFolderName = "scenes";
- public const string SampleFolderName = "samples";
- public const string ShortsFolderName = "shorts";
- public const string FeaturettesFolderName = "featurettes";
/// <summary>
/// The supported image extensions.
@@ -91,17 +84,19 @@ namespace MediaBrowser.Controller.Entities
Model.Entities.ExtraType.Scene
};
- public static readonly char[] SlugReplaceChars = { '?', '/', '&' };
- public static readonly string[] AllExtrasTypesFolderNames =
- {
- ExtrasFolderName,
- BehindTheScenesFolderName,
- DeletedScenesFolderName,
- InterviewFolderName,
- SceneFolderName,
- SampleFolderName,
- ShortsFolderName,
- FeaturettesFolderName
+ /// <summary>
+ /// The supported extra folder names and types. See <see cref="Emby.Naming.Common.NamingOptions" />.
+ /// </summary>
+ public static readonly Dictionary<string, ExtraType> AllExtrasTypesFolderNames = new Dictionary<string, ExtraType>(StringComparer.OrdinalIgnoreCase)
+ {
+ ["extras"] = MediaBrowser.Model.Entities.ExtraType.Unknown,
+ ["behind the scenes"] = MediaBrowser.Model.Entities.ExtraType.BehindTheScenes,
+ ["deleted scenes"] = MediaBrowser.Model.Entities.ExtraType.DeletedScene,
+ ["interviews"] = MediaBrowser.Model.Entities.ExtraType.Interview,
+ ["scenes"] = MediaBrowser.Model.Entities.ExtraType.Scene,
+ ["samples"] = MediaBrowser.Model.Entities.ExtraType.Sample,
+ ["shorts"] = MediaBrowser.Model.Entities.ExtraType.Clip,
+ ["featurettes"] = MediaBrowser.Model.Entities.ExtraType.Clip
};
private string _sortName;
@@ -357,11 +352,6 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- // if (IsOffline)
- // {
- // return LocationType.Offline;
- // }
-
var path = Path;
if (string.IsNullOrEmpty(path))
{
@@ -394,7 +384,7 @@ namespace MediaBrowser.Controller.Entities
}
[JsonIgnore]
- public bool IsFileProtocol => IsPathProtocol(MediaProtocol.File);
+ public bool IsFileProtocol => PathProtocol == MediaProtocol.File;
[JsonIgnore]
public bool HasPathProtocol => PathProtocol.HasValue;
@@ -586,14 +576,7 @@ namespace MediaBrowser.Controller.Entities
}
[JsonIgnore]
- public virtual Guid DisplayParentId
- {
- get
- {
- var parentId = ParentId;
- return parentId;
- }
- }
+ public virtual Guid DisplayParentId => ParentId;
[JsonIgnore]
public BaseItem DisplayParent
@@ -856,13 +839,6 @@ namespace MediaBrowser.Controller.Entities
return Id.ToString("N", CultureInfo.InvariantCulture);
}
- public bool IsPathProtocol(MediaProtocol protocol)
- {
- var current = PathProtocol;
-
- return current.HasValue && current.Value == protocol;
- }
-
private List<Tuple<StringBuilder, bool>> GetSortChunks(string s1)
{
var list = new List<Tuple<StringBuilder, bool>>();
@@ -990,7 +966,7 @@ namespace MediaBrowser.Controller.Entities
ReadOnlySpan<char> idString = Id.ToString("N", CultureInfo.InvariantCulture);
- return System.IO.Path.Join(basePath, "library", idString.Slice(0, 2), idString);
+ return System.IO.Path.Join(basePath, "library", idString[..2], idString);
}
/// <summary>
@@ -1305,8 +1281,7 @@ namespace MediaBrowser.Controller.Entities
terms.Add(item.Name);
}
- var video = item as Video;
- if (video != null)
+ if (item is Video video)
{
if (video.Video3DFormat.HasValue)
{
@@ -1341,7 +1316,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- return string.Join('/', terms.ToArray());
+ return string.Join('/', terms);
}
/// <summary>
@@ -1357,16 +1332,14 @@ namespace MediaBrowser.Controller.Entities
// Support plex/xbmc convention
files.AddRange(fileSystemChildren
- .Where(i => !i.IsDirectory && System.IO.Path.GetFileNameWithoutExtension(i.FullName.AsSpan()).Equals(ThemeSongFilename, StringComparison.OrdinalIgnoreCase)));
+ .Where(i => !i.IsDirectory && System.IO.Path.GetFileNameWithoutExtension(i.FullName.AsSpan()).Equals(ThemeSongFileName, StringComparison.OrdinalIgnoreCase)));
return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Audio.Audio>()
.Select(audio =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(audio.Id) as Audio.Audio;
-
- if (dbItem != null)
+ if (LibraryManager.GetItemById(audio.Id) is Audio.Audio dbItem)
{
audio = dbItem;
}
@@ -1416,39 +1389,24 @@ namespace MediaBrowser.Controller.Entities
protected virtual BaseItem[] LoadExtras(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
- var extras = new List<Video>();
-
- var libraryOptions = new LibraryOptions();
- var folders = fileSystemChildren.Where(i => i.IsDirectory).ToList();
- foreach (var extraFolderName in AllExtrasTypesFolderNames)
- {
- var files = folders
- .Where(i => string.Equals(i.Name, extraFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => FileSystem.GetFiles(i.FullName));
-
- // Re-using the same instance of LibraryOptions since it looks like it's never being altered.
- extras.AddRange(LibraryManager.ResolvePaths(files, directoryService, null, libraryOptions)
+ return fileSystemChildren
+ .Where(child => child.IsDirectory && AllExtrasTypesFolderNames.ContainsKey(child.Name))
+ .SelectMany(folder => LibraryManager
+ .ResolvePaths(FileSystem.GetFiles(folder.FullName), directoryService, null, new LibraryOptions())
.OfType<Video>()
- .Select(item =>
+ .Select(video =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
- if (LibraryManager.GetItemById(item.Id) is Video dbItem)
+ if (LibraryManager.GetItemById(video.Id) is Video dbItem)
{
- item = dbItem;
+ video = dbItem;
}
- // Use some hackery to get the extra type based on foldername
- item.ExtraType = Enum.TryParse(extraFolderName.Replace(" ", string.Empty, StringComparison.Ordinal), true, out ExtraType extraType)
- ? extraType
- : Model.Entities.ExtraType.Unknown;
-
- return item;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path));
- }
-
- return extras.ToArray();
+ video.ExtraType = AllExtrasTypesFolderNames[folder.Name];
+ return video;
+ })
+ .OrderBy(video => video.Path)) // Sort them so that the list can be easily compared for changes
+ .ToArray();
}
public Task RefreshMetadata(CancellationToken cancellationToken)
@@ -1588,8 +1546,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- var hasTrailers = this as IHasTrailers;
- if (hasTrailers != null)
+ if (this is IHasTrailers hasTrailers)
{
localTrailersChanged = await RefreshLocalTrailers(hasTrailers, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
}
@@ -2286,7 +2243,11 @@ namespace MediaBrowser.Controller.Entities
var existingImage = GetImageInfo(image.Type, index);
- if (existingImage != null)
+ if (existingImage == null)
+ {
+ AddImage(image);
+ }
+ else
{
existingImage.Path = image.Path;
existingImage.DateModified = image.DateModified;
@@ -2294,15 +2255,6 @@ namespace MediaBrowser.Controller.Entities
existingImage.Height = image.Height;
existingImage.BlurHash = image.BlurHash;
}
- else
- {
- var current = ImageInfos;
- var currentCount = current.Length;
- var newArr = new ItemImageInfo[currentCount + 1];
- current.CopyTo(newArr, 0);
- newArr[currentCount] = image;
- ImageInfos = newArr;
- }
}
public void SetImagePath(ImageType type, int index, FileSystemMetadata file)
@@ -2316,7 +2268,7 @@ namespace MediaBrowser.Controller.Entities
if (image == null)
{
- ImageInfos = ImageInfos.Concat(new[] { GetImageInfo(file, type) }).ToArray();
+ AddImage(GetImageInfo(file, type));
}
else
{
@@ -2360,14 +2312,24 @@ namespace MediaBrowser.Controller.Entities
public void RemoveImage(ItemImageInfo image)
{
- RemoveImages(new List<ItemImageInfo> { image });
+ RemoveImages(new[] { image });
}
- public void RemoveImages(List<ItemImageInfo> deletedImages)
+ public void RemoveImages(IEnumerable<ItemImageInfo> deletedImages)
{
ImageInfos = ImageInfos.Except(deletedImages).ToArray();
}
+ public void AddImage(ItemImageInfo image)
+ {
+ var current = ImageInfos;
+ var currentCount = current.Length;
+ var newArr = new ItemImageInfo[currentCount + 1];
+ current.CopyTo(newArr, 0);
+ newArr[currentCount] = image;
+ ImageInfos = newArr;
+ }
+
public virtual Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
=> LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken);
@@ -2391,7 +2353,7 @@ namespace MediaBrowser.Controller.Entities
if (deletedImages.Count > 0)
{
- ImageInfos = ImageInfos.Except(deletedImages).ToArray();
+ RemoveImages(deletedImages);
}
return deletedImages.Count > 0;
@@ -2439,6 +2401,17 @@ namespace MediaBrowser.Controller.Entities
};
}
+ // Music albums usually don't have dedicated backdrops, so return one from the artist instead
+ if (GetType() == typeof(MusicAlbum) && imageType == ImageType.Backdrop)
+ {
+ var artist = FindParent<MusicArtist>();
+
+ if (artist != null)
+ {
+ return artist.GetImages(imageType).ElementAtOrDefault(imageIndex);
+ }
+ }
+
return GetImages(imageType)
.ElementAtOrDefault(imageIndex);
}
@@ -2502,11 +2475,11 @@ namespace MediaBrowser.Controller.Entities
}
/// <summary>
- /// Adds the images.
+ /// Adds the images, updating metadata if they already are part of this item.
/// </summary>
/// <param name="imageType">Type of the image.</param>
/// <param name="images">The images.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
+ /// <returns><c>true</c> if images were added or updated, <c>false</c> otherwise.</returns>
/// <exception cref="ArgumentException">Cannot call AddImages with chapter images.</exception>
public bool AddImages(ImageType imageType, List<FileSystemMetadata> images)
{
@@ -2519,7 +2492,6 @@ namespace MediaBrowser.Controller.Entities
.ToList();
var newImageList = new List<FileSystemMetadata>();
- var imageAdded = false;
var imageUpdated = false;
foreach (var newImage in images)
@@ -2535,7 +2507,6 @@ namespace MediaBrowser.Controller.Entities
if (existing == null)
{
newImageList.Add(newImage);
- imageAdded = true;
}
else
{
@@ -2556,19 +2527,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- if (imageAdded || images.Count != existingImages.Count)
- {
- var newImagePaths = images.Select(i => i.FullName).ToList();
-
- var deleted = existingImages
- .FindAll(i => i.IsLocalFile && !newImagePaths.Contains(i.Path.AsSpan(), StringComparison.OrdinalIgnoreCase) && !File.Exists(i.Path));
-
- if (deleted.Count > 0)
- {
- ImageInfos = ImageInfos.Except(deleted).ToArray();
- }
- }
-
if (newImageList.Count > 0)
{
ImageInfos = ImageInfos.Concat(newImageList.Select(i => GetImageInfo(i, imageType))).ToArray();
@@ -2619,7 +2577,7 @@ namespace MediaBrowser.Controller.Entities
public bool AllowsMultipleImages(ImageType type)
{
- return type == ImageType.Backdrop || type == ImageType.Screenshot || type == ImageType.Chapter;
+ return type == ImageType.Backdrop || type == ImageType.Chapter;
}
public Task SwapImagesAsync(ImageType type, int index1, int index2)
@@ -2737,7 +2695,7 @@ namespace MediaBrowser.Controller.Entities
protected static string GetMappedPath(BaseItem item, string path, MediaProtocol? protocol)
{
- if (protocol.HasValue && protocol.Value == MediaProtocol.File)
+ if (protocol == MediaProtocol.File)
{
return LibraryManager.GetPathAfterNetworkSubstitution(path, item);
}
@@ -2765,8 +2723,10 @@ namespace MediaBrowser.Controller.Entities
protected Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
- var newOptions = new MetadataRefreshOptions(options);
- newOptions.SearchResult = null;
+ var newOptions = new MetadataRefreshOptions(options)
+ {
+ SearchResult = null
+ };
var item = this;
@@ -2827,8 +2787,10 @@ namespace MediaBrowser.Controller.Entities
protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
{
- var newOptions = new MetadataRefreshOptions(options);
- newOptions.SearchResult = null;
+ var newOptions = new MetadataRefreshOptions(options)
+ {
+ SearchResult = null
+ };
var id = LibraryManager.GetNewItemId(path, typeof(Video));
@@ -2842,14 +2804,6 @@ namespace MediaBrowser.Controller.Entities
newOptions.ForceSave = true;
}
- // var parentId = Id;
- // if (!video.IsOwnedItem || video.ParentId != parentId)
- // {
- // video.IsOwnedItem = true;
- // video.ParentId = parentId;
- // newOptions.ForceSave = true;
- // }
-
if (video == null)
{
return Task.FromResult(true);
@@ -2933,7 +2887,7 @@ namespace MediaBrowser.Controller.Entities
.Select(i => i.OfficialRating)
.Where(i => !string.IsNullOrEmpty(i))
.Distinct(StringComparer.OrdinalIgnoreCase)
- .Select(i => new Tuple<string, int?>(i, LocalizationManager.GetRatingLevel(i)))
+ .Select(i => (i, LocalizationManager.GetRatingLevel(i)))
.OrderBy(i => i.Item2 ?? 1000)
.Select(i => i.Item1);
@@ -2980,18 +2934,6 @@ namespace MediaBrowser.Controller.Entities
.Where(i => i.ExtraType.HasValue && extraTypes.Contains(i.ExtraType.Value));
}
- public IEnumerable<BaseItem> GetTrailers()
- {
- if (this is IHasTrailers)
- {
- return ((IHasTrailers)this).LocalTrailerIds.Select(LibraryManager.GetItemById).Where(i => i != null).OrderBy(i => i.SortName);
- }
- else
- {
- return Array.Empty<BaseItem>();
- }
- }
-
public virtual long GetRunTimeTicksForPlayState()
{
return RunTimeTicks ?? 0;
@@ -3004,7 +2946,7 @@ namespace MediaBrowser.Controller.Entities
}
/// <inheritdoc />
- public bool Equals(BaseItem other) => object.Equals(Id, other?.Id);
+ public bool Equals(BaseItem other) => Equals(Id, other?.Id);
/// <inheritdoc />
public override int GetHashCode() => HashCode.Combine(Id);