diff options
| author | hatharry <hatharry@hotmail.com> | 2016-10-11 17:21:21 +1300 |
|---|---|---|
| committer | hatharry <hatharry@hotmail.com> | 2016-10-11 17:21:21 +1300 |
| commit | d6862cefd83e3733a7a459ffd7cec616db006c22 (patch) | |
| tree | a712bbef2227b60d8d870898e4205328fbf02484 /MediaBrowser.Controller | |
| parent | 91225bc9688327e89224c91651dcec7eafa05234 (diff) | |
| parent | 9b0ac4bde5beb74703a258d582f477c6411ec6ec (diff) | |
Merge branch 'dev' of https://github.com/hatharry/Emby.git
Diffstat (limited to 'MediaBrowser.Controller')
61 files changed, 566 insertions, 802 deletions
diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index e3d2d0440..9177e2d81 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -31,6 +31,8 @@ namespace MediaBrowser.Controller.Channels /// <returns>ChannelFeatures.</returns> ChannelFeatures GetChannelFeatures(string id); + bool SupportsSync(string channelId); + /// <summary> /// Gets all channel features. /// </summary> @@ -132,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/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Controller/Collections/ManualCollectionsFolder.cs new file mode 100644 index 000000000..d2d28e504 --- /dev/null +++ b/MediaBrowser.Controller/Collections/ManualCollectionsFolder.cs @@ -0,0 +1,36 @@ +using MediaBrowser.Controller.Entities; + +namespace MediaBrowser.Controller.Collections +{ + public class ManualCollectionsFolder : BasePluginFolder, IHiddenFromDisplay + { + public ManualCollectionsFolder() + { + Name = "Collections"; + DisplayMediaType = "CollectionFolder"; + } + + public override bool IsHidden + { + get + { + return true; + } + } + + public bool IsHiddenFromUser(User user) + { + return !ConfigurationManager.Configuration.DisplayCollectionsView; + } + + public override string CollectionType + { + get { return Model.Entities.CollectionType.BoxSets; } + } + + public override string GetClientTypeName() + { + return typeof(CollectionFolder).Name; + } + } +}
\ No newline at end of file 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..9709813dc 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -34,6 +34,12 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool IsPhysicalRoot + { + get { return true; } + } + public override bool CanDelete() { return false; diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 1af55a389..891fb7d52 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; } @@ -63,7 +62,7 @@ namespace MediaBrowser.Controller.Entities.Audio [IgnoreDataMember] public override bool SupportsAddingToPlaylist { - get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } + get { return true; } } [IgnoreDataMember] @@ -84,21 +83,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 +246,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/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 81d1deaa2..076a7031a 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 { @@ -111,11 +109,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..cc4a8fdb9 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,22 @@ namespace MediaBrowser.Controller.Entities public bool IsInMixedFolder { get; set; } [IgnoreDataMember] + protected virtual bool SupportsIsInMixedFolderDetection + { + get { return false; } + } + + public bool DetectIsInMixedFolder() + { + if (SupportsIsInMixedFolderDetection) + { + + } + + return IsInMixedFolder; + } + + [IgnoreDataMember] public virtual bool SupportsRemoteImageDownloading { get @@ -254,6 +279,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 +446,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsInternetMetadataEnabled() { - return ConfigurationManager.Configuration.EnableInternetProviders; + return LibraryManager.GetLibraryOptions(this).EnableInternetProviders; } public virtual bool CanDelete() @@ -784,6 +822,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 +882,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 +998,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 +1034,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 +1120,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 +1144,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 +1188,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 +1219,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 +1296,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 +1379,9 @@ namespace MediaBrowser.Controller.Entities return false; } - return ConfigurationManager.Configuration.SaveLocalMeta; + var libraryOptions = LibraryManager.GetLibraryOptions(this); + + return libraryOptions.SaveLocalMetadata; } /// <summary> @@ -2107,14 +2164,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 597ecf973..04ba53263 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -48,24 +48,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 +90,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 = 1; + options.SchemaVersion = 3; XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index bf47ada0d..e5994fde5 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,12 @@ namespace MediaBrowser.Controller.Entities get { return false; } } + [IgnoreDataMember] + public virtual bool IsPhysicalRoot + { + get { return false; } + } + /// <summary> /// Gets a value indicating whether this instance is folder. /// </summary> @@ -117,19 +131,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 +179,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 +206,6 @@ namespace MediaBrowser.Controller.Entities get { return GetIndexByOptions(); } } - #endregion - /// <summary> /// Gets the actual children. /// </summary> @@ -1057,11 +1054,21 @@ namespace MediaBrowser.Controller.Entities /// <returns>IList{BaseItem}.</returns> public IList<BaseItem> GetRecursiveChildren() { - return GetRecursiveChildren(i => true); + return GetRecursiveChildren(true); + } + + public IList<BaseItem> GetRecursiveChildren(bool includeLinkedChildren) + { + return GetRecursiveChildren(i => true, includeLinkedChildren); } public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter) { + return GetRecursiveChildren(filter, true); + } + + public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter, bool includeLinkedChildren) + { var result = new Dictionary<Guid, BaseItem>(); AddChildrenToList(result, true, true, filter); @@ -1139,29 +1146,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..59bfc2363 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -8,11 +8,8 @@ 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>(); @@ -39,6 +36,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 +101,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/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/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index deea63112..f375e1b1c 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,51 @@ 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.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 +237,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..9a10a63bd 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; } @@ -81,7 +74,7 @@ namespace MediaBrowser.Controller.Entities.Movies // 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 +112,7 @@ namespace MediaBrowser.Controller.Entities.Movies { var info = GetItemLookupInfo<MovieInfo>(); - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { info.Name = System.IO.Path.GetFileName(ContainingFolderPath); } @@ -145,7 +138,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..41e25e406 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 { diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 65b7c9955..62af14159 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -85,9 +85,7 @@ namespace MediaBrowser.Controller.Entities.TV public override int GetChildCount(User user) { - Logger.Debug("Season {0} getting child cound", (Path ?? Name)); var result = GetChildren(user, true).Count(); - Logger.Debug("Season {0} child cound: ", result); return result; } @@ -156,15 +154,10 @@ namespace MediaBrowser.Controller.Entities.TV Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); - var id = Guid.NewGuid().ToString("N"); - - Logger.Debug("Season.GetItemsInternal entering GetEpisodes. Request id: " + id); var items = GetEpisodes(user).Where(filter); - Logger.Debug("Season.GetItemsInternal entering PostFilterAndSort. Request id: " + id); var result = PostFilterAndSort(items, query, false, false); - Logger.Debug("Season.GetItemsInternal complete. Request id: " + id); return Task.FromResult(result); } @@ -185,34 +178,12 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable<Episode> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes) { - return series.GetSeasonEpisodes(user, this, allSeriesEpisodes); + return series.GetSeasonEpisodes(this, user, allSeriesEpisodes); } public IEnumerable<Episode> GetEpisodes() { - var episodes = GetRecursiveChildren().OfType<Episode>(); - var series = Series; - - if (series != null && series.ContainsEpisodesWithoutSeasonFolders) - { - var seasonNumber = IndexNumber; - var list = episodes.ToList(); - - if (seasonNumber.HasValue) - { - list.AddRange(series.GetRecursiveChildren().OfType<Episode>() - .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value)); - } - else - { - list.AddRange(series.GetRecursiveChildren().OfType<Episode>() - .Where(i => !i.ParentIndexNumber.HasValue)); - } - - episodes = list.DistinctBy(i => i.Id); - } - - return episodes; + return Series.GetSeasonEpisodes(this, null, null); } public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 4915cfedc..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>(); @@ -209,7 +206,6 @@ namespace MediaBrowser.Controller.Entities.TV var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey); var query = new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = seriesKey, @@ -267,7 +263,6 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable<Episode> GetEpisodes(User user) { var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey); var query = new InternalItemsQuery(user) { @@ -291,8 +286,6 @@ namespace MediaBrowser.Controller.Entities.TV var allItems = LibraryManager.GetItemList(query).ToList(); - Logger.Debug("GetEpisodes return {0} items from database", allItems.Count); - var allSeriesEpisodes = allItems.OfType<Episode>().ToList(); var allEpisodes = allItems.OfType<Season>() @@ -373,27 +366,9 @@ namespace MediaBrowser.Controller.Entities.TV progress.Report(100); } - private IEnumerable<Episode> GetAllEpisodes(User user) - { - Logger.Debug("Series.GetAllEpisodes entering GetItemList"); - - var result = LibraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName } - - }).Cast<Episode>().ToList(); - - Logger.Debug("Series.GetAllEpisodes returning {0} episodes", result.Count); - - return result; - } - - public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason) + public IEnumerable<Episode> GetSeasonEpisodes(Season parentSeason, User user) { var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetSeasonEpisodes seriesKey: {0}", seriesKey); var query = new InternalItemsQuery(user) { @@ -401,34 +376,35 @@ namespace MediaBrowser.Controller.Entities.TV IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName } }; - var config = user.Configuration; - if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) + if (user != null) { - query.IsVirtualItem = false; - } - else if (!config.DisplayMissingEpisodes) - { - query.IsMissing = false; - } - else if (!config.DisplayUnairedEpisodes) - { - query.IsVirtualUnaired = false; + var config = user.Configuration; + if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) + { + query.IsVirtualItem = false; + } + else if (!config.DisplayMissingEpisodes) + { + query.IsMissing = false; + } + else if (!config.DisplayUnairedEpisodes) + { + query.IsVirtualUnaired = false; + } } var allItems = LibraryManager.GetItemList(query).OfType<Episode>(); - return GetSeasonEpisodes(user, parentSeason, allItems); + return GetSeasonEpisodes(parentSeason, user, allItems); } - public IEnumerable<Episode> GetSeasonEpisodes(User user, Season parentSeason, IEnumerable<Episode> allSeriesEpisodes) + public IEnumerable<Episode> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<Episode> allSeriesEpisodes) { if (allSeriesEpisodes == null) { - Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null"); - return GetSeasonEpisodes(user, parentSeason); + return GetSeasonEpisodes(parentSeason, user); } - Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason"); var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons); var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder; diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 306ce35ec..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) + 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/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 35375e7e6..92f8e8a9d 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; } 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..baf9293bf 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; } @@ -64,6 +63,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 +170,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public override bool SupportsAddingToPlaylist { - get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } + get { return true; } } [IgnoreDataMember] @@ -197,21 +202,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 +470,7 @@ namespace MediaBrowser.Controller.Entities public override IEnumerable<string> GetDeletePaths() { - if (!IsInMixedFolder) + if (!DetectIsInMixedFolder()) { return new[] { ContainingFolderPath }; } @@ -600,7 +590,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/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index f4c0e7658..d6744e804 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -89,5 +89,7 @@ namespace MediaBrowser.Controller string GetLocalApiUrl(IPAddress ipAddress); void LaunchUrl(string url); + + void EnableLoopback(string appName); } } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 0862e3eaf..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); @@ -566,5 +569,8 @@ namespace MediaBrowser.Controller.Library QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query); QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query); QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query); + + void RegisterIgnoredPath(string path); + void UnRegisterIgnoredPath(string path); } }
\ No newline at end of file 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/Library/NameExtensions.cs b/MediaBrowser.Controller/Library/NameExtensions.cs index 6973dce64..72f036b0a 100644 --- a/MediaBrowser.Controller/Library/NameExtensions.cs +++ b/MediaBrowser.Controller/Library/NameExtensions.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Controller.Library } } - class TextComparer : IComparer<string>, IEqualityComparer<string> + public class DistinctNameComparer : IComparer<string>, IEqualityComparer<string> { public int Compare(string x, string y) { @@ -63,7 +63,7 @@ namespace MediaBrowser.Controller.Library return 0; } - return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace); + return string.Compare(x.RemoveDiacritics(), y.RemoveDiacritics(), StringComparison.OrdinalIgnoreCase); } public bool Equals(string x, string y) diff --git a/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs b/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs deleted file mode 100644 index 3626c18e5..000000000 --- a/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using MediaBrowser.Model.Entities; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.LiveTv -{ - public interface IHasRegistrationInfo - { - /// <summary> - /// Gets the registration information. - /// </summary> - /// <param name="feature">The feature.</param> - /// <returns>Task<MBRegistrationRecord>.</returns> - Task<MBRegistrationRecord> GetRegistrationInfo(string feature); - } -} diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index ed64127c3..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> @@ -108,6 +109,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="cancellationToken">The cancellation token.</param> /// <returns>QueryResult{RecordingInfoDto}.</returns> Task<QueryResult<BaseItemDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken); + Task<QueryResult<BaseItemDto>> GetRecordingSeries(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken); /// <summary> /// Gets the timers. @@ -124,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> @@ -155,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> @@ -219,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. @@ -241,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. @@ -302,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. @@ -330,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> @@ -364,11 +357,9 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the registration information. /// </summary> - /// <param name="channelId">The channel identifier.</param> - /// <param name="programId">The program identifier.</param> /// <param name="feature">The feature.</param> /// <returns>Task<MBRegistrationRecord>.</returns> - Task<MBRegistrationRecord> GetRegistrationInfo(string channelId, string programId, string feature); + Task<MBRegistrationRecord> GetRegistrationInfo(string feature); /// <summary> /// Adds the channel information. @@ -396,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..69a1c24ea 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -9,7 +9,7 @@ using System.Runtime.Serialization; namespace MediaBrowser.Controller.LiveTv { - public class LiveTvChannel : BaseItem, IHasMediaSources + public class LiveTvChannel : BaseItem, IHasMediaSources, IHasProgramAttributes { public override List<string> GetUserDataKeys() { @@ -137,5 +137,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..e26dd6a77 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; } @@ -111,7 +112,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 a6a3e6108..d0377fbfd 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.LiveTv; using System; using System.Collections.Generic; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.LiveTv { @@ -66,6 +67,8 @@ namespace MediaBrowser.Controller.LiveTv /// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value> public bool? IsHD { get; set; } + public bool? Is3D { get; set; } + /// <summary> /// Gets or sets the audio. /// </summary> @@ -84,6 +87,8 @@ namespace MediaBrowser.Controller.LiveTv /// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value> public bool IsRepeat { get; set; } + public bool IsSubjectToBlackout { get; set; } + /// <summary> /// Gets or sets the episode title. /// </summary> @@ -102,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> @@ -144,6 +151,8 @@ namespace MediaBrowser.Controller.LiveTv /// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value> public bool IsKids { get; set; } + public bool IsEducational { get; set; } + /// <summary> /// Gets or sets a value indicating whether this instance is premiere. /// </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 e7eaa1dc0..11ed0f674 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -91,13 +91,11 @@ <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" /> + <Compile Include="Collections\ManualCollectionsFolder.cs" /> <Compile Include="Connect\ConnectSupporterSummary.cs" /> <Compile Include="Connect\IConnectManager.cs" /> <Compile Include="Connect\UserLinkResult.cs" /> @@ -134,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" /> @@ -146,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" /> @@ -198,9 +192,9 @@ <Compile Include="Library\NameExtensions.cs" /> <Compile Include="Library\PlaybackStopEventArgs.cs" /> <Compile Include="Library\UserDataSaveEventArgs.cs" /> - <Compile Include="LiveTv\IHasRegistrationInfo.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..f97fe9560 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. 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/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 c0912708c..13d43eee6 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -23,14 +23,18 @@ namespace MediaBrowser.Controller.Providers /// The logger /// </summary> protected ILogger Logger { get; private set; } + protected IProviderManager ProviderManager { get; private set; } + + private Dictionary<string, string> _validProviderIds; /// <summary> /// Initializes a new instance of the <see cref="BaseItemXmlParser{T}" /> class. /// </summary> /// <param name="logger">The logger.</param> - public BaseItemXmlParser(ILogger logger) + public BaseItemXmlParser(ILogger logger, IProviderManager providerManager) { Logger = logger; + ProviderManager = providerManager; } /// <summary> @@ -60,6 +64,22 @@ namespace MediaBrowser.Controller.Providers ValidationType = ValidationType.None }; + _validProviderIds = _validProviderIds = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); + + var idInfos = ProviderManager.GetExternalIdInfos(item.Item); + + foreach (var info in idInfos) + { + var id = info.Key + "Id"; + if (!_validProviderIds.ContainsKey(id)) + { + _validProviderIds.Add(id, info.Key); + } + } + + //Additional Mappings + _validProviderIds.Add("IMDB", "Imdb"); + //Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken); Fetch(item, metadataFile, settings, Encoding.UTF8, cancellationToken); } @@ -327,7 +347,7 @@ namespace MediaBrowser.Controller.Providers var person = item as Person; if (person != null) { - person.PlaceOfBirth = val; + person.ProductionLocations = new List<string> { val }; } } @@ -657,14 +677,6 @@ namespace MediaBrowser.Controller.Providers break; } - case "TvDbId": - var tvdbId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tvdbId)) - { - item.SetProviderId(MetadataProviders.Tvdb, tvdbId); - } - break; - case "VoteCount": { var val = reader.ReadElementContentAsString(); @@ -679,95 +691,7 @@ namespace MediaBrowser.Controller.Providers } break; } - case "MusicBrainzAlbumId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbz); - } - break; - } - case "MusicBrainzAlbumArtistId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mbz); - } - break; - } - case "MusicBrainzArtistId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzArtist, mbz); - } - break; - } - case "MusicBrainzReleaseGroupId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, mbz); - } - break; - } - case "TVRageId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.TvRage, id); - } - break; - } - case "TvMazeId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.TvMaze, id); - } - break; - } - case "AudioDbArtistId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.AudioDbArtist, id); - } - break; - } - case "AudioDbAlbumId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.AudioDbAlbum, id); - } - break; - } - case "RottenTomatoesId": - var rtId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(rtId)) - { - item.SetProviderId(MetadataProviders.RottenTomatoes, rtId); - } - break; - - case "TMDbId": - var tmdb = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tmdb)) - { - item.SetProviderId(MetadataProviders.Tmdb, tmdb); - } - break; - - case "TMDbCollectionId": + case "CollectionNumber": var tmdbCollection = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(tmdbCollection)) { @@ -775,30 +699,6 @@ namespace MediaBrowser.Controller.Providers } break; - case "TVcomId": - var TVcomId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(TVcomId)) - { - item.SetProviderId(MetadataProviders.Tvcom, TVcomId); - } - break; - - case "Zap2ItId": - var zap2ItId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(zap2ItId)) - { - item.SetProviderId(MetadataProviders.Zap2It, zap2ItId); - } - break; - - case "IMDB": - var imDbId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(imDbId)) - { - item.SetProviderId(MetadataProviders.Imdb, imDbId); - } - break; - case "Genres": { using (var subtree = reader.ReadSubtree()) @@ -890,8 +790,25 @@ namespace MediaBrowser.Controller.Providers } default: - reader.Skip(); - break; + { + string readerName = reader.Name; + string providerIdValue; + if (_validProviderIds.TryGetValue(readerName, out providerIdValue)) + { + var id = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(id)) + { + item.SetProviderId(providerIdValue, id); + } + } + else + { + reader.Skip(); + } + + break; + + } } } @@ -976,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; } @@ -1017,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; } - } -} diff --git a/MediaBrowser.Controller/Session/AuthenticationRequest.cs b/MediaBrowser.Controller/Session/AuthenticationRequest.cs index bfd7f928b..362f5b2b9 100644 --- a/MediaBrowser.Controller/Session/AuthenticationRequest.cs +++ b/MediaBrowser.Controller/Session/AuthenticationRequest.cs @@ -4,6 +4,7 @@ namespace MediaBrowser.Controller.Session public class AuthenticationRequest { public string Username { get; set; } + public string UserId { get; set; } public string PasswordSha1 { get; set; } public string PasswordMd5 { get; set; } public string App { get; set; } |
