aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs')
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs769
1 files changed, 416 insertions, 353 deletions
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index a82775de7..f6c69d8d6 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -17,7 +17,6 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
using System;
@@ -54,9 +53,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly ConcurrentDictionary<string, LiveStreamData> _openStreams =
new ConcurrentDictionary<string, LiveStreamData>();
- private List<Guid> _channelIdList = new List<Guid>();
- private Dictionary<Guid, LiveTvProgram> _programs;
- private readonly ConcurrentDictionary<Guid, bool> _refreshedPrograms = new ConcurrentDictionary<Guid, bool>();
+ private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1);
public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager)
{
@@ -108,44 +105,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
}
- private readonly object _programsDataLock = new object();
- private Dictionary<Guid, LiveTvProgram> GetProgramsDictionary()
- {
- if (_programs == null)
- {
- lock (_programsDataLock)
- {
- if (_programs == null)
- {
- var dict = new Dictionary<Guid, LiveTvProgram>();
-
- foreach (var item in _itemRepo.GetItemsOfType(typeof (LiveTvProgram))
- .Cast<LiveTvProgram>()
- .ToList())
- {
- dict[item.Id] = item;
- }
-
- _programs = dict;
- }
- }
- }
-
- return _programs;
- }
-
- private IEnumerable<LiveTvProgram> GetPrograms()
- {
- return GetProgramsDictionary().Values;
- }
-
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
{
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
- var channels = _channelIdList.Select(_libraryManager.GetItemById)
- .Where(i => i != null)
- .OfType<LiveTvChannel>();
+ var channels = _libraryManager.GetItems(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(LiveTvChannel).Name }
+
+ }).Items.Cast<LiveTvChannel>();
if (user != null)
{
@@ -258,9 +226,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var returnList = new List<ChannelInfoDto>();
+ var now = DateTime.UtcNow;
+
+ var programs = _libraryManager.GetItems(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
+ MaxStartDate = now,
+ MinEndDate = now
+
+ }).Items.Cast<LiveTvProgram>().OrderBy(i => i.StartDate).ToList();
+
foreach (var channel in internalResult.Items)
{
- var currentProgram = GetCurrentProgram(channel.ExternalId);
+ var channelIdString = channel.Id.ToString("N");
+ var currentProgram = programs.FirstOrDefault(i => string.Equals(i.ChannelId, channelIdString, StringComparison.OrdinalIgnoreCase));
returnList.Add(_tvDtoService.GetChannelInfoDto(channel, currentProgram, user));
}
@@ -284,36 +263,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return _libraryManager.GetItemById(id) as LiveTvChannel;
}
- private LiveTvProgram GetInternalProgram(string id)
+ internal LiveTvProgram GetInternalProgram(string id)
{
- var guid = new Guid(id);
-
- LiveTvProgram obj = null;
-
- GetProgramsDictionary().TryGetValue(guid, out obj);
-
- if (obj != null)
- {
- RefreshIfNeeded(obj);
- }
- return obj;
+ return _libraryManager.GetItemById(id) as LiveTvProgram;
}
- private void RefreshIfNeeded(LiveTvProgram program)
+ internal LiveTvProgram GetInternalProgram(Guid id)
{
- if (!_refreshedPrograms.ContainsKey(program.Id))
- {
- _refreshedPrograms.TryAdd(program.Id, true);
- _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions());
- }
- }
-
- private void RefreshIfNeeded(IEnumerable<LiveTvProgram> programs)
- {
- foreach (var program in programs)
- {
- RefreshIfNeeded(program);
- }
+ return _libraryManager.GetItemById(id) as LiveTvProgram;
}
public async Task<ILiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken)
@@ -404,8 +361,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase);
var service = GetService(recording);
- _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.RecordingInfo.Id);
- info = await service.GetRecordingStream(recording.RecordingInfo.Id, null, cancellationToken).ConfigureAwait(false);
+ _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId);
+ info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false);
info.RequiresClosing = true;
if (info.RequiresClosing)
@@ -598,14 +555,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
- private async Task<LiveTvProgram> GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
+ private async Task<LiveTvProgram> GetProgram(ProgramInfo info, string channelId, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
{
var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
var item = _libraryManager.GetItemById(id) as LiveTvProgram;
+ var isNew = false;
if (item == null)
{
+ isNew = true;
item = new LiveTvProgram
{
Name = info.Name,
@@ -619,8 +578,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.ServiceName = serviceName;
item.Audio = info.Audio;
- item.ExternalChannelId = info.ChannelId;
- item.CommunityRating = info.CommunityRating;
+ item.ChannelId = channelId;
+ item.CommunityRating = item.CommunityRating ?? info.CommunityRating;
item.EndDate = info.EndDate;
item.EpisodeTitle = info.EpisodeTitle;
item.ExternalId = info.Id;
@@ -636,8 +595,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.IsSeries = info.IsSeries;
item.IsSports = info.IsSports;
item.Name = info.Name;
- item.OfficialRating = info.OfficialRating;
- item.Overview = info.Overview;
+ item.OfficialRating = item.OfficialRating ?? info.OfficialRating;
+ item.Overview = item.Overview ?? info.Overview;
item.OriginalAirDate = info.OriginalAirDate;
item.ProviderImagePath = info.ImagePath;
item.ProviderImageUrl = info.ImageUrl;
@@ -647,18 +606,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.ProductionYear = info.ProductionYear;
item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate;
- await item.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+ if (isNew)
+ {
+ await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+ }
+
+ _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions());
return item;
}
- private async Task<ILiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
+ private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
{
var isNew = false;
var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);
- var item = _itemRepo.RetrieveItem(id) as ILiveTvRecording;
+ var item = _itemRepo.RetrieveItem(id);
if (item == null)
{
@@ -687,8 +655,39 @@ namespace MediaBrowser.Server.Implementations.LiveTv
isNew = true;
}
- item.RecordingInfo = info;
- item.ServiceName = serviceName;
+ item.ChannelId = _tvDtoService.GetInternalChannelId(serviceName, info.ChannelId).ToString("N");
+ item.CommunityRating = info.CommunityRating;
+ item.OfficialRating = info.OfficialRating;
+ item.Overview = info.Overview;
+ item.EndDate = info.EndDate;
+ item.Genres = info.Genres;
+
+ var recording = (ILiveTvRecording)item;
+
+ recording.ExternalId = info.Id;
+
+ recording.ProgramId = _tvDtoService.GetInternalProgramId(serviceName, info.ProgramId).ToString("N");
+ recording.Audio = info.Audio;
+ recording.ChannelType = info.ChannelType;
+ recording.EndDate = info.EndDate;
+ recording.EpisodeTitle = info.EpisodeTitle;
+ recording.ProviderImagePath = info.ImagePath;
+ recording.ProviderImageUrl = info.ImageUrl;
+ recording.IsHD = info.IsHD;
+ recording.IsKids = info.IsKids;
+ recording.IsLive = info.IsLive;
+ recording.IsMovie = info.IsMovie;
+ recording.IsNews = info.IsNews;
+ recording.IsPremiere = info.IsPremiere;
+ recording.IsRepeat = info.IsRepeat;
+ recording.IsSeries = info.IsSeries;
+ recording.IsSports = info.IsSports;
+ recording.OriginalAirDate = info.OriginalAirDate;
+ recording.SeriesTimerId = info.SeriesTimerId;
+ recording.StartDate = info.StartDate;
+ recording.Status = info.Status;
+
+ recording.ServiceName = serviceName;
var originalPath = item.Path;
@@ -703,101 +702,58 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var pathChanged = !string.Equals(originalPath, item.Path);
- await item.RefreshMetadata(new MetadataRefreshOptions
+ if (isNew)
{
- ForceSave = isNew || pathChanged
-
- }, cancellationToken);
-
- _libraryManager.RegisterItem((BaseItem)item);
-
- return item;
- }
-
- private LiveTvChannel GetChannel(LiveTvProgram program)
- {
- var programChannelId = program.ExternalChannelId;
-
- if (string.IsNullOrWhiteSpace(programChannelId)) return null;
+ await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ }
+ else if (pathChanged)
+ {
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+ }
- var internalProgramChannelId = _tvDtoService.GetInternalChannelId(program.ServiceName, programChannelId);
+ _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions());
- return GetInternalChannel(internalProgramChannelId);
+ return item.Id;
}
- public async Task<ProgramInfoDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
+ public async Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
{
var program = GetInternalProgram(id);
- var channel = GetChannel(program);
-
- var dto = _tvDtoService.GetProgramInfoDto(program, channel, user);
+ var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
await AddRecordingInfo(new[] { dto }, cancellationToken).ConfigureAwait(false);
return dto;
}
- public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
+ public async Task<QueryResult<BaseItemDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
{
- IEnumerable<LiveTvProgram> programs = GetPrograms();
-
- if (query.MinEndDate.HasValue)
- {
- var val = query.MinEndDate.Value;
-
- programs = programs.Where(i => i.EndDate.HasValue && i.EndDate.Value >= val);
- }
-
- if (query.MinStartDate.HasValue)
+ var internalQuery = new InternalItemsQuery
{
- var val = query.MinStartDate.Value;
-
- programs = programs.Where(i => i.StartDate >= val);
- }
-
- if (query.MaxEndDate.HasValue)
- {
- var val = query.MaxEndDate.Value;
-
- programs = programs.Where(i => i.EndDate.HasValue && i.EndDate.Value <= val);
- }
-
- if (query.MaxStartDate.HasValue)
- {
- var val = query.MaxStartDate.Value;
-
- programs = programs.Where(i => i.StartDate <= val);
- }
+ IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
+ MinEndDate = query.MinEndDate,
+ MinStartDate = query.MinStartDate,
+ MaxEndDate = query.MaxEndDate,
+ MaxStartDate = query.MaxStartDate,
+ ChannelIds = query.ChannelIds,
+ IsMovie = query.IsMovie,
+ IsSports = query.IsSports
+ };
if (query.HasAired.HasValue)
{
- var val = query.HasAired.Value;
- programs = programs.Where(i => i.HasAired == val);
- }
-
- if (query.ChannelIds.Length > 0)
- {
- var guids = query.ChannelIds.Select(i => new Guid(i)).ToList();
-
- programs = programs.Where(i =>
+ if (query.HasAired.Value)
{
- var programChannelId = i.ExternalChannelId;
-
- var service = GetService(i);
- var internalProgramChannelId = _tvDtoService.GetInternalChannelId(service.Name, programChannelId);
-
- return guids.Contains(internalProgramChannelId);
- });
+ internalQuery.MaxEndDate = DateTime.UtcNow;
+ }
+ else
+ {
+ internalQuery.MinEndDate = DateTime.UtcNow;
+ }
}
- var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
- if (user != null)
- {
- // Avoid implicitly captured closure
- var currentUser = user;
- programs = programs.Where(i => i.IsVisible(currentUser));
- }
+ IEnumerable<LiveTvProgram> programs = _libraryManager.GetItems(internalQuery).Items.Cast<LiveTvProgram>();
// Apply genre filter
if (query.Genres.Length > 0)
@@ -805,14 +761,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
programs = programs.Where(p => p.Genres.Any(g => query.Genres.Contains(g, StringComparer.OrdinalIgnoreCase)));
}
- if (query.IsMovie.HasValue)
- {
- programs = programs.Where(p => p.IsMovie == query.IsMovie);
- }
-
- if (query.IsSports.HasValue)
+ var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+ if (user != null)
{
- programs = programs.Where(p => p.IsSports == query.IsSports);
+ // Avoid implicitly captured closure
+ var currentUser = user;
+ programs = programs.Where(i => i.IsVisible(currentUser));
}
programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending)
@@ -832,19 +786,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
var returnArray = returnPrograms
- .Select(i =>
- {
- var channel = GetChannel(i);
-
- return _tvDtoService.GetProgramInfoDto(i, channel, user);
- })
+ .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user))
.ToArray();
- RefreshIfNeeded(programList);
-
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
- var result = new QueryResult<ProgramInfoDto>
+ var result = new QueryResult<BaseItemDto>
{
Items = returnArray,
TotalRecordCount = programList.Count
@@ -855,35 +802,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken)
{
- IEnumerable<LiveTvProgram> programs = GetPrograms();
-
- var user = _userManager.GetUserById(query.UserId);
-
- // Avoid implicitly captured closure
- var currentUser = user;
- programs = programs.Where(i => i.IsVisible(currentUser));
-
- if (query.IsAiring.HasValue)
+ var internalQuery = new InternalItemsQuery
{
- var val = query.IsAiring.Value;
- programs = programs.Where(i => i.IsAiring == val);
- }
+ IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
+ IsAiring = query.IsAiring,
+ IsMovie = query.IsMovie,
+ IsSports = query.IsSports
+ };
if (query.HasAired.HasValue)
{
- var val = query.HasAired.Value;
- programs = programs.Where(i => i.HasAired == val);
+ if (query.HasAired.Value)
+ {
+ internalQuery.MaxEndDate = DateTime.UtcNow;
+ }
+ else
+ {
+ internalQuery.MinEndDate = DateTime.UtcNow;
+ }
}
- if (query.IsMovie.HasValue)
- {
- programs = programs.Where(p => p.IsMovie == query.IsMovie.Value);
- }
+ IEnumerable<LiveTvProgram> programs = _libraryManager.GetItems(internalQuery).Items.Cast<LiveTvProgram>();
- if (query.IsSports.HasValue)
- {
- programs = programs.Where(p => p.IsSports == query.IsSports.Value);
- }
+ var user = _userManager.GetUserById(query.UserId);
+
+ // Avoid implicitly captured closure
+ var currentUser = user;
+ programs = programs.Where(i => i.IsVisible(currentUser));
var programList = programs.ToList();
@@ -904,8 +849,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
programList = programs.ToList();
- RefreshIfNeeded(programList);
-
var returnArray = programList.ToArray();
var result = new QueryResult<LiveTvProgram>
@@ -917,24 +860,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return result;
}
- public async Task<QueryResult<ProgramInfoDto>> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken)
+ public async Task<QueryResult<BaseItemDto>> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken)
{
var internalResult = await GetRecommendedProgramsInternal(query, cancellationToken).ConfigureAwait(false);
var user = _userManager.GetUserById(query.UserId);
var returnArray = internalResult.Items
- .Select(i =>
- {
- var channel = GetChannel(i);
-
- return _tvDtoService.GetProgramInfoDto(i, channel, user);
- })
+ .Select(i => _dtoService.GetBaseItemDto(i, new DtoOptions(), user))
.ToArray();
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
- var result = new QueryResult<ProgramInfoDto>
+ var result = new QueryResult<BaseItemDto>
{
Items = returnArray,
TotalRecordCount = internalResult.TotalRecordCount
@@ -957,8 +895,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
score++;
}
- var internalChannelId = _tvDtoService.GetInternalChannelId(program.ServiceName, program.ExternalChannelId);
- var channel = GetInternalChannel(internalChannelId);
+ var channel = GetInternalChannel(program.ChannelId);
var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey());
@@ -1013,54 +950,49 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}).Sum();
}
- private async Task AddRecordingInfo(IEnumerable<ProgramInfoDto> programs, CancellationToken cancellationToken)
+ private async Task AddRecordingInfo(IEnumerable<BaseItemDto> programs, CancellationToken cancellationToken)
{
var timers = new Dictionary<string, List<TimerInfo>>();
foreach (var program in programs)
{
+ var internalProgram = GetInternalProgram(program.Id);
+
List<TimerInfo> timerList;
- if (!timers.TryGetValue(program.ServiceName, out timerList))
+ if (!timers.TryGetValue(internalProgram.ServiceName, out timerList))
{
try
{
- var tempTimers = await GetService(program.ServiceName).GetTimersAsync(cancellationToken).ConfigureAwait(false);
- timers[program.ServiceName] = timerList = tempTimers.ToList();
+ var tempTimers = await GetService(internalProgram.ServiceName).GetTimersAsync(cancellationToken).ConfigureAwait(false);
+ timers[internalProgram.ServiceName] = timerList = tempTimers.ToList();
}
catch (Exception ex)
{
_logger.ErrorException("Error getting timer infos", ex);
- timers[program.ServiceName] = timerList = new List<TimerInfo>();
+ timers[internalProgram.ServiceName] = timerList = new List<TimerInfo>();
}
}
- var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, program.ExternalId, StringComparison.OrdinalIgnoreCase));
+
+ var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, internalProgram.ExternalId, StringComparison.OrdinalIgnoreCase));
if (timer != null)
{
- program.TimerId = _tvDtoService.GetInternalTimerId(program.ServiceName, timer.Id)
+ program.TimerId = _tvDtoService.GetInternalTimerId(internalProgram.ServiceName, timer.Id)
.ToString("N");
if (!string.IsNullOrEmpty(timer.SeriesTimerId))
{
- program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(program.ServiceName, timer.SeriesTimerId)
+ program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(internalProgram.ServiceName, timer.SeriesTimerId)
.ToString("N");
}
}
}
}
- internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
+ internal Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{
- var innerProgress = new ActionableProgress<double>();
- innerProgress.RegisterAction(p => progress.Report(p * .9));
- await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false);
-
- innerProgress = new ActionableProgress<double>();
- innerProgress.RegisterAction(p => progress.Report(90 + (p * .1)));
- await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false);
-
- RefreshIfNeeded(GetPrograms().ToList());
+ return RefreshChannelsInternal(progress, cancellationToken);
}
private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken)
@@ -1070,6 +1002,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
? 0
: 1 / _services.Count;
+ var newChannelIdList = new List<Guid>();
+ var newProgramIdList = new List<Guid>();
+
foreach (var service in _services)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -1079,7 +1014,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var innerProgress = new ActionableProgress<double>();
innerProgress.RegisterAction(p => progress.Report(p * progressPerService));
- await RefreshChannelsInternal(service, innerProgress, cancellationToken).ConfigureAwait(false);
+ var idList = await RefreshChannelsInternal(service, innerProgress, cancellationToken).ConfigureAwait(false);
+
+ newChannelIdList.AddRange(idList.Item1);
+ newProgramIdList.AddRange(idList.Item2);
}
catch (OperationCanceledException)
{
@@ -1097,10 +1035,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(100 * percent);
}
+ await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false);
+ await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false);
+
+ // Load these now which will prefetch metadata
+ var dtoOptions = new DtoOptions();
+ dtoOptions.Fields.Remove(ItemFields.SyncInfo);
+ await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false);
+
progress.Report(100);
}
- private async Task RefreshChannelsInternal(ILiveTvService service, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task<Tuple<List<Guid>, List<Guid>>> RefreshChannelsInternal(ILiveTvService service, IProgress<double> progress, CancellationToken cancellationToken)
{
progress.Report(10);
@@ -1139,23 +1085,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(5 * percent + 10);
}
- _channelIdList = list.Select(i => i.Id).ToList();
progress.Report(15);
numComplete = 0;
- var programs = new List<LiveTvProgram>();
+ var programs = new List<Guid>();
+ var channels = new List<Guid>();
var guideDays = GetGuideDays(list.Count);
cancellationToken.ThrowIfCancellationRequested();
- foreach (var item in list)
+ foreach (var currentChannel in list)
{
+ channels.Add(currentChannel.Id);
cancellationToken.ThrowIfCancellationRequested();
- // Avoid implicitly captured closure
- var currentChannel = item;
-
try
{
var start = DateTime.UtcNow.AddHours(-1);
@@ -1163,9 +1107,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
+ var channelId = currentChannel.Id.ToString("N");
+
foreach (var program in channelPrograms)
{
- programs.Add(await GetProgram(program, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false));
+ var programItem = await GetProgram(program, channelId, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
+ programs.Add(programItem.Id);
}
}
catch (OperationCanceledException)
@@ -1183,44 +1130,36 @@ namespace MediaBrowser.Server.Implementations.LiveTv
progress.Report(80 * percent + 10);
}
-
- lock (_programsDataLock)
- {
- _programs = programs.ToDictionary(i => i.Id);
- }
-
- _refreshedPrograms.Clear();
- progress.Report(90);
-
- // Load these now which will prefetch metadata
- var dtoOptions = new DtoOptions();
- dtoOptions.Fields.Remove(ItemFields.SyncInfo);
- await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false);
progress.Report(100);
- }
- private Task CleanDatabaseInternal(IProgress<double> progress, CancellationToken cancellationToken)
- {
- return DeleteOldPrograms(GetProgramsDictionary().Keys.ToList(), progress, cancellationToken);
+ return new Tuple<List<Guid>, List<Guid>>(channels, programs);
}
- private async Task DeleteOldPrograms(List<Guid> currentIdList, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task CleanDatabaseInternal(List<Guid> currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken)
{
- var list = _itemRepo.GetItemIdsOfType(typeof(LiveTvProgram)).ToList();
+ var list = _itemRepo.GetItemIds(new InternalItemsQuery
+ {
+ IncludeItemTypes = validTypes
+
+ }).Items.ToList();
var numComplete = 0;
- foreach (var programId in list)
+ foreach (var itemId in list)
{
cancellationToken.ThrowIfCancellationRequested();
- if (!currentIdList.Contains(programId))
+ if (!currentIdList.Contains(itemId))
{
- var program = _libraryManager.GetItemById(programId);
+ var item = _libraryManager.GetItemById(itemId);
- if (program != null)
+ if (item != null)
{
- await _libraryManager.DeleteItem(program).ConfigureAwait(false);
+ await _libraryManager.DeleteItem(item, new DeleteOptions
+ {
+ DeleteFileLocation = false
+
+ }).ConfigureAwait(false);
}
}
@@ -1257,64 +1196,103 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return channels.Select(i => new Tuple<string, ChannelInfo>(service.Name, i));
}
- public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
+ private DateTime _lastRecordingRefreshTime;
+ private async Task RefreshRecordings(CancellationToken cancellationToken)
{
- var tasks = _services.Select(async i =>
+ const int cacheMinutes = 5;
+
+ if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes)
{
- try
+ return;
+ }
+
+ await _refreshRecordingsLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes)
{
- var recs = await i.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
- return recs.Select(r => new Tuple<RecordingInfo, ILiveTvService>(r, i));
+ return;
}
- catch (Exception ex)
+
+ var tasks = _services.Select(async i =>
{
- _logger.ErrorException("Error getting recordings", ex);
- return new List<Tuple<RecordingInfo, ILiveTvService>>();
- }
- });
- var results = await Task.WhenAll(tasks).ConfigureAwait(false);
- var recordings = results.SelectMany(i => i.ToList());
+ try
+ {
+ var recs = await i.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
+ return recs.Select(r => new Tuple<RecordingInfo, ILiveTvService>(r, i));
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting recordings", ex);
+ return new List<Tuple<RecordingInfo, ILiveTvService>>();
+ }
+ });
- var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+ var results = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, cancellationToken));
+
+ var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
+
+ CleanDatabaseInternal(idList.ToList(), new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new Progress<double>(), cancellationToken).ConfigureAwait(false);
+
+ _lastRecordingRefreshTime = DateTime.UtcNow;
+ }
+ finally
+ {
+ _refreshRecordingsLock.Release();
+ }
+ }
+ public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
+ {
+ var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
if (user != null && !IsLiveTvEnabled(user))
{
- recordings = new List<Tuple<RecordingInfo, ILiveTvService>>();
+ return new QueryResult<BaseItem>();
}
- if (!string.IsNullOrEmpty(query.ChannelId))
+ await RefreshRecordings(cancellationToken).ConfigureAwait(false);
+
+ var internalQuery = new InternalItemsQuery
{
- var guid = new Guid(query.ChannelId);
+ IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }
+ };
- recordings = recordings
- .Where(i => _tvDtoService.GetInternalChannelId(i.Item2.Name, i.Item1.ChannelId) == guid);
+ if (!string.IsNullOrEmpty(query.ChannelId))
+ {
+ internalQuery.ChannelIds = new[] { query.ChannelId };
}
+ var queryResult = _libraryManager.GetItems(internalQuery);
+ IEnumerable<ILiveTvRecording> recordings = queryResult.Items.Cast<ILiveTvRecording>();
+
if (!string.IsNullOrEmpty(query.Id))
{
var guid = new Guid(query.Id);
recordings = recordings
- .Where(i => _tvDtoService.GetInternalRecordingId(i.Item2.Name, i.Item1.Id) == guid);
+ .Where(i => i.Id == guid);
}
if (!string.IsNullOrEmpty(query.GroupId))
{
var guid = new Guid(query.GroupId);
- recordings = recordings.Where(i => GetRecordingGroupIds(i.Item1).Contains(guid));
+ recordings = recordings.Where(i => GetRecordingGroupIds(i).Contains(guid));
}
if (query.IsInProgress.HasValue)
{
var val = query.IsInProgress.Value;
- recordings = recordings.Where(i => (i.Item1.Status == RecordingStatus.InProgress) == val);
+ recordings = recordings.Where(i => (i.Status == RecordingStatus.InProgress) == val);
}
if (query.Status.HasValue)
{
var val = query.Status.Value;
- recordings = recordings.Where(i => (i.Item1.Status == val));
+ recordings = recordings.Where(i => (i.Status == val));
}
if (!string.IsNullOrEmpty(query.SeriesTimerId))
@@ -1322,21 +1300,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var guid = new Guid(query.SeriesTimerId);
recordings = recordings
- .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.Item2.Name, i.Item1.SeriesTimerId) == guid);
+ .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid);
}
- recordings = recordings.OrderByDescending(i => i.Item1.StartDate);
-
- IEnumerable<ILiveTvRecording> entities = await GetEntities(recordings, cancellationToken).ConfigureAwait(false);
-
if (user != null)
{
var currentUser = user;
- entities = entities.Where(i => i.IsParentalAllowed(currentUser));
+ recordings = recordings.Where(i => i.IsParentalAllowed(currentUser));
}
- var entityList = entities.ToList();
- entities = entityList;
+ recordings = recordings.OrderByDescending(i => i.StartDate);
+
+ var entityList = recordings.ToList();
+ IEnumerable<ILiveTvRecording> entities = entityList;
if (query.StartIndex.HasValue)
{
@@ -1355,20 +1331,122 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
- public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken)
+ public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, User user = null)
{
- var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+ var program = (LiveTvProgram)item;
+ var service = GetService(program);
- var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
+ var channel = GetInternalChannel(program.ChannelId);
- var returnArray = internalResult.Items.Cast<ILiveTvRecording>()
- .Select(i =>
+ dto.Id = _tvDtoService.GetInternalProgramId(service.Name, program.ExternalId).ToString("N");
+
+ dto.ChannelId = item.ChannelId;
+
+ dto.StartDate = program.StartDate;
+ dto.IsRepeat = program.IsRepeat;
+ dto.EpisodeTitle = program.EpisodeTitle;
+ dto.ChannelType = program.ChannelType;
+ dto.Audio = program.Audio;
+ dto.IsHD = program.IsHD;
+ dto.IsMovie = program.IsMovie;
+ dto.IsSeries = program.IsSeries;
+ dto.IsSports = program.IsSports;
+ dto.IsLive = program.IsLive;
+ dto.IsNews = program.IsNews;
+ dto.IsKids = program.IsKids;
+ dto.IsPremiere = program.IsPremiere;
+ dto.OriginalAirDate = program.OriginalAirDate;
+
+ if (channel != null)
+ {
+ dto.ChannelName = channel.Name;
+
+ if (!string.IsNullOrEmpty(channel.PrimaryImagePath))
{
- var service = GetService(i);
+ dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
+ }
+ }
+ }
- var channel = string.IsNullOrEmpty(i.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.RecordingInfo.ChannelId));
- return _tvDtoService.GetRecordingInfoDto(i, channel, service, user);
- })
+ public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null)
+ {
+ var recording = (ILiveTvRecording)item;
+ var service = GetService(recording);
+
+ var channel = string.IsNullOrWhiteSpace(recording.ChannelId) ? null : GetInternalChannel(recording.ChannelId);
+
+ var info = recording;
+
+ dto.Id = item.Id.ToString("N");
+ dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
+ ? null
+ : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
+
+ dto.ChannelId = item.ChannelId;
+
+ dto.StartDate = info.StartDate;
+ dto.RecordingStatus = info.Status;
+ dto.IsRepeat = info.IsRepeat;
+ dto.EpisodeTitle = info.EpisodeTitle;
+ dto.ChannelType = info.ChannelType;
+ dto.Audio = info.Audio;
+ dto.IsHD = info.IsHD;
+ dto.IsMovie = info.IsMovie;
+ dto.IsSeries = info.IsSeries;
+ dto.IsSports = info.IsSports;
+ dto.IsLive = info.IsLive;
+ dto.IsNews = info.IsNews;
+ dto.IsKids = info.IsKids;
+ dto.IsPremiere = info.IsPremiere;
+ dto.OriginalAirDate = info.OriginalAirDate;
+
+ dto.CanDelete = user == null
+ ? recording.CanDelete()
+ : recording.CanDelete(user);
+
+ if (dto.MediaSources == null)
+ {
+ dto.MediaSources = recording.GetMediaSources(true).ToList();
+ }
+
+ if (dto.MediaStreams == null)
+ {
+ dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList();
+ }
+
+ if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue)
+ {
+ var now = DateTime.UtcNow.Ticks;
+ var start = info.StartDate.Ticks;
+ var end = info.EndDate.Value.Ticks;
+
+ var pct = now - start;
+ pct /= end;
+ pct *= 100;
+ dto.CompletionPercentage = pct;
+ }
+
+ dto.ProgramId = info.ProgramId;
+
+ if (channel != null)
+ {
+ dto.ChannelName = channel.Name;
+
+ if (!string.IsNullOrEmpty(channel.PrimaryImagePath))
+ {
+ dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
+ }
+ }
+ }
+
+ public async Task<QueryResult<BaseItemDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken)
+ {
+ var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
+
+ var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
+
+ var returnArray = internalResult.Items
+ .Select(i => _dtoService.GetBaseItemDto(i, options, user))
.ToArray();
if (user != null)
@@ -1376,20 +1454,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
_dtoService.FillSyncInfo(returnArray, new DtoOptions(), user);
}
- return new QueryResult<RecordingInfoDto>
+ return new QueryResult<BaseItemDto>
{
Items = returnArray,
TotalRecordCount = internalResult.TotalRecordCount
};
}
- private Task<ILiveTvRecording[]> GetEntities(IEnumerable<Tuple<RecordingInfo, ILiveTvService>> recordings, CancellationToken cancellationToken)
- {
- var tasks = recordings.Select(i => GetRecording(i.Item1, i.Item2.Name, cancellationToken));
-
- return Task.WhenAll(tasks);
- }
-
public async Task<QueryResult<TimerInfoDto>> GetTimers(TimerQuery query, CancellationToken cancellationToken)
{
var tasks = _services.Select(async i =>
@@ -1448,10 +1519,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task DeleteRecording(string recordingId)
{
- var dtoOptions = new DtoOptions();
- dtoOptions.Fields.Remove(ItemFields.SyncInfo);
-
- var recording = await GetRecording(recordingId, dtoOptions, CancellationToken.None).ConfigureAwait(false);
+ var recording = await GetInternalRecording(recordingId, CancellationToken.None).ConfigureAwait(false);
if (recording == null)
{
@@ -1461,6 +1529,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(recording.ServiceName);
await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task CancelTimer(string id)
@@ -1475,6 +1544,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task CancelSeriesTimer(string id)
@@ -1489,18 +1559,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
- public async Task<RecordingInfoDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null)
+ public async Task<BaseItemDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null)
{
- var results = await GetRecordings(new RecordingQuery
- {
- UserId = user == null ? null : user.Id.ToString("N"),
- Id = id
+ var item = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false);
- }, options, cancellationToken).ConfigureAwait(false);
+ if (item == null)
+ {
+ return null;
+ }
- return results.Items.FirstOrDefault();
+ return _dtoService.GetBaseItemDto((BaseItem)item, options, user);
}
public async Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken)
@@ -1576,29 +1647,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var channel = GetInternalChannel(id);
- var currentProgram = GetCurrentProgram(channel.ExternalId);
-
- var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user);
+ var now = DateTime.UtcNow;
- return dto;
- }
+ var programs = _libraryManager.GetItems(new InternalItemsQuery
+ {
+ IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
+ ChannelIds = new[] { id },
+ MaxStartDate = now,
+ MinEndDate = now,
+ Limit = 1
- private LiveTvProgram GetCurrentProgram(string externalChannelId)
- {
- var now = DateTime.UtcNow;
+ }).Items.Cast<LiveTvProgram>();
- var program = GetPrograms()
- .Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase))
+ var currentProgram = programs
.OrderBy(i => i.StartDate)
- .SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue))
.FirstOrDefault();
- if (program != null)
- {
- RefreshIfNeeded(program);
- }
+ var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user);
- return program;
+ return dto;
}
private async Task<Tuple<SeriesTimerInfo, ILiveTvService>> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null)
@@ -1611,10 +1678,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (program != null)
{
+ var channel = GetInternalChannel(program.ChannelId);
+
programInfo = new ProgramInfo
{
Audio = program.Audio,
- ChannelId = program.ExternalChannelId,
+ ChannelId = channel.ExternalId,
CommunityRating = program.CommunityRating,
EndDate = program.EndDate ?? DateTime.MinValue,
EpisodeTitle = program.EpisodeTitle,
@@ -1678,7 +1747,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
info.Name = program.Name;
info.Overview = program.Overview;
info.ProgramId = programDto.Id;
- info.ExternalProgramId = programDto.ExternalId;
+ info.ExternalProgramId = program.ExternalId;
if (program.EndDate.HasValue)
{
@@ -1699,6 +1768,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
info.Priority = defaultValues.Priority;
await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken)
@@ -1712,6 +1782,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
info.Priority = defaultValues.Priority;
await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken)
@@ -1721,6 +1792,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.UpdateTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
public async Task UpdateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken)
@@ -1730,9 +1802,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = GetService(timer.ServiceName);
await service.UpdateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false);
+ _lastRecordingRefreshTime = DateTime.MinValue;
}
- private IEnumerable<string> GetRecordingGroupNames(RecordingInfo recording)
+ private IEnumerable<string> GetRecordingGroupNames(ILiveTvRecording recording)
{
var list = new List<string>();
@@ -1769,64 +1842,61 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return list;
}
- private List<Guid> GetRecordingGroupIds(RecordingInfo recording)
+ private List<Guid> GetRecordingGroupIds(ILiveTvRecording recording)
{
return GetRecordingGroupNames(recording).Select(i => i.ToLower()
.GetMD5())
.ToList();
}
- public async Task<QueryResult<RecordingGroupDto>> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken)
+ public async Task<QueryResult<BaseItemDto>> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken)
{
- var dtoOptions = new DtoOptions();
- dtoOptions.Fields.Remove(ItemFields.SyncInfo);
-
- var recordingResult = await GetRecordings(new RecordingQuery
+ var recordingResult = await GetInternalRecordings(new RecordingQuery
{
UserId = query.UserId
- }, dtoOptions, cancellationToken).ConfigureAwait(false);
+ }, cancellationToken).ConfigureAwait(false);
- var recordings = recordingResult.Items;
+ var recordings = recordingResult.Items.Cast<ILiveTvRecording>().ToList();
- var groups = new List<RecordingGroupDto>();
+ var groups = new List<BaseItemDto>();
var series = recordings
.Where(i => i.IsSeries)
.ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
- groups.AddRange(series.OrderByString(i => i.Key).Select(i => new RecordingGroupDto
+ groups.AddRange(series.OrderByString(i => i.Key).Select(i => new BaseItemDto
{
Name = i.Key,
RecordingCount = i.Count()
}));
- groups.Add(new RecordingGroupDto
+ groups.Add(new BaseItemDto
{
Name = "Kids",
RecordingCount = recordings.Count(i => i.IsKids)
});
- groups.Add(new RecordingGroupDto
+ groups.Add(new BaseItemDto
{
Name = "Movies",
RecordingCount = recordings.Count(i => i.IsMovie)
});
- groups.Add(new RecordingGroupDto
+ groups.Add(new BaseItemDto
{
Name = "News",
RecordingCount = recordings.Count(i => i.IsNews)
});
- groups.Add(new RecordingGroupDto
+ groups.Add(new BaseItemDto
{
Name = "Sports",
RecordingCount = recordings.Count(i => i.IsSports)
});
- groups.Add(new RecordingGroupDto
+ groups.Add(new BaseItemDto
{
Name = "Others",
RecordingCount = recordings.Count(i => !i.IsSports && !i.IsNews && !i.IsMovie && !i.IsKids && !i.IsSeries)
@@ -1841,7 +1911,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
group.Id = group.Name.ToLower().GetMD5().ToString("N");
}
- return new QueryResult<RecordingGroupDto>
+ return new QueryResult<BaseItemDto>
{
Items = groups.ToArray(),
TotalRecordCount = groups.Count
@@ -1893,15 +1963,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public GuideInfo GetGuideInfo()
{
- var programs = GetPrograms().OrderBy(i => i.StartDate).ToList();
-
- var startDate = programs.Count == 0 ?
- DateTime.MinValue :
- programs[0].StartDate;
-
- var endDate = programs.Count == 0 ?
- DateTime.MinValue :
- programs[programs.Count - 1].StartDate;
+ var startDate = DateTime.UtcNow;
+ var endDate = startDate.AddDays(14);
return new GuideInfo
{