diff options
Diffstat (limited to 'MediaBrowser.Controller/Entities')
28 files changed, 354 insertions, 311 deletions
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index efc450248..7b769deb3 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -34,11 +34,26 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool IsPhysicalRoot + { + get { return true; } + } + public override bool CanDelete() { return false; } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + /// <summary> /// The _virtual children /// </summary> diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 1af55a389..56c3248f3 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -23,8 +23,7 @@ namespace MediaBrowser.Controller.Entities.Audio IHasMusicGenres, IHasLookupInfo<SongInfo>, IHasMediaSources, - IThemeMedia, - IArchivable + IThemeMedia { public List<ChannelMediaInfo> ChannelMediaSources { get; set; } @@ -61,9 +60,18 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return true; + } + } + + [IgnoreDataMember] public override bool SupportsAddingToPlaylist { - get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } + get { return true; } } [IgnoreDataMember] @@ -84,21 +92,6 @@ namespace MediaBrowser.Controller.Entities.Audio } } - [IgnoreDataMember] - public bool IsArchive - { - get - { - if (string.IsNullOrWhiteSpace(Path)) - { - return false; - } - var ext = System.IO.Path.GetExtension(Path) ?? string.Empty; - - return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase); - } - } - public override bool CanDownload() { var locationType = LocationType; @@ -262,7 +255,7 @@ namespace MediaBrowser.Controller.Entities.Audio Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File, MediaStreams = MediaSourceManager.GetMediaStreams(i.Id).ToList(), Name = i.Name, - Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path, + Path = enablePathSubstituion ? GetMappedPath(i, i.Path, locationType) : i.Path, RunTimeTicks = i.RunTimeTicks, Container = i.Container, Size = i.Size diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 1f3b0c92a..3f457d89a 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -17,6 +17,9 @@ namespace MediaBrowser.Controller.Entities.Audio /// </summary> public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer { + public List<string> AlbumArtists { get; set; } + public List<string> Artists { get; set; } + public MusicAlbum() { Artists = new List<string>(); @@ -49,6 +52,15 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + + [IgnoreDataMember] public override bool SupportsCumulativeRunTimeTicks { get @@ -83,8 +95,6 @@ namespace MediaBrowser.Controller.Entities.Audio get { return false; } } - public List<string> AlbumArtists { get; set; } - /// <summary> /// Gets the tracks. /// </summary> @@ -103,8 +113,6 @@ namespace MediaBrowser.Controller.Entities.Audio return Tracks; } - public List<string> Artists { get; set; } - public override List<string> GetUserDataKeys() { var list = base.GetUserDataKeys(); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 81d1deaa2..a31f04fc4 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// <summary> /// Class MusicArtist /// </summary> - public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasProductionLocations, IHasLookupInfo<ArtistInfo> + public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo> { [IgnoreDataMember] public bool IsAccessedByName @@ -24,8 +24,6 @@ namespace MediaBrowser.Controller.Entities.Audio get { return ParentId == Guid.Empty; } } - public List<string> ProductionLocations { get; set; } - [IgnoreDataMember] public override bool IsFolder { @@ -50,6 +48,15 @@ namespace MediaBrowser.Controller.Entities.Audio get { return true; } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + public override bool CanDelete() { return !IsAccessedByName; @@ -111,11 +118,6 @@ namespace MediaBrowser.Controller.Entities.Audio return base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService); } - public MusicArtist() - { - ProductionLocations = new List<string>(); - } - public override List<string> GetUserDataKeys() { var list = base.GetUserDataKeys(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 55aaf04ff..7eb84fc80 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -37,6 +37,8 @@ namespace MediaBrowser.Controller.Entities { protected BaseItem() { + ThemeSongIds = new List<Guid>(); + ThemeVideoIds = new List<Guid>(); Keywords = new List<string>(); Tags = new List<string>(); Genres = new List<string>(); @@ -44,6 +46,8 @@ namespace MediaBrowser.Controller.Entities ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); LockedFields = new List<MetadataFields>(); ImageInfos = new List<ItemImageInfo>(); + InheritedTags = new List<string>(); + ProductionLocations = new List<string>(); } public static readonly char[] SlugReplaceChars = { '?', '/', '&' }; @@ -64,6 +68,9 @@ namespace MediaBrowser.Controller.Entities public static string ThemeSongFilename = "theme"; public static string ThemeVideosFolderName = "backdrops"; + public List<Guid> ThemeSongIds { get; set; } + public List<Guid> ThemeVideoIds { get; set; } + [IgnoreDataMember] public string PreferredMetadataCountryCode { get; set; } [IgnoreDataMember] @@ -72,6 +79,8 @@ namespace MediaBrowser.Controller.Entities public long? Size { get; set; } public string Container { get; set; } public string ShortOverview { get; set; } + [IgnoreDataMember] + public string Tagline { get; set; } public List<ItemImageInfo> ImageInfos { get; set; } @@ -115,6 +124,31 @@ namespace MediaBrowser.Controller.Entities public bool IsInMixedFolder { get; set; } [IgnoreDataMember] + protected virtual bool SupportsIsInMixedFolderDetection + { + get { return false; } + } + + [IgnoreDataMember] + public virtual bool SupportsPlayedStatus + { + get + { + return false; + } + } + + public bool DetectIsInMixedFolder() + { + if (SupportsIsInMixedFolderDetection) + { + + } + + return IsInMixedFolder; + } + + [IgnoreDataMember] public virtual bool SupportsRemoteImageDownloading { get @@ -254,6 +288,19 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public string ExternalSeriesId { get; set; } + + [IgnoreDataMember] + public string ExternalSeriesIdLegacy + { + get { return this.GetProviderId("ProviderExternalSeriesId"); } + set + { + this.SetProviderId("ProviderExternalSeriesId", value); + } + } + /// <summary> /// Gets or sets the etag. /// </summary> @@ -408,7 +455,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsInternetMetadataEnabled() { - return ConfigurationManager.Configuration.EnableInternetProviders; + return LibraryManager.GetLibraryOptions(this).EnableInternetProviders; } public virtual bool CanDelete() @@ -784,6 +831,9 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public int InheritedParentalRatingValue { get; set; } + [IgnoreDataMember] + public List<string> InheritedTags { get; set; } + /// <summary> /// Gets or sets the critic rating. /// </summary> @@ -841,6 +891,7 @@ namespace MediaBrowser.Controller.Entities public List<string> Tags { get; set; } public List<string> Keywords { get; set; } + public List<string> ProductionLocations { get; set; } /// <summary> /// Gets or sets the home page URL. @@ -956,7 +1007,7 @@ namespace MediaBrowser.Controller.Entities /// Loads the theme songs. /// </summary> /// <returns>List{Audio.Audio}.</returns> - private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) + private static IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) { var files = fileSystemChildren.Where(i => i.IsDirectory) .Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase)) @@ -992,7 +1043,7 @@ namespace MediaBrowser.Controller.Entities /// Loads the video backdrops. /// </summary> /// <returns>List{Video}.</returns> - private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) + private static IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) { var files = fileSystemChildren.Where(i => i.IsDirectory) .Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase)) @@ -1078,6 +1129,12 @@ namespace MediaBrowser.Controller.Entities get { return true; } } + [IgnoreDataMember] + public virtual bool SupportsThemeMedia + { + get { return false; } + } + /// <summary> /// Refreshes owned items such as trailers, theme videos, special features, etc. /// Returns true or false indicating if changes were found. @@ -1096,14 +1153,13 @@ namespace MediaBrowser.Controller.Entities if (LocationType == LocationType.FileSystem && GetParent() != null) { - var hasThemeMedia = this as IHasThemeMedia; - if (hasThemeMedia != null) + if (SupportsThemeMedia) { - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { - themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + themeSongsChanged = await RefreshThemeSongs(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); - themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + themeVideosChanged = await RefreshThemeVideos(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); } } @@ -1141,7 +1197,7 @@ namespace MediaBrowser.Controller.Entities return itemsChanged; } - private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) + private static async Task<bool> RefreshThemeVideos(BaseItem item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) { var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList(); @@ -1172,7 +1228,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Refreshes the theme songs. /// </summary> - private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) + private static async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) { var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList(); var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList(); @@ -1249,7 +1305,15 @@ namespace MediaBrowser.Controller.Entities { var current = this; - return current.IsInMixedFolder == newItem.IsInMixedFolder; + if (!SupportsIsInMixedFolderDetection) + { + if (current.IsInMixedFolder != newItem.IsInMixedFolder) + { + return false; + } + } + + return true; } public void AfterMetadataRefresh() @@ -1324,7 +1388,9 @@ namespace MediaBrowser.Controller.Entities return false; } - return ConfigurationManager.Configuration.SaveLocalMeta; + var libraryOptions = LibraryManager.GetLibraryOptions(this); + + return libraryOptions.SaveLocalMetadata; } /// <summary> @@ -2107,14 +2173,11 @@ namespace MediaBrowser.Controller.Entities return hasChanges; } - protected static string GetMappedPath(string path, LocationType locationType) + protected static string GetMappedPath(BaseItem item, string path, LocationType locationType) { if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) { - foreach (var map in ConfigurationManager.Configuration.PathSubstitutions) - { - path = LibraryManager.SubstitutePath(path, map.From, map.To); - } + return LibraryManager.GetPathAfterNetworkSubstitution(path, item); } return path; diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 30ea26eb6..41e277b7c 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -38,6 +38,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + public override bool CanDelete() { return false; @@ -48,24 +57,14 @@ namespace MediaBrowser.Controller.Entities private static readonly Dictionary<string, LibraryOptions> LibraryOptions = new Dictionary<string, LibraryOptions>(); public LibraryOptions GetLibraryOptions() { - lock (LibraryOptions) - { - LibraryOptions options; - if (!LibraryOptions.TryGetValue(Path, out options)) - { - options = LoadLibraryOptions(); - LibraryOptions[Path] = options; - } - - return options; - } + return GetLibraryOptions(Path); } - private LibraryOptions LoadLibraryOptions() + private static LibraryOptions LoadLibraryOptions(string path) { try { - var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(Path)) as LibraryOptions; + var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) as LibraryOptions; if (result == null) { @@ -100,13 +99,28 @@ namespace MediaBrowser.Controller.Entities SaveLibraryOptions(Path, options); } + public static LibraryOptions GetLibraryOptions(string path) + { + lock (LibraryOptions) + { + LibraryOptions options; + if (!LibraryOptions.TryGetValue(path, out options)) + { + options = LoadLibraryOptions(path); + LibraryOptions[path] = options; + } + + return options; + } + } + public static void SaveLibraryOptions(string path, LibraryOptions options) { lock (LibraryOptions) { LibraryOptions[path] = options; - options.SchemaVersion = 2; + options.SchemaVersion = 3; XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index f1d8def4b..1e466ec08 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -22,13 +22,18 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Class Folder /// </summary> - public class Folder : BaseItem, IHasThemeMedia + public class Folder : BaseItem { public static IUserManager UserManager { get; set; } public static IUserViewManager UserViewManager { get; set; } - public List<Guid> ThemeSongIds { get; set; } - public List<Guid> ThemeVideoIds { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is root. + /// </summary> + /// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value> + public bool IsRoot { get; set; } + + public virtual List<LinkedChild> LinkedChildren { get; set; } [IgnoreDataMember] public DateTime? DateLastMediaAdded { get; set; } @@ -36,9 +41,12 @@ namespace MediaBrowser.Controller.Entities public Folder() { LinkedChildren = new List<LinkedChild>(); + } - ThemeSongIds = new List<Guid>(); - ThemeVideoIds = new List<Guid>(); + [IgnoreDataMember] + public override bool SupportsThemeMedia + { + get { return true; } } [IgnoreDataMember] @@ -47,6 +55,21 @@ namespace MediaBrowser.Controller.Entities get { return false; } } + [IgnoreDataMember] + public virtual bool IsPhysicalRoot + { + get { return false; } + } + + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return true; + } + } + /// <summary> /// Gets a value indicating whether this instance is folder. /// </summary> @@ -117,19 +140,6 @@ namespace MediaBrowser.Controller.Entities return true; } - /// <summary> - /// Gets or sets a value indicating whether this instance is physical root. - /// </summary> - /// <value><c>true</c> if this instance is physical root; otherwise, <c>false</c>.</value> - public bool IsPhysicalRoot { get; set; } - /// <summary> - /// Gets or sets a value indicating whether this instance is root. - /// </summary> - /// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value> - public bool IsRoot { get; set; } - - public virtual List<LinkedChild> LinkedChildren { get; set; } - [IgnoreDataMember] protected virtual bool SupportsShortcutChildren { @@ -178,8 +188,6 @@ namespace MediaBrowser.Controller.Entities item.SetParent(null); } - #region Indexing - /// <summary> /// Returns the valid set of index by options for this folder type. /// Override or extend to modify. @@ -207,8 +215,6 @@ namespace MediaBrowser.Controller.Entities get { return GetIndexByOptions(); } } - #endregion - /// <summary> /// Gets the actual children. /// </summary> @@ -801,18 +807,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.HasThemeSong.HasValue) - { - Logger.Debug("Query requires post-filtering due to HasThemeSong"); - return true; - } - - if (query.HasThemeVideo.HasValue) - { - Logger.Debug("Query requires post-filtering due to HasThemeVideo"); - return true; - } - // Filter by VideoType if (query.VideoTypes.Length > 0) { @@ -1149,29 +1143,19 @@ namespace MediaBrowser.Controller.Entities return LinkedChildren .Select(i => { - var requiresPostFilter = true; - - if (!string.IsNullOrWhiteSpace(i.Path)) - { - requiresPostFilter = false; - - if (!locations.Any(l => FileSystem.ContainsSubPath(l, i.Path))) - { - return null; - } - } - var child = GetLinkedChild(i); - if (requiresPostFilter && child != null) + if (child != null) { - if (string.IsNullOrWhiteSpace(child.Path)) + var childLocationType = child.LocationType; + if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual) { - Logger.Debug("Found LinkedChild with null path: {0}", child.Name); - return child; + if (!child.IsVisibleStandalone(user)) + { + return null; + } } - - if (!locations.Any(l => FileSystem.ContainsSubPath(l, child.Path))) + else if (childLocationType == LocationType.FileSystem && !locations.Any(l => FileSystem.ContainsSubPath(l, child.Path))) { return null; } diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index 24910498f..aa2ccf4bc 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -8,19 +8,14 @@ using System.Runtime.Serialization; namespace MediaBrowser.Controller.Entities { - public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo> + public class Game : BaseItem, IHasTrailers, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo> { - public List<Guid> ThemeSongIds { get; set; } - public List<Guid> ThemeVideoIds { get; set; } - public Game() { MultiPartGameFiles = new List<string>(); RemoteTrailers = new List<MediaUrl>(); LocalTrailerIds = new List<Guid>(); RemoteTrailerIds = new List<Guid>(); - ThemeSongIds = new List<Guid>(); - ThemeVideoIds = new List<Guid>(); } public List<Guid> LocalTrailerIds { get; set; } @@ -39,6 +34,12 @@ namespace MediaBrowser.Controller.Entities get { return true; } } + [IgnoreDataMember] + public override bool SupportsThemeMedia + { + get { return true; } + } + /// <summary> /// Gets or sets the remote trailers. /// </summary> @@ -98,7 +99,7 @@ namespace MediaBrowser.Controller.Entities public override IEnumerable<string> GetDeletePaths() { - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { return new[] { System.IO.Path.GetDirectoryName(Path) }; } diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index 1c09ee507..9e00ab260 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -26,6 +26,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + /// <summary> /// Gets or sets the game system. /// </summary> diff --git a/MediaBrowser.Controller/Entities/IArchivable.cs b/MediaBrowser.Controller/Entities/IArchivable.cs deleted file mode 100644 index 575d203a7..000000000 --- a/MediaBrowser.Controller/Entities/IArchivable.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace MediaBrowser.Controller.Entities -{ - public interface IArchivable - { - bool IsArchive { get; } - } -} diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index a38b7394d..1ab0566e0 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -150,11 +150,7 @@ namespace MediaBrowser.Controller.Entities /// <value><c>true</c> if [supports local metadata]; otherwise, <c>false</c>.</value> bool SupportsLocalMetadata { get; } - /// <summary> - /// Gets a value indicating whether this instance is in mixed folder. - /// </summary> - /// <value><c>true</c> if this instance is in mixed folder; otherwise, <c>false</c>.</value> - bool IsInMixedFolder { get; } + bool DetectIsInMixedFolder(); /// <summary> /// Gets a value indicating whether this instance is locked. diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index cf2f7db64..aee58b445 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { @@ -62,5 +63,7 @@ namespace MediaBrowser.Controller.Entities int? GetInheritedParentalRatingValue(); int InheritedParentalRatingValue { get; set; } + List<string> GetInheritedTags(); + List<string> InheritedTags { get; set; } } } diff --git a/MediaBrowser.Controller/Entities/IHasProductionLocations.cs b/MediaBrowser.Controller/Entities/IHasProductionLocations.cs deleted file mode 100644 index e4652fa8d..000000000 --- a/MediaBrowser.Controller/Entities/IHasProductionLocations.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Controller.Entities -{ - /// <summary> - /// Interface IHasProductionLocations - /// </summary> - public interface IHasProductionLocations - { - /// <summary> - /// Gets or sets the production locations. - /// </summary> - /// <value>The production locations.</value> - List<string> ProductionLocations { get; set; } - } - - public static class ProductionLocationExtensions - { - public static void AddProductionLocation(this IHasProductionLocations item, string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - if (!item.ProductionLocations.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - item.ProductionLocations.Add(name); - } - } - } -} diff --git a/MediaBrowser.Controller/Entities/IHasTaglines.cs b/MediaBrowser.Controller/Entities/IHasTaglines.cs deleted file mode 100644 index 8025d6b44..000000000 --- a/MediaBrowser.Controller/Entities/IHasTaglines.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Controller.Entities -{ - /// <summary> - /// Interface IHasTaglines - /// </summary> - public interface IHasTaglines - { - /// <summary> - /// Gets or sets the taglines. - /// </summary> - /// <value>The taglines.</value> - List<string> Taglines { get; set; } - } - - public static class TaglineExtensions - { - /// <summary> - /// Adds the tagline. - /// </summary> - /// <param name="tagline">The tagline.</param> - /// <exception cref="System.ArgumentNullException">tagline</exception> - public static void AddTagline(this IHasTaglines item, string tagline) - { - if (string.IsNullOrWhiteSpace(tagline)) - { - throw new ArgumentNullException("tagline"); - } - - if (!item.Taglines.Contains(tagline, StringComparer.OrdinalIgnoreCase)) - { - item.Taglines.Add(tagline); - } - } - } -} diff --git a/MediaBrowser.Controller/Entities/IHasThemeMedia.cs b/MediaBrowser.Controller/Entities/IHasThemeMedia.cs deleted file mode 100644 index acc0050ce..000000000 --- a/MediaBrowser.Controller/Entities/IHasThemeMedia.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Entities -{ - /// <summary> - /// Interface IHasThemeMedia - /// </summary> - public interface IHasThemeMedia - { - /// <summary> - /// Gets or sets the theme song ids. - /// </summary> - /// <value>The theme song ids.</value> - List<Guid> ThemeSongIds { get; set; } - - /// <summary> - /// Gets or sets the theme video ids. - /// </summary> - /// <value>The theme video ids.</value> - List<Guid> ThemeVideoIds { get; set; } - } -} diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs index 2495b0ccd..c21e170ae 100644 --- a/MediaBrowser.Controller/Entities/IHasUserData.cs +++ b/MediaBrowser.Controller/Entities/IHasUserData.cs @@ -20,5 +20,7 @@ namespace MediaBrowser.Controller.Entities Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user); bool EnableRememberingTrackSelections { get; } + + bool SupportsPlayedStatus { get; } } } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index deea63112..fec703b94 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -2,6 +2,9 @@ using System; using System.Collections.Generic; using MediaBrowser.Model.Configuration; +using System.Linq; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Entities { @@ -101,6 +104,8 @@ namespace MediaBrowser.Controller.Entities public bool? IsMovie { get; set; } public bool? IsSports { get; set; } public bool? IsKids { get; set; } + public bool? IsNews { get; set; } + public bool? IsSeries { get; set; } public int? MinPlayers { get; set; } public int? MaxPlayers { get; set; } @@ -137,6 +142,7 @@ namespace MediaBrowser.Controller.Entities public DayOfWeek[] AirDays { get; set; } public SeriesStatus[] SeriesStatuses { get; set; } public string AlbumArtistStartsWithOrGreater { get; set; } + public string ExternalSeriesId { get; set; } public string[] AlbumNames { get; set; } public string[] ArtistNames { get; set; } @@ -149,11 +155,53 @@ namespace MediaBrowser.Controller.Entities public Dictionary<string, string> ExcludeProviderIds { get; set; } public bool EnableGroupByMetadataKey { get; set; } + public List<Tuple<string, SortOrder>> OrderBy { get; set; } + + public DateTime? MinDateCreated { get; set; } + public DateTime? MinDateLastSaved { get; set; } + + public DtoOptions DtoOptions { get; set; } + + public bool HasField(ItemFields name) + { + var fields = DtoOptions.Fields; + + switch (name) + { + case ItemFields.ThemeSongIds: + case ItemFields.ThemeVideoIds: + case ItemFields.ProductionLocations: + case ItemFields.Keywords: + case ItemFields.Taglines: + case ItemFields.ShortOverview: + case ItemFields.CustomRating: + case ItemFields.DateCreated: + case ItemFields.SortName: + case ItemFields.Overview: + case ItemFields.OfficialRatingDescription: + case ItemFields.HomePageUrl: + case ItemFields.VoteCount: + case ItemFields.DisplayMediaType: + case ItemFields.ServiceName: + case ItemFields.Genres: + case ItemFields.Studios: + case ItemFields.Settings: + case ItemFields.OriginalTitle: + case ItemFields.Tags: + case ItemFields.DateLastMediaAdded: + case ItemFields.CriticRatingSummary: + return fields.Count == 0 || fields.Contains(name); + default: + return true; + } + } + public InternalItemsQuery() { GroupByPresentationUniqueKey = true; EnableTotalRecordCount = true; + DtoOptions = new DtoOptions(); AlbumNames = new string[] { }; ArtistNames = new string[] { }; ExcludeArtistIds = new string[] { }; @@ -191,6 +239,7 @@ namespace MediaBrowser.Controller.Entities TrailerTypes = new TrailerType[] { }; AirDays = new DayOfWeek[] { }; SeriesStatuses = new SeriesStatus[] { }; + OrderBy = new List<Tuple<string, SortOrder>>(); } public InternalItemsQuery(User user) diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index f0270497c..22cc0316a 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -15,24 +15,17 @@ namespace MediaBrowser.Controller.Entities.Movies /// <summary> /// Class Movie /// </summary> - public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle + public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle { public List<Guid> SpecialFeatureIds { get; set; } - public List<Guid> ThemeSongIds { get; set; } - public List<Guid> ThemeVideoIds { get; set; } - public List<string> ProductionLocations { get; set; } - public Movie() { SpecialFeatureIds = new List<Guid>(); RemoteTrailers = new List<MediaUrl>(); LocalTrailerIds = new List<Guid>(); RemoteTrailerIds = new List<Guid>(); - ThemeSongIds = new List<Guid>(); - ThemeVideoIds = new List<Guid>(); Taglines = new List<string>(); - ProductionLocations = new List<string>(); } public string AwardSummary { get; set; } @@ -75,13 +68,22 @@ namespace MediaBrowser.Controller.Entities.Movies set { TmdbCollectionName = value; } } + [IgnoreDataMember] + protected override bool SupportsIsInMixedFolderDetection + { + get + { + return false; + } + } + protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) { var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); // Must have a parent to have special features // In other words, it must be part of the Parent/Child tree - if (LocationType == LocationType.FileSystem && GetParent() != null && !IsInMixedFolder) + if (LocationType == LocationType.FileSystem && GetParent() != null && !DetectIsInMixedFolder()) { var specialFeaturesChanged = await RefreshSpecialFeatures(options, fileSystemChildren, cancellationToken).ConfigureAwait(false); @@ -119,7 +121,7 @@ namespace MediaBrowser.Controller.Entities.Movies { var info = GetItemLookupInfo<MovieInfo>(); - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { info.Name = System.IO.Path.GetFileName(ContainingFolderPath); } @@ -145,7 +147,7 @@ namespace MediaBrowser.Controller.Entities.Movies else { // Try to get the year from the folder name - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath)); diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index 8b749b7a5..6e632a26c 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -6,7 +6,7 @@ using System.Runtime.Serialization; namespace MediaBrowser.Controller.Entities { - public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasProductionLocations, IHasBudget, IHasLookupInfo<MusicVideoInfo> + public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasBudget, IHasLookupInfo<MusicVideoInfo> { /// <summary> /// Gets or sets the budget. @@ -19,12 +19,10 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <value>The revenue.</value> public double? Revenue { get; set; } - public List<string> ProductionLocations { get; set; } public List<string> Artists { get; set; } public MusicVideo() { - ProductionLocations = new List<string>(); Artists = new List<string>(); } @@ -37,6 +35,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + protected override bool SupportsIsInMixedFolderDetection + { + get + { + return true; + } + } + public override UnratedItem GetBlockUnratedType() { return UnratedItem.Music; @@ -65,7 +72,7 @@ namespace MediaBrowser.Controller.Entities else { // Try to get the year from the folder name - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath)); diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 965616eb5..a42fce8bb 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -1,19 +1,11 @@ using MediaBrowser.Model.Drawing; -using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; namespace MediaBrowser.Controller.Entities { - public class Photo : BaseItem, IHasTaglines + public class Photo : BaseItem { - public List<string> Taglines { get; set; } - - public Photo() - { - Taglines = new List<string>(); - } - [IgnoreDataMember] public override bool SupportsLocalMetadata { @@ -37,13 +29,13 @@ namespace MediaBrowser.Controller.Entities { get { - return Album; + return AlbumEntity; } } [IgnoreDataMember] - public PhotoAlbum Album + public PhotoAlbum AlbumEntity { get { diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index b0ddcfb8c..cb5c5c453 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -16,6 +16,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Other); diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ff3e53b69..62af14159 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -154,8 +154,6 @@ namespace MediaBrowser.Controller.Entities.TV Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); - var id = Guid.NewGuid().ToString("N"); - var items = GetEpisodes(user).Where(filter); var result = PostFilterAndSort(items, query, false, false); diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 7e8ba0516..39703f67a 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -17,17 +17,14 @@ namespace MediaBrowser.Controller.Entities.TV /// <summary> /// Class Series /// </summary> - public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IHasSpecialFeatures, IMetadataContainer, IHasOriginalTitle + public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer, IHasOriginalTitle { - public List<Guid> SpecialFeatureIds { get; set; } - public int? AnimeSeriesIndex { get; set; } public Series() { AirDays = new List<DayOfWeek>(); - SpecialFeatureIds = new List<Guid>(); RemoteTrailers = new List<MediaUrl>(); LocalTrailerIds = new List<Guid>(); RemoteTrailerIds = new List<Guid>(); diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 7a987a68e..0bcd5c14e 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -10,16 +10,12 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Class Trailer /// </summary> - public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo> + public class Trailer : Video, IHasCriticRating, IHasBudget, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo> { - public List<string> ProductionLocations { get; set; } - public Trailer() { RemoteTrailers = new List<MediaUrl>(); - Taglines = new List<string>(); Keywords = new List<string>(); - ProductionLocations = new List<string>(); TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer }; } @@ -36,12 +32,6 @@ namespace MediaBrowser.Controller.Entities } /// <summary> - /// Gets or sets the taglines. - /// </summary> - /// <value>The taglines.</value> - public List<string> Taglines { get; set; } - - /// <summary> /// Gets or sets the budget. /// </summary> /// <value>The budget.</value> @@ -64,7 +54,7 @@ namespace MediaBrowser.Controller.Entities info.IsLocalTrailer = TrailerTypes.Contains(TrailerType.LocalTrailer); - if (!IsInMixedFolder && LocationType == LocationType.FileSystem) + if (!DetectIsInMixedFolder() && LocationType == LocationType.FileSystem) { info.Name = System.IO.Path.GetFileName(ContainingFolderPath); } @@ -90,7 +80,7 @@ namespace MediaBrowser.Controller.Entities else { // Try to get the year from the folder name - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath)); diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index aff1f5e28..b67817846 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -33,6 +33,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + private void ClearCache() { lock (_childIdsLock) diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 35375e7e6..a689e0d09 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -13,7 +13,6 @@ namespace MediaBrowser.Controller.Entities public class UserView : Folder { public string ViewType { get; set; } - public Guid ParentId { get; set; } public Guid DisplayParentId { get; set; } public Guid? UserId { get; set; } @@ -45,6 +44,15 @@ namespace MediaBrowser.Controller.Entities return list; } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return false; + } + } + public override int GetChildCount(User user) { return GetChildren(user, true).Count(); diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 9f3acc3fc..3b7e3c5d2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Entities Limit = query.Limit, IsAiring = true - }, CancellationToken.None).ConfigureAwait(false); + }, new Dto.DtoOptions(), CancellationToken.None).ConfigureAwait(false); return GetResult(result); } @@ -1497,13 +1497,7 @@ namespace MediaBrowser.Controller.Entities { var filterValue = query.HasThemeSong.Value; - var themeCount = 0; - var iHasThemeMedia = item as IHasThemeMedia; - - if (iHasThemeMedia != null) - { - themeCount = iHasThemeMedia.ThemeSongIds.Count; - } + var themeCount = item.ThemeSongIds.Count; var ok = filterValue ? themeCount > 0 : themeCount == 0; if (!ok) @@ -1516,13 +1510,7 @@ namespace MediaBrowser.Controller.Entities { var filterValue = query.HasThemeVideo.Value; - var themeCount = 0; - var iHasThemeMedia = item as IHasThemeMedia; - - if (iHasThemeMedia != null) - { - themeCount = iHasThemeMedia.ThemeVideoIds.Count; - } + var themeCount = item.ThemeVideoIds.Count; var ok = filterValue ? themeCount > 0 : themeCount == 0; if (!ok) diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 8809f155c..5aaff6fef 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -25,8 +25,7 @@ namespace MediaBrowser.Controller.Entities ISupportsPlaceHolders, IHasMediaSources, IHasShortOverview, - IThemeMedia, - IArchivable + IThemeMedia { [IgnoreDataMember] public string PrimaryVersionId { get; set; } @@ -45,6 +44,24 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return true; + } + } + + [IgnoreDataMember] + protected override bool SupportsIsInMixedFolderDetection + { + get + { + return true; + } + } + public override string CreatePresentationUniqueKey() { if (!string.IsNullOrWhiteSpace(PrimaryVersionId)) @@ -64,6 +81,12 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsThemeMedia + { + get { return true; } + } + public int? TotalBitrate { get; set; } public ExtraType? ExtraType { get; set; } @@ -165,7 +188,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public override bool SupportsAddingToPlaylist { - get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } + get { return true; } } [IgnoreDataMember] @@ -197,21 +220,6 @@ namespace MediaBrowser.Controller.Entities get { return LocalAlternateVersions.Count > 0; } } - [IgnoreDataMember] - public bool IsArchive - { - get - { - if (string.IsNullOrWhiteSpace(Path)) - { - return false; - } - var ext = System.IO.Path.GetExtension(Path) ?? string.Empty; - - return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase); - } - } - public IEnumerable<Guid> GetAdditionalPartIds() { return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); @@ -480,7 +488,7 @@ namespace MediaBrowser.Controller.Entities public override IEnumerable<string> GetDeletePaths() { - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { return new[] { ContainingFolderPath }; } @@ -600,7 +608,7 @@ namespace MediaBrowser.Controller.Entities Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File, MediaStreams = mediaStreams, Name = GetMediaSourceName(i, mediaStreams), - Path = enablePathSubstitution ? GetMappedPath(i.Path, locationType) : i.Path, + Path = enablePathSubstitution ? GetMappedPath(i, i.Path, locationType) : i.Path, RunTimeTicks = i.RunTimeTicks, Video3DFormat = i.Video3DFormat, VideoType = i.VideoType, |
