diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 486221bc6a..966d481742 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -260,20 +260,10 @@ namespace MediaBrowser.Api.Playback { var quality = ServerConfigurationManager.Configuration.EncodingQuality; - if (quality == EncodingQuality.Auto) - { - var cpuCount = Environment.ProcessorCount; - - if (cpuCount >= 4) - { - return 0; - } - - return cpuCount; - } - switch (quality) { + case EncodingQuality.Auto: + return 0; case EncodingQuality.HighSpeed: return 2; case EncodingQuality.HighQuality: diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index b5317319fa..07c0f8ab7a 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager #if __MonoCS__ return GetMonoRequest(options, method, enableHttpCompression); #endif - + var request = HttpWebRequest.CreateHttp(options.Url); if (!string.IsNullOrEmpty(options.AcceptHeader)) @@ -172,9 +172,64 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager /// Task{HttpResponseInfo}. /// /// - public async Task GetResponse(HttpRequestOptions options) + public Task GetResponse(HttpRequestOptions options) + { + return SendAsync(options, "GET"); + } + + /// + /// Performs a GET request and returns the resulting stream + /// + /// The options. + /// Task{Stream}. + /// + /// + public async Task Get(HttpRequestOptions options) + { + var response = await GetResponse(options).ConfigureAwait(false); + + return response.Content; + } + + /// + /// Performs a GET request and returns the resulting stream + /// + /// The URL. + /// The resource pool. + /// The cancellation token. + /// Task{Stream}. + public Task Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken) { - ValidateParams(options.Url, options.CancellationToken); + return Get(new HttpRequestOptions + { + Url = url, + ResourcePool = resourcePool, + CancellationToken = cancellationToken, + }); + } + + /// + /// Gets the specified URL. + /// + /// The URL. + /// The cancellation token. + /// Task{Stream}. + public Task Get(string url, CancellationToken cancellationToken) + { + return Get(url, null, cancellationToken); + } + + /// + /// send as an asynchronous operation. + /// + /// The options. + /// The HTTP method. + /// Task{HttpResponseInfo}. + /// + /// + private async Task SendAsync(HttpRequestOptions options, string httpMethod) + { + ValidateParams(options); options.CancellationToken.ThrowIfCancellationRequested(); @@ -185,7 +240,17 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true }; } - var httpWebRequest = GetRequest(options, "GET", options.EnableHttpCompression); + var httpWebRequest = GetRequest(options, httpMethod, options.EnableHttpCompression); + + if (!string.IsNullOrEmpty(options.RequestContent) || string.Equals(httpMethod, "post", StringComparison.OrdinalIgnoreCase)) + { + var content = options.RequestContent ?? string.Empty; + var bytes = Encoding.UTF8.GetBytes(content); + + httpWebRequest.ContentType = options.RequestContentType ?? "application/x-www-form-urlencoded"; + httpWebRequest.ContentLength = bytes.Length; + httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length); + } if (options.ResourcePool != null) { @@ -202,7 +267,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true }; } - _logger.Info("HttpClientManager.GET url: {0}", options.Url); + _logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url); try { @@ -275,46 +340,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager } } - /// - /// Performs a GET request and returns the resulting stream - /// - /// The options. - /// Task{Stream}. - /// - /// - public async Task Get(HttpRequestOptions options) + public Task Post(HttpRequestOptions options) { - var response = await GetResponse(options).ConfigureAwait(false); - - return response.Content; - } - - /// - /// Performs a GET request and returns the resulting stream - /// - /// The URL. - /// The resource pool. - /// The cancellation token. - /// Task{Stream}. - public Task Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken) - { - return Get(new HttpRequestOptions - { - Url = url, - ResourcePool = resourcePool, - CancellationToken = cancellationToken, - }); - } - - /// - /// Gets the specified URL. - /// - /// The URL. - /// The cancellation token. - /// Task{Stream}. - public Task Get(string url, CancellationToken cancellationToken) - { - return Get(url, null, cancellationToken); + return SendAsync(options, "POST"); } /// @@ -329,82 +357,15 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager /// public async Task Post(HttpRequestOptions options, Dictionary postData) { - ValidateParams(options.Url, options.CancellationToken); - - options.CancellationToken.ThrowIfCancellationRequested(); - - var httpWebRequest = GetRequest(options, "POST", options.EnableHttpCompression); - var strings = postData.Keys.Select(key => string.Format("{0}={1}", key, postData[key])); var postContent = string.Join("&", strings.ToArray()); - var bytes = Encoding.UTF8.GetBytes(postContent); - - httpWebRequest.ContentType = "application/x-www-form-urlencoded"; - httpWebRequest.ContentLength = bytes.Length; - httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length); - - if (options.ResourcePool != null) - { - await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false); - } - - _logger.Info("HttpClientManager.POST url: {0}", options.Url); - - try - { - options.CancellationToken.ThrowIfCancellationRequested(); - - using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false)) - { - var httpResponse = (HttpWebResponse)response; - - EnsureSuccessStatusCode(httpResponse); - - options.CancellationToken.ThrowIfCancellationRequested(); - - using (var stream = httpResponse.GetResponseStream()) - { - var memoryStream = new MemoryStream(); - - await stream.CopyToAsync(memoryStream).ConfigureAwait(false); - memoryStream.Position = 0; + options.RequestContent = postContent; + options.RequestContentType = "application/x-www-form-urlencoded"; - return memoryStream; - } - } - } - catch (OperationCanceledException ex) - { - var exception = GetCancellationException(options.Url, options.CancellationToken, ex); + var response = await Post(options).ConfigureAwait(false); - throw exception; - } - catch (HttpRequestException ex) - { - _logger.ErrorException("Error getting response from " + options.Url, ex); - - throw new HttpException(ex.Message, ex); - } - catch (WebException ex) - { - _logger.ErrorException("Error getting response from " + options.Url, ex); - - throw new HttpException(ex.Message, ex); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting response from " + options.Url, ex); - - throw; - } - finally - { - if (options.ResourcePool != null) - { - options.ResourcePool.Release(); - } - } + return response.Content; } /// @@ -443,7 +404,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager public async Task GetTempFileResponse(HttpRequestOptions options) { - ValidateParams(options.Url, options.CancellationToken); + ValidateParams(options); Directory.CreateDirectory(_appPaths.TempDirectory); @@ -592,7 +553,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager { return new HttpException(ex.Message, ex); } - + return ex; } @@ -608,17 +569,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager } } - /// - /// Validates the params. - /// - /// The URL. - /// The cancellation token. - /// url - private void ValidateParams(string url, CancellationToken cancellationToken) + private void ValidateParams(HttpRequestOptions options) { - if (string.IsNullOrEmpty(url)) + if (string.IsNullOrEmpty(options.Url)) { - throw new ArgumentNullException("url"); + throw new ArgumentNullException("options"); } } diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs index 977a6aabe8..db78fc927c 100644 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs @@ -66,6 +66,10 @@ namespace MediaBrowser.Common.Net public Dictionary RequestHeaders { get; private set; } + public string RequestContentType { get; set; } + + public string RequestContent { get; set; } + private string GetHeaderValue(string name) { string value; diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs index 54d6665e23..a3d90cb0d8 100644 --- a/MediaBrowser.Common/Net/IHttpClient.cs +++ b/MediaBrowser.Common/Net/IHttpClient.cs @@ -64,6 +64,13 @@ namespace MediaBrowser.Common.Net /// Task{Stream}. Task Post(string url, Dictionary postData, CancellationToken cancellationToken); + /// + /// Posts the specified options. + /// + /// The options. + /// Task{HttpResponseInfo}. + Task Post(HttpRequestOptions options); + /// /// Downloads the contents of a given url into a temporary location /// diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index ce7a4a598b..5cf8fb721d 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -17,6 +17,12 @@ namespace MediaBrowser.Controller.LiveTv /// The channel identifier. public string ChannelId { get; set; } + /// + /// Gets or sets the name of the channel. + /// + /// The name of the channel. + public string ChannelName { get; set; } + /// /// Name of the program /// diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index 4fc8c0f7a3..40a53e6591 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -38,6 +38,12 @@ namespace MediaBrowser.Controller.LiveTv /// The path. public string Path { get; set; } + /// + /// Gets or sets the URL. + /// + /// The URL. + public string Url { get; set; } + /// /// Gets or sets the overview. /// diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs index 6072827964..b92ec4a430 100644 --- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs @@ -48,11 +48,23 @@ namespace MediaBrowser.Controller.LiveTv public DateTime EndDate { get; set; } /// - /// Gets or sets the type of the recurrence. + /// Gets or sets a value indicating whether [record any time]. /// - /// The type of the recurrence. - public RecurrenceType RecurrenceType { get; set; } + /// true if [record any time]; otherwise, false. + public bool RecordAnyTime { get; set; } + /// + /// Gets or sets a value indicating whether [record any channel]. + /// + /// true if [record any channel]; otherwise, false. + public bool RecordAnyChannel { get; set; } + + /// + /// Gets or sets a value indicating whether [record new only]. + /// + /// true if [record new only]; otherwise, false. + public bool RecordNewOnly { get; set; } + /// /// Gets or sets the days. /// diff --git a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs index b3542fcf81..106b785507 100644 --- a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs @@ -23,6 +23,12 @@ namespace MediaBrowser.Model.LiveTv /// The channel identifier. public string ChannelId { get; set; } + /// + /// Gets or sets the name of the channel. + /// + /// The name of the channel. + public string ChannelName { get; set; } + /// /// Gets or sets the community rating. /// diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs index 501e3b6210..2f836dc4d7 100644 --- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs @@ -50,6 +50,12 @@ namespace MediaBrowser.Model.LiveTv /// The path. public string Path { get; set; } + /// + /// Gets or sets the URL. + /// + /// The URL. + public string Url { get; set; } + /// /// Overview of the recording. /// diff --git a/MediaBrowser.Model/LiveTv/RecordingStatus.cs b/MediaBrowser.Model/LiveTv/RecordingStatus.cs index 06bc98e63e..95e9dcb01e 100644 --- a/MediaBrowser.Model/LiveTv/RecordingStatus.cs +++ b/MediaBrowser.Model/LiveTv/RecordingStatus.cs @@ -14,15 +14,6 @@ namespace MediaBrowser.Model.LiveTv Error } - public enum RecurrenceType - { - Manual, - NewProgramEventsOneChannel, - AllProgramEventsOneChannel, - NewProgramEventsAllChannels, - AllProgramEventsAllChannels - } - public enum DayPattern { Daily, diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs index 0853400135..fd61b87228 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -71,10 +71,22 @@ namespace MediaBrowser.Model.LiveTv public DateTime EndDate { get; set; } /// - /// Gets or sets the type of the recurrence. + /// Gets or sets a value indicating whether [record any time]. /// - /// The type of the recurrence. - public RecurrenceType RecurrenceType { get; set; } + /// true if [record any time]; otherwise, false. + public bool RecordAnyTime { get; set; } + + /// + /// Gets or sets a value indicating whether [record any channel]. + /// + /// true if [record any channel]; otherwise, false. + public bool RecordAnyChannel { get; set; } + + /// + /// Gets or sets a value indicating whether [record new only]. + /// + /// true if [record new only]; otherwise, false. + public bool RecordNewOnly { get; set; } /// /// Gets or sets the days. diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs index d962f784f1..b19099c4cd 100644 --- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs @@ -43,6 +43,12 @@ namespace MediaBrowser.Model.LiveTv /// The program identifier. public string ProgramId { get; set; } + /// + /// Gets or sets the external program identifier. + /// + /// The external program identifier. + public string ExternalProgramId { get; set; } + /// /// Name of the recording. /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index fc030dbf8d..a30d1cfbb3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -47,7 +47,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds, ExternalChannelId = info.ChannelId, ExternalSeriesTimerId = info.SeriesTimerId, - ServiceName = service.Name + ServiceName = service.Name, + ExternalProgramId = info.ProgramId }; var duration = info.EndDate - info.StartDate; @@ -78,7 +79,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds, Days = info.Days, Priority = info.Priority, - RecurrenceType = info.RecurrenceType, + RecordAnyChannel = info.RecordAnyChannel, + RecordAnyTime = info.RecordAnyTime, + RecordNewOnly = info.RecordNewOnly, ExternalChannelId = info.ChannelId, ExternalProgramId = info.ProgramId, ServiceName = service.Name @@ -146,7 +149,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv OfficialRating = info.OfficialRating, Audio = info.Audio, IsHD = info.IsHD, - ServiceName = service.Name + ServiceName = service.Name, + Url = info.Url }; if (user != null) @@ -219,7 +223,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv CommunityRating = program.CommunityRating, AspectRatio = program.AspectRatio, IsRepeat = program.IsRepeat, - EpisodeTitle = program.EpisodeTitle + EpisodeTitle = program.EpisodeTitle, + ChannelName = program.ChannelName }; if (user != null) @@ -302,7 +307,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv RequestedPostPaddingSeconds = dto.RequestedPostPaddingSeconds, RequestedPrePaddingSeconds = dto.RequestedPrePaddingSeconds, RequiredPostPaddingSeconds = dto.RequiredPostPaddingSeconds, - RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds + RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds, + ProgramId = dto.ExternalProgramId }; } @@ -323,8 +329,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds, Days = dto.Days, Priority = dto.Priority, - RecurrenceType = dto.RecurrenceType, - ProgramId = dto.ExternalProgramId + ProgramId = dto.ExternalProgramId, + RecordAnyChannel = dto.RecordAnyChannel, + RecordAnyTime = dto.RecordAnyTime, + RecordNewOnly = dto.RecordNewOnly }; } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index e06b99999a..b56f94a364 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -336,7 +336,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv .ToList(); } - var returnArray = list.OrderByDescending(i => i.StartDate) + var returnArray = list.OrderBy(i => i.StartDate) .ToArray(); return new QueryResult diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 4e44f156ae..8088d35b70 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -275,7 +275,9 @@ namespace MediaBrowser.WebDashboard.Api // Don't cache if not configured to do so // But always cache images to simulate production - if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching && !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) + if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching && + !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) && + !contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase)) { return ResultFactory.GetResult(GetResourceStream(path).Result, contentType); } @@ -284,7 +286,7 @@ namespace MediaBrowser.WebDashboard.Api // Cache images unconditionally - updates to image files will require new filename // If there's a version number in the query string we can cache this unconditionally - if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || !string.IsNullOrEmpty(request.V)) + if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase) || !string.IsNullOrEmpty(request.V)) { cacheDuration = TimeSpan.FromDays(365); } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index d453d67573..7878753f24 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.273 + 3.0.275 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 16ebaa8a80..34133bf6e4 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.273 + 3.0.275 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 33470aa627..92bd239e4b 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.273 + 3.0.275 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - +