From 01e65c93eeeddff27fc2e0e4833678c5cc2829a0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 14 Dec 2013 20:17:57 -0500 Subject: [PATCH] updated live tv + nuget --- MediaBrowser.Api/Images/ImageService.cs | 2 + MediaBrowser.Api/LiveTv/LiveTvService.cs | 76 +++- .../BaseApplicationPaths.cs | 33 +- .../Configuration/BaseConfigurationManager.cs | 39 ++- .../HttpClientManager/HttpClientManager.cs | 2 + .../IServerApplicationPaths.cs | 8 +- .../LiveTv/ILiveTvManager.cs | 58 +++- .../LiveTv/ILiveTvService.cs | 11 +- .../LiveTv/ImageResponseInfo.cs | 6 - .../LiveTv/SeriesTimerInfo.cs | 42 ++- .../Providers/BaseItemXmlParser.cs | 108 ++---- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + .../BaseApplicationConfiguration.cs | 8 +- MediaBrowser.Model/LiveTv/ProgramInfoDto.cs | 7 + MediaBrowser.Model/LiveTv/RecordingInfoDto.cs | 7 + MediaBrowser.Model/LiveTv/RecordingQuery.cs | 10 + MediaBrowser.Model/LiveTv/RecordingStatus.cs | 9 +- .../LiveTv/SeriesTimerInfoDto.cs | 120 +++++++ MediaBrowser.Model/LiveTv/TimerInfoDto.cs | 12 + MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + MediaBrowser.Model/System/SystemInfo.cs | 6 + .../Movies/MovieDbProvider.cs | 3 +- .../Savers/XmlSaverHelpers.cs | 10 +- .../ServerConfigurationManager.cs | 39 ++- .../Drawing/ImageProcessor.cs | 38 +- .../LiveTv/ChannelImageProvider.cs | 8 +- .../LiveTv/LiveTvDtoService.cs | 324 ++++++++++++++++++ .../LiveTv/LiveTvManager.cs | 296 +++++----------- ...MediaBrowser.Server.Implementations.csproj | 3 +- .../ApplicationHost.cs | 3 +- .../Native/ServerAuthorization.cs | 2 + .../Api/DashboardService.cs | 19 +- MediaBrowser.WebDashboard/ApiClient.js | 98 +++++- .../MediaBrowser.WebDashboard.csproj | 2 +- MediaBrowser.WebDashboard/packages.config | 2 +- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 39 files changed, 1002 insertions(+), 426 deletions(-) create mode 100644 MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs create mode 100644 MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 2de78d75b2..ba6809f4d2 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -796,6 +796,8 @@ namespace MediaBrowser.Api.Images /// The file2. private void SwapFiles(string file1, string file2) { + Directory.CreateDirectory(_appPaths.TempDirectory); + var temp1 = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp"); var temp2 = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp"); diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 9e83a56de7..979088ee00 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; using ServiceStack; @@ -23,7 +24,7 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "Type", Description = "Optional filter by channel type.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public ChannelType? Type { get; set; } - [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string UserId { get; set; } } @@ -38,7 +39,7 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } - [ApiMember(Name = "UserId", Description = "Optional user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string UserId { get; set; } } @@ -48,6 +49,9 @@ namespace MediaBrowser.Api.LiveTv { [ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string ChannelId { get; set; } + + [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string UserId { get; set; } } [Route("/LiveTv/Recordings/{Id}", "GET")] @@ -56,6 +60,9 @@ namespace MediaBrowser.Api.LiveTv { [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } + + [ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string UserId { get; set; } } [Route("/LiveTv/Timers/{Id}", "GET")] @@ -100,14 +107,36 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } } - + + [Route("/LiveTv/Timers/{Id}", "POST")] + [Api(Description = "Updates a live tv timer")] + public class UpdateTimer : TimerInfoDto, IReturnVoid + { + } + + [Route("/LiveTv/Timers/{Id}", "GET")] + [Api(Description = "Gets a live tv series timer")] + public class GetSeriesTimer : IReturn + { + [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + [Route("/LiveTv/SeriesTimers", "GET")] + [Api(Description = "Gets live tv series timers")] + public class GetSeriesTimers : IReturn> + { + } + public class LiveTvService : BaseApiService { private readonly ILiveTvManager _liveTvManager; + private readonly IUserManager _userManager; - public LiveTvService(ILiveTvManager liveTvManager) + public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager) { _liveTvManager = liveTvManager; + _userManager = userManager; } public object Get(GetServices request) @@ -134,14 +163,16 @@ namespace MediaBrowser.Api.LiveTv ChannelType = request.Type, UserId = request.UserId - }); + }, CancellationToken.None).Result; return ToOptimizedResult(result); } public object Get(GetChannel request) { - var result = _liveTvManager.GetChannelInfoDto(request.Id, request.UserId); + var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(new Guid(request.UserId)); + + var result = _liveTvManager.GetChannel(request.Id, CancellationToken.None, user).Result; return ToOptimizedResult(result); } @@ -162,7 +193,8 @@ namespace MediaBrowser.Api.LiveTv { var result = _liveTvManager.GetRecordings(new RecordingQuery { - ChannelId = request.ChannelId + ChannelId = request.ChannelId, + UserId = request.UserId }, CancellationToken.None).Result; @@ -171,7 +203,9 @@ namespace MediaBrowser.Api.LiveTv public object Get(GetRecording request) { - var result = _liveTvManager.GetRecording(request.Id, CancellationToken.None).Result; + var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(new Guid(request.UserId)); + + var result = _liveTvManager.GetRecording(request.Id, CancellationToken.None, user).Result; return ToOptimizedResult(result); } @@ -207,5 +241,29 @@ namespace MediaBrowser.Api.LiveTv Task.WaitAll(task); } + + public void Post(UpdateTimer request) + { + var task = _liveTvManager.UpdateTimer(request, CancellationToken.None); + + Task.WaitAll(task); + } + + public object Get(GetSeriesTimers request) + { + var result = _liveTvManager.GetSeriesTimers(new SeriesTimerQuery + { + + }, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } + + public object Get(GetSeriesTimer request) + { + var result = _liveTvManager.GetSeriesTimer(request.Id, CancellationToken.None).Result; + + return ToOptimizedResult(result); + } } } \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs index 6acaac5c97..eba8f56988 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs @@ -2,7 +2,6 @@ using System; using System.Configuration; using System.IO; -using System.Reflection; namespace MediaBrowser.Common.Implementations { @@ -81,10 +80,6 @@ namespace MediaBrowser.Common.Implementations } } - /// - /// The _image cache path - /// - private string _imageCachePath; /// /// Gets the image cache path. /// @@ -93,14 +88,7 @@ namespace MediaBrowser.Common.Implementations { get { - if (_imageCachePath == null) - { - _imageCachePath = Path.Combine(CachePath, "images"); - - Directory.CreateDirectory(_imageCachePath); - } - - return _imageCachePath; + return Path.Combine(CachePath, "images"); } } @@ -233,7 +221,7 @@ namespace MediaBrowser.Common.Implementations { get { - if (_cachePath == null) + if (string.IsNullOrEmpty(_cachePath)) { _cachePath = Path.Combine(ProgramDataPath, "cache"); @@ -242,12 +230,12 @@ namespace MediaBrowser.Common.Implementations return _cachePath; } + set + { + _cachePath = value; + } } - /// - /// The _temp directory - /// - private string _tempDirectory; /// /// Gets the folder path to the temp directory within the cache folder /// @@ -256,14 +244,7 @@ namespace MediaBrowser.Common.Implementations { get { - if (_tempDirectory == null) - { - _tempDirectory = Path.Combine(CachePath, "temp"); - - Directory.CreateDirectory(_tempDirectory); - } - - return _tempDirectory; + return Path.Combine(CachePath, "temp"); } } diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index 317a288ff1..3c00673baa 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Configuration; +using System.IO; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; @@ -84,6 +85,8 @@ namespace MediaBrowser.Common.Implementations.Configuration CommonApplicationPaths = applicationPaths; XmlSerializer = xmlSerializer; Logger = logManager.GetLogger(GetType().Name); + + UpdateCachePath(); } /// @@ -109,6 +112,8 @@ namespace MediaBrowser.Common.Implementations.Configuration /// protected virtual void OnConfigurationUpdated() { + UpdateCachePath(); + EventHelper.QueueEventIfNotNull(ConfigurationUpdated, this, EventArgs.Empty, Logger); } @@ -124,8 +129,40 @@ namespace MediaBrowser.Common.Implementations.Configuration throw new ArgumentNullException("newConfiguration"); } + ValidateCachePath(newConfiguration); + CommonConfiguration = newConfiguration; SaveConfiguration(); } + + /// + /// Updates the items by name path. + /// + private void UpdateCachePath() + { + ((BaseApplicationPaths)CommonApplicationPaths).CachePath = string.IsNullOrEmpty(CommonConfiguration.CachePath) ? + null : + CommonConfiguration.CachePath; + } + + /// + /// Replaces the cache path. + /// + /// The new configuration. + /// + private void ValidateCachePath(BaseApplicationConfiguration newConfig) + { + var newPath = newConfig.CachePath; + + if (!string.IsNullOrWhiteSpace(newPath) + && !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath)) + { + // Validate + if (!Directory.Exists(newPath)) + { + throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath)); + } + } + } } } diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index 19091885d1..b5317319fa 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -445,6 +445,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager { ValidateParams(options.Url, options.CancellationToken); + Directory.CreateDirectory(_appPaths.TempDirectory); + var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp"); if (options.Progress == null) diff --git a/MediaBrowser.Controller/IServerApplicationPaths.cs b/MediaBrowser.Controller/IServerApplicationPaths.cs index 57cb7c7dd4..f8b78299c4 100644 --- a/MediaBrowser.Controller/IServerApplicationPaths.cs +++ b/MediaBrowser.Controller/IServerApplicationPaths.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Controller /// Gets the path to the Images By Name directory /// /// The images by name path. - string ItemsByNamePath { get; set; } + string ItemsByNamePath { get; } /// /// Gets the path to the People directory @@ -51,13 +51,13 @@ namespace MediaBrowser.Controller /// /// The game genre path. string GameGenrePath { get; } - + /// /// Gets the artists path. /// /// The artists path. string ArtistsPath { get; } - + /// /// Gets the path to the Studio directory /// @@ -87,7 +87,7 @@ namespace MediaBrowser.Controller /// /// The media info images path. string MediaInfoImagesPath { get; } - + /// /// Gets the path to the user configuration directory /// diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index b8dfbe05dd..9ed7b633d9 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.LiveTv; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; using System.Collections.Generic; using System.Threading; @@ -54,17 +55,28 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the channels. /// /// The query. + /// The cancellation token. /// IEnumerable{Channel}. - QueryResult GetChannels(ChannelQuery query); + Task> GetChannels(ChannelQuery query, CancellationToken cancellationToken); /// /// Gets the recording. /// /// The identifier. + /// The user. /// The cancellation token. /// Task{RecordingInfoDto}. - Task GetRecording(string id, CancellationToken cancellationToken); + Task GetRecording(string id, CancellationToken cancellationToken, User user = null); + /// + /// Gets the channel. + /// + /// The identifier. + /// The cancellation token. + /// The user. + /// Task{RecordingInfoDto}. + Task GetChannel(string id, CancellationToken cancellationToken, User user = null); + /// /// Gets the timer. /// @@ -73,6 +85,14 @@ namespace MediaBrowser.Controller.LiveTv /// Task{TimerInfoDto}. Task GetTimer(string id, CancellationToken cancellationToken); + /// + /// Gets the series timer. + /// + /// The identifier. + /// The cancellation token. + /// Task{TimerInfoDto}. + Task GetSeriesTimer(string id, CancellationToken cancellationToken); + /// /// Gets the recordings. /// @@ -89,6 +109,14 @@ namespace MediaBrowser.Controller.LiveTv /// Task{QueryResult{TimerInfoDto}}. Task> GetTimers(TimerQuery query, CancellationToken cancellationToken); + /// + /// Gets the series timers. + /// + /// The query. + /// The cancellation token. + /// Task{QueryResult{SeriesTimerInfoDto}}. + Task> GetSeriesTimers(SeriesTimerQuery query, CancellationToken cancellationToken); + /// /// Gets the channel. /// @@ -96,14 +124,6 @@ namespace MediaBrowser.Controller.LiveTv /// Channel. Channel GetChannel(string id); - /// - /// Gets the channel. - /// - /// The identifier. - /// The user identifier. - /// Channel. - ChannelInfoDto GetChannelInfoDto(string id, string userId); - /// /// Gets the programs. /// @@ -111,5 +131,21 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// IEnumerable{ProgramInfo}. Task> GetPrograms(ProgramQuery query, CancellationToken cancellationToken); + + /// + /// Updates the timer. + /// + /// The timer. + /// The cancellation token. + /// Task. + Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken); + + /// + /// Updates the timer. + /// + /// The timer. + /// The cancellation token. + /// Task. + Task UpdateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index de75ee7528..8b1801f9e8 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Net; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -55,6 +54,14 @@ namespace MediaBrowser.Controller.LiveTv /// Task. Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken); + /// + /// Updates the timer asynchronous. + /// + /// The information. + /// The cancellation token. + /// Task. + Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken); + /// /// Updates the series timer asynchronous. /// diff --git a/MediaBrowser.Controller/LiveTv/ImageResponseInfo.cs b/MediaBrowser.Controller/LiveTv/ImageResponseInfo.cs index 6b6123e540..d454a1ef8d 100644 --- a/MediaBrowser.Controller/LiveTv/ImageResponseInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ImageResponseInfo.cs @@ -15,11 +15,5 @@ namespace MediaBrowser.Controller.LiveTv /// /// The type of the MIME. public string MimeType { get; set; } - - /// - /// Gets or sets the image path. - /// - /// The image path. - public string ImagePath { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs index 44594882cd..6072827964 100644 --- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.LiveTv /// ChannelId of the recording. /// public string ChannelId { get; set; } - + /// /// ChannelName of the recording. /// @@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.LiveTv /// /// The program identifier. public string ProgramId { get; set; } - + /// /// Name of the recording. /// @@ -35,7 +35,7 @@ namespace MediaBrowser.Controller.LiveTv /// /// Description of the recording. /// - public string Description { get; set; } + public string Overview { get; set; } /// /// The start date of the recording, in UTC. @@ -47,18 +47,6 @@ namespace MediaBrowser.Controller.LiveTv /// public DateTime EndDate { get; set; } - /// - /// Gets or sets the pre padding seconds. - /// - /// The pre padding seconds. - public int PrePaddingSeconds { get; set; } - - /// - /// Gets or sets the post padding seconds. - /// - /// The post padding seconds. - public int PostPaddingSeconds { get; set; } - /// /// Gets or sets the type of the recurrence. /// @@ -77,6 +65,30 @@ namespace MediaBrowser.Controller.LiveTv /// The priority. public int Priority { get; set; } + /// + /// Gets or sets the requested pre padding seconds. + /// + /// The requested pre padding seconds. + public int RequestedPrePaddingSeconds { get; set; } + + /// + /// Gets or sets the requested post padding seconds. + /// + /// The requested post padding seconds. + public int RequestedPostPaddingSeconds { get; set; } + + /// + /// Gets or sets the required pre padding seconds. + /// + /// The required pre padding seconds. + public int RequiredPrePaddingSeconds { get; set; } + + /// + /// Gets or sets the required post padding seconds. + /// + /// The required post padding seconds. + public int RequiredPostPaddingSeconds { get; set; } + public SeriesTimerInfo() { Days = new List(); diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 9c35a4e999..c9f57a9270 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -759,11 +759,30 @@ namespace MediaBrowser.Controller.Providers break; } - case "MediaInfo": + case "Format3D": { - using (var subtree = reader.ReadSubtree()) + var video = item as Video; + + if (video != null) { - FetchFromMediaInfoNode(subtree, item); + var val = reader.ReadElementContentAsString(); + + if (string.Equals("HSBS", val)) + { + video.Video3DFormat = Video3DFormat.HalfSideBySide; + } + else if (string.Equals("HTAB", val)) + { + video.Video3DFormat = Video3DFormat.HalfTopAndBottom; + } + else if (string.Equals("FTAB", val)) + { + video.Video3DFormat = Video3DFormat.FullTopAndBottom; + } + else if (string.Equals("FSBS", val)) + { + video.Video3DFormat = Video3DFormat.FullSideBySide; + } } break; } @@ -774,89 +793,6 @@ namespace MediaBrowser.Controller.Providers } } - /// - /// Fetches from media info node. - /// - /// The reader. - /// The item. - private void FetchFromMediaInfoNode(XmlReader reader, T item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Video": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromMediaInfoVideoNode(subtree, item); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - /// - /// Fetches from media info video node. - /// - /// The reader. - /// The item. - private void FetchFromMediaInfoVideoNode(XmlReader reader, T item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Format3D": - { - var video = item as Video; - - if (video != null) - { - var val = reader.ReadElementContentAsString(); - - if (string.Equals("HSBS", val)) - { - video.Video3DFormat = Video3DFormat.HalfSideBySide; - } - else if (string.Equals("HTAB", val)) - { - video.Video3DFormat = Video3DFormat.HalfTopAndBottom; - } - else if (string.Equals("FTAB", val)) - { - video.Video3DFormat = Video3DFormat.FullTopAndBottom; - } - else if (string.Equals("FSBS", val)) - { - video.Video3DFormat = Video3DFormat.FullSideBySide; - } - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - /// /// Fetches from taglines node. /// diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index f6e2725a6b..c89dcf4a5b 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -248,6 +248,9 @@ LiveTv\RecordingStatus.cs + + LiveTv\SeriesTimerInfoDto.cs + LiveTv\TimerInfoDto.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index efafc7f629..78f970969b 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -235,6 +235,9 @@ LiveTv\RecordingStatus.cs + + LiveTv\SeriesTimerInfoDto.cs + LiveTv\TimerInfoDto.cs diff --git a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs index b99fefcca3..19620890e7 100644 --- a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs +++ b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs @@ -43,7 +43,13 @@ namespace MediaBrowser.Model.Configuration /// /// true if this instance is first run; otherwise, false. public bool IsStartupWizardCompleted { get; set; } - + + /// + /// Gets or sets the cache path. + /// + /// The cache path. + public string CachePath { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs index a330c6c3a9..b3542fcf81 100644 --- a/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ProgramInfoDto.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Model.LiveTv { @@ -101,6 +102,12 @@ namespace MediaBrowser.Model.LiveTv /// The episode title. public string EpisodeTitle { get; set; } + /// + /// Gets or sets the user data. + /// + /// The user data. + public UserItemDataDto UserData { get; set; } + public ProgramInfoDto() { Genres = new List(); diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs index a095e1751b..d17ebee6dc 100644 --- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Model.LiveTv { @@ -123,6 +124,12 @@ namespace MediaBrowser.Model.LiveTv /// The audio. public ProgramAudio? Audio { get; set; } + /// + /// Gets or sets the user data. + /// + /// The user data. + public UserItemDataDto UserData { get; set; } + public RecordingInfoDto() { Genres = new List(); diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs index cd5ebe6282..3aa94ff834 100644 --- a/MediaBrowser.Model/LiveTv/RecordingQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs @@ -10,6 +10,12 @@ /// /// The channel identifier. public string ChannelId { get; set; } + + /// + /// Gets or sets the user identifier. + /// + /// The user identifier. + public string UserId { get; set; } } public class TimerQuery @@ -20,4 +26,8 @@ /// The channel identifier. public string ChannelId { get; set; } } + + public class SeriesTimerQuery + { + } } diff --git a/MediaBrowser.Model/LiveTv/RecordingStatus.cs b/MediaBrowser.Model/LiveTv/RecordingStatus.cs index 5334d75a37..06bc98e63e 100644 --- a/MediaBrowser.Model/LiveTv/RecordingStatus.cs +++ b/MediaBrowser.Model/LiveTv/RecordingStatus.cs @@ -7,7 +7,7 @@ namespace MediaBrowser.Model.LiveTv Scheduled, InProgress, Completed, - Abored, + Aborted, Cancelled, ConflictedOk, ConflictedNotOk, @@ -22,4 +22,11 @@ namespace MediaBrowser.Model.LiveTv NewProgramEventsAllChannels, AllProgramEventsAllChannels } + + public enum DayPattern + { + Daily, + Weekdays, + Weekends + } } diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs new file mode 100644 index 0000000000..3862c07450 --- /dev/null +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Model.LiveTv +{ + public class SeriesTimerInfoDto + { + /// + /// Id of the recording. + /// + public string Id { get; set; } + + /// + /// Gets or sets the external identifier. + /// + /// The external identifier. + public string ExternalId { get; set; } + + /// + /// ChannelId of the recording. + /// + public string ChannelId { get; set; } + + /// + /// Gets or sets the external channel identifier. + /// + /// The external channel identifier. + public string ExternalChannelId { get; set; } + + /// + /// ChannelName of the recording. + /// + public string ChannelName { get; set; } + + /// + /// Gets or sets the program identifier. + /// + /// 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. + /// + public string Name { get; set; } + + /// + /// Description of the recording. + /// + public string Overview { get; set; } + + /// + /// The start date of the recording, in UTC. + /// + public DateTime StartDate { get; set; } + + /// + /// The end date of the recording, in UTC. + /// + public DateTime EndDate { get; set; } + + /// + /// Gets or sets the type of the recurrence. + /// + /// The type of the recurrence. + public RecurrenceType RecurrenceType { get; set; } + + /// + /// Gets or sets the days. + /// + /// The days. + public List Days { get; set; } + + /// + /// Gets or sets the day pattern. + /// + /// The day pattern. + public DayPattern? DayPattern { get; set; } + + /// + /// Gets or sets the priority. + /// + /// The priority. + public int Priority { get; set; } + + /// + /// Gets or sets the requested pre padding seconds. + /// + /// The requested pre padding seconds. + public int RequestedPrePaddingSeconds { get; set; } + + /// + /// Gets or sets the requested post padding seconds. + /// + /// The requested post padding seconds. + public int RequestedPostPaddingSeconds { get; set; } + + /// + /// Gets or sets the required pre padding seconds. + /// + /// The required pre padding seconds. + public int RequiredPrePaddingSeconds { get; set; } + + /// + /// Gets or sets the required post padding seconds. + /// + /// The required post padding seconds. + public int RequiredPostPaddingSeconds { get; set; } + + public SeriesTimerInfoDto() + { + Days = new List(); + } + } +} diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs index b9a7e369a2..6b7ab42d3c 100644 --- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs @@ -20,6 +20,12 @@ namespace MediaBrowser.Model.LiveTv /// public string ChannelId { get; set; } + /// + /// Gets or sets the external channel identifier. + /// + /// The external channel identifier. + public string ExternalChannelId { get; set; } + /// /// ChannelName of the recording. /// @@ -63,6 +69,12 @@ namespace MediaBrowser.Model.LiveTv /// The series timer identifier. public string SeriesTimerId { get; set; } + /// + /// Gets or sets the external series timer identifier. + /// + /// The external series timer identifier. + public string ExternalSeriesTimerId { get; set; } + /// /// Gets or sets the requested pre padding seconds. /// diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 4dfa0ec64b..071f5bdde4 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -77,6 +77,7 @@ + diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index ade4e96fdf..d475517dc6 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -98,6 +98,12 @@ namespace MediaBrowser.Model.System /// The items by name path. public string ItemsByNamePath { get; set; } + /// + /// Gets or sets the cache path. + /// + /// The cache path. + public string CachePath { get; set; } + /// /// Gets or sets the log path. /// diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index ecf5a59510..a038d9b4c9 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -263,7 +263,8 @@ namespace MediaBrowser.Providers.Movies id = item.GetProviderId(MetadataProviders.Imdb); } - if (string.IsNullOrEmpty(id)) + // Don't search for music video id's because it is very easy to misidentify. + if (string.IsNullOrEmpty(id) && !(item is MusicVideo)) { id = await FindId(item, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index 551da20b0f..ac8270dfe7 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.Savers "LocalTitle", "LockData", "LockedFields", - "MediaInfo", + "Format3D", "MPAARating", "MusicbrainzId", "MusicBrainzReleaseGroupId", @@ -536,10 +536,6 @@ namespace MediaBrowser.Providers.Savers if (video != null && video.Video3DFormat.HasValue) { - builder.Append(""); - - builder.Append(""); - - builder.Append(""); } } } diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index 8165e11eb0..94438e3e0f 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -69,10 +69,9 @@ namespace MediaBrowser.Server.Implementations.Configuration /// private void UpdateItemsByNamePath() { - if (!string.IsNullOrEmpty(Configuration.ItemsByNamePath)) - { - ApplicationPaths.ItemsByNamePath = Configuration.ItemsByNamePath; - } + ((ServerApplicationPaths) ApplicationPaths).ItemsByNamePath = string.IsNullOrEmpty(Configuration.ItemsByNamePath) ? + null : + Configuration.ItemsByNamePath; } /// @@ -84,19 +83,29 @@ namespace MediaBrowser.Server.Implementations.Configuration { var newConfig = (ServerConfiguration) newConfiguration; - var newIbnPath = newConfig.ItemsByNamePath; - - if (!string.IsNullOrWhiteSpace(newIbnPath) - && !string.Equals(Configuration.ItemsByNamePath ?? string.Empty, newIbnPath)) - { - // Validate - if (!Directory.Exists(newIbnPath)) - { - throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newConfig.ItemsByNamePath)); - } - } + ValidateItemByNamePath(newConfig); base.ReplaceConfiguration(newConfiguration); } + + /// + /// Replaces the item by name path. + /// + /// The new configuration. + /// + private void ValidateItemByNamePath(ServerConfiguration newConfig) + { + var newPath = newConfig.ItemsByNamePath; + + if (!string.IsNullOrWhiteSpace(newPath) + && !string.Equals(Configuration.ItemsByNamePath ?? string.Empty, newPath)) + { + // Validate + if (!Directory.Exists(newPath)) + { + throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath)); + } + } + } } } diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index 27ce90787e..36b6e5a901 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -53,10 +53,6 @@ namespace MediaBrowser.Server.Implementations.Drawing private readonly IJsonSerializer _jsonSerializer; private readonly IServerApplicationPaths _appPaths; - private readonly string _croppedWhitespaceImageCachePath; - private readonly string _enhancedImageCachePath; - private readonly string _resizedImageCachePath; - public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer) { _logger = logger; @@ -64,10 +60,6 @@ namespace MediaBrowser.Server.Implementations.Drawing _jsonSerializer = jsonSerializer; _appPaths = appPaths; - _croppedWhitespaceImageCachePath = Path.Combine(appPaths.ImageCachePath, "cropped-images"); - _enhancedImageCachePath = Path.Combine(appPaths.ImageCachePath, "enhanced-images"); - _resizedImageCachePath = Path.Combine(appPaths.ImageCachePath, "resized-images"); - _saveImageSizeTimer = new Timer(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite); Dictionary sizeDictionary; @@ -92,6 +84,30 @@ namespace MediaBrowser.Server.Implementations.Drawing _cachedImagedSizes = new ConcurrentDictionary(sizeDictionary); } + private string ResizedImageCachePath + { + get + { + return Path.Combine(_appPaths.ImageCachePath, "resized-images"); + } + } + + private string EnhancedImageCachePath + { + get + { + return Path.Combine(_appPaths.ImageCachePath, "enhanced-images"); + } + } + + private string CroppedWhitespaceImageCachePath + { + get + { + return Path.Combine(_appPaths.ImageCachePath, "cropped-images"); + } + } + public void AddParts(IEnumerable enhancers) { ImageEnhancers = enhancers.ToArray(); @@ -391,7 +407,7 @@ namespace MediaBrowser.Server.Implementations.Drawing var name = originalImagePath; name += "datemodified=" + dateModified.Ticks; - var croppedImagePath = GetCachePath(_croppedWhitespaceImageCachePath, name, Path.GetExtension(originalImagePath)); + var croppedImagePath = GetCachePath(CroppedWhitespaceImageCachePath, name, Path.GetExtension(originalImagePath)); var semaphore = GetLock(croppedImagePath); @@ -480,7 +496,7 @@ namespace MediaBrowser.Server.Implementations.Drawing filename += "b=" + backgroundColor; } - return GetCachePath(_resizedImageCachePath, filename, Path.GetExtension(originalPath)); + return GetCachePath(ResizedImageCachePath, filename, Path.GetExtension(originalPath)); } /// @@ -708,7 +724,7 @@ namespace MediaBrowser.Server.Implementations.Drawing var cacheGuid = GetImageCacheTag(item, imageType, originalImagePath, dateModified, supportedEnhancers); // All enhanced images are saved as png to allow transparency - var enhancedImagePath = GetCachePath(_enhancedImageCachePath, cacheGuid + ".png"); + var enhancedImagePath = GetCachePath(EnhancedImageCachePath, cacheGuid + ".png"); var semaphore = GetLock(enhancedImagePath); diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index 3a24135406..4a8b2d6386 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; @@ -7,6 +8,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; using System; +using System.IO; using System.Linq; using System.Net; using System.Threading; @@ -18,12 +20,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv { private readonly ILiveTvManager _liveTvManager; private readonly IProviderManager _providerManager; + private readonly IFileSystem _fileSystem; - public ChannelImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager) + public ChannelImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem) : base(logManager, configurationManager) { _liveTvManager = liveTvManager; _providerManager = providerManager; + _fileSystem = fileSystem; } public override bool Supports(BaseItem item) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs new file mode 100644 index 0000000000..f93821cc97 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -0,0 +1,324 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using System; + +namespace MediaBrowser.Server.Implementations.LiveTv +{ + public class LiveTvDtoService + { + private readonly ILogger _logger; + private readonly IImageProcessor _imageProcessor; + + private readonly IUserDataManager _userDataManager; + private readonly IDtoService _dtoService; + + public LiveTvDtoService(IDtoService dtoService, IUserDataManager userDataManager, IImageProcessor imageProcessor, ILogger logger) + { + _dtoService = dtoService; + _userDataManager = userDataManager; + _imageProcessor = imageProcessor; + _logger = logger; + } + + public TimerInfoDto GetTimerInfoDto(TimerInfo info, ILiveTvService service) + { + var dto = new TimerInfoDto + { + Id = GetInternalTimerId(service.Name, info.Id).ToString("N"), + ChannelName = info.ChannelName, + Overview = info.Overview, + EndDate = info.EndDate, + Name = info.Name, + StartDate = info.StartDate, + ExternalId = info.Id, + ChannelId = GetInternalChannelId(service.Name, info.ChannelId, info.ChannelName).ToString("N"), + Status = info.Status, + SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) ? null : GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"), + RequestedPostPaddingSeconds = info.RequestedPostPaddingSeconds, + RequestedPrePaddingSeconds = info.RequestedPrePaddingSeconds, + RequiredPostPaddingSeconds = info.RequiredPostPaddingSeconds, + RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds, + ExternalChannelId = info.ChannelId, + ExternalSeriesTimerId = info.SeriesTimerId + }; + + var duration = info.EndDate - info.StartDate; + dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds); + + if (!string.IsNullOrEmpty(info.ProgramId)) + { + dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); + } + + return dto; + } + + public SeriesTimerInfoDto GetSeriesTimerInfoDto(SeriesTimerInfo info, ILiveTvService service) + { + var dto = new SeriesTimerInfoDto + { + Id = GetInternalSeriesTimerId(service.Name, info.Id).ToString("N"), + ChannelName = info.ChannelName, + Overview = info.Overview, + EndDate = info.EndDate, + Name = info.Name, + StartDate = info.StartDate, + ExternalId = info.Id, + ChannelId = GetInternalChannelId(service.Name, info.ChannelId, info.ChannelName).ToString("N"), + RequestedPostPaddingSeconds = info.RequestedPostPaddingSeconds, + RequestedPrePaddingSeconds = info.RequestedPrePaddingSeconds, + RequiredPostPaddingSeconds = info.RequiredPostPaddingSeconds, + RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds, + Days = info.Days, + Priority = info.Priority, + RecurrenceType = info.RecurrenceType, + ExternalChannelId = info.ChannelId, + ExternalProgramId = info.ProgramId + }; + + if (!string.IsNullOrEmpty(info.ProgramId)) + { + dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); + } + + DayPattern? pattern = null; + + if (info.Days != null && info.Days.Count > 0) + { + if (info.Days.Count == 7) + { + pattern = DayPattern.Daily; + } + else if (info.Days.Count == 2) + { + if (info.Days.Contains(DayOfWeek.Saturday) && info.Days.Contains(DayOfWeek.Sunday)) + { + pattern = DayPattern.Weekends; + } + } + else if (info.Days.Count == 5) + { + if (info.Days.Contains(DayOfWeek.Monday) && info.Days.Contains(DayOfWeek.Tuesday) && info.Days.Contains(DayOfWeek.Wednesday) && info.Days.Contains(DayOfWeek.Thursday) && info.Days.Contains(DayOfWeek.Friday)) + { + pattern = DayPattern.Weekdays; + } + } + } + + dto.DayPattern = pattern; + + return dto; + } + + public RecordingInfoDto GetRecordingInfoDto(RecordingInfo info, ILiveTvService service, User user = null) + { + var dto = new RecordingInfoDto + { + Id = GetInternalRecordingId(service.Name, info.Id).ToString("N"), + ChannelName = info.ChannelName, + Overview = info.Overview, + EndDate = info.EndDate, + Name = info.Name, + StartDate = info.StartDate, + ExternalId = info.Id, + ChannelId = GetInternalChannelId(service.Name, info.ChannelId, info.ChannelName).ToString("N"), + Status = info.Status, + Path = info.Path, + Genres = info.Genres, + IsRepeat = info.IsRepeat, + EpisodeTitle = info.EpisodeTitle, + ChannelType = info.ChannelType, + MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video, + CommunityRating = info.CommunityRating, + OfficialRating = info.OfficialRating, + Audio = info.Audio, + IsHD = info.IsHD + }; + + if (user != null) + { + //dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey())); + } + + var duration = info.EndDate - info.StartDate; + dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds); + + if (!string.IsNullOrEmpty(info.ProgramId)) + { + dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); + } + + return dto; + } + + /// + /// Gets the channel info dto. + /// + /// The info. + /// The user. + /// ChannelInfoDto. + public ChannelInfoDto GetChannelInfoDto(Channel info, User user = null) + { + var dto = new ChannelInfoDto + { + Name = info.Name, + ServiceName = info.ServiceName, + ChannelType = info.ChannelType, + Number = info.ChannelNumber, + Type = info.GetType().Name, + Id = info.Id.ToString("N"), + MediaType = info.MediaType + }; + + if (user != null) + { + dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey())); + } + + var imageTag = GetLogoImageTag(info); + + if (imageTag.HasValue) + { + dto.ImageTags[ImageType.Primary] = imageTag.Value; + } + + return dto; + } + + public ProgramInfoDto GetProgramInfoDto(ProgramInfo program, Channel channel, User user = null) + { + var dto = new ProgramInfoDto + { + Id = GetInternalProgramId(channel.ServiceName, program.Id).ToString("N"), + ChannelId = channel.Id.ToString("N"), + Overview = program.Overview, + EndDate = program.EndDate, + Genres = program.Genres, + ExternalId = program.Id, + Name = program.Name, + ServiceName = channel.ServiceName, + StartDate = program.StartDate, + OfficialRating = program.OfficialRating, + IsHD = program.IsHD, + OriginalAirDate = program.OriginalAirDate, + Audio = program.Audio, + CommunityRating = program.CommunityRating, + AspectRatio = program.AspectRatio, + IsRepeat = program.IsRepeat, + EpisodeTitle = program.EpisodeTitle + }; + + if (user != null) + { + //dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey())); + } + + return dto; + } + + private Guid? GetLogoImageTag(Channel info) + { + var path = info.PrimaryImagePath; + + if (string.IsNullOrEmpty(path)) + { + return null; + } + + try + { + return _imageProcessor.GetImageCacheTag(info, ImageType.Primary, path); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting channel image info for {0}", ex, info.Name); + } + + return null; + } + + public Guid GetInternalChannelId(string serviceName, string externalId, string channelName) + { + var name = serviceName + externalId + channelName; + + return name.ToLower().GetMBId(typeof(Channel)); + } + + public Guid GetInternalTimerId(string serviceName, string externalId) + { + var name = serviceName + externalId; + + return name.ToLower().GetMD5(); + } + + public Guid GetInternalSeriesTimerId(string serviceName, string externalId) + { + var name = serviceName + externalId; + + return name.ToLower().GetMD5(); + } + + public Guid GetInternalProgramId(string serviceName, string externalId) + { + var name = serviceName + externalId; + + return name.ToLower().GetMD5(); + } + + public Guid GetInternalRecordingId(string serviceName, string externalId) + { + var name = serviceName + externalId; + + return name.ToLower().GetMD5(); + } + + public TimerInfo GetTimerInfo(TimerInfoDto dto) + { + return new TimerInfo + { + Id = dto.ExternalId, + ChannelName = dto.ChannelName, + Overview = dto.Overview, + EndDate = dto.EndDate, + Name = dto.Name, + StartDate = dto.StartDate, + ChannelId = dto.ExternalChannelId, + Status = dto.Status, + SeriesTimerId = dto.ExternalSeriesTimerId, + RequestedPostPaddingSeconds = dto.RequestedPostPaddingSeconds, + RequestedPrePaddingSeconds = dto.RequestedPrePaddingSeconds, + RequiredPostPaddingSeconds = dto.RequiredPostPaddingSeconds, + RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds + }; + } + + public SeriesTimerInfo GetSeriesTimerInfo(SeriesTimerInfoDto dto) + { + return new SeriesTimerInfo + { + Id = dto.ExternalId, + ChannelName = dto.ChannelName, + Overview = dto.Overview, + EndDate = dto.EndDate, + Name = dto.Name, + StartDate = dto.StartDate, + ChannelId = dto.ExternalChannelId, + RequestedPostPaddingSeconds = dto.RequestedPostPaddingSeconds, + RequestedPrePaddingSeconds = dto.RequestedPrePaddingSeconds, + RequiredPostPaddingSeconds = dto.RequiredPostPaddingSeconds, + RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds, + Days = dto.Days, + Priority = dto.Priority, + RecurrenceType = dto.RecurrenceType, + ProgramId = dto.ExternalProgramId + }; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 4cd18a5236..318f450f12 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -8,7 +8,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Persistence; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; @@ -30,29 +29,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly IFileSystem _fileSystem; private readonly ILogger _logger; private readonly IItemRepository _itemRepo; - private readonly IImageProcessor _imageProcessor; - private readonly IUserManager _userManager; + private readonly ILocalizationManager _localization; - private readonly IUserDataManager _userDataManager; - private readonly IDtoService _dtoService; + private readonly LiveTvDtoService _tvDtoService; private readonly List _services = new List(); private List _channels = new List(); private List _programs = new List(); - public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserManager userManager, ILocalizationManager localization, IUserDataManager userDataManager, IDtoService dtoService) + public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, ILocalizationManager localization, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager) { _appPaths = appPaths; _fileSystem = fileSystem; _logger = logger; _itemRepo = itemRepo; - _imageProcessor = imageProcessor; - _userManager = userManager; _localization = localization; - _userDataManager = userDataManager; - _dtoService = dtoService; + _userManager = userManager; + + _tvDtoService = new LiveTvDtoService(dtoService, userDataManager, imageProcessor, logger); } /// @@ -77,62 +73,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv ActiveService = _services.FirstOrDefault(); } - /// - /// Gets the channel info dto. - /// - /// The info. - /// The user. - /// ChannelInfoDto. - public ChannelInfoDto GetChannelInfoDto(Channel info, User user) - { - var dto = new ChannelInfoDto - { - Name = info.Name, - ServiceName = info.ServiceName, - ChannelType = info.ChannelType, - Number = info.ChannelNumber, - Type = info.GetType().Name, - Id = info.Id.ToString("N"), - MediaType = info.MediaType - }; - - if (user != null) - { - dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey())); - } - - var imageTag = GetLogoImageTag(info); - - if (imageTag.HasValue) - { - dto.ImageTags[ImageType.Primary] = imageTag.Value; - } - - return dto; - } - - private Guid? GetLogoImageTag(Channel info) - { - var path = info.PrimaryImagePath; - - if (string.IsNullOrEmpty(path)) - { - return null; - } - - try - { - return _imageProcessor.GetImageCacheTag(info, ImageType.Primary, path); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting channel image info for {0}", ex, info.Name); - } - - return null; - } - - public QueryResult GetChannels(ChannelQuery query) + public Task> GetChannels(ChannelQuery query, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId)); @@ -167,14 +108,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv return number; }).ThenBy(i => i.Name) - .Select(i => GetChannelInfoDto(i, user)) + .Select(i => _tvDtoService.GetChannelInfoDto(i, user)) .ToArray(); - return new QueryResult + var result = new QueryResult { Items = returnChannels, TotalRecordCount = returnChannels.Length }; + + return Task.FromResult(result); } public Channel GetChannel(string id) @@ -184,55 +127,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv return _channels.FirstOrDefault(i => i.Id == guid); } - public ChannelInfoDto GetChannelInfoDto(string id, string userId) - { - var channel = GetChannel(id); - - var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(new Guid(userId)); - - return channel == null ? null : GetChannelInfoDto(channel, user); - } - - private ProgramInfoDto GetProgramInfoDto(ProgramInfo program, Channel channel) - { - var id = GetInternalProgramIdId(channel.ServiceName, program.Id).ToString("N"); - - return new ProgramInfoDto - { - ChannelId = channel.Id.ToString("N"), - Overview = program.Overview, - EndDate = program.EndDate, - Genres = program.Genres, - ExternalId = program.Id, - Id = id, - Name = program.Name, - ServiceName = channel.ServiceName, - StartDate = program.StartDate, - OfficialRating = program.OfficialRating, - IsHD = program.IsHD, - OriginalAirDate = program.OriginalAirDate, - Audio = program.Audio, - CommunityRating = program.CommunityRating, - AspectRatio = program.AspectRatio, - IsRepeat = program.IsRepeat, - EpisodeTitle = program.EpisodeTitle - }; - } - - private Guid GetInternalChannelId(string serviceName, string externalChannelId, string channelName) - { - var name = serviceName + externalChannelId + channelName; - - return name.ToLower().GetMBId(typeof(Channel)); - } - - private Guid GetInternalProgramIdId(string serviceName, string externalProgramId) - { - var name = serviceName + externalProgramId; - - return name.ToLower().GetMD5(); - } - private async Task GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken) { var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(serviceName), _fileSystem.GetValidFilename(channelInfo.Name)); @@ -254,7 +148,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv isNew = true; } - var id = GetInternalChannelId(serviceName, channelInfo.Id, channelInfo.Name); + var id = _tvDtoService.GetInternalChannelId(serviceName, channelInfo.Id, channelInfo.Name); var item = _itemRepo.RetrieveItem(id) as Channel; @@ -335,7 +229,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channelPrograms = await service.GetProgramsAsync(channelInfo.Item2.Id, cancellationToken).ConfigureAwait(false); - programs.AddRange(channelPrograms.Select(program => GetProgramInfoDto(program, item))); + programs.AddRange(channelPrograms.Select(program => _tvDtoService.GetProgramInfoDto(program, item))); list.Add(item); } @@ -366,61 +260,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv return channels.Select(i => new Tuple(service.Name, i)); } - private async Task> GetRecordings(ILiveTvService service, CancellationToken cancellationToken) - { - var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false); - - return recordings.Select(i => GetRecordingInfoDto(i, service)); - } - - private RecordingInfoDto GetRecordingInfoDto(RecordingInfo info, ILiveTvService service) - { - var id = service.Name + info.ChannelId + info.Id; - id = id.GetMD5().ToString("N"); - - var dto = new RecordingInfoDto - { - ChannelName = info.ChannelName, - Overview = info.Overview, - EndDate = info.EndDate, - Name = info.Name, - StartDate = info.StartDate, - Id = id, - ExternalId = info.Id, - ChannelId = GetInternalChannelId(service.Name, info.ChannelId, info.ChannelName).ToString("N"), - Status = info.Status, - Path = info.Path, - Genres = info.Genres, - IsRepeat = info.IsRepeat, - EpisodeTitle = info.EpisodeTitle, - ChannelType = info.ChannelType, - MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video, - CommunityRating = info.CommunityRating, - OfficialRating = info.OfficialRating, - Audio = info.Audio, - IsHD = info.IsHD - }; - - var duration = info.EndDate - info.StartDate; - dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds); - - if (!string.IsNullOrEmpty(info.ProgramId)) - { - dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N"); - } - - return dto; - } - public async Task> GetRecordings(RecordingQuery query, CancellationToken cancellationToken) { + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId)); + var list = new List(); if (ActiveService != null) { - var recordings = await GetRecordings(ActiveService, cancellationToken).ConfigureAwait(false); + var recordings = await ActiveService.GetRecordingsAsync(cancellationToken).ConfigureAwait(false); - list.AddRange(recordings); + var dtos = recordings.Select(i => _tvDtoService.GetRecordingInfoDto(i, ActiveService, user)); + + list.AddRange(dtos); } if (!string.IsNullOrEmpty(query.ChannelId)) @@ -471,9 +323,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (ActiveService != null) { - var timers = await GetTimers(ActiveService, cancellationToken).ConfigureAwait(false); + var timers = await ActiveService.GetTimersAsync(cancellationToken).ConfigureAwait(false); - list.AddRange(timers); + var dtos = timers.Select(i => _tvDtoService.GetTimerInfoDto(i, ActiveService)); + + list.AddRange(dtos); } if (!string.IsNullOrEmpty(query.ChannelId)) @@ -492,47 +346,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } - private async Task> GetTimers(ILiveTvService service, CancellationToken cancellationToken) - { - var timers = await service.GetTimersAsync(cancellationToken).ConfigureAwait(false); - - return timers.Select(i => GetTimerInfoDto(i, service)); - } - - private TimerInfoDto GetTimerInfoDto(TimerInfo info, ILiveTvService service) - { - var id = service.Name + info.ChannelId + info.Id; - id = id.GetMD5().ToString("N"); - - var dto = new TimerInfoDto - { - ChannelName = info.ChannelName, - Overview = info.Overview, - EndDate = info.EndDate, - Name = info.Name, - StartDate = info.StartDate, - Id = id, - ExternalId = info.Id, - ChannelId = GetInternalChannelId(service.Name, info.ChannelId, info.ChannelName).ToString("N"), - Status = info.Status, - SeriesTimerId = info.SeriesTimerId, - RequestedPostPaddingSeconds = info.RequestedPostPaddingSeconds, - RequestedPrePaddingSeconds = info.RequestedPrePaddingSeconds, - RequiredPostPaddingSeconds = info.RequiredPostPaddingSeconds, - RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds - }; - - var duration = info.EndDate - info.StartDate; - dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds); - - 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 @@ -579,9 +392,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); } - public async Task GetRecording(string id, CancellationToken cancellationToken) + public async Task GetRecording(string id, CancellationToken cancellationToken, User user = null) { - var results = await GetRecordings(new RecordingQuery(), cancellationToken).ConfigureAwait(false); + var results = await GetRecordings(new RecordingQuery + { + UserId = user == null ? null : user.Id.ToString("N") + + }, cancellationToken).ConfigureAwait(false); return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture)); } @@ -592,5 +409,60 @@ namespace MediaBrowser.Server.Implementations.LiveTv return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture)); } + + public async Task GetSeriesTimer(string id, CancellationToken cancellationToken) + { + var results = await GetSeriesTimers(new SeriesTimerQuery(), cancellationToken).ConfigureAwait(false); + + return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture)); + } + + public Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken) + { + var info = _tvDtoService.GetTimerInfo(timer); + + return ActiveService.UpdateTimerAsync(info, cancellationToken); + } + + public Task UpdateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) + { + var info = _tvDtoService.GetSeriesTimerInfo(timer); + + return ActiveService.UpdateSeriesTimerAsync(info, cancellationToken); + } + + public async Task> GetSeriesTimers(SeriesTimerQuery query, CancellationToken cancellationToken) + { + var list = new List(); + + if (ActiveService != null) + { + var timers = await ActiveService.GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false); + + var dtos = timers.Select(i => _tvDtoService.GetSeriesTimerInfoDto(i, ActiveService)); + + list.AddRange(dtos); + } + + var returnArray = list.OrderByDescending(i => i.StartDate) + .ToArray(); + + return new QueryResult + { + Items = returnArray, + TotalRecordCount = returnArray.Length + }; + } + + public async Task GetChannel(string id, CancellationToken cancellationToken, User user = null) + { + var results = await GetChannels(new ChannelQuery + { + UserId = user == null ? null : user.Id.ToString("N") + + }, cancellationToken).ConfigureAwait(false); + + return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture)); + } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 031fc6e922..2516a3ae37 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -151,6 +151,7 @@ + @@ -338,7 +339,7 @@ swagger-ui\swagger-ui.min.js PreserveNewest - + diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index d4b96b6b86..77b49fbf11 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -281,7 +281,7 @@ namespace MediaBrowser.ServerApplication DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor); RegisterSingleInstance(DtoService); - LiveTvManager = new LiveTvManager(ApplicationPaths, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserManager, LocalizationManager, UserDataManager, DtoService); + LiveTvManager = new LiveTvManager(ApplicationPaths, FileSystemManager, Logger, ItemRepository, ImageProcessor, LocalizationManager, UserDataManager, DtoService, UserManager); RegisterSingleInstance(LiveTvManager); progress.Report(15); @@ -609,6 +609,7 @@ namespace MediaBrowser.ServerApplication ProgramDataPath = ApplicationPaths.ProgramDataPath, LogPath = ApplicationPaths.LogDirectoryPath, ItemsByNamePath = ApplicationPaths.ItemsByNamePath, + CachePath = ApplicationPaths.CachePath, MacAddress = GetMacAddress(), HttpServerPortNumber = ServerConfigurationManager.Configuration.HttpServerPortNumber, OperatingSystem = Environment.OSVersion.ToString(), diff --git a/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs index 91f0974eb9..d2e5425367 100644 --- a/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs +++ b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs @@ -20,6 +20,8 @@ namespace MediaBrowser.ServerApplication.Native /// The temp directory. public static void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int webSocketPort, int udpPort, string tempDirectory) { + Directory.CreateDirectory(tempDirectory); + // Create a temp file path to extract the bat file to var tmpFile = Path.Combine(tempDirectory, Guid.NewGuid() + ".bat"); diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 7dcc34c5b6..2188722b2a 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -242,7 +242,24 @@ namespace MediaBrowser.WebDashboard.Api pages = pages.Where(p => p.ConfigurationPageType == request.PageType.Value); } - return ResultFactory.GetOptimizedResult(Request, pages.Select(p => new ConfigurationPageInfo(p)).ToList()); + // Don't allow a failing plugin to fail them all + var configPages = pages.Select(p => + { + + try + { + return new ConfigurationPageInfo(p); + } + catch (Exception ex) + { + Logger.ErrorException("Error getting plugin information from {0}", ex, p.GetType().Name); + return null; + } + }) + .Where(i => i != null) + .ToList(); + + return ResultFactory.GetOptimizedResult(Request, configPages); } /// diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 16e2ae3b96..53f4fde2af 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -506,20 +506,110 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }); }; - self.createLiveTvTimer = function (options) { + self.createLiveTvTimer = function (item) { - if (!options) { - throw new Error("null options"); + if (!item) { + throw new Error("null item"); } - var url = self.getUrl("LiveTv/Timers", options); + var url = self.getUrl("LiveTv/Timers"); return self.ajax({ type: "POST", + url: url, + data: JSON.stringify(item), + contentType: "application/json" + }); + }; + + self.updateLiveTvTimer = function (item) { + + if (!item) { + throw new Error("null item"); + } + + var url = self.getUrl("LiveTv/Timers/" + item.Id); + + return self.ajax({ + type: "POST", + url: url, + data: JSON.stringify(item), + contentType: "application/json" + }); + }; + + self.getLiveTvSeriesTimers = function (options) { + + var url = self.getUrl("LiveTv/SeriesTimers", options || {}); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + + self.getLiveTvSeriesTimer = function (id) { + + if (!id) { + throw new Error("null id"); + } + + var url = self.getUrl("LiveTv/SeriesTimers/" + id); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + + self.cancelLiveTvSeriesTimer = function (id) { + + if (!id) { + throw new Error("null id"); + } + + var url = self.getUrl("LiveTv/SeriesTimers/" + id); + + return self.ajax({ + type: "DELETE", url: url }); }; + self.createLiveTvSeriesTimer = function (item) { + + if (!item) { + throw new Error("null item"); + } + + var url = self.getUrl("LiveTv/SeriesTimers"); + + return self.ajax({ + type: "POST", + url: url, + data: JSON.stringify(item), + contentType: "application/json" + }); + }; + + self.updateLiveTvSeriesTimer = function (item) { + + if (!item) { + throw new Error("null item"); + } + + var url = self.getUrl("LiveTv/SeriesTimers/" + item.Id); + + return self.ajax({ + type: "POST", + url: url, + data: JSON.stringify(item), + contentType: "application/json" + }); + }; + /** * Gets the current server status */ diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 67a54e4b7a..09e68f59fa 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1232,7 +1232,7 @@ - + diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 9cbd2cd590..808183a672 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index fac2d62c41..116671f44a 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.269 + 3.0.271 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 bf80369c3e..126ddf4ca1 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.269 + 3.0.271 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 8b70187cac..7de6b9e00a 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.269 + 3.0.271 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 - +