aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/BaseItem.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities/BaseItem.cs')
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs242
1 files changed, 140 insertions, 102 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 594b5ca93..ec688bd9f 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -23,6 +23,7 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Controller.Entities
{
@@ -38,7 +39,6 @@ namespace MediaBrowser.Controller.Entities
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LockedFields = new List<MetadataFields>();
ImageInfos = new List<ItemImageInfo>();
- Identities = new List<IItemIdentity>();
}
/// <summary>
@@ -56,12 +56,16 @@ namespace MediaBrowser.Controller.Entities
public static string ThemeSongFilename = "theme";
public static string ThemeVideosFolderName = "backdrops";
+ public string PreferredMetadataCountryCode { get; set; }
+ public string PreferredMetadataLanguage { get; set; }
+
public List<ItemImageInfo> ImageInfos { get; set; }
/// <summary>
/// Gets or sets the channel identifier.
/// </summary>
/// <value>The channel identifier.</value>
+ [IgnoreDataMember]
public string ChannelId { get; set; }
[IgnoreDataMember]
@@ -121,6 +125,12 @@ namespace MediaBrowser.Controller.Entities
public Guid Id { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether this instance is hd.
+ /// </summary>
+ /// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value>
+ public bool? IsHD { get; set; }
+
+ /// <summary>
/// Return the id that should be used to key display prefs for this item.
/// Default is based on the type for everything except actual generic folders.
/// </summary>
@@ -162,6 +172,26 @@ namespace MediaBrowser.Controller.Entities
}
}
+ /// <summary>
+ /// Id of the program.
+ /// </summary>
+ [IgnoreDataMember]
+ public string ExternalId
+ {
+ get { return this.GetProviderId("ProviderExternalId"); }
+ set
+ {
+ this.SetProviderId("ProviderExternalId", value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the etag.
+ /// </summary>
+ /// <value>The etag.</value>
+ [IgnoreDataMember]
+ public string ExternalEtag { get; set; }
+
[IgnoreDataMember]
public virtual bool IsHidden
{
@@ -183,7 +213,7 @@ namespace MediaBrowser.Controller.Entities
{
// Local trailer, special feature, theme video, etc.
// An item that belongs to another item but is not part of the Parent-Child tree
- return !IsFolder && Parent == null && LocationType == LocationType.FileSystem;
+ return !IsFolder && ParentId == Guid.Empty && LocationType == LocationType.FileSystem;
}
}
@@ -305,6 +335,9 @@ namespace MediaBrowser.Controller.Entities
public DateTime DateLastSaved { get; set; }
+ [IgnoreDataMember]
+ public DateTime DateLastRefreshed { get; set; }
+
/// <summary>
/// The logger
/// </summary>
@@ -331,30 +364,8 @@ namespace MediaBrowser.Controller.Entities
return Name;
}
- /// <summary>
- /// Returns true if this item should not attempt to fetch metadata
- /// </summary>
- /// <value><c>true</c> if [dont fetch meta]; otherwise, <c>false</c>.</value>
- [Obsolete("Please use IsLocked instead of DontFetchMeta")]
- public bool DontFetchMeta { get; set; }
-
- [IgnoreDataMember]
- public bool IsLocked
- {
- get
- {
- return DontFetchMeta;
- }
- set
- {
- DontFetchMeta = value;
- }
- }
-
- public bool IsUnidentified { get; set; }
-
[IgnoreDataMember]
- public List<IItemIdentity> Identities { get; set; }
+ public bool IsLocked { get; set; }
/// <summary>
/// Gets or sets the locked fields.
@@ -484,7 +495,6 @@ namespace MediaBrowser.Controller.Entities
public Guid ParentId { get; set; }
- private Folder _parent;
/// <summary>
/// Gets or sets the parent.
/// </summary>
@@ -494,11 +504,6 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (_parent != null)
- {
- return _parent;
- }
-
if (ParentId != Guid.Empty)
{
return LibraryManager.GetItemById(ParentId) as Folder;
@@ -506,12 +511,14 @@ namespace MediaBrowser.Controller.Entities
return null;
}
- set { _parent = value; }
+ set
+ {
+
+ }
}
public void SetParent(Folder parent)
{
- Parent = parent;
ParentId = parent == null ? Guid.Empty : parent.Id;
}
@@ -558,6 +565,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the end date.
/// </summary>
/// <value>The end date.</value>
+ [IgnoreDataMember]
public DateTime? EndDate { get; set; }
/// <summary>
@@ -582,6 +590,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the custom rating.
/// </summary>
/// <value>The custom rating.</value>
+ //[IgnoreDataMember]
public string CustomRating { get; set; }
/// <summary>
@@ -591,12 +600,6 @@ namespace MediaBrowser.Controller.Entities
public string Overview { get; set; }
/// <summary>
- /// Gets or sets the people.
- /// </summary>
- /// <value>The people.</value>
- public List<PersonInfo> People { get; set; }
-
- /// <summary>
/// Gets or sets the studios.
/// </summary>
/// <value>The studios.</value>
@@ -618,6 +621,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the community rating.
/// </summary>
/// <value>The community rating.</value>
+ //[IgnoreDataMember]
public float? CommunityRating { get; set; }
/// <summary>
@@ -643,6 +647,7 @@ namespace MediaBrowser.Controller.Entities
/// This could be episode number, album track number, etc.
/// </summary>
/// <value>The index number.</value>
+ //[IgnoreDataMember]
public int? IndexNumber { get; set; }
/// <summary>
@@ -662,7 +667,7 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (!string.IsNullOrEmpty(CustomRating))
+ if (!string.IsNullOrWhiteSpace(CustomRating))
{
return CustomRating;
}
@@ -701,16 +706,16 @@ namespace MediaBrowser.Controller.Entities
/// Loads the theme songs.
/// </summary>
/// <returns>List{Audio.Audio}.</returns>
- private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
+ private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
- var files = fileSystemChildren.OfType<DirectoryInfo>()
+ var files = fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
+ .SelectMany(i => directoryService.GetFiles(i.FullName))
.ToList();
// Support plex/xbmc convention
- files.AddRange(fileSystemChildren.OfType<FileInfo>()
- .Where(i => string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
+ files.AddRange(fileSystemChildren
+ .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
);
return LibraryManager.ResolvePaths(files, directoryService, null)
@@ -737,11 +742,11 @@ namespace MediaBrowser.Controller.Entities
/// Loads the video backdrops.
/// </summary>
/// <returns>List{Video}.</returns>
- private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
+ private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
- var files = fileSystemChildren.OfType<DirectoryInfo>()
+ var files = fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly));
+ .SelectMany(i => directoryService.GetFiles(i.FullName));
return LibraryManager.ResolvePaths(files, directoryService, null)
.OfType<Video>()
@@ -765,7 +770,7 @@ namespace MediaBrowser.Controller.Entities
public Task RefreshMetadata(CancellationToken cancellationToken)
{
- return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService()), cancellationToken);
+ return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
}
/// <summary>
@@ -786,7 +791,7 @@ namespace MediaBrowser.Controller.Entities
{
var files = locationType != LocationType.Remote && locationType != LocationType.Virtual ?
GetFileSystemChildren(options.DirectoryService).ToList() :
- new List<FileSystemInfo>();
+ new List<FileSystemMetadata>();
var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false);
@@ -833,7 +838,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="fileSystemChildren"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
- protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var themeSongsChanged = false;
@@ -864,14 +869,14 @@ namespace MediaBrowser.Controller.Entities
return themeSongsChanged || themeVideosChanged || localTrailersChanged;
}
- protected virtual IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
+ protected virtual IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{
var path = ContainingFolderPath;
return directoryService.GetFileSystemEntries(path);
}
- private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newItems = LibraryManager.FindTrailers(this, fileSystemChildren, options.DirectoryService).ToList();
@@ -888,7 +893,7 @@ namespace MediaBrowser.Controller.Entities
return itemsChanged;
}
- private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList();
@@ -902,7 +907,7 @@ namespace MediaBrowser.Controller.Entities
if (!i.IsThemeMedia)
{
- i.IsThemeMedia = true;
+ i.ExtraType = ExtraType.ThemeVideo;
subOptions.ForceSave = true;
}
@@ -919,7 +924,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Refreshes the theme songs.
/// </summary>
- private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList();
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList();
@@ -932,7 +937,7 @@ namespace MediaBrowser.Controller.Entities
if (!i.IsThemeMedia)
{
- i.IsThemeMedia = true;
+ i.ExtraType = ExtraType.ThemeSong;
subOptions.ForceSave = true;
}
@@ -999,18 +1004,11 @@ namespace MediaBrowser.Controller.Entities
/// <returns>System.String.</returns>
public string GetPreferredMetadataLanguage()
{
- string lang = null;
-
- var hasLang = this as IHasPreferredMetadataLanguage;
-
- if (hasLang != null)
- {
- lang = hasLang.PreferredMetadataLanguage;
- }
+ string lang = PreferredMetadataLanguage;
if (string.IsNullOrWhiteSpace(lang))
{
- lang = Parents.OfType<IHasPreferredMetadataLanguage>()
+ lang = Parents
.Select(i => i.PreferredMetadataLanguage)
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
@@ -1036,18 +1034,11 @@ namespace MediaBrowser.Controller.Entities
/// <returns>System.String.</returns>
public string GetPreferredMetadataCountryCode()
{
- string lang = null;
-
- var hasLang = this as IHasPreferredMetadataLanguage;
-
- if (hasLang != null)
- {
- lang = hasLang.PreferredMetadataCountryCode;
- }
+ string lang = PreferredMetadataCountryCode;
if (string.IsNullOrWhiteSpace(lang))
{
- lang = Parents.OfType<IHasPreferredMetadataLanguage>()
+ lang = Parents
.Select(i => i.PreferredMetadataCountryCode)
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
@@ -1114,7 +1105,14 @@ namespace MediaBrowser.Controller.Entities
// Could not determine the integer value
if (!value.HasValue)
{
- return true;
+ var isAllowed = !GetBlockUnratedValue(user.Policy);
+
+ if (!isAllowed)
+ {
+ Logger.Debug("{0} has an unrecognized parental rating of {1}.", Name, rating);
+ }
+
+ return isAllowed;
}
return value.Value <= maxAllowedRating.Value;
@@ -1165,6 +1163,17 @@ namespace MediaBrowser.Controller.Entities
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
protected virtual bool GetBlockUnratedValue(UserPolicy config)
{
+ // Don't block plain folders that are unrated. Let the media underneath get blocked
+ // Special folders like series and albums will override this method.
+ if (IsFolder)
+ {
+ return false;
+ }
+ if (this is IItemByName)
+ {
+ return false;
+ }
+
return config.BlockUnratedItems.Contains(UnratedItem.Other);
}
@@ -1418,7 +1427,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns>
public virtual Task ChangedExternally()
{
- ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions());
+ ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(FileSystem));
return Task.FromResult(true);
}
@@ -1434,7 +1443,24 @@ namespace MediaBrowser.Controller.Entities
return GetImageInfo(type, imageIndex) != null;
}
- public void SetImagePath(ImageType type, int index, FileSystemInfo file)
+ public void SetImage(ItemImageInfo image, int index)
+ {
+ if (image.Type == ImageType.Chapter)
+ {
+ throw new ArgumentException("Cannot set chapter images using SetImagePath");
+ }
+
+ var existingImage = GetImageInfo(image.Type, index);
+
+ if (existingImage != null)
+ {
+ ImageInfos.Remove(existingImage);
+ }
+
+ ImageInfos.Add(image);
+ }
+
+ public void SetImagePath(ImageType type, int index, FileSystemMetadata file)
{
if (type == ImageType.Chapter)
{
@@ -1475,18 +1501,21 @@ namespace MediaBrowser.Controller.Entities
// Remove it from the item
RemoveImage(info);
- // Delete the source file
- var currentFile = new FileInfo(info.Path);
-
- // Deletion will fail if the file is hidden so remove the attribute first
- if (currentFile.Exists)
+ if (info.IsLocalFile)
{
- if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ // Delete the source file
+ var currentFile = new FileInfo(info.Path);
+
+ // Deletion will fail if the file is hidden so remove the attribute first
+ if (currentFile.Exists)
{
- currentFile.Attributes &= ~FileAttributes.Hidden;
- }
+ if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ {
+ currentFile.Attributes &= ~FileAttributes.Hidden;
+ }
- FileSystem.DeleteFile(currentFile.FullName);
+ FileSystem.DeleteFile(currentFile.FullName);
+ }
}
return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
@@ -1507,11 +1536,16 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public bool ValidateImages(IDirectoryService directoryService)
{
- var allDirectories = ImageInfos.Select(i => System.IO.Path.GetDirectoryName(i.Path)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
- var allFiles = allDirectories.SelectMany(directoryService.GetFiles).Select(i => i.FullName).ToList();
+ var allFiles = ImageInfos
+ .Where(i => i.IsLocalFile)
+ .Select(i => System.IO.Path.GetDirectoryName(i.Path))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .SelectMany(directoryService.GetFiles)
+ .Select(i => i.FullName)
+ .ToList();
var deletedImages = ImageInfos
- .Where(image => !allFiles.Contains(image.Path, StringComparer.OrdinalIgnoreCase))
+ .Where(image => image.IsLocalFile && !allFiles.Contains(image.Path, StringComparer.OrdinalIgnoreCase))
.ToList();
if (deletedImages.Count > 0)
@@ -1584,11 +1618,6 @@ namespace MediaBrowser.Controller.Entities
return ImageInfos.Where(i => i.Type == imageType);
}
- public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images)
- {
- return AddImages(imageType, images.Cast<FileSystemInfo>().ToList());
- }
-
/// <summary>
/// Adds the images.
/// </summary>
@@ -1596,7 +1625,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="images">The images.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
/// <exception cref="System.ArgumentException">Cannot call AddImages with chapter images</exception>
- public bool AddImages(ImageType imageType, List<FileSystemInfo> images)
+ public bool AddImages(ImageType imageType, List<FileSystemMetadata> images)
{
if (imageType == ImageType.Chapter)
{
@@ -1606,7 +1635,7 @@ namespace MediaBrowser.Controller.Entities
var existingImages = GetImages(imageType)
.ToList();
- var newImageList = new List<FileSystemInfo>();
+ var newImageList = new List<FileSystemMetadata>();
var imageAdded = false;
foreach (var newImage in images)
@@ -1626,7 +1655,10 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
+ if (existing.IsLocalFile)
+ {
+ existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
+ }
}
}
@@ -1635,7 +1667,7 @@ namespace MediaBrowser.Controller.Entities
var newImagePaths = images.Select(i => i.FullName).ToList();
var deleted = existingImages
- .Where(i => !newImagePaths.Contains(i.Path, StringComparer.OrdinalIgnoreCase) && !File.Exists(i.Path))
+ .Where(i => i.IsLocalFile && !newImagePaths.Contains(i.Path, StringComparer.OrdinalIgnoreCase) && !FileSystem.FileExists(i.Path))
.ToList();
ImageInfos = ImageInfos.Except(deleted).ToList();
@@ -1646,7 +1678,7 @@ namespace MediaBrowser.Controller.Entities
return newImageList.Count > 0;
}
- private ItemImageInfo GetImageInfo(FileSystemInfo file, ImageType type)
+ private ItemImageInfo GetImageInfo(FileSystemMetadata file, ImageType type)
{
return new ItemImageInfo
{
@@ -1686,6 +1718,12 @@ namespace MediaBrowser.Controller.Entities
return Task.FromResult(true);
}
+ if (!info1.IsLocalFile || !info2.IsLocalFile)
+ {
+ // TODO: Not supported yet
+ return Task.FromResult(true);
+ }
+
var path1 = info1.Path;
var path2 = info2.Path;
@@ -1769,7 +1807,7 @@ namespace MediaBrowser.Controller.Entities
{
foreach (var map in ConfigurationManager.Configuration.PathSubstitutions)
{
- path = FileSystem.SubstitutePath(path, map.From, map.To);
+ path = LibraryManager.SubstitutePath(path, map.From, map.To);
}
}
@@ -1810,7 +1848,7 @@ namespace MediaBrowser.Controller.Entities
if (video == null)
{
- video = LibraryManager.ResolvePath(new FileInfo(path)) as Video;
+ video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
newOptions.ForceSave = true;
}