diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index ba4f0fb101..9f45df8e6a 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -5,7 +5,6 @@ using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
using ServiceStack;
using System;
-using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
@@ -83,7 +82,7 @@ namespace MediaBrowser.Api.LiveTv
[ApiMember(Name = "Status", Description = "Optional filter by recordings that are in progress, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsInProgress { get; set; }
-
+
[ApiMember(Name = "SeriesTimerId", Description = "Optional filter by recordings belonging to a series timer", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string SeriesTimerId { get; set; }
}
@@ -295,27 +294,17 @@ namespace MediaBrowser.Api.LiveTv
public object Get(GetLiveTvInfo request)
{
- var services = _liveTvManager.Services
- .Select(GetServiceInfo)
- .ToList();
+ var services = _liveTvManager.GetServiceInfos(CancellationToken.None).Result;
var info = new LiveTvInfo
{
- Services = services,
+ Services = services.ToList(),
ActiveServiceName = _liveTvManager.ActiveService == null ? null : _liveTvManager.ActiveService.Name
};
return ToOptimizedResult(info);
}
- private LiveTvServiceInfo GetServiceInfo(ILiveTvService service)
- {
- return new LiveTvServiceInfo
- {
- Name = service.Name
- };
- }
-
public object Get(GetChannels request)
{
var result = _liveTvManager.GetChannels(new ChannelQuery
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index 31c336932f..88e2c9b4e1 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -24,6 +24,13 @@ namespace MediaBrowser.Controller.LiveTv
/// The services.
IReadOnlyList Services { get; }
+ ///
+ /// Gets the service infos.
+ ///
+ /// The cancellation token.
+ /// Task{IEnumerable{LiveTvServiceInfo}}.
+ Task> GetServiceInfos(CancellationToken cancellationToken);
+
///
/// Gets the new timer defaults asynchronous.
///
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
index 7217b6e13c..955d81b031 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
@@ -26,6 +26,13 @@ namespace MediaBrowser.Controller.LiveTv
/// The name.
string Name { get; }
+ ///
+ /// Gets the status information asynchronous.
+ ///
+ /// The cancellation token.
+ /// Task{LiveTvServiceStatusInfo}.
+ Task GetStatusInfoAsync(CancellationToken cancellationToken);
+
///
/// Gets the channels async.
///
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
new file mode 100644
index 0000000000..3da00de49a
--- /dev/null
+++ b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs
@@ -0,0 +1,19 @@
+using MediaBrowser.Model.LiveTv;
+
+namespace MediaBrowser.Controller.LiveTv
+{
+ public class LiveTvServiceStatusInfo
+ {
+ ///
+ /// Gets or sets the status.
+ ///
+ /// The status.
+ public LiveTvServiceStatus Status { get; set; }
+
+ ///
+ /// Gets or sets the status message.
+ ///
+ /// The status message.
+ public string StatusMessage { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 9452700b5e..353e92444f 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -121,6 +121,7 @@
+
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 55ca9edc78..edabd4abac 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -951,6 +951,15 @@ namespace MediaBrowser.Model.ApiClient
/// Task{LiveTvInfo}.
Task> GetLiveTvChannelsAsync(ChannelQuery query, CancellationToken cancellationToken);
+ ///
+ /// Gets the live tv channel asynchronous.
+ ///
+ /// The identifier.
+ /// The user identifier.
+ /// The cancellation token.
+ /// Task{ChannelInfoDto}.
+ Task GetLiveTvChannelAsync(string id, string userId, CancellationToken cancellationToken);
+
///
/// Gets the live tv recordings asynchronous.
///
@@ -959,6 +968,15 @@ namespace MediaBrowser.Model.ApiClient
/// Task{QueryResult{RecordingInfoDto}}.
Task> GetLiveTvRecordingsAsync(RecordingQuery query, CancellationToken cancellationToken);
+ ///
+ /// Gets the live tv recording asynchronous.
+ ///
+ /// The identifier.
+ /// The user identifier.
+ /// The cancellation token.
+ /// Task{RecordingInfoDto}.
+ Task GetLiveTvRecordingAsync(string id, string userId, CancellationToken cancellationToken);
+
///
/// Gets the live tv recording groups asynchronous.
///
@@ -966,5 +984,70 @@ namespace MediaBrowser.Model.ApiClient
/// The cancellation token.
/// Task{QueryResult{RecordingGroupDto}}.
Task> GetLiveTvRecordingGroupsAsync(RecordingGroupQuery query, CancellationToken cancellationToken);
+
+ ///
+ /// Gets the live tv recording group asynchronous.
+ ///
+ /// The identifier.
+ /// The user identifier.
+ /// The cancellation token.
+ /// Task{RecordingGroupDto}.
+ Task GetLiveTvRecordingGroupAsync(string id, string userId, CancellationToken cancellationToken);
+
+ ///
+ /// Gets the live tv timers asynchronous.
+ ///
+ /// The query.
+ /// The cancellation token.
+ /// Task{QueryResult{TimerInfoDto}}.
+ Task> GetLiveTvTimersAsync(TimerQuery query, CancellationToken cancellationToken);
+
+ ///
+ /// Gets the live tv timer asynchronous.
+ ///
+ /// The identifier.
+ /// The cancellation token.
+ /// Task{TimerInfoDto}.
+ Task GetLiveTvTimerAsync(string id, CancellationToken cancellationToken);
+
+ ///
+ /// Gets the live tv series timers asynchronous.
+ ///
+ /// The query.
+ /// The cancellation token.
+ /// Task{QueryResult{SeriesTimerInfoDto}}.
+ Task> GetLiveTvSeriesTimersAsync(SeriesTimerQuery query, CancellationToken cancellationToken);
+
+ ///
+ /// Gets the live tv series timer asynchronous.
+ ///
+ /// The identifier.
+ /// The cancellation token.
+ /// Task{SeriesTimerInfoDto}.
+ Task GetLiveTvSeriesTimerAsync(string id, CancellationToken cancellationToken);
+
+ ///
+ /// Cancels the live tv timer asynchronous.
+ ///
+ /// The identifier.
+ /// The cancellation token.
+ /// Task.
+ Task CancelLiveTvTimerAsync(string id, CancellationToken cancellationToken);
+
+ ///
+ /// Cancels the live tv series timer asynchronous.
+ ///
+ /// The identifier.
+ /// The cancellation token.
+ /// Task.
+ Task CancelLiveTvSeriesTimerAsync(string id, CancellationToken cancellationToken);
+
+ ///
+ /// Deletes the live tv recording asynchronous.
+ ///
+ /// The identifier.
+ /// The cancellation token.
+ /// Task.
+ Task DeleteLiveTvRecordingAsync(string id, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index f7b4cf3735..281f1350c4 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -234,7 +234,7 @@ namespace MediaBrowser.Model.Configuration
: base()
{
MediaEncodingQuality = EncodingQuality.HighSpeed;
- ImageSavingConvention = ImageSavingConvention.Legacy;
+ ImageSavingConvention = ImageSavingConvention.Compatible;
HttpServerPortNumber = 8096;
LegacyWebSocketPortNumber = 8945;
EnableHttpLevelLogging = true;
diff --git a/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs b/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs
index c93779b5a9..f59a707adf 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs
@@ -13,6 +13,18 @@ namespace MediaBrowser.Model.LiveTv
///
/// The name.
public string Name { get; set; }
+
+ ///
+ /// Gets or sets the status.
+ ///
+ /// The status.
+ public LiveTvServiceStatus Status { get; set; }
+
+ ///
+ /// Gets or sets the status message.
+ ///
+ /// The status message.
+ public string StatusMessage { get; set; }
}
public class GuideInfo
@@ -49,4 +61,10 @@ namespace MediaBrowser.Model.LiveTv
Services = new List();
}
}
+
+ public enum LiveTvServiceStatus
+ {
+ Ok = 0,
+ Unavailable = 1
+ }
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 5781dd69a9..2269ab0c52 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1130,7 +1130,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.UpdateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false);
}
- private List GetRecordingGroupNames(RecordingInfo recording)
+ private IEnumerable GetRecordingGroupNames(RecordingInfo recording)
{
var list = new List();
@@ -1292,5 +1292,37 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
}
}
+
+ public async Task> GetServiceInfos(CancellationToken cancellationToken)
+ {
+ var tasks = Services.Select(i => GetServiceInfo(i, cancellationToken));
+
+ return await Task.WhenAll(tasks).ConfigureAwait(false);
+ }
+
+ private async Task GetServiceInfo(ILiveTvService service, CancellationToken cancellationToken)
+ {
+ var info = new LiveTvServiceInfo
+ {
+ Name = service.Name
+ };
+
+ try
+ {
+ var statusInfo = await service.GetStatusInfoAsync(cancellationToken).ConfigureAwait(false);
+
+ info.Status = statusInfo.Status;
+ info.StatusMessage = statusInfo.StatusMessage;
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting service status info from {0}", ex, service.Name);
+
+ info.Status = LiveTvServiceStatus.Unavailable;
+ info.StatusMessage = ex.Message;
+ }
+
+ return info;
+ }
}
}
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 3681209e77..f6053f9981 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -421,6 +421,7 @@ namespace MediaBrowser.ServerApplication
LocalizedStrings.ApplicationPaths = ApplicationPaths;
Folder.UserManager = UserManager;
BaseItem.FileSystem = FileSystemManager;
+ BaseItem.UserDataManager = UserDataManager;
}
///
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 0505b0992d..45ec23ac9b 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.302
+ 3.0.303
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 e6ea16efa0..a4ce5fc2d6 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.302
+ 3.0.303
MediaBrowser.Common
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 2935fb958a..3571d202d2 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.302
+ 3.0.303
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
-
+