diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
index f35b6d5c63..0e4be52e3a 100644
--- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
@@ -20,6 +20,12 @@ namespace MediaBrowser.Controller.LiveTv
///
public string ChannelName { get; set; }
+ ///
+ /// Gets or sets the program identifier.
+ ///
+ /// The program identifier.
+ public string ProgramId { get; set; }
+
///
/// Name of the recording.
///
@@ -46,14 +52,10 @@ namespace MediaBrowser.Controller.LiveTv
public string Status { get; set; } //TODO: Enum for status?? Difference NextPvr,Argus,...
///
- /// Quality of the Recording.
+ /// Gets or sets a value indicating whether this instance is recurring.
///
- public string Quality { get; set; } // TODO: Enum for quality?? Difference NextPvr,Argus,...
-
- ///
- /// Recurring recording?
- ///
- public bool Recurring { get; set; }
+ /// true if this instance is recurring; otherwise, false.
+ public bool IsRecurring { get; set; }
///
/// Parent recurring.
diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
index b24af04a03..782652f37b 100644
--- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
namespace MediaBrowser.Model.LiveTv
{
@@ -10,6 +9,18 @@ namespace MediaBrowser.Model.LiveTv
///
public string Id { get; set; }
+ ///
+ /// Gets or sets the external identifier.
+ ///
+ /// The external identifier.
+ public string ExternalId { get; set; }
+
+ ///
+ /// Gets or sets the program identifier.
+ ///
+ /// The program identifier.
+ public string ProgramId { get; set; }
+
///
/// ChannelId of the recording.
///
@@ -41,38 +52,8 @@ namespace MediaBrowser.Model.LiveTv
public DateTime EndDate { get; set; }
///
- /// Status of the recording.
+ /// IsRecurring recording?
///
- public string Status { get; set; } //TODO: Enum for status?? Difference NextPvr,Argus,...
-
- ///
- /// Quality of the Recording.
- ///
- public string Quality { get; set; } // TODO: Enum for quality?? Difference NextPvr,Argus,...
-
- ///
- /// Recurring recording?
- ///
- public bool Recurring { get; set; }
-
- ///
- /// Parent recurring.
- ///
- public string RecurringParent { get; set; }
-
- ///
- /// Start date for the recurring, in UTC.
- ///
- public DateTime RecurrringStartDate { get; set; }
-
- ///
- /// End date for the recurring, in UTC
- ///
- public DateTime RecurringEndDate { get; set; }
-
- ///
- /// When do we need the recording?
- ///
- public List DayMask { get; set; }
+ public bool IsRecurring { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index fe58f292ca..791da74e05 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -7,13 +7,13 @@ using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Model.Querying;
namespace MediaBrowser.Server.Implementations.LiveTv
{
@@ -32,6 +32,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private List _channels = new List();
private List _programs = new List();
+ private List _recordings = new List();
+
+ private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1);
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor)
{
@@ -137,62 +140,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return _channels.FirstOrDefault(i => i.Id == guid);
}
- internal async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken)
- {
- // Avoid implicitly captured closure
- var currentCancellationToken = cancellationToken;
-
- var channelTasks = _services.Select(i => i.GetChannelsAsync(currentCancellationToken));
-
- progress.Report(10);
-
- var results = await Task.WhenAll(channelTasks).ConfigureAwait(false);
-
- var allChannels = results.SelectMany(i => i).ToList();
-
- var list = new List();
- var programs = new List();
-
- var numComplete = 0;
-
- foreach (var channelInfo in allChannels)
- {
- try
- {
- var item = await GetChannel(channelInfo, cancellationToken).ConfigureAwait(false);
-
- var service = GetService(channelInfo);
-
- var channelPrograms = await service.GetProgramsAsync(channelInfo.Id, cancellationToken).ConfigureAwait(false);
-
- programs.AddRange(channelPrograms.Select(program => GetProgramInfoDto(program, item)));
-
- list.Add(item);
- }
- catch (OperationCanceledException)
- {
- throw;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name);
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= allChannels.Count;
-
- progress.Report(90 * percent + 10);
- }
-
- _programs = programs;
- _channels = list;
- }
-
private ProgramInfoDto GetProgramInfoDto(ProgramInfo program, Channel channel)
{
- var id = channel.ServiceName + channel.ChannelId + program.Id;
- id = id.GetMD5().ToString("N");
+ var id = GetInternalProgramIdId(channel.ServiceName, program.Id).ToString("N");
return new ProgramInfoDto
{
@@ -208,6 +158,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
+ private Guid GetInternalChannelId(string serviceName, string externalChannelId)
+ {
+ var name = serviceName + externalChannelId;
+
+ 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, CancellationToken cancellationToken)
{
var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.ServiceName), _fileSystem.GetValidFilename(channelInfo.Name));
@@ -229,9 +193,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
isNew = true;
}
- var type = typeof(Channel);
-
- var id = (path + channelInfo.Number).GetMBId(type);
+ var id = GetInternalChannelId(channelInfo.ServiceName, channelInfo.Id);
var item = _itemRepo.RetrieveItem(id) as Channel;
@@ -286,5 +248,134 @@ namespace MediaBrowser.Server.Implementations.LiveTv
TotalRecordCount = returnArray.Length
};
}
+
+ internal async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken)
+ {
+ await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ await RefreshChannelsInternal(progress, cancellationToken).ConfigureAwait(false);
+ }
+ finally
+ {
+ _updateSemaphore.Release();
+ }
+
+ await RefreshRecordings(new Progress(), cancellationToken).ConfigureAwait(false);
+ }
+
+ private async Task RefreshChannelsInternal(IProgress progress, CancellationToken cancellationToken)
+ {
+ // Avoid implicitly captured closure
+ var currentCancellationToken = cancellationToken;
+
+ var channelTasks = _services.Select(i => i.GetChannelsAsync(currentCancellationToken));
+
+ progress.Report(10);
+
+ var results = await Task.WhenAll(channelTasks).ConfigureAwait(false);
+
+ var allChannels = results.SelectMany(i => i).ToList();
+
+ var list = new List();
+ var programs = new List();
+
+ var numComplete = 0;
+
+ foreach (var channelInfo in allChannels)
+ {
+ try
+ {
+ var item = await GetChannel(channelInfo, cancellationToken).ConfigureAwait(false);
+
+ var service = GetService(channelInfo);
+
+ var channelPrograms = await service.GetProgramsAsync(channelInfo.Id, cancellationToken).ConfigureAwait(false);
+
+ programs.AddRange(channelPrograms.Select(program => GetProgramInfoDto(program, item)));
+
+ list.Add(item);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name);
+ }
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= allChannels.Count;
+
+ progress.Report(90 * percent + 10);
+ }
+
+ _programs = programs;
+ _channels = list;
+ }
+
+ internal async Task RefreshRecordings(IProgress progress, CancellationToken cancellationToken)
+ {
+ await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ await RefreshRecordingsInternal(progress, cancellationToken).ConfigureAwait(false);
+ }
+ finally
+ {
+ _updateSemaphore.Release();
+ }
+ }
+
+ private async Task RefreshRecordingsInternal(IProgress progress, CancellationToken cancellationToken)
+ {
+ var list = new List();
+
+ foreach (var service in _services)
+ {
+ var recordings = await GetRecordings(service, cancellationToken).ConfigureAwait(false);
+
+ list.AddRange(recordings);
+ }
+
+ _recordings = list;
+ }
+
+ 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,
+ Description = info.Description,
+ EndDate = info.EndDate,
+ Name = info.Name,
+ IsRecurring = info.IsRecurring,
+ StartDate = info.StartDate,
+ Id = id,
+ ExternalId = info.Id,
+ ChannelId = GetInternalChannelId(service.Name, info.ChannelId).ToString("N")
+ };
+
+ if (!string.IsNullOrEmpty(info.ProgramId))
+ {
+ dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N");
+ }
+
+ return dto;
+ }
}
}
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 5a32ce2dd7..f0c2c4308c 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.248
+ 3.0.249
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 e363cf621e..ff211ee1b6 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.248
+ 3.0.249
MediaBrowser.Common
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 83861329ba..25198e155d 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.248
+ 3.0.249
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
-
+