diff options
26 files changed, 280 insertions, 81 deletions
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 2961c920f..4cd75afca 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -1,4 +1,5 @@ using System.Threading; +using System.Threading.Tasks; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; @@ -82,6 +83,22 @@ namespace MediaBrowser.Api.LiveTv public string UserId { get; set; } } + [Route("/LiveTv/Recordings/{Id}", "DELETE")] + [Api(Description = "Deletes a live tv recording")] + public class DeleteRecording : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + [Route("/LiveTv/Timers/{Id}", "DELETE")] + [Api(Description = "Cancels a live tv timer")] + public class CancelTimer : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + public class LiveTvService : BaseApiService { private readonly ILiveTvManager _liveTvManager; @@ -176,5 +193,19 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedResult(result); } + + public void Delete(DeleteRecording request) + { + var task = _liveTvManager.DeleteRecording(request.Id); + + Task.WaitAll(task); + } + + public void Delete(CancelTimer request) + { + var task = _liveTvManager.CancelTimer(request.Id); + + Task.WaitAll(task); + } } }
\ No newline at end of file diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index 2674529e5..d17a38e07 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -31,7 +31,8 @@ namespace MediaBrowser.Api.ScheduledTasks [Api(Description = "Gets scheduled tasks")] public class GetScheduledTasks : IReturn<List<TaskInfo>> { - + [ApiMember(Name = "IsHidden", Description = "Optional filter tasks that are hidden, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsHidden { get; set; } } /// <summary> @@ -112,10 +113,33 @@ namespace MediaBrowser.Api.ScheduledTasks /// <returns>IEnumerable{TaskInfo}.</returns> public object Get(GetScheduledTasks request) { - var result = TaskManager.ScheduledTasks.OrderBy(i => i.Name) - .Select(ScheduledTaskHelpers.GetTaskInfo).ToList(); + IEnumerable<IScheduledTaskWorker> result = TaskManager.ScheduledTasks + .OrderBy(i => i.Name); - return ToOptimizedResult(result); + if (request.IsHidden.HasValue) + { + var val = request.IsHidden.Value; + + result = result.Where(i => + { + var isHidden = false; + + var configurableTask = i.ScheduledTask as IConfigurableScheduledTask; + + if (configurableTask != null) + { + isHidden = configurableTask.IsHidden; + } + + return isHidden == val; + }); + } + + var infos = result + .Select(ScheduledTaskHelpers.GetTaskInfo) + .ToList(); + + return ToOptimizedResult(infos); } /// <summary> diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 20634301a..c143635bf 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -46,8 +46,10 @@ namespace MediaBrowser.Api.ScheduledTasks /// <returns>Task{IEnumerable{TaskInfo}}.</returns> protected override Task<IEnumerable<TaskInfo>> GetDataToSend(object state) { - return Task.FromResult(TaskManager.ScheduledTasks.OrderBy(i => i.Name) - .Select(ScheduledTaskHelpers.GetTaskInfo)); + return Task.FromResult(TaskManager.ScheduledTasks + .OrderBy(i => i.Name) + .Select(ScheduledTaskHelpers.GetTaskInfo) + .Where(i => !i.IsHidden)); } } } diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 95bde2d28..23b8efa7b 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -81,8 +81,11 @@ namespace MediaBrowser.Api [ApiMember(Name = "Season", Description = "Optional filter by season number.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public int? Season { get; set; } - [ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string ExcludeLocationTypes { get; set; } + [ApiMember(Name = "IsMissing", Description = "Optional filter by items that are missing episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsMissing { get; set; } + + [ApiMember(Name = "IsVirtualUnaired", Description = "Optional filter by items that are virtual unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsVirtualUnaired { get; set; } } [Route("/Shows/{Id}/Seasons", "GET")] @@ -106,11 +109,14 @@ namespace MediaBrowser.Api [ApiMember(Name = "Id", Description = "The series id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] public Guid Id { get; set; } - [ApiMember(Name = "ExcludeLocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string ExcludeLocationTypes { get; set; } - [ApiMember(Name = "IsSpecialSeason", Description = "Optional. Filter by special season.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsSpecialSeason { get; set; } + + [ApiMember(Name = "IsMissing", Description = "Optional filter by items that are missing episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsMissing { get; set; } + + [ApiMember(Name = "IsVirtualUnaired", Description = "Optional filter by items that are virtual unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool? IsVirtualUnaired { get; set; } } /// <summary> @@ -380,12 +386,7 @@ namespace MediaBrowser.Api } } - // ExcludeLocationTypes - if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) - { - var vals = request.ExcludeLocationTypes.Split(','); - seasons = seasons.Where(f => !vals.Contains(f.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)); - } + seasons = FilterVirtualSeasons(request, seasons); seasons = _libraryManager.Sort(seasons, user, new[] { sortOrder }, SortOrder.Ascending) .Cast<Season>(); @@ -400,6 +401,34 @@ namespace MediaBrowser.Api }; } + private IEnumerable<Season> FilterVirtualSeasons(GetSeasons request, IEnumerable<Season> items) + { + if (request.IsMissing.HasValue && request.IsVirtualUnaired.HasValue) + { + var isMissing = request.IsMissing.Value; + var isVirtualUnaired = request.IsVirtualUnaired.Value; + + if (!isMissing && !isVirtualUnaired) + { + return items.Where(i => !i.IsMissingOrVirtualUnaired); + } + } + + if (request.IsMissing.HasValue) + { + var val = request.IsMissing.Value; + items = items.Where(i => i.IsMissingSeason == val); + } + + if (request.IsVirtualUnaired.HasValue) + { + var val = request.IsVirtualUnaired.Value; + items = items.Where(i => i.IsVirtualUnaired == val); + } + + return items; + } + public object Get(GetEpisodes request) { var user = _userManager.GetUserById(request.UserId); @@ -431,11 +460,16 @@ namespace MediaBrowser.Api episodes = episodes.Where(i => !i.IsVirtualUnaired); } - // ExcludeLocationTypes - if (!string.IsNullOrEmpty(request.ExcludeLocationTypes)) + if (request.IsMissing.HasValue) + { + var val = request.IsMissing.Value; + episodes = episodes.Where(i => i.IsMissingEpisode == val); + } + + if (request.IsVirtualUnaired.HasValue) { - var vals = request.ExcludeLocationTypes.Split(','); - episodes = episodes.Where(f => !vals.Contains(f.LocationType.ToString(), StringComparer.OrdinalIgnoreCase)); + var val = request.IsVirtualUnaired.Value; + episodes = episodes.Where(i => i.IsVirtualUnaired == val); } episodes = _libraryManager.Sort(episodes, user, new[] { sortOrder }, SortOrder.Ascending) diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index ee22b7baa..f1d8c94e5 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -218,7 +218,7 @@ namespace MediaBrowser.Common.Implementations try { // Increase the max http request limit - ServicePointManager.DefaultConnectionLimit = Math.Max(48, ServicePointManager.DefaultConnectionLimit); + ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); } catch (Exception ex) { diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index 0d6ba5c1d..181c83fd3 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Configuration; +using System.Reflection; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs index e04cadfc5..6d886bc69 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteCacheFileTask.cs @@ -29,7 +29,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// <summary> /// Initializes a new instance of the <see cref="DeleteCacheFileTask" /> class. /// </summary> - /// <param name="appPaths">The app paths.</param> public DeleteCacheFileTask(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem) { ApplicationPaths = appPaths; diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs index 351e96c7d..2ee4fb4b5 100644 --- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs +++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs @@ -42,4 +42,9 @@ namespace MediaBrowser.Common.ScheduledTasks /// <returns>IEnumerable{BaseTaskTrigger}.</returns> IEnumerable<ITaskTrigger> GetDefaultTriggers(); } + + public interface IConfigurableScheduledTask + { + bool IsHidden { get; } + } } diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs index f31650986..39148166b 100644 --- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs +++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs @@ -16,6 +16,15 @@ namespace MediaBrowser.Common.ScheduledTasks /// <returns>TaskInfo.</returns> public static TaskInfo GetTaskInfo(IScheduledTaskWorker task) { + var isHidden = false; + + var configurableTask = task.ScheduledTask as IConfigurableScheduledTask; + + if (configurableTask != null) + { + isHidden = configurableTask.IsHidden; + } + return new TaskInfo { Name = task.Name, @@ -25,7 +34,8 @@ namespace MediaBrowser.Common.ScheduledTasks LastExecutionResult = task.LastExecutionResult, Triggers = task.Triggers.Select(GetTriggerInfo).ToList(), Description = task.Description, - Category = task.Category + Category = task.Category, + IsHidden = isHidden }; } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 7938c38ec..d5b9cea27 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -25,6 +25,20 @@ namespace MediaBrowser.Controller.LiveTv Task ScheduleRecording(string programId); /// <summary> + /// Deletes the recording. + /// </summary> + /// <param name="id">The identifier.</param> + /// <returns>Task.</returns> + Task DeleteRecording(string id); + + /// <summary> + /// Cancels the timer. + /// </summary> + /// <param name="id">The identifier.</param> + /// <returns>Task.</returns> + Task CancelTimer(string id); + + /// <summary> /// Adds the parts. /// </summary> /// <param name="services">The services.</param> diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index e903ad5ec..9bc032af3 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -48,14 +48,6 @@ namespace MediaBrowser.Controller.LiveTv Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken); /// <summary> - /// Updates the timer asynchronous. - /// </summary> - /// <param name="info">The information.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken); - - /// <summary> /// Gets the channel image asynchronous. /// </summary> /// <param name="channelId">The channel identifier.</param> diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index f0daac5f9..88d093f64 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -41,6 +41,12 @@ namespace MediaBrowser.Controller.LiveTv public DateTime EndDate { get; set; } /// <summary> + /// Gets or sets the program identifier. + /// </summary> + /// <value>The program identifier.</value> + public string ProgramId { get; set; } + + /// <summary> /// Gets or sets the status. /// </summary> /// <value>The status.</value> diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs index f0f936b52..7401dafec 100644 --- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -1,6 +1,5 @@ using MediaBrowser.Model.LiveTv; using System; -using System.Collections.Generic; namespace MediaBrowser.Controller.LiveTv { @@ -22,6 +21,12 @@ namespace MediaBrowser.Controller.LiveTv public string ChannelName { get; set; } /// <summary> + /// Gets or sets the program identifier. + /// </summary> + /// <value>The program identifier.</value> + public string ProgramId { get; set; } + + /// <summary> /// Name of the recording. /// </summary> public string Name { get; set; } @@ -52,16 +57,5 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value><c>true</c> if this instance is recurring; otherwise, <c>false</c>.</value> public bool IsRecurring { get; set; } - - /// <summary> - /// Gets or sets the recurring days. - /// </summary> - /// <value>The recurring days.</value> - public List<DayOfWeek> RecurringDays { get; set; } - - public TimerInfo() - { - RecurringDays = new List<DayOfWeek>(); - } } } diff --git a/MediaBrowser.Model/LiveTv/RecordingStatus.cs b/MediaBrowser.Model/LiveTv/RecordingStatus.cs index b8af8f6e2..778977340 100644 --- a/MediaBrowser.Model/LiveTv/RecordingStatus.cs +++ b/MediaBrowser.Model/LiveTv/RecordingStatus.cs @@ -10,4 +10,11 @@ namespace MediaBrowser.Model.LiveTv Conflicted, Deleted } + + public enum RecurrenceType + { + Manual, + NewProgramEvents, + AllProgramEvents + } } diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs index 6a8339031..ddefce59e 100644 --- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs @@ -1,11 +1,10 @@ using System; -using System.Collections.Generic; namespace MediaBrowser.Model.LiveTv { public class TimerInfoDto { - /// <summary> + /// <summary> /// Id of the recording. /// </summary> public string Id { get; set; } @@ -15,7 +14,7 @@ namespace MediaBrowser.Model.LiveTv /// </summary> /// <value>The external identifier.</value> public string ExternalId { get; set; } - + /// <summary> /// ChannelId of the recording. /// </summary> @@ -27,6 +26,12 @@ namespace MediaBrowser.Model.LiveTv public string ChannelName { get; set; } /// <summary> + /// Gets or sets the program identifier. + /// </summary> + /// <value>The program identifier.</value> + public string ProgramId { get; set; } + + /// <summary> /// Name of the recording. /// </summary> public string Name { get; set; } @@ -57,16 +62,5 @@ namespace MediaBrowser.Model.LiveTv /// </summary> /// <value><c>true</c> if this instance is recurring; otherwise, <c>false</c>.</value> public bool IsRecurring { get; set; } - - /// <summary> - /// Gets or sets the recurring days. - /// </summary> - /// <value>The recurring days.</value> - public List<DayOfWeek> RecurringDays { get; set; } - - public TimerInfoDto() - { - RecurringDays = new List<DayOfWeek>(); - } - } + } } diff --git a/MediaBrowser.Model/Querying/EpisodeQuery.cs b/MediaBrowser.Model/Querying/EpisodeQuery.cs index 406ac9844..56c50da7f 100644 --- a/MediaBrowser.Model/Querying/EpisodeQuery.cs +++ b/MediaBrowser.Model/Querying/EpisodeQuery.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Entities; - + namespace MediaBrowser.Model.Querying { public class EpisodeQuery @@ -8,7 +7,9 @@ namespace MediaBrowser.Model.Querying public string SeriesId { get; set; } - public LocationType[] ExcludeLocationTypes { get; set; } + public bool? IsMissing { get; set; } + + public bool? IsVirtualUnaired { get; set; } public int? SeasonNumber { get; set; } @@ -17,7 +18,6 @@ namespace MediaBrowser.Model.Querying public EpisodeQuery() { Fields = new ItemFields[] { }; - ExcludeLocationTypes = new LocationType[] { }; } } @@ -27,7 +27,9 @@ namespace MediaBrowser.Model.Querying public string SeriesId { get; set; } - public LocationType[] ExcludeLocationTypes { get; set; } + public bool? IsMissing { get; set; } + + public bool? IsVirtualUnaired { get; set; } public ItemFields[] Fields { get; set; } @@ -36,7 +38,6 @@ namespace MediaBrowser.Model.Querying public SeasonQuery() { Fields = new ItemFields[] { }; - ExcludeLocationTypes = new LocationType[] { }; } } } diff --git a/MediaBrowser.Model/Tasks/TaskInfo.cs b/MediaBrowser.Model/Tasks/TaskInfo.cs index dee4fea7f..a7d500303 100644 --- a/MediaBrowser.Model/Tasks/TaskInfo.cs +++ b/MediaBrowser.Model/Tasks/TaskInfo.cs @@ -57,6 +57,12 @@ namespace MediaBrowser.Model.Tasks public string Category { get; set; } /// <summary> + /// Gets or sets a value indicating whether this instance is hidden. + /// </summary> + /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value> + public bool IsHidden { get; set; } + + /// <summary> /// Initializes a new instance of the <see cref="TaskInfo"/> class. /// </summary> public TaskInfo() diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 00ac83f15..4d3d87788 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -397,6 +397,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv Status = info.Status }; + if (!string.IsNullOrEmpty(info.ProgramId)) + { + dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N"); + } + return dto; } @@ -503,13 +508,61 @@ namespace MediaBrowser.Server.Implementations.LiveTv ExternalId = info.Id, ChannelId = GetInternalChannelId(service.Name, info.ChannelId).ToString("N"), Status = info.Status, - IsRecurring = info.IsRecurring, - RecurringDays = info.RecurringDays + IsRecurring = info.IsRecurring }; + if (!string.IsNullOrEmpty(info.ProgramId)) + { + dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N"); + } + return dto; } + public async Task DeleteRecording(string recordingId) + { + var recordings = await GetRecordings(new RecordingQuery + { + + }, CancellationToken.None).ConfigureAwait(false); + + var recording = recordings.Items + .FirstOrDefault(i => string.Equals(recordingId, i.Id, StringComparison.OrdinalIgnoreCase)); + + if (recording == null) + { + throw new ResourceNotFoundException(string.Format("Recording with Id {0} not found", recordingId)); + } + + var channel = GetChannel(recording.ChannelId); + var service = GetServices(channel.ServiceName, null) + .First(); + + await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false); + } + + public async Task CancelTimer(string id) + { + var timers = await GetTimers(new TimerQuery + { + + }, CancellationToken.None).ConfigureAwait(false); + + var timer = timers.Items + .FirstOrDefault(i => string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)); + + if (timer == null) + { + throw new ResourceNotFoundException(string.Format("Timer with Id {0} not found", id)); + } + + var channel = GetChannel(timer.ChannelId); + + var service = GetServices(channel.ServiceName, null) + .First(); + + await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs index c3803d9bb..00bf9e55b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv { - class RefreshChannelsScheduledTask : IScheduledTask + class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask { private readonly ILiveTvManager _liveTvManager; @@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public Task Execute(System.Threading.CancellationToken cancellationToken, IProgress<double> progress) { - var manager = (LiveTvManager) _liveTvManager; + var manager = (LiveTvManager)_liveTvManager; return manager.RefreshChannels(progress, cancellationToken); } @@ -50,5 +50,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv new IntervalTrigger{ Interval = TimeSpan.FromHours(2)} }; } + + public bool IsHidden + { + get { return _liveTvManager.Services.Count == 0; } + } } } diff --git a/MediaBrowser.ServerApplication/Native/HttpClientFactory.cs b/MediaBrowser.ServerApplication/Native/HttpClientFactory.cs index 57f00ba03..368c60254 100644 --- a/MediaBrowser.ServerApplication/Native/HttpClientFactory.cs +++ b/MediaBrowser.ServerApplication/Native/HttpClientFactory.cs @@ -17,14 +17,19 @@ namespace MediaBrowser.ServerApplication.Native /// <returns>HttpClient.</returns> public static HttpClient GetHttpClient(bool enableHttpCompression) { - return new HttpClient(new WebRequestHandler + var client = new HttpClient(new WebRequestHandler { CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate), AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None + }) { Timeout = TimeSpan.FromSeconds(20) }; + + client.DefaultRequestHeaders.Add("Connection", "Keep-Alive"); + + return client; } } } diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 36476511e..de96c4de9 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -506,6 +506,20 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }); }; + self.createLiveTvTimer = function (options) { + + if (!options) { + throw new Error("null options"); + } + + var url = self.getUrl("LiveTv/Timers", options); + + return self.ajax({ + type: "POST", + url: url + }); + }; + /** * Gets the current server status */ @@ -1019,9 +1033,11 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi /** * Gets the server's scheduled tasks */ - self.getScheduledTasks = function () { + self.getScheduledTasks = function (options) { - var url = self.getUrl("ScheduledTasks"); + options = options || {}; + + var url = self.getUrl("ScheduledTasks", options); return self.ajax({ type: "GET", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5585e0db5..4aca619aa 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -284,10 +284,10 @@ <Content Include="dashboard-ui\css\images\userdata\thumbs_up_on.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\userdata\playedoff.png">
+ <Content Include="dashboard-ui\css\images\userdata\checkedoff.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\userdata\playedon.png">
+ <Content Include="dashboard-ui\css\images\userdata\checkedon.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\librarybrowser.css">
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 25938a358..a839ece18 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="MediaBrowser.ApiClient.Javascript" version="3.0.201" targetFramework="net45" /> + <package id="MediaBrowser.ApiClient.Javascript" version="3.0.203" targetFramework="net45" /> <package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" /> <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 51bdf43d6..77765ddc6 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.252</version> + <version>3.0.253</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.252" /> + <dependency id="MediaBrowser.Common" version="3.0.253" /> <dependency id="NLog" version="2.1.0" /> <dependency id="ServiceStack.Text" version="3.9.58" /> <dependency id="SimpleInjector" version="2.3.6" /> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 6ccfca542..ac6b606cd 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.252</version> + <version>3.0.253</version> <title>MediaBrowser.Common</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index de9b90a46..a6c1bee11 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.252</version> + <version>3.0.253</version> <title>Media Browser.Server.Core</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Media Browser Server.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.252" /> + <dependency id="MediaBrowser.Common" version="3.0.253" /> </dependencies> </metadata> <files> |
