diff options
Diffstat (limited to 'MediaBrowser.Controller')
63 files changed, 613 insertions, 619 deletions
diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index 3c46247a7..9177e2d81 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -134,15 +134,5 @@ namespace MediaBrowser.Controller.Channels /// <param name="cancellationToken">The cancellation token.</param> /// <returns>BaseItemDto.</returns> Task<BaseItemDto> GetChannelFolder(string userId, CancellationToken cancellationToken); - - /// <summary> - /// Downloads the channel item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="destinationPath">The destination path.</param> - /// <param name="progress">The progress.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - Task DownloadChannelItem(BaseItem item, string destinationPath, IProgress<double> progress, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Chapters/ChapterResponse.cs b/MediaBrowser.Controller/Chapters/ChapterResponse.cs deleted file mode 100644 index 3c1b8ed07..000000000 --- a/MediaBrowser.Controller/Chapters/ChapterResponse.cs +++ /dev/null @@ -1,19 +0,0 @@ -using MediaBrowser.Model.Chapters; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Chapters -{ - public class ChapterResponse - { - /// <summary> - /// Gets or sets the chapters. - /// </summary> - /// <value>The chapters.</value> - public List<RemoteChapterInfo> Chapters { get; set; } - - public ChapterResponse() - { - Chapters = new List<RemoteChapterInfo>(); - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Chapters/ChapterSearchRequest.cs b/MediaBrowser.Controller/Chapters/ChapterSearchRequest.cs deleted file mode 100644 index 982dc35bb..000000000 --- a/MediaBrowser.Controller/Chapters/ChapterSearchRequest.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using System; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Chapters -{ - public class ChapterSearchRequest : IHasProviderIds - { - public string Language { get; set; } - - public VideoContentType ContentType { get; set; } - - public string MediaPath { get; set; } - public string SeriesName { get; set; } - public string Name { get; set; } - public int? IndexNumber { get; set; } - public int? IndexNumberEnd { get; set; } - public int? ParentIndexNumber { get; set; } - public int? ProductionYear { get; set; } - public long? RuntimeTicks { get; set; } - public Dictionary<string, string> ProviderIds { get; set; } - - public bool SearchAllProviders { get; set; } - - public ChapterSearchRequest() - { - ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Chapters/IChapterManager.cs b/MediaBrowser.Controller/Chapters/IChapterManager.cs index 27e06fb8d..4b39e66cc 100644 --- a/MediaBrowser.Controller/Chapters/IChapterManager.cs +++ b/MediaBrowser.Controller/Chapters/IChapterManager.cs @@ -1,6 +1,4 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Chapters; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Configuration; @@ -14,12 +12,6 @@ namespace MediaBrowser.Controller.Chapters public interface IChapterManager { /// <summary> - /// Adds the parts. - /// </summary> - /// <param name="chapterProviders">The chapter providers.</param> - void AddParts(IEnumerable<IChapterProvider> chapterProviders); - - /// <summary> /// Gets the chapters. /// </summary> /// <param name="itemId">The item identifier.</param> @@ -36,43 +28,6 @@ namespace MediaBrowser.Controller.Chapters Task SaveChapters(string itemId, List<ChapterInfo> chapters, CancellationToken cancellationToken); /// <summary> - /// Searches the specified video. - /// </summary> - /// <param name="video">The video.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{IEnumerable{RemoteChapterResult}}.</returns> - Task<IEnumerable<RemoteChapterResult>> Search(Video video, CancellationToken cancellationToken); - - /// <summary> - /// Searches the specified request. - /// </summary> - /// <param name="request">The request.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{IEnumerable{RemoteChapterResult}}.</returns> - Task<IEnumerable<RemoteChapterResult>> Search(ChapterSearchRequest request, CancellationToken cancellationToken); - - /// <summary> - /// Gets the chapters. - /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ChapterResponse}.</returns> - Task<ChapterResponse> GetChapters(string id, CancellationToken cancellationToken); - - /// <summary> - /// Gets the providers. - /// </summary> - /// <param name="itemId">The item identifier.</param> - /// <returns>IEnumerable{ChapterProviderInfo}.</returns> - IEnumerable<ChapterProviderInfo> GetProviders(string itemId); - - /// <summary> - /// Gets the providers. - /// </summary> - /// <returns>IEnumerable{ChapterProviderInfo}.</returns> - IEnumerable<ChapterProviderInfo> GetProviders(); - - /// <summary> /// Gets the configuration. /// </summary> /// <returns>ChapterOptions.</returns> diff --git a/MediaBrowser.Controller/Chapters/IChapterProvider.cs b/MediaBrowser.Controller/Chapters/IChapterProvider.cs deleted file mode 100644 index a7505347b..000000000 --- a/MediaBrowser.Controller/Chapters/IChapterProvider.cs +++ /dev/null @@ -1,39 +0,0 @@ -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Chapters; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Chapters -{ - public interface IChapterProvider - { - /// <summary> - /// Gets the name. - /// </summary> - /// <value>The name.</value> - string Name { get; } - - /// <summary> - /// Gets the supported media types. - /// </summary> - /// <value>The supported media types.</value> - IEnumerable<VideoContentType> SupportedMediaTypes { get; } - - /// <summary> - /// Searches the specified request. - /// </summary> - /// <param name="request">The request.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{IEnumerable{RemoteChapterResult}}.</returns> - Task<IEnumerable<RemoteChapterResult>> Search(ChapterSearchRequest request, CancellationToken cancellationToken); - - /// <summary> - /// Gets the chapters. - /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{ChapterResponse}.</returns> - Task<ChapterResponse> GetChapters(string id, CancellationToken cancellationToken); - } -} diff --git a/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs b/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs index e8083b363..d2c5b9e4e 100644 --- a/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs +++ b/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs @@ -1,10 +1,20 @@ using System; +using System.Collections.Generic; +using System.Net; +using MediaBrowser.Model.Events; namespace MediaBrowser.Controller.Dlna { public interface IDeviceDiscovery { - event EventHandler<SsdpMessageEventArgs> DeviceDiscovered; - event EventHandler<SsdpMessageEventArgs> DeviceLeft; + event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered; + event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft; + } + + public class UpnpDeviceInfo + { + public Uri Location { get; set; } + public Dictionary<string, string> Headers { get; set; } + public IPEndPoint LocalEndPoint { get; set; } } } diff --git a/MediaBrowser.Controller/Dlna/ISsdpHandler.cs b/MediaBrowser.Controller/Dlna/ISsdpHandler.cs index e4126ddcf..ec3a00aad 100644 --- a/MediaBrowser.Controller/Dlna/ISsdpHandler.cs +++ b/MediaBrowser.Controller/Dlna/ISsdpHandler.cs @@ -4,6 +4,5 @@ namespace MediaBrowser.Controller.Dlna { public interface ISsdpHandler { - event EventHandler<SsdpMessageEventArgs> MessageReceived; } } 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, diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 04268bcea..975c59659 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -506,6 +506,8 @@ namespace MediaBrowser.Controller.Library /// <returns>QueryResult<BaseItem>.</returns> QueryResult<BaseItem> QueryItems(InternalItemsQuery query); + string GetPathAfterNetworkSubstitution(string path, BaseItem ownerItem = null); + /// <summary> /// Substitutes the path. /// </summary> @@ -554,9 +556,10 @@ namespace MediaBrowser.Controller.Library /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> bool IgnoreFile(FileSystemMetadata file, BaseItem parent); - void AddVirtualFolder(string name, string collectionType, string[] mediaPaths, LibraryOptions options, bool refreshLibrary); + void AddVirtualFolder(string name, string collectionType, LibraryOptions options, bool refreshLibrary); void RemoveVirtualFolder(string name, bool refreshLibrary); - void AddMediaPath(string virtualFolderName, string path); + void AddMediaPath(string virtualFolderName, MediaPathInfo path); + void UpdateMediaPath(string virtualFolderName, MediaPathInfo path); void RemoveMediaPath(string virtualFolderName, string path); QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query); diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs index a77d88049..1ab0e4cb0 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceManager.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using System.IO; namespace MediaBrowser.Controller.Library { @@ -60,11 +61,8 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Gets the static media source. /// </summary> - /// <param name="item">The item.</param> - /// <param name="mediaSourceId">The media source identifier.</param> - /// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param> /// <returns>MediaSourceInfo.</returns> - Task<MediaSourceInfo> GetMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution); + Task<MediaSourceInfo> GetMediaSource(IHasMediaSources item, string mediaSourceId, string liveStreamId, bool enablePathSubstitution, CancellationToken cancellationToken); /// <summary> /// Opens the media source. @@ -82,6 +80,8 @@ namespace MediaBrowser.Controller.Library /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<MediaSourceInfo>.</returns> Task<MediaSourceInfo> GetLiveStream(string id, CancellationToken cancellationToken); + + Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> GetLiveStreamWithDirectStreamProvider(string id, CancellationToken cancellationToken); /// <summary> /// Pings the media source. @@ -95,8 +95,12 @@ namespace MediaBrowser.Controller.Library /// Closes the media source. /// </summary> /// <param name="id">The live stream identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task CloseLiveStream(string id, CancellationToken cancellationToken); + Task CloseLiveStream(string id); + } + + public interface IDirectStreamProvider + { + Task CopyToAsync(Stream stream, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs index 5b033af4a..b0881ba7c 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Dto; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using System; namespace MediaBrowser.Controller.Library { @@ -22,14 +23,13 @@ namespace MediaBrowser.Controller.Library /// <param name="openToken">The open token.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<MediaSourceInfo>.</returns> - Task<MediaSourceInfo> OpenMediaSource(string openToken, CancellationToken cancellationToken); + Task<Tuple<MediaSourceInfo,IDirectStreamProvider>> OpenMediaSource(string openToken, CancellationToken cancellationToken); /// <summary> /// Closes the media source. /// </summary> /// <param name="liveStreamId">The live stream identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task CloseMediaSource(string liveStreamId, CancellationToken cancellationToken); + Task CloseMediaSource(string liveStreamId); } } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index a8e42749b..8e3c1931b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Events; +using MediaBrowser.Controller.Library; namespace MediaBrowser.Controller.LiveTv { @@ -37,7 +38,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{SeriesTimerInfoDto}.</returns> Task<SeriesTimerInfoDto> GetNewTimerDefaults(string programId, CancellationToken cancellationToken); - + /// <summary> /// Deletes the recording. /// </summary> @@ -51,7 +52,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="recording">The recording.</param> /// <returns>Task.</returns> Task DeleteRecording(BaseItem recording); - + /// <summary> /// Cancels the timer. /// </summary> @@ -83,7 +84,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="user">The user.</param> /// <returns>Task{RecordingInfoDto}.</returns> Task<BaseItemDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null); - + /// <summary> /// Gets the timer. /// </summary> @@ -125,14 +126,14 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{QueryResult{SeriesTimerInfoDto}}.</returns> Task<QueryResult<SeriesTimerInfoDto>> GetSeriesTimers(SeriesTimerQuery query, CancellationToken cancellationToken); - + /// <summary> /// Gets the channel. /// </summary> /// <param name="id">The identifier.</param> /// <returns>Channel.</returns> LiveTvChannel GetInternalChannel(string id); - + /// <summary> /// Gets the recording. /// </summary> @@ -156,8 +157,8 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="mediaSourceId">The media source identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{StreamResponseInfo}.</returns> - Task<MediaSourceInfo> GetChannelStream(string id, string mediaSourceId, CancellationToken cancellationToken); - + Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> GetChannelStream(string id, string mediaSourceId, CancellationToken cancellationToken); + /// <summary> /// Gets the program. /// </summary> @@ -220,9 +221,8 @@ namespace MediaBrowser.Controller.LiveTv /// Closes the live stream. /// </summary> /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task CloseLiveStream(string id, CancellationToken cancellationToken); + Task CloseLiveStream(string id); /// <summary> /// Gets the guide information. @@ -242,10 +242,8 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the recommended programs internal. /// </summary> - /// <param name="query">The query.</param> - /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<QueryResult<LiveTvProgram>>.</returns> - Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken); + Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken); /// <summary> /// Gets the live tv information. @@ -303,18 +301,12 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the recording media sources. /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns> - Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(string id, CancellationToken cancellationToken); + Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken); /// <summary> /// Gets the channel media sources. /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns> - Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken); + Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken); /// <summary> /// Adds the information to recording dto. @@ -331,8 +323,8 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="fields">The fields.</param> /// <param name="user">The user.</param> /// <returns>Task.</returns> - Task AddInfoToProgramDto(List<Tuple<BaseItem,BaseItemDto>> programs, List<ItemFields> fields, User user = null); - + Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> programs, List<ItemFields> fields, User user = null); + /// <summary> /// Saves the tuner host. /// </summary> @@ -395,7 +387,7 @@ namespace MediaBrowser.Controller.LiveTv Task<List<ChannelInfo>> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken); Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken); - List<IListingsProvider> ListingProviders { get;} + List<IListingsProvider> ListingProviders { get; } event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled; event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled; diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 257024d01..1bbd1a008 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.LiveTv bool CanDelete(User user); string SeriesTimerId { get; set; } + string TimerId { get; set; } RecordingStatus Status { get; set; } DateTime? EndDate { get; set; } DateTime DateLastSaved { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index d7d8336d0..cea2d6e21 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Library; namespace MediaBrowser.Controller.LiveTv { @@ -245,4 +246,14 @@ namespace MediaBrowser.Controller.LiveTv /// <returns>Task.</returns> Task<string> CreateSeriesTimer(SeriesTimerInfo info, CancellationToken cancellationToken); } + + public interface ISupportsDirectStreamProvider + { + Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, CancellationToken cancellationToken); + } + + public interface ISupportsUpdatingDefaults + { + Task UpdateTimerDefaults(SeriesTimerInfo info, CancellationToken cancellationToken); + } } diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs index 1e7aa3de5..89d035649 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -22,9 +22,8 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the channels. /// </summary> - /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<IEnumerable<ChannelInfo>>.</returns> - Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken); + Task<IEnumerable<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken); /// <summary> /// Gets the tuner infos. /// </summary> @@ -38,7 +37,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="streamId">The stream identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<MediaSourceInfo>.</returns> - Task<Tuple<MediaSourceInfo,SemaphoreSlim>> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken); + Task<LiveStream> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken); /// <summary> /// Gets the channel stream media sources. /// </summary> @@ -46,8 +45,6 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<List<MediaSourceInfo>>.</returns> Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); - - string ApplyDuration(string streamPath, TimeSpan duration); } public interface IConfigurableTunerHost { diff --git a/MediaBrowser.Controller/LiveTv/LiveStream.cs b/MediaBrowser.Controller/LiveTv/LiveStream.cs new file mode 100644 index 000000000..0908c3ecc --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveStream.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Dto; + +namespace MediaBrowser.Controller.LiveTv +{ + public class LiveStream + { + public MediaSourceInfo OriginalMediaSource { get; set; } + public MediaSourceInfo OpenedMediaSource { get; set; } + public int ConsumerCount { + get { return SharedStreamIds.Count; } + } + public ITunerHost TunerHost { get; set; } + public string OriginalStreamId { get; set; } + public bool EnableStreamSharing { get; set; } + public string UniqueId = Guid.NewGuid().ToString("N"); + + public List<string> SharedStreamIds = new List<string>(); + + public LiveStream(MediaSourceInfo mediaSource) + { + OriginalMediaSource = mediaSource; + OpenedMediaSource = mediaSource; + EnableStreamSharing = true; + } + + public Task Open(CancellationToken cancellationToken) + { + return OpenInternal(cancellationToken); + } + + protected virtual Task OpenInternal(CancellationToken cancellationToken) + { + return Task.FromResult(true); + } + + public virtual Task Close() + { + return Task.FromResult(true); + } + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index e6f472414..e6fefbf72 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } + public string TimerId { get; set; } [IgnoreDataMember] public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } @@ -112,7 +113,7 @@ namespace MediaBrowser.Controller.LiveTv public override bool CanDelete() { - return true; + return Status == RecordingStatus.Completed; } public override bool IsAuthorizedToDelete(User user) diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 50aeed27d..610d4b6f8 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -5,11 +5,12 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using System.Collections.Generic; +using System.Globalization; using System.Runtime.Serialization; namespace MediaBrowser.Controller.LiveTv { - public class LiveTvChannel : BaseItem, IHasMediaSources + public class LiveTvChannel : BaseItem, IHasMediaSources, IHasProgramAttributes { public override List<string> GetUserDataKeys() { @@ -81,10 +82,10 @@ namespace MediaBrowser.Controller.LiveTv if (!string.IsNullOrEmpty(Number)) { - double.TryParse(Number, out number); + double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number); } - return number.ToString("000-") + (Name ?? string.Empty); + return number.ToString("00000-") + (Name ?? string.Empty); } [IgnoreDataMember] @@ -137,5 +138,56 @@ namespace MediaBrowser.Controller.LiveTv { return false; } + + [IgnoreDataMember] + public bool IsMovie { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is sports. + /// </summary> + /// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsSports { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is series. + /// </summary> + /// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsSeries { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is live. + /// </summary> + /// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsLive { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is news. + /// </summary> + /// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsNews { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is kids. + /// </summary> + /// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value> + [IgnoreDataMember] + public bool IsKids { get; set; } + + [IgnoreDataMember] + public bool IsPremiere { get; set; } + + [IgnoreDataMember] + public bool IsRepeat { get; set; } + + /// <summary> + /// Gets or sets the episode title. + /// </summary> + /// <value>The episode title.</value> + [IgnoreDataMember] + public string EpisodeTitle { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index f4dba070d..c255630f5 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -19,6 +19,7 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } + public string TimerId { get; set; } [IgnoreDataMember] public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } @@ -54,6 +55,24 @@ namespace MediaBrowser.Controller.LiveTv } [IgnoreDataMember] + protected override bool SupportsIsInMixedFolderDetection + { + get + { + return false; + } + } + + [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return Status == RecordingStatus.Completed && base.SupportsPlayedStatus; + } + } + + [IgnoreDataMember] public override LocationType LocationType { get @@ -111,7 +130,7 @@ namespace MediaBrowser.Controller.LiveTv public override bool CanDelete() { - return true; + return Status == RecordingStatus.Completed; } public override bool IsAuthorizedToDelete(User user) diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index ea5e6dbc6..d0377fbfd 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -107,6 +107,8 @@ namespace MediaBrowser.Controller.LiveTv /// <value>The image URL.</value> public string ImageUrl { get; set; } + public string LogoImageUrl { get; set; } + /// <summary> /// Gets or sets a value indicating whether this instance has image. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs index 2d79473f0..5c73ed833 100644 --- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Controller.LiveTv { @@ -26,6 +27,8 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> public string Name { get; set; } + public string ServiceName { get; set; } + /// <summary> /// Description of the recording. /// </summary> @@ -53,6 +56,11 @@ namespace MediaBrowser.Controller.LiveTv /// <value><c>true</c> if [record any channel]; otherwise, <c>false</c>.</value> public bool RecordAnyChannel { get; set; } + public int KeepUpTo { get; set; } + public KeepUntil KeepUntil { get; set; } + + public bool SkipEpisodesInLibrary { get; set; } + /// <summary> /// Gets or sets a value indicating whether [record new only]. /// </summary> @@ -104,6 +112,8 @@ namespace MediaBrowser.Controller.LiveTv public SeriesTimerInfo() { Days = new List<DayOfWeek>(); + SkipEpisodesInLibrary = true; + KeepUntil = KeepUntil.UntilDeleted; } } } diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs index 5d92a212f..fd614253a 100644 --- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -1,10 +1,17 @@ using MediaBrowser.Model.LiveTv; using System; +using System.Collections.Generic; namespace MediaBrowser.Controller.LiveTv { public class TimerInfo { + public TimerInfo() + { + Genres = new List<string>(); + KeepUntil = KeepUntil.UntilDeleted; + } + /// <summary> /// Id of the recording. /// </summary> @@ -15,7 +22,7 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The series timer identifier.</value> public string SeriesTimerId { get; set; } - + /// <summary> /// ChannelId of the recording. /// </summary> @@ -26,7 +33,7 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The program identifier.</value> public string ProgramId { get; set; } - + /// <summary> /// Name of the recording. /// </summary> @@ -76,11 +83,36 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value> public bool IsPostPaddingRequired { get; set; } - + /// <summary> /// Gets or sets the priority. /// </summary> /// <value>The priority.</value> public int Priority { get; set; } + + + // Program properties + public int? SeasonNumber { get; set; } + /// <summary> + /// Gets or sets the episode number. + /// </summary> + /// <value>The episode number.</value> + public int? EpisodeNumber { get; set; } + public bool IsMovie { get; set; } + public bool IsKids { get; set; } + public bool IsSports { get; set; } + public bool IsNews { get; set; } + public int? ProductionYear { get; set; } + public string EpisodeTitle { get; set; } + public DateTime? OriginalAirDate { get; set; } + public bool IsProgramSeries { get; set; } + public bool IsRepeat { get; set; } + public string HomePageUrl { get; set; } + public float? CommunityRating { get; set; } + public string ShortOverview { get; set; } + public string OfficialRating { get; set; } + public List<string> Genres { get; set; } + public string RecordingPath { get; set; } + public KeepUntil KeepUntil { get; set; } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 7cfd56c1e..11ed0f674 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -91,10 +91,7 @@ <Compile Include="Channels\InternalChannelItemQuery.cs" /> <Compile Include="Channels\IRequiresMediaInfoCallback.cs" /> <Compile Include="Channels\ISearchableChannel.cs" /> - <Compile Include="Chapters\ChapterSearchRequest.cs" /> <Compile Include="Chapters\IChapterManager.cs" /> - <Compile Include="Chapters\IChapterProvider.cs" /> - <Compile Include="Chapters\ChapterResponse.cs" /> <Compile Include="Collections\CollectionCreationOptions.cs" /> <Compile Include="Collections\CollectionEvents.cs" /> <Compile Include="Collections\ICollectionManager.cs" /> @@ -135,7 +132,6 @@ <Compile Include="Entities\Game.cs" /> <Compile Include="Entities\GameGenre.cs" /> <Compile Include="Entities\GameSystem.cs" /> - <Compile Include="Entities\IArchivable.cs" /> <Compile Include="Entities\IByReferenceItem.cs" /> <Compile Include="Entities\IHasAspectRatio.cs" /> <Compile Include="Entities\IHasBudget.cs" /> @@ -147,15 +143,12 @@ <Compile Include="Entities\IHasMediaSources.cs" /> <Compile Include="Entities\IHasMetascore.cs" /> <Compile Include="Entities\IHasOriginalTitle.cs" /> - <Compile Include="Entities\IHasProductionLocations.cs" /> <Compile Include="Entities\IHasProgramAttributes.cs" /> <Compile Include="Entities\IHasScreenshots.cs" /> <Compile Include="Entities\IHasSeries.cs" /> <Compile Include="Entities\IHasShortOverview.cs" /> <Compile Include="Entities\IHasSpecialFeatures.cs" /> <Compile Include="Entities\IHasStartDate.cs" /> - <Compile Include="Entities\IHasTaglines.cs" /> - <Compile Include="Entities\IHasThemeMedia.cs" /> <Compile Include="Entities\IHasTrailers.cs" /> <Compile Include="Entities\IHasUserData.cs" /> <Compile Include="Entities\IHiddenFromDisplay.cs" /> @@ -201,6 +194,7 @@ <Compile Include="Library\UserDataSaveEventArgs.cs" /> <Compile Include="LiveTv\IListingsProvider.cs" /> <Compile Include="LiveTv\ITunerHost.cs" /> + <Compile Include="LiveTv\LiveStream.cs" /> <Compile Include="LiveTv\RecordingGroup.cs" /> <Compile Include="LiveTv\RecordingStatusChangedEventArgs.cs" /> <Compile Include="LiveTv\ILiveTvRecording.cs" /> @@ -266,7 +260,6 @@ <Compile Include="Playlists\IPlaylistManager.cs" /> <Compile Include="Playlists\Playlist.cs" /> <Compile Include="Plugins\ILocalizablePlugin.cs" /> - <Compile Include="Power\IPowerManagement.cs" /> <Compile Include="Providers\AlbumInfo.cs" /> <Compile Include="Providers\ArtistInfo.cs" /> <Compile Include="Providers\BookInfo.cs" /> @@ -290,9 +283,7 @@ <Compile Include="Providers\IHasItemChangeMonitor.cs" /> <Compile Include="Providers\IHasLookupInfo.cs" /> <Compile Include="Providers\IHasOrder.cs" /> - <Compile Include="Providers\IImageFileSaver.cs" /> <Compile Include="Providers\IImageProvider.cs" /> - <Compile Include="Providers\IImageSaver.cs" /> <Compile Include="Providers\ILocalImageFileProvider.cs" /> <Compile Include="Providers\ILocalMetadataProvider.cs" /> <Compile Include="Providers\ImageRefreshMode.cs" /> @@ -319,7 +310,6 @@ <Compile Include="Providers\SongInfo.cs" /> <Compile Include="Providers\TrailerInfo.cs" /> <Compile Include="Providers\VideoContentType.cs" /> - <Compile Include="RelatedMedia\IRelatedMediaProvider.cs" /> <Compile Include="Security\AuthenticationInfo.cs" /> <Compile Include="Security\AuthenticationInfoQuery.cs" /> <Compile Include="Security\IAuthenticationRepository.cs" /> diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 7fdbf020c..866a08aa1 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -45,9 +45,9 @@ namespace MediaBrowser.Controller.MediaEncoding /// <param name="offset">The offset.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{Stream}.</returns> - Task<string> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); + Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); - Task<string> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken); + Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken); /// <summary> /// Extracts the video images on interval. @@ -84,7 +84,7 @@ namespace MediaBrowser.Controller.MediaEncoding /// <param name="inputFiles">The input files.</param> /// <param name="protocol">The protocol.</param> /// <returns>System.String.</returns> - string GetProbeSizeArgument(string[] inputFiles, MediaProtocol protocol); + string GetProbeSizeAndAnalyzeDurationArgument(string[] inputFiles, MediaProtocol protocol); /// <summary> /// Gets the input argument. diff --git a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs index ca0c2fdbb..9ff7567d4 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs @@ -15,6 +15,7 @@ namespace MediaBrowser.Controller.MediaEncoding public IIsoMount MountedIso { get; set; } public VideoType VideoType { get; set; } public List<string> PlayableStreamFileNames { get; set; } + public int AnalyzeDurationSections { get; set; } public MediaInfoRequest() { diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index 3756f1d93..be177cb02 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -120,7 +120,7 @@ namespace MediaBrowser.Controller.Net var cancellationTokenSource = new CancellationTokenSource(); - Logger.Info("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); + Logger.Debug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); var timer = SendOnTimer ? new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : @@ -267,7 +267,7 @@ namespace MediaBrowser.Controller.Net /// <param name="connection">The connection.</param> private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim> connection) { - Logger.Info("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); + Logger.Debug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); var timer = connection.Item3; diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs index 8fdb1ce37..ca453840f 100644 --- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -12,14 +12,6 @@ namespace MediaBrowser.Controller.Net public interface IHttpResultFactory { /// <summary> - /// Throws the error. - /// </summary> - /// <param name="statusCode">The status code.</param> - /// <param name="errorMessage">The error message.</param> - /// <param name="responseHeaders">The response headers.</param> - void ThrowError(int statusCode, string errorMessage, IDictionary<string, string> responseHeaders = null); - - /// <summary> /// Gets the result. /// </summary> /// <param name="content">The content.</param> diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 654b97d7d..6ab85f079 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -32,6 +32,15 @@ namespace MediaBrowser.Controller.Playlists } [IgnoreDataMember] + public override bool SupportsPlayedStatus + { + get + { + return string.Equals(MediaType, "Video", StringComparison.OrdinalIgnoreCase); + } + } + + [IgnoreDataMember] public override bool AlwaysScanInternalMetadataPath { get @@ -198,15 +207,15 @@ namespace MediaBrowser.Controller.Playlists public override bool IsVisible(User user) { - if (base.IsVisible(user)) - { - var userId = user.Id.ToString("N"); + var userId = user.Id.ToString("N"); - return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) || - string.Equals(OwnerUserId, userId, StringComparison.OrdinalIgnoreCase); - } + return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) || + string.Equals(OwnerUserId, userId, StringComparison.OrdinalIgnoreCase); + } - return false; + public override bool IsVisibleStandalone(User user) + { + return IsVisible(user); } } } diff --git a/MediaBrowser.Controller/Power/IPowerManagement.cs b/MediaBrowser.Controller/Power/IPowerManagement.cs deleted file mode 100644 index faa289695..000000000 --- a/MediaBrowser.Controller/Power/IPowerManagement.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace MediaBrowser.Controller.Power -{ - public interface IPowerManagement - { - /// <summary> - /// Schedules the wake. - /// </summary> - /// <param name="utcTime">The UTC time.</param> - void ScheduleWake(DateTime utcTime); - } -} diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index fccbd9211..13d43eee6 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -347,7 +347,7 @@ namespace MediaBrowser.Controller.Providers var person = item as Person; if (person != null) { - person.PlaceOfBirth = val; + person.ProductionLocations = new List<string> { val }; } } @@ -790,7 +790,7 @@ namespace MediaBrowser.Controller.Providers } default: - { + { string readerName = reader.Name; string providerIdValue; if (_validProviderIds.TryGetValue(readerName, out providerIdValue)) @@ -893,14 +893,6 @@ namespace MediaBrowser.Controller.Providers if (!string.IsNullOrWhiteSpace(val)) { - var hasProductionLocations = item as IHasProductionLocations; - if (hasProductionLocations != null) - { - if (!string.IsNullOrWhiteSpace(val)) - { - hasProductionLocations.AddProductionLocation(val); - } - } } break; } @@ -934,14 +926,7 @@ namespace MediaBrowser.Controller.Providers if (!string.IsNullOrWhiteSpace(val)) { - var hasTaglines = item as IHasTaglines; - if (hasTaglines != null) - { - if (!string.IsNullOrWhiteSpace(val)) - { - hasTaglines.AddTagline(val); - } - } + item.Tagline = val; } break; } diff --git a/MediaBrowser.Controller/Providers/IImageFileSaver.cs b/MediaBrowser.Controller/Providers/IImageFileSaver.cs deleted file mode 100644 index 3e11d8bf8..000000000 --- a/MediaBrowser.Controller/Providers/IImageFileSaver.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Drawing; -using MediaBrowser.Model.Entities; - -namespace MediaBrowser.Controller.Providers -{ - public interface IImageFileSaver : IImageSaver - { - /// <summary> - /// Gets the save paths. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="format">The format.</param> - /// <param name="index">The index.</param> - /// <returns>IEnumerable{System.String}.</returns> - IEnumerable<string> GetSavePaths(IHasImages item, ImageType type, ImageFormat format, int index); - } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IImageSaver.cs b/MediaBrowser.Controller/Providers/IImageSaver.cs deleted file mode 100644 index 62017160f..000000000 --- a/MediaBrowser.Controller/Providers/IImageSaver.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public interface IImageSaver - { - /// <summary> - /// Gets the name. - /// </summary> - /// <value>The name.</value> - string Name { get; } - } -} diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 3eefa9647..d3e5685bb 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -95,15 +95,8 @@ namespace MediaBrowser.Controller.Providers /// <summary> /// Adds the metadata providers. /// </summary> - /// <param name="imageProviders">The image providers.</param> - /// <param name="metadataServices">The metadata services.</param> - /// <param name="metadataProviders">The metadata providers.</param> - /// <param name="savers">The savers.</param> - /// <param name="imageSavers">The image savers.</param> - /// <param name="externalIds">The external ids.</param> void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> savers, - IEnumerable<IImageSaver> imageSavers, IEnumerable<IExternalId> externalIds); /// <summary> diff --git a/MediaBrowser.Controller/Providers/ItemInfo.cs b/MediaBrowser.Controller/Providers/ItemInfo.cs index 63cc48058..8de11b743 100644 --- a/MediaBrowser.Controller/Providers/ItemInfo.cs +++ b/MediaBrowser.Controller/Providers/ItemInfo.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Controller.Providers { Path = item.Path; ContainingFolderPath = item.ContainingFolderPath; - IsInMixedFolder = item.IsInMixedFolder; + IsInMixedFolder = item.DetectIsInMixedFolder(); var video = item as Video; if (video != null) diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs index 17175f91c..99402a969 100644 --- a/MediaBrowser.Controller/Providers/MetadataResult.cs +++ b/MediaBrowser.Controller/Providers/MetadataResult.cs @@ -13,13 +13,15 @@ namespace MediaBrowser.Controller.Providers public MetadataResult() { Images = new List<LocalImageInfo>(); + ResultLanguage = "en"; } public List<PersonInfo> People { get; set; } public bool HasMetadata { get; set; } public T Item { get; set; } - + public string ResultLanguage { get; set; } + public bool QueriedById { get; set; } public void AddPerson(PersonInfo p) { if (People == null) diff --git a/MediaBrowser.Controller/RelatedMedia/IRelatedMediaProvider.cs b/MediaBrowser.Controller/RelatedMedia/IRelatedMediaProvider.cs deleted file mode 100644 index bb2a0cd89..000000000 --- a/MediaBrowser.Controller/RelatedMedia/IRelatedMediaProvider.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MediaBrowser.Controller.RelatedMedia -{ - public interface IRelatedMediaProvider - { - /// <summary> - /// Gets the name. - /// </summary> - /// <value>The name.</value> - string Name { get; } - } -} |
