diff options
Diffstat (limited to 'MediaBrowser.Model')
49 files changed, 685 insertions, 375 deletions
diff --git a/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs b/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs index b5bf29990..4ae4fe822 100644 --- a/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs +++ b/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs @@ -35,7 +35,14 @@ namespace MediaBrowser.Model.ApiClient public static Task<SyncDialogOptions> GetSyncOptions(this IApiClient apiClient, SyncJob job) { - return apiClient.GetSyncOptions(job.RequestedItemIds, job.UserId, job.ParentId, job.Category); + return apiClient.GetSyncOptions(new SyncJobRequest + { + Category = job.Category, + ItemIds = job.RequestedItemIds, + ParentId = job.ParentId, + TargetId = job.TargetId, + UserId = job.UserId + }); } } } diff --git a/MediaBrowser.Model/ApiClient/ConnectionOptions.cs b/MediaBrowser.Model/ApiClient/ConnectionOptions.cs index 445eaa04e..e12676311 100644 --- a/MediaBrowser.Model/ApiClient/ConnectionOptions.cs +++ b/MediaBrowser.Model/ApiClient/ConnectionOptions.cs @@ -13,11 +13,17 @@ namespace MediaBrowser.Model.ApiClient /// </summary> /// <value><c>true</c> if [report capabilities]; otherwise, <c>false</c>.</value> public bool ReportCapabilities { get; set; } + /// <summary> + /// Gets or sets a value indicating whether [update date last accessed]. + /// </summary> + /// <value><c>true</c> if [update date last accessed]; otherwise, <c>false</c>.</value> + public bool UpdateDateLastAccessed { get; set; } public ConnectionOptions() { EnableWebSocket = true; ReportCapabilities = true; + UpdateDateLastAccessed = true; } } } diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index ca49c6c5a..ef99e444f 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -251,12 +251,12 @@ namespace MediaBrowser.Model.ApiClient Task<ItemsResult> GetAdditionalParts(string itemId, string userId); /// <summary> - /// Gets the live media information. + /// Gets the playback information. /// </summary> /// <param name="itemId">The item identifier.</param> /// <param name="userId">The user identifier.</param> /// <returns>Task<LiveMediaInfoResult>.</returns> - Task<LiveMediaInfoResult> GetLiveMediaInfo(string itemId, string userId); + Task<LiveMediaInfoResult> GetPlaybackInfo(string itemId, string userId); /// <summary> /// Gets the users async. @@ -344,14 +344,14 @@ namespace MediaBrowser.Model.ApiClient /// </summary> /// <param name="query">The query.</param> /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetInstantMixFromArtistAsync(SimilarItemsByNameQuery query); + Task<ItemsResult> GetInstantMixFromArtistAsync(SimilarItemsQuery query); /// <summary> /// Gets the instant mix from music genre async. /// </summary> /// <param name="query">The query.</param> /// <returns>Task{ItemsResult}.</returns> - Task<ItemsResult> GetInstantMixFromMusicGenreAsync(SimilarItemsByNameQuery query); + Task<ItemsResult> GetInstantMixFromMusicGenreAsync(SimilarItemsQuery query); /// <summary> /// Gets the similar movies async. @@ -418,15 +418,6 @@ namespace MediaBrowser.Model.ApiClient Task<ItemsResult> GetAlbumArtistsAsync(ArtistsQuery query); /// <summary> - /// Gets a studio - /// </summary> - /// <param name="name">The name.</param> - /// <param name="userId">The user id.</param> - /// <returns>Task{BaseItemDto}.</returns> - /// <exception cref="ArgumentNullException">userId</exception> - Task<BaseItemDto> GetStudioAsync(string name, string userId); - - /// <summary> /// Gets the next up async. /// </summary> /// <param name="query">The query.</param> @@ -495,15 +486,6 @@ namespace MediaBrowser.Model.ApiClient Task<BaseItemDto> GetGameGenreAsync(string name, string userId); /// <summary> - /// Gets the artist async. - /// </summary> - /// <param name="name">The name.</param> - /// <param name="userId">The user id.</param> - /// <returns>Task{BaseItemDto}.</returns> - /// <exception cref="ArgumentNullException">name</exception> - Task<BaseItemDto> GetArtistAsync(string name, string userId); - - /// <summary> /// Restarts the server. /// </summary> /// <returns>Task.</returns> @@ -1014,14 +996,6 @@ namespace MediaBrowser.Model.ApiClient /// <summary> /// Gets an image url that can be used to download an image from the api /// </summary> - /// <param name="year">The year.</param> - /// <param name="options">The options.</param> - /// <returns>System.String.</returns> - string GetYearImageUrl(int year, ImageOptions options); - - /// <summary> - /// Gets an image url that can be used to download an image from the api - /// </summary> /// <param name="name">The name.</param> /// <param name="options">The options.</param> /// <returns>System.String.</returns> @@ -1045,24 +1019,6 @@ namespace MediaBrowser.Model.ApiClient string GetGameGenreImageUrl(string name, ImageOptions options); /// <summary> - /// Gets an image url that can be used to download an image from the api - /// </summary> - /// <param name="name">The name.</param> - /// <param name="options">The options.</param> - /// <returns>System.String.</returns> - /// <exception cref="ArgumentNullException">name</exception> - string GetStudioImageUrl(string name, ImageOptions options); - - /// <summary> - /// Gets the artist image URL. - /// </summary> - /// <param name="name">The name.</param> - /// <param name="options">The options.</param> - /// <returns>System.String.</returns> - /// <exception cref="ArgumentNullException">name</exception> - string GetArtistImageUrl(string name, ImageOptions options); - - /// <summary> /// This is a helper to get a list of backdrop url's from a given ApiBaseItemWrapper. If the actual item does not have any backdrops it will return backdrops from the first parent that does. /// </summary> /// <param name="item">A given item.</param> @@ -1362,7 +1318,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> Task SendContextMessageAsync(string itemType, string itemId, string itemName, string context, - CancellationToken cancellationToken); + CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Gets the content upload history. @@ -1380,7 +1336,7 @@ namespace MediaBrowser.Model.ApiClient /// <returns>Task.</returns> Task UploadFile(Stream stream, LocalFileInfo file, - CancellationToken cancellationToken); + CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Gets the devices options options. @@ -1436,7 +1392,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="id">The identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<Stream>.</returns> - Task<Stream> GetSyncJobItemFile(string id, CancellationToken cancellationToken); + Task<Stream> GetSyncJobItemFile(string id, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Gets the synchronize job item additional file. @@ -1519,11 +1475,20 @@ namespace MediaBrowser.Model.ApiClient /// <summary> /// Gets the synchronize options. /// </summary> - /// <param name="userId">The user identifier.</param> - /// <param name="itemIds">The item ids.</param> - /// <param name="parentId">The parent identifier.</param> - /// <param name="category">The category.</param> + /// <param name="jobInfo">The job information.</param> /// <returns>Task<SyncOptions>.</returns> - Task<SyncDialogOptions> GetSyncOptions(IEnumerable<string> itemIds, string userId, string parentId = null, SyncCategory? category = null); + Task<SyncDialogOptions> GetSyncOptions(SyncJobRequest jobInfo); + /// <summary> + /// Gets the synchronize options. + /// </summary> + /// <param name="jobInfo">The job information.</param> + /// <returns>Task<SyncDialogOptions>.</returns> + Task<SyncDialogOptions> GetSyncOptions(SyncJob jobInfo); + /// <summary> + /// Gets the movie recommendations. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>Task<List<RecommendationDto>>.</returns> + Task<List<RecommendationDto>> GetMovieRecommendations(MovieRecommendationQuery query); } }
\ No newline at end of file diff --git a/MediaBrowser.Model/ApiClient/IConnectionManager.cs b/MediaBrowser.Model/ApiClient/IConnectionManager.cs index 341df2728..6ff48a044 100644 --- a/MediaBrowser.Model/ApiClient/IConnectionManager.cs +++ b/MediaBrowser.Model/ApiClient/IConnectionManager.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Connect; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Events; +using MediaBrowser.Model.Session; using System; using System.Collections.Generic; using System.Threading; @@ -48,6 +49,12 @@ namespace MediaBrowser.Model.ApiClient bool SaveLocalCredentials { get; set; } /// <summary> + /// Gets the client capabilities. + /// </summary> + /// <value>The client capabilities.</value> + ClientCapabilities ClientCapabilities { get; } + + /// <summary> /// Gets the API client. /// </summary> /// <param name="item">The item.</param> @@ -66,7 +73,7 @@ namespace MediaBrowser.Model.ApiClient /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<ConnectionResult>.</returns> - Task<ConnectionResult> Connect(CancellationToken cancellationToken); + Task<ConnectionResult> Connect(CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Connects the specified API client. @@ -74,7 +81,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="apiClient">The API client.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<ConnectionResult>.</returns> - Task<ConnectionResult> Connect(IApiClient apiClient, CancellationToken cancellationToken); + Task<ConnectionResult> Connect(IApiClient apiClient, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Connects the specified server. @@ -82,7 +89,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="server">The server.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<ConnectionResult>.</returns> - Task<ConnectionResult> Connect(ServerInfo server, CancellationToken cancellationToken); + Task<ConnectionResult> Connect(ServerInfo server, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Connects the specified server. @@ -91,7 +98,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="options">The options.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<ConnectionResult>.</returns> - Task<ConnectionResult> Connect(ServerInfo server, ConnectionOptions options, CancellationToken cancellationToken); + Task<ConnectionResult> Connect(ServerInfo server, ConnectionOptions options, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Connects the specified server. @@ -99,7 +106,7 @@ namespace MediaBrowser.Model.ApiClient /// <param name="address">The address.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<ConnectionResult>.</returns> - Task<ConnectionResult> Connect(string address, CancellationToken cancellationToken); + Task<ConnectionResult> Connect(string address, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Logouts this instance. @@ -139,10 +146,17 @@ namespace MediaBrowser.Model.ApiClient Task ExchangePin(PinCreationResult pin); /// <summary> + /// Gets the server information. + /// </summary> + /// <param name="id">The identifier.</param> + /// <returns>Task<ServerInfo>.</returns> + Task<ServerInfo> GetServerInfo(string id); + + /// <summary> /// Gets the available servers. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> - Task<List<ServerInfo>> GetAvailableServers(CancellationToken cancellationToken); + Task<List<ServerInfo>> GetAvailableServers(CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Authenticates an offline user with their password diff --git a/MediaBrowser.Model/ApiClient/IDevice.cs b/MediaBrowser.Model/ApiClient/IDevice.cs index 84927c20a..7b67122fb 100644 --- a/MediaBrowser.Model/ApiClient/IDevice.cs +++ b/MediaBrowser.Model/ApiClient/IDevice.cs @@ -39,6 +39,6 @@ namespace MediaBrowser.Model.ApiClient /// <param name="apiClient">The API client.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task UploadFile(LocalFileInfo file, IApiClient apiClient, CancellationToken cancellationToken); + Task UploadFile(LocalFileInfo file, IApiClient apiClient, CancellationToken cancellationToken = default(CancellationToken)); } } diff --git a/MediaBrowser.Model/Configuration/DlnaOptions.cs b/MediaBrowser.Model/Configuration/DlnaOptions.cs index df7ae5c49..277102a50 100644 --- a/MediaBrowser.Model/Configuration/DlnaOptions.cs +++ b/MediaBrowser.Model/Configuration/DlnaOptions.cs @@ -10,6 +10,7 @@ namespace MediaBrowser.Model.Configuration public int ClientDiscoveryIntervalSeconds { get; set; } public int BlastAliveMessageIntervalSeconds { get; set; } public string DefaultUserId { get; set; } + public bool EnableEnhancedMovies { get; set; } public DlnaOptions() { @@ -18,6 +19,7 @@ namespace MediaBrowser.Model.Configuration BlastAliveMessages = true; ClientDiscoveryIntervalSeconds = 60; BlastAliveMessageIntervalSeconds = 30; + EnableEnhancedMovies = true; } } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index a28d3bd5d..c06aedb50 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -45,6 +45,12 @@ namespace MediaBrowser.Model.Configuration public bool EnableHttps { get; set; } /// <summary> + /// Gets or sets a value indicating whether [enable user specific user views]. + /// </summary> + /// <value><c>true</c> if [enable user specific user views]; otherwise, <c>false</c>.</value> + public bool EnableUserSpecificUserViews { get; set; } + + /// <summary> /// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. /// </summary> /// <value>The value pointing to the file system where the ssl certiifcate is located..</value> @@ -203,8 +209,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableAudioArchiveFiles { get; set; } public bool EnableVideoArchiveFiles { get; set; } - public bool EnableLegacyCollectionInView { get; set; } - /// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index aa49ee50d..a78161140 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -33,20 +33,12 @@ namespace MediaBrowser.Model.Configuration public bool DisplayMissingEpisodes { get; set; } public bool DisplayUnairedEpisodes { get; set; } - public bool EnableLiveTvManagement { get; set; } - public bool EnableLiveTvAccess { get; set; } - - public bool EnableMediaPlayback { get; set; } - public bool EnableContentDeletion { get; set; } - public bool GroupMoviesIntoBoxSets { get; set; } public string[] DisplayChannelsWithinViews { get; set; } public string[] ExcludeFoldersFromGrouping { get; set; } - public UnratedItem[] BlockUnratedItems { get; set; } - public SubtitlePlaybackMode SubtitleMode { get; set; } public bool DisplayCollectionsView { get; set; } public bool DisplayFoldersView { get; set; } @@ -69,14 +61,10 @@ namespace MediaBrowser.Model.Configuration public UserConfiguration() { PlayDefaultAudioTrack = true; - EnableLiveTvManagement = true; - EnableMediaPlayback = true; - EnableLiveTvAccess = true; LatestItemsExcludes = new string[] { }; OrderedViews = new string[] { }; DisplayChannelsWithinViews = new string[] { }; - BlockUnratedItems = new UnratedItem[] { }; ExcludeFoldersFromGrouping = new string[] { }; DisplayCollectionsView = true; diff --git a/MediaBrowser.Model/Devices/DeviceInfo.cs b/MediaBrowser.Model/Devices/DeviceInfo.cs index e5efe9f60..726e9d6e5 100644 --- a/MediaBrowser.Model/Devices/DeviceInfo.cs +++ b/MediaBrowser.Model/Devices/DeviceInfo.cs @@ -46,6 +46,11 @@ namespace MediaBrowser.Model.Devices /// <value>The name of the application.</value> public string AppName { get; set; } /// <summary> + /// Gets or sets the application version. + /// </summary> + /// <value>The application version.</value> + public string AppVersion { get; set; } + /// <summary> /// Gets or sets the last user identifier. /// </summary> /// <value>The last user identifier.</value> diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs index cddfd8955..6ad4fa265 100644 --- a/MediaBrowser.Model/Dlna/AudioOptions.cs +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -46,17 +46,6 @@ namespace MediaBrowser.Model.Dlna /// </summary> /// <value>The audio transcoding bitrate.</value> public int? AudioTranscodingBitrate { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether [supports direct remote content]. - /// </summary> - /// <value><c>true</c> if [supports direct remote content]; otherwise, <c>false</c>.</value> - public bool SupportsDirectRemoteContent { get; set; } - /// <summary> - /// Gets or sets a value indicating whether [supports custom HTTP headers]. - /// </summary> - /// <value><c>true</c> if [supports custom HTTP headers]; otherwise, <c>false</c>.</value> - public bool SupportsCustomHttpHeaders { get; set; } /// <summary> /// Gets the maximum bitrate. diff --git a/MediaBrowser.Model/Dlna/ILocalPlayer.cs b/MediaBrowser.Model/Dlna/ILocalPlayer.cs new file mode 100644 index 000000000..55e11ec4b --- /dev/null +++ b/MediaBrowser.Model/Dlna/ILocalPlayer.cs @@ -0,0 +1,26 @@ + +namespace MediaBrowser.Model.Dlna +{ + public interface ILocalPlayer + { + /// <summary> + /// Determines whether this instance [can access file] the specified path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if this instance [can access file] the specified path; otherwise, <c>false</c>.</returns> + bool CanAccessFile(string path); + /// <summary> + /// Determines whether this instance [can access directory] the specified path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if this instance [can access directory] the specified path; otherwise, <c>false</c>.</returns> + bool CanAccessDirectory(string path); + /// <summary> + /// Determines whether this instance [can access URL] the specified URL. + /// </summary> + /// <param name="url">The URL.</param> + /// <param name="requiresCustomRequestHeaders">if set to <c>true</c> [requires custom request headers].</param> + /// <returns><c>true</c> if this instance [can access URL] the specified URL; otherwise, <c>false</c>.</returns> + bool CanAccessUrl(string url, bool requiresCustomRequestHeaders); + } +} diff --git a/MediaBrowser.Model/Dlna/NullLocalPlayer.cs b/MediaBrowser.Model/Dlna/NullLocalPlayer.cs new file mode 100644 index 000000000..c34b63887 --- /dev/null +++ b/MediaBrowser.Model/Dlna/NullLocalPlayer.cs @@ -0,0 +1,21 @@ + +namespace MediaBrowser.Model.Dlna +{ + public class NullLocalPlayer : ILocalPlayer + { + public bool CanAccessFile(string path) + { + return false; + } + + public bool CanAccessDirectory(string path) + { + return false; + } + + public bool CanAccessUrl(string url, bool requiresCustomRequestHeaders) + { + return false; + } + } +} diff --git a/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs b/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs new file mode 100644 index 000000000..4ed412985 --- /dev/null +++ b/MediaBrowser.Model/Dlna/PlaybackErrorCode.cs @@ -0,0 +1,10 @@ + +namespace MediaBrowser.Model.Dlna +{ + public enum PlaybackErrorCode + { + NotAllowed = 0, + NoCompatibleStream = 1, + RateLimitExceeded = 2 + } +} diff --git a/MediaBrowser.Model/Dlna/PlaybackException.cs b/MediaBrowser.Model/Dlna/PlaybackException.cs new file mode 100644 index 000000000..761fa1c90 --- /dev/null +++ b/MediaBrowser.Model/Dlna/PlaybackException.cs @@ -0,0 +1,9 @@ +using System; + +namespace MediaBrowser.Model.Dlna +{ + public class PlaybackException : Exception + { + public PlaybackErrorCode ErrorCode { get; set;} + } +} diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 6fa29a533..6edbe00da 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -10,28 +10,40 @@ namespace MediaBrowser.Model.Dlna { public class StreamBuilder { + private readonly ILocalPlayer _localPlayer; + + public StreamBuilder(ILocalPlayer localPlayer) + { + _localPlayer = localPlayer; + } + public StreamBuilder() + : this(new NullLocalPlayer()) + { + } + public StreamInfo BuildAudioItem(AudioOptions options) { ValidateAudioInput(options); - List<MediaSourceInfo> mediaSources = options.MediaSources; - - // If the client wants a specific media source, filter now - if (!string.IsNullOrEmpty(options.MediaSourceId)) + List<MediaSourceInfo> mediaSources = new List<MediaSourceInfo>(); + foreach (MediaSourceInfo i in options.MediaSources) { - List<MediaSourceInfo> newMediaSources = new List<MediaSourceInfo>(); - foreach (MediaSourceInfo i in mediaSources) + if (string.IsNullOrEmpty(options.MediaSourceId) || + StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId)) { - if (StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId)) - newMediaSources.Add(i); + mediaSources.Add(i); } - - mediaSources = newMediaSources; } List<StreamInfo> streams = new List<StreamInfo>(); foreach (MediaSourceInfo i in mediaSources) - streams.Add(BuildAudioItem(i, options)); + { + StreamInfo streamInfo = BuildAudioItem(i, options); + if (streamInfo != null) + { + streams.Add(streamInfo); + } + } foreach (StreamInfo stream in streams) { @@ -46,24 +58,25 @@ namespace MediaBrowser.Model.Dlna { ValidateInput(options); - List<MediaSourceInfo> mediaSources = options.MediaSources; - - // If the client wants a specific media source, filter now - if (!string.IsNullOrEmpty(options.MediaSourceId)) + List<MediaSourceInfo> mediaSources = new List<MediaSourceInfo>(); + foreach (MediaSourceInfo i in options.MediaSources) { - List<MediaSourceInfo> newMediaSources = new List<MediaSourceInfo>(); - foreach (MediaSourceInfo i in mediaSources) + if (string.IsNullOrEmpty(options.MediaSourceId) || + StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId)) { - if (StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId)) - newMediaSources.Add(i); + mediaSources.Add(i); } - - mediaSources = newMediaSources; } List<StreamInfo> streams = new List<StreamInfo>(); foreach (MediaSourceInfo i in mediaSources) - streams.Add(BuildVideoItem(i, options)); + { + StreamInfo streamInfo = BuildVideoItem(i, options); + if (streamInfo != null) + { + streams.Add(streamInfo); + } + } foreach (StreamInfo stream in streams) { @@ -97,7 +110,10 @@ namespace MediaBrowser.Model.Dlna { return stream; } - return null; + + PlaybackException error = new PlaybackException(); + error.ErrorCode = PlaybackErrorCode.NoCompatibleStream; + throw error; } private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options) @@ -112,64 +128,66 @@ namespace MediaBrowser.Model.Dlna DeviceProfile = options.Profile }; - int? maxBitrateSetting = options.GetMaxBitrate(); - - MediaStream audioStream = item.DefaultAudioStream; + List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, options); - // Honor the max bitrate setting - if (IsAudioEligibleForDirectPlay(item, maxBitrateSetting)) + if (directPlayMethods.Count > 0) { - DirectPlayProfile directPlay = null; - foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles) - { - if (i.Type == playlistItem.MediaType && IsAudioDirectPlaySupported(i, item, audioStream)) - { - directPlay = i; - break; - } - } + MediaStream audioStream = item.DefaultAudioStream; - if (directPlay != null) + string audioCodec = audioStream == null ? null : audioStream.Codec; + + // Make sure audio codec profiles are satisfied + if (!string.IsNullOrEmpty(audioCodec)) { - string audioCodec = audioStream == null ? null : audioStream.Codec; + ConditionProcessor conditionProcessor = new ConditionProcessor(); - // Make sure audio codec profiles are satisfied - if (!string.IsNullOrEmpty(audioCodec)) + List<ProfileCondition> conditions = new List<ProfileCondition>(); + foreach (CodecProfile i in options.Profile.CodecProfiles) { - ConditionProcessor conditionProcessor = new ConditionProcessor(); - - List<ProfileCondition> conditions = new List<ProfileCondition>(); - foreach (CodecProfile i in options.Profile.CodecProfiles) + if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec)) { - if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec)) + foreach (ProfileCondition c in i.Conditions) { - foreach (ProfileCondition c in i.Conditions) - { - conditions.Add(c); - } + conditions.Add(c); } } + } - int? audioChannels = audioStream.Channels; - int? audioBitrate = audioStream.BitRate; + int? audioChannels = audioStream.Channels; + int? audioBitrate = audioStream.BitRate; - bool all = true; - foreach (ProfileCondition c in conditions) + bool all = true; + foreach (ProfileCondition c in conditions) + { + if (!conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate)) { - if (!conditionProcessor.IsAudioConditionSatisfied(c, audioChannels, audioBitrate)) - { - all = false; - break; - } + all = false; + break; } + } - if (all) + if (all) + { + if (item.Protocol == MediaProtocol.File && + directPlayMethods.Contains(PlayMethod.DirectPlay) && + _localPlayer.CanAccessFile(item.Path)) + { + playlistItem.PlayMethod = PlayMethod.DirectPlay; + } + else if (item.Protocol == MediaProtocol.Http && + directPlayMethods.Contains(PlayMethod.DirectPlay) && + _localPlayer.CanAccessUrl(item.Path, item.RequiredHttpHeaders.Count > 0)) + { + playlistItem.PlayMethod = PlayMethod.DirectPlay; + } + else if (directPlayMethods.Contains(PlayMethod.DirectStream)) { playlistItem.PlayMethod = PlayMethod.DirectStream; - playlistItem.Container = item.Container; - - return playlistItem; } + + playlistItem.Container = item.Container; + + return playlistItem; } } } @@ -186,6 +204,11 @@ namespace MediaBrowser.Model.Dlna if (transcodingProfile != null) { + if (!item.SupportsTranscoding) + { + return null; + } + playlistItem.PlayMethod = PlayMethod.Transcode; playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength; @@ -233,6 +256,41 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } + private List<PlayMethod> GetAudioDirectPlayMethods(MediaSourceInfo item, AudioOptions options) + { + MediaStream audioStream = item.DefaultAudioStream; + + DirectPlayProfile directPlayProfile = null; + foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles) + { + if (i.Type == DlnaProfileType.Audio && IsAudioDirectPlaySupported(i, item, audioStream)) + { + directPlayProfile = i; + break; + } + } + + List<PlayMethod> playMethods = new List<PlayMethod>(); + + if (directPlayProfile != null) + { + // While options takes the network and other factors into account. Only applies to direct stream + if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate())) + { + playMethods.Add(PlayMethod.DirectStream); + } + + // The profile describes what the device supports + // If device requirements are satisfied then allow both direct stream and direct play + if (IsAudioEligibleForDirectPlay(item, options.Profile.MaxStaticBitrate)) + { + playMethods.Add(PlayMethod.DirectPlay); + } + } + + return playMethods; + } + private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options) { StreamInfo playlistItem = new StreamInfo @@ -267,7 +325,7 @@ namespace MediaBrowser.Model.Dlna if (subtitleStream != null) { - SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile); + SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile, options.Context); playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method; playlistItem.SubtitleFormat = subtitleProfile.Format; @@ -290,9 +348,14 @@ namespace MediaBrowser.Model.Dlna if (transcodingProfile != null) { + if (!item.SupportsTranscoding) + { + return null; + } + if (subtitleStream != null) { - SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile); + SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile, options.Context); playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method; playlistItem.SubtitleFormat = subtitleProfile.Format; @@ -505,18 +568,25 @@ namespace MediaBrowser.Model.Dlna if (mediaSource.Protocol == MediaProtocol.Http) { - if (!options.SupportsDirectRemoteContent) + if (_localPlayer.CanAccessUrl(mediaSource.Path, mediaSource.RequiredHttpHeaders.Count > 0)) { - return null; + return PlayMethod.DirectPlay; } + } - if (mediaSource.RequiredHttpHeaders.Count > 0 && !options.SupportsCustomHttpHeaders) + else if (mediaSource.Protocol == MediaProtocol.File) + { + if (_localPlayer.CanAccessFile(mediaSource.Path)) { - return null; + return PlayMethod.DirectPlay; } - return PlayMethod.DirectPlay; } + if (!mediaSource.SupportsDirectStream) + { + return null; + } + return PlayMethod.DirectStream; } @@ -527,7 +597,7 @@ namespace MediaBrowser.Model.Dlna { if (subtitleStream != null) { - SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile); + SubtitleProfile subtitleProfile = GetSubtitleProfile(subtitleStream, options.Profile, options.Context); if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed) { @@ -538,14 +608,20 @@ namespace MediaBrowser.Model.Dlna return IsAudioEligibleForDirectPlay(item, maxBitrate); } - public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, DeviceProfile deviceProfile) + public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, DeviceProfile deviceProfile, EncodingContext context) { // Look for an external profile that matches the stream type (text/graphical) foreach (SubtitleProfile profile in deviceProfile.SubtitleProfiles) { - if (subtitleStream.SupportsExternalStream) + if (profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) { - if (profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) + if (subtitleStream.SupportsExternalStream) + { + return profile; + } + + // For sync we can handle the longer extraction times + if (context == EncodingContext.Static && subtitleStream.IsTextSubtitleStream) { return profile; } diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 57a3899d4..9e7561967 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -262,7 +262,7 @@ namespace MediaBrowser.Model.Dlna private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream) { - SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, DeviceProfile); + SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, DeviceProfile, Context); if (subtitleProfile.Method != SubtitleDeliveryMethod.External) { @@ -617,5 +617,30 @@ namespace MediaBrowser.Model.Dlna return MaxHeight; } } + + public List<MediaStream> GetSelectableAudioStreams() + { + return GetSelectableStreams(MediaStreamType.Audio); + } + + public List<MediaStream> GetSelectableSubtitleStreams() + { + return GetSelectableStreams(MediaStreamType.Subtitle); + } + + public List<MediaStream> GetSelectableStreams(MediaStreamType type) + { + List<MediaStream> list = new List<MediaStream>(); + + foreach (MediaStream stream in MediaSource.MediaStreams) + { + if (type == stream.Type) + { + list.Add(stream); + } + } + + return list; + } } } diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index be3cd99be..7a1c78112 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -67,6 +67,7 @@ namespace MediaBrowser.Model.Dto public float? Metascore { get; set; } public bool? IsUnidentified { get; set; } + public bool? HasDynamicCategories { get; set; } public int? AnimeSeriesIndex { get; set; } @@ -466,6 +467,12 @@ namespace MediaBrowser.Model.Dto public List<string> Artists { get; set; } /// <summary> + /// Gets or sets the artist items. + /// </summary> + /// <value>The artist items.</value> + public List<NameIdPair> ArtistItems { get; set; } + + /// <summary> /// Gets or sets the album. /// </summary> /// <value>The album.</value> @@ -507,6 +514,12 @@ namespace MediaBrowser.Model.Dto public string AlbumArtist { get; set; } /// <summary> + /// Gets or sets the album artists. + /// </summary> + /// <value>The album artists.</value> + public List<NameIdPair> AlbumArtists { get; set; } + + /// <summary> /// Gets or sets the name of the season. /// </summary> /// <value>The name of the season.</value> diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index 068443238..3a9c1e7d4 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -22,6 +22,8 @@ namespace MediaBrowser.Model.Dto public long? RunTimeTicks { get; set; } public bool ReadAtNativeFramerate { get; set; } + public bool SupportsTranscoding { get; set; } + public bool SupportsDirectStream { get; set; } public VideoType? VideoType { get; set; } @@ -45,6 +47,8 @@ namespace MediaBrowser.Model.Dto MediaStreams = new List<MediaStream>(); RequiredHttpHeaders = new Dictionary<string, string>(); PlayableStreamFileNames = new List<string>(); + SupportsTranscoding = true; + SupportsDirectStream = true; } public int? DefaultAudioStreamIndex { get; set; } diff --git a/MediaBrowser.Model/Dto/NameIdPair.cs b/MediaBrowser.Model/Dto/NameIdPair.cs new file mode 100644 index 000000000..d3931516c --- /dev/null +++ b/MediaBrowser.Model/Dto/NameIdPair.cs @@ -0,0 +1,17 @@ + +namespace MediaBrowser.Model.Dto +{ + public class NameIdPair + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + /// <summary> + /// Gets or sets the identifier. + /// </summary> + /// <value>The identifier.</value> + public string Id { get; set; } + } +} diff --git a/MediaBrowser.Model/LiveTv/LiveTvInfo.cs b/MediaBrowser.Model/LiveTv/LiveTvInfo.cs index dd31c5a6b..f4d3e21d9 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvInfo.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvInfo.cs @@ -11,12 +11,6 @@ namespace MediaBrowser.Model.LiveTv public List<LiveTvServiceInfo> Services { get; set; } /// <summary> - /// Gets or sets the name of the active service. - /// </summary> - /// <value>The name of the active service.</value> - public string ActiveServiceName { get; set; } - - /// <summary> /// Gets or sets a value indicating whether this instance is enabled. /// </summary> /// <value><c>true</c> if this instance is enabled; otherwise, <c>false</c>.</value> @@ -28,18 +22,6 @@ namespace MediaBrowser.Model.LiveTv /// <value>The enabled users.</value> public List<string> EnabledUsers { get; set; } - /// <summary> - /// Gets or sets the status. - /// </summary> - /// <value>The status.</value> - public LiveTvServiceStatus Status { get; set; } - - /// <summary> - /// Gets or sets the status message. - /// </summary> - /// <value>The status message.</value> - public string StatusMessage { get; set; } - public LiveTvInfo() { Services = new List<LiveTvServiceInfo>(); diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 05fdc00b1..c6f6ed84c 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -3,6 +3,11 @@ public class LiveTvOptions { public int? GuideDays { get; set; } - public string ActiveService { get; set; } + public bool EnableMovieProviders { get; set; } + + public LiveTvOptions() + { + EnableMovieProviders = true; + } } }
\ No newline at end of file diff --git a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs index f511a7a17..06136459f 100644 --- a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs @@ -95,7 +95,13 @@ namespace MediaBrowser.Model.LiveTv /// </summary> /// <value>The official rating.</value> public string OfficialRating { get; set; } - + + /// <summary> + /// Gets or sets the production year. + /// </summary> + /// <value>The production year.</value> + public int? ProductionYear { get; set; } + /// <summary> /// Gets or sets the name of the service. /// </summary> diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs index 36c06d4c0..bbd396c33 100644 --- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs @@ -1,4 +1,5 @@ -using System; +using MediaBrowser.Model.Entities; +using System; namespace MediaBrowser.Model.LiveTv { @@ -7,11 +8,18 @@ namespace MediaBrowser.Model.LiveTv /// </summary> public class ProgramQuery { + public ProgramQuery() + { + ChannelIds = new string[] { }; + SortBy = new string[] { }; + Genres = new string[] { }; + } + /// <summary> - /// Gets or sets the channel identifier. + /// Gets or sets the channel ids. /// </summary> - /// <value>The channel identifier.</value> - public string[] ChannelIdList { get; set; } + /// <value>The channel ids.</value> + public string[] ChannelIds { get; set; } /// <summary> /// Gets or sets the user identifier. @@ -19,17 +27,64 @@ namespace MediaBrowser.Model.LiveTv /// <value>The user identifier.</value> public string UserId { get; set; } + /// <summary> + /// The earliest date for which a program starts to return + /// </summary> public DateTime? MinStartDate { get; set; } + /// <summary> + /// The latest date for which a program starts to return + /// </summary> public DateTime? MaxStartDate { get; set; } + /// <summary> + /// The earliest date for which a program ends to return + /// </summary> public DateTime? MinEndDate { get; set; } + /// <summary> + /// The latest date for which a program ends to return + /// </summary> public DateTime? MaxEndDate { get; set; } - - public ProgramQuery() - { - ChannelIdList = new string[] { }; - } + + /// <summary> + /// Used to specific whether to return movies or not + /// </summary> + /// <remarks>If set to null, all programs will be returned</remarks> + public bool? IsMovie { get; set; } + + /// <summary> + /// Skips over a given number of items within the results. Use for paging. + /// </summary> + public int? StartIndex { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance has aired. + /// </summary> + /// <value><c>null</c> if [has aired] contains no value, <c>true</c> if [has aired]; otherwise, <c>false</c>.</value> + public bool? HasAired { get; set; } + + /// <summary> + /// The maximum number of items to return + /// </summary> + public int? Limit { get; set; } + + /// <summary> + /// What to sort the results by + /// </summary> + /// <value>The sort by.</value> + public string[] SortBy { get; set; } + + /// <summary> + /// The sort order to return results with + /// </summary> + /// <value>The sort order.</value> + public SortOrder? SortOrder { get; set; } + + /// <summary> + /// Limit results to items containing specific genres + /// </summary> + /// <value>The genres.</value> + public string[] Genres { get; set; } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs index 907902123..9ba8e0e5f 100644 --- a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs @@ -25,5 +25,11 @@ /// </summary> /// <value>The limit.</value> public int? Limit { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this instance is movie. + /// </summary> + /// <value><c>null</c> if [is movie] contains no value, <c>true</c> if [is movie]; otherwise, <c>false</c>.</value> + public bool? IsMovie { get; set; } } }
\ No newline at end of file diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs index a6cd85d8d..d6d698038 100644 --- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs @@ -273,6 +273,10 @@ namespace MediaBrowser.Model.LiveTv /// <value>The type.</value> public string Type { get; set; } + /// <summary> + /// Gets or sets the media sources. + /// </summary> + /// <value>The media sources.</value> public List<MediaSourceInfo> MediaSources { get; set; } public RecordingInfoDto() diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 9fd632cbd..3a6eda620 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -125,6 +125,10 @@ <Compile Include="Devices\DeviceInfo.cs" /> <Compile Include="Devices\DevicesOptions.cs" /> <Compile Include="Dlna\EncodingContext.cs" /> + <Compile Include="Dlna\ILocalPlayer.cs" /> + <Compile Include="Dlna\NullLocalPlayer.cs" /> + <Compile Include="Dlna\PlaybackErrorCode.cs" /> + <Compile Include="Dlna\PlaybackException.cs" /> <Compile Include="Dlna\Profiles\DefaultProfile.cs" /> <Compile Include="Dlna\ResolutionConfiguration.cs" /> <Compile Include="Dlna\ResolutionNormalizer.cs" /> @@ -134,6 +138,7 @@ <Compile Include="Drawing\ImageOrientation.cs" /> <Compile Include="Dto\IHasServerId.cs" /> <Compile Include="Dto\MetadataEditorInfo.cs" /> + <Compile Include="Dto\NameIdPair.cs" /> <Compile Include="Dto\NameValuePair.cs" /> <Compile Include="MediaInfo\LiveMediaInfoResult.cs" /> <Compile Include="Dto\MediaSourceType.cs" /> @@ -310,15 +315,16 @@ <Compile Include="Querying\ItemsByNameQuery.cs" /> <Compile Include="Entities\BaseItemInfo.cs" /> <Compile Include="Querying\LatestItemsQuery.cs" /> + <Compile Include="Querying\MovieRecommendationQuery.cs" /> <Compile Include="Querying\NextUpQuery.cs" /> <Compile Include="Querying\QueryFilters.cs" /> <Compile Include="Querying\QueryResult.cs" /> <Compile Include="Querying\SeasonQuery.cs" /> <Compile Include="Querying\SessionQuery.cs" /> - <Compile Include="Querying\SimilarItemsByNameQuery.cs" /> <Compile Include="Querying\SimilarItemsQuery.cs" /> <Compile Include="Querying\UpcomingEpisodesQuery.cs" /> <Compile Include="Querying\UserQuery.cs" /> + <Compile Include="Registration\RegistrationInfo.cs" /> <Compile Include="Search\SearchQuery.cs" /> <Compile Include="Session\BrowseRequest.cs" /> <Compile Include="Session\ClientCapabilities.cs" /> @@ -374,12 +380,13 @@ <Compile Include="Sync\ItemFIleInfo.cs" /> <Compile Include="Sync\ItemFileType.cs" /> <Compile Include="Sync\LocalItem.cs" /> + <Compile Include="Sync\LocalItemInfo.cs" /> + <Compile Include="Sync\LocalItemQuery.cs" /> <Compile Include="Sync\SyncCategory.cs" /> <Compile Include="Sync\SyncDataRequest.cs" /> <Compile Include="Sync\SyncDataResponse.cs" /> <Compile Include="Sync\SyncDialogOptions.cs" /> <Compile Include="Sync\SyncedItem.cs" /> - <Compile Include="Sync\SyncHelper.cs" /> <Compile Include="Sync\SyncJob.cs" /> <Compile Include="Sync\SyncJobCreationResult.cs" /> <Compile Include="Sync\SyncJobItem.cs" /> @@ -390,7 +397,8 @@ <Compile Include="Sync\SyncJobStatus.cs" /> <Compile Include="Sync\SyncOptions.cs" /> <Compile Include="Sync\SyncParameter.cs" /> - <Compile Include="Sync\SyncQuality.cs" /> + <Compile Include="Sync\SyncProfileOption.cs" /> + <Compile Include="Sync\SyncQualityOption.cs" /> <Compile Include="Sync\SyncTarget.cs" /> <Compile Include="System\LogFile.cs" /> <Compile Include="System\PublicSystemInfo.cs" /> diff --git a/MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs b/MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs index afd5c890f..4a206ea20 100644 --- a/MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs +++ b/MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Dto; using System.Collections.Generic; namespace MediaBrowser.Model.MediaInfo @@ -17,6 +18,12 @@ namespace MediaBrowser.Model.MediaInfo /// <value>The live stream identifier.</value> public string LiveStreamId { get; set; } + /// <summary> + /// Gets or sets the error code. + /// </summary> + /// <value>The error code.</value> + public PlaybackErrorCode? ErrorCode { get; set; } + public LiveMediaInfoResult() { MediaSources = new List<MediaSourceInfo>(); diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 1f54e48d1..56cfff733 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -265,12 +265,7 @@ namespace MediaBrowser.Model.Net return "application/ttml+xml"; } - if (ext.Equals(".bif", StringComparison.OrdinalIgnoreCase)) - { - return "application/octet-stream"; - } - - throw new ArgumentException("Argument not supported: " + path); + return "application/octet-stream"; } public static string ToExtension(string mimeType) diff --git a/MediaBrowser.Model/Notifications/NotificationOptions.cs b/MediaBrowser.Model/Notifications/NotificationOptions.cs index 7d80f3177..e57955c9e 100644 --- a/MediaBrowser.Model/Notifications/NotificationOptions.cs +++ b/MediaBrowser.Model/Notifications/NotificationOptions.cs @@ -64,6 +64,12 @@ namespace MediaBrowser.Model.Notifications Type = NotificationType.PluginError.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins + }, + new NotificationOption + { + Type = NotificationType.UserLockedOut.ToString(), + Enabled = true, + SendToUserMode = SendToUserType.Admins } }; } diff --git a/MediaBrowser.Model/Notifications/NotificationType.cs b/MediaBrowser.Model/Notifications/NotificationType.cs index 269e27a4f..f5e3624f0 100644 --- a/MediaBrowser.Model/Notifications/NotificationType.cs +++ b/MediaBrowser.Model/Notifications/NotificationType.cs @@ -19,6 +19,7 @@ namespace MediaBrowser.Model.Notifications NewLibraryContentMultiple, ServerRestartRequired, TaskFailed, - CameraImageUploaded + CameraImageUploaded, + UserLockedOut } }
\ No newline at end of file diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index 0f929fa9b..0cdf5ca7a 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -39,11 +39,11 @@ namespace MediaBrowser.Model.Querying public string[] SortBy { get; set; } /// <summary> - /// Filter by artists + /// Gets or sets the artist ids. /// </summary> - /// <value>The artists.</value> - public string[] Artists { get; set; } - + /// <value>The artist ids.</value> + public string[] ArtistIds { get; set; } + /// <summary> /// The sort order to return results with /// </summary> @@ -93,16 +93,10 @@ namespace MediaBrowser.Model.Querying public string[] Genres { get; set; } /// <summary> - /// Limit results to items containing specific genres - /// </summary> - /// <value>The genres.</value> - public string[] AllGenres { get; set; } - - /// <summary> - /// Limit results to items containing specific studios + /// Gets or sets the studio ids. /// </summary> - /// <value>The studios.</value> - public string[] Studios { get; set; } + /// <value>The studio ids.</value> + public string[] StudioIds { get; set; } /// <summary> /// Gets or sets the exclude item types. @@ -126,7 +120,7 @@ namespace MediaBrowser.Model.Querying /// Limit results to items containing a specific person /// </summary> /// <value>The person.</value> - public string Person { get; set; } + public string[] PersonIds { get; set; } /// <summary> /// If the Person filter is used, this can also be used to restrict to a specific person type @@ -306,13 +300,14 @@ namespace MediaBrowser.Model.Querying VideoTypes = new VideoType[] { }; Genres = new string[] { }; - Studios = new string[] { }; + StudioIds = new string[] { }; IncludeItemTypes = new string[] { }; ExcludeItemTypes = new string[] { }; Years = new int[] { }; PersonTypes = new string[] { }; Ids = new string[] { }; - Artists = new string[] { }; + ArtistIds = new string[] { }; + PersonIds = new string[] { }; ImageTypes = new ImageType[] { }; AirDays = new DayOfWeek[] { }; diff --git a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs new file mode 100644 index 000000000..91417a4a7 --- /dev/null +++ b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs @@ -0,0 +1,39 @@ + +namespace MediaBrowser.Model.Querying +{ + public class MovieRecommendationQuery + { + /// <summary> + /// Gets or sets the user identifier. + /// </summary> + /// <value>The user identifier.</value> + public string UserId { get; set; } + /// <summary> + /// Gets or sets the parent identifier. + /// </summary> + /// <value>The parent identifier.</value> + public string ParentId { get; set; } + /// <summary> + /// Gets or sets the item limit. + /// </summary> + /// <value>The item limit.</value> + public int ItemLimit { get; set; } + /// <summary> + /// Gets or sets the category limit. + /// </summary> + /// <value>The category limit.</value> + public int CategoryLimit { get; set; } + /// <summary> + /// Gets or sets the fields. + /// </summary> + /// <value>The fields.</value> + public ItemFields[] Fields { get; set; } + + public MovieRecommendationQuery() + { + ItemLimit = 10; + CategoryLimit = 6; + Fields = new ItemFields[] { }; + } + } +} diff --git a/MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs b/MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs deleted file mode 100644 index 7d0d4da31..000000000 --- a/MediaBrowser.Model/Querying/SimilarItemsByNameQuery.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace MediaBrowser.Model.Querying -{ - public class SimilarItemsByNameQuery - { - /// <summary> - /// The user to localize search results for - /// </summary> - /// <value>The user id.</value> - public string UserId { get; set; } - - /// <summary> - /// Gets or sets the name. - /// </summary> - /// <value>The name.</value> - public string Name { get; set; } - - /// <summary> - /// The maximum number of items to return - /// </summary> - /// <value>The limit.</value> - public int? Limit { get; set; } - - /// <summary> - /// Fields to return within the items, in addition to basic information - /// </summary> - /// <value>The fields.</value> - public ItemFields[] Fields { get; set; } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Model/Registration/RegistrationInfo.cs b/MediaBrowser.Model/Registration/RegistrationInfo.cs new file mode 100644 index 000000000..4e97989cf --- /dev/null +++ b/MediaBrowser.Model/Registration/RegistrationInfo.cs @@ -0,0 +1,28 @@ +using System; + +namespace MediaBrowser.Model.Registration +{ + public class RegistrationInfo + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + /// <summary> + /// Gets or sets the expiration date. + /// </summary> + /// <value>The expiration date.</value> + public DateTime ExpirationDate { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is trial. + /// </summary> + /// <value><c>true</c> if this instance is trial; otherwise, <c>false</c>.</value> + public bool IsTrial { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is registered. + /// </summary> + /// <value><c>true</c> if this instance is registered; otherwise, <c>false</c>.</value> + public bool IsRegistered { get; set; } + } +} diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs index 6ca4507c0..9361a60ea 100644 --- a/MediaBrowser.Model/Session/ClientCapabilities.cs +++ b/MediaBrowser.Model/Session/ClientCapabilities.cs @@ -20,11 +20,6 @@ namespace MediaBrowser.Model.Session public DeviceProfile DeviceProfile { get; set; } - /// <summary> - /// Usage should be migrated to SupportsPersistentIdentifier. Keeping this to preserve data. - /// </summary> - public bool? SupportsUniqueIdentifier { get; set; } - public ClientCapabilities() { PlayableMediaTypes = new List<string>(); diff --git a/MediaBrowser.Model/Sync/LocalItemInfo.cs b/MediaBrowser.Model/Sync/LocalItemInfo.cs new file mode 100644 index 000000000..f52873b2f --- /dev/null +++ b/MediaBrowser.Model/Sync/LocalItemInfo.cs @@ -0,0 +1,11 @@ + +namespace MediaBrowser.Model.Sync +{ + public class LocalItemInfo + { + public string ServerId { get; set; } + public string Id { get; set; } + public string Name { get; set; } + public string PrimaryImageTag { get; set; } + } +} diff --git a/MediaBrowser.Model/Sync/LocalItemQuery.cs b/MediaBrowser.Model/Sync/LocalItemQuery.cs new file mode 100644 index 000000000..099392908 --- /dev/null +++ b/MediaBrowser.Model/Sync/LocalItemQuery.cs @@ -0,0 +1,19 @@ + +namespace MediaBrowser.Model.Sync +{ + public class LocalItemQuery + { + public string ServerId { get; set; } + public string AlbumArtist { get; set; } + public string AlbumId { get; set; } + public string SeriesId { get; set; } + public string Type { get; set; } + public string MediaType { get; set; } + public string[] ExcludeTypes { get; set; } + + public LocalItemQuery() + { + ExcludeTypes = new string[] { }; + } + } +} diff --git a/MediaBrowser.Model/Sync/SyncDialogOptions.cs b/MediaBrowser.Model/Sync/SyncDialogOptions.cs index cf8b0130b..a987a6cd6 100644 --- a/MediaBrowser.Model/Sync/SyncDialogOptions.cs +++ b/MediaBrowser.Model/Sync/SyncDialogOptions.cs @@ -18,19 +18,19 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the quality options. /// </summary> /// <value>The quality options.</value> - public List<SyncQuality> QualityOptions { get; set; } - + public List<SyncQualityOption> QualityOptions { get; set; } + /// <summary> + /// Gets or sets the profile options. + /// </summary> + /// <value>The profile options.</value> + public List<SyncProfileOption> ProfileOptions { get; set; } + public SyncDialogOptions() { Targets = new List<SyncTarget>(); Options = new List<SyncJobOption>(); - QualityOptions = new List<SyncQuality> - { - SyncQuality.Original, - SyncQuality.High, - SyncQuality.Medium, - SyncQuality.Low - }; + QualityOptions = new List<SyncQualityOption>(); + ProfileOptions = new List<SyncProfileOption>(); } } } diff --git a/MediaBrowser.Model/Sync/SyncHelper.cs b/MediaBrowser.Model/Sync/SyncHelper.cs deleted file mode 100644 index 34a5ba995..000000000 --- a/MediaBrowser.Model/Sync/SyncHelper.cs +++ /dev/null @@ -1,74 +0,0 @@ -using MediaBrowser.Model.Dto; -using System.Collections.Generic; - -namespace MediaBrowser.Model.Sync -{ - public static class SyncHelper - { - public static List<SyncJobOption> GetSyncOptions(List<BaseItemDto> items) - { - List<SyncJobOption> options = new List<SyncJobOption>(); - - if (items.Count > 1) - { - options.Add(SyncJobOption.Name); - } - - foreach (BaseItemDto item in items) - { - if (item.SupportsSync ?? false) - { - if (item.IsVideo) - { - options.Add(SyncJobOption.Quality); - if (items.Count > 1) - { - options.Add(SyncJobOption.UnwatchedOnly); - } - break; - } - if (item.IsFolder && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre) - { - options.Add(SyncJobOption.Quality); - options.Add(SyncJobOption.UnwatchedOnly); - break; - } - if (item.IsGenre) - { - options.Add(SyncJobOption.SyncNewContent); - options.Add(SyncJobOption.ItemLimit); - break; - } - } - } - - foreach (BaseItemDto item in items) - { - if (item.SupportsSync ?? false) - { - if (item.IsFolder || item.IsGameGenre || item.IsMusicGenre || item.IsGenre || item.IsArtist || item.IsStudio || item.IsPerson) - { - options.Add(SyncJobOption.SyncNewContent); - options.Add(SyncJobOption.ItemLimit); - break; - } - } - } - - return options; - } - - public static List<SyncJobOption> GetSyncOptions(SyncCategory category) - { - List<SyncJobOption> options = new List<SyncJobOption>(); - - options.Add(SyncJobOption.Name); - options.Add(SyncJobOption.Quality); - options.Add(SyncJobOption.UnwatchedOnly); - options.Add(SyncJobOption.SyncNewContent); - options.Add(SyncJobOption.ItemLimit); - - return options; - } - } -} diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs index 93e73d22e..6709426b8 100644 --- a/MediaBrowser.Model/Sync/SyncJob.cs +++ b/MediaBrowser.Model/Sync/SyncJob.cs @@ -24,7 +24,17 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the quality. /// </summary> /// <value>The quality.</value> - public SyncQuality Quality { get; set; } + public string Quality { get; set; } + /// <summary> + /// Gets or sets the bitrate. + /// </summary> + /// <value>The bitrate.</value> + public int? Bitrate { get; set; } + /// <summary> + /// Gets or sets the profile. + /// </summary> + /// <value>The profile.</value> + public string Profile { get; set; } /// <summary> /// Gets or sets the category. /// </summary> @@ -98,7 +108,6 @@ namespace MediaBrowser.Model.Sync public SyncJob() { RequestedItemIds = new List<string>(); - Quality = SyncQuality.High; } } } diff --git a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs index d21138204..74d3ac096 100644 --- a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; - + namespace MediaBrowser.Model.Sync { public class SyncJobItemQuery @@ -20,6 +19,11 @@ namespace MediaBrowser.Model.Sync /// <value>The job identifier.</value> public string JobId { get; set; } /// <summary> + /// Gets or sets the item identifier. + /// </summary> + /// <value>The item identifier.</value> + public string ItemId { get; set; } + /// <summary> /// Gets or sets the target identifier. /// </summary> /// <value>The target identifier.</value> @@ -28,7 +32,7 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the status. /// </summary> /// <value>The status.</value> - public List<SyncJobItemStatus> Statuses { get; set; } + public SyncJobItemStatus[] Statuses { get; set; } /// <summary> /// Gets or sets a value indicating whether [add metadata]. /// </summary> @@ -37,7 +41,7 @@ namespace MediaBrowser.Model.Sync public SyncJobItemQuery() { - Statuses = new List<SyncJobItemStatus>(); + Statuses = new SyncJobItemStatus[] {}; } } } diff --git a/MediaBrowser.Model/Sync/SyncJobQuery.cs b/MediaBrowser.Model/Sync/SyncJobQuery.cs index 233dc7878..e86ec929f 100644 --- a/MediaBrowser.Model/Sync/SyncJobQuery.cs +++ b/MediaBrowser.Model/Sync/SyncJobQuery.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; - + namespace MediaBrowser.Model.Sync { public class SyncJobQuery @@ -28,7 +27,7 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the status. /// </summary> /// <value>The status.</value> - public List<SyncJobStatus> Statuses { get; set; } + public SyncJobStatus[] Statuses { get; set; } /// <summary> /// Gets or sets a value indicating whether [synchronize new content]. /// </summary> @@ -37,7 +36,7 @@ namespace MediaBrowser.Model.Sync public SyncJobQuery() { - Statuses = new List<SyncJobStatus>(); + Statuses = new SyncJobStatus[] { }; } } } diff --git a/MediaBrowser.Model/Sync/SyncJobRequest.cs b/MediaBrowser.Model/Sync/SyncJobRequest.cs index 7d3016d0e..a96c86ed9 100644 --- a/MediaBrowser.Model/Sync/SyncJobRequest.cs +++ b/MediaBrowser.Model/Sync/SyncJobRequest.cs @@ -28,7 +28,12 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the quality. /// </summary> /// <value>The quality.</value> - public SyncQuality Quality { get; set; } + public string Quality { get; set; } + /// <summary> + /// Gets or sets the profile. + /// </summary> + /// <value>The profile.</value> + public string Profile { get; set; } /// <summary> /// Gets or sets the name. /// </summary> @@ -54,6 +59,11 @@ namespace MediaBrowser.Model.Sync /// </summary> /// <value>The limit.</value> public int? ItemLimit { get; set; } + /// <summary> + /// Gets or sets the bitrate. + /// </summary> + /// <value>The bitrate.</value> + public int? Bitrate { get; set; } public SyncJobRequest() { diff --git a/MediaBrowser.Model/Sync/SyncParameter.cs b/MediaBrowser.Model/Sync/SyncParameter.cs index def4ab3e3..bce2a4f30 100644 --- a/MediaBrowser.Model/Sync/SyncParameter.cs +++ b/MediaBrowser.Model/Sync/SyncParameter.cs @@ -7,6 +7,7 @@ namespace MediaBrowser.Model.Sync Quality = 1, UnwatchedOnly = 2, SyncNewContent = 3, - ItemLimit = 4 + ItemLimit = 4, + Profile = 5 } } diff --git a/MediaBrowser.Model/Sync/SyncProfileOption.cs b/MediaBrowser.Model/Sync/SyncProfileOption.cs new file mode 100644 index 000000000..605af6b25 --- /dev/null +++ b/MediaBrowser.Model/Sync/SyncProfileOption.cs @@ -0,0 +1,37 @@ + +namespace MediaBrowser.Model.Sync +{ + public class SyncProfileOption + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + /// <summary> + /// Gets or sets the description. + /// </summary> + /// <value>The description.</value> + public string Description { get; set; } + /// <summary> + /// Gets or sets the identifier. + /// </summary> + /// <value>The identifier.</value> + public string Id { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is default. + /// </summary> + /// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value> + public bool IsDefault { get; set; } + /// <summary> + /// Gets or sets a value indicating whether [enable quality options]. + /// </summary> + /// <value><c>true</c> if [enable quality options]; otherwise, <c>false</c>.</value> + public bool EnableQualityOptions { get; set; } + + public SyncProfileOption() + { + EnableQualityOptions = true; + } + } +} diff --git a/MediaBrowser.Model/Sync/SyncQuality.cs b/MediaBrowser.Model/Sync/SyncQuality.cs deleted file mode 100644 index 27ee756a3..000000000 --- a/MediaBrowser.Model/Sync/SyncQuality.cs +++ /dev/null @@ -1,25 +0,0 @@ - -namespace MediaBrowser.Model.Sync -{ - public enum SyncQuality - { - /// <summary> - /// The good - /// </summary> - Low = 0, - - /// <summary> - /// The better - /// </summary> - Medium = 1, - - /// <summary> - /// The best - /// </summary> - High = 2, - /// <summary> - /// The original - /// </summary> - Original = 3 - } -} diff --git a/MediaBrowser.Model/Sync/SyncQualityOption.cs b/MediaBrowser.Model/Sync/SyncQualityOption.cs new file mode 100644 index 000000000..597b98727 --- /dev/null +++ b/MediaBrowser.Model/Sync/SyncQualityOption.cs @@ -0,0 +1,27 @@ + +namespace MediaBrowser.Model.Sync +{ + public class SyncQualityOption + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + /// <summary> + /// Gets or sets the description. + /// </summary> + /// <value>The description.</value> + public string Description { get; set; } + /// <summary> + /// Gets or sets the identifier. + /// </summary> + /// <value>The identifier.</value> + public string Id { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is default. + /// </summary> + /// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value> + public bool IsDefault { get; set; } + } +} diff --git a/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs b/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs index e03d85984..aacd56e65 100644 --- a/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs +++ b/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs @@ -36,5 +36,11 @@ namespace MediaBrowser.Model.Tasks /// </summary> /// <value>The day of week.</value> public DayOfWeek? DayOfWeek { get; set; } + + /// <summary> + /// Gets or sets the maximum runtime ms. + /// </summary> + /// <value>The maximum runtime ms.</value> + public int? MaxRuntimeMs { get; set; } } } diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 410cdc51f..7efc2cf6f 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -59,6 +59,8 @@ namespace MediaBrowser.Model.Users public string[] EnabledFolders { get; set; } public bool EnableAllFolders { get; set; } + public int InvalidLoginAttemptCount { get; set; } + public UserPolicy() { EnableLiveTvManagement = true; |
