|
@@ -32,6 +32,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|
private readonly ILogger _logger;
|
|
private readonly ILogger _logger;
|
|
private readonly IItemRepository _itemRepo;
|
|
private readonly IItemRepository _itemRepo;
|
|
private readonly IUserManager _userManager;
|
|
private readonly IUserManager _userManager;
|
|
|
|
+ private readonly IUserDataManager _userDataManager;
|
|
private readonly ILibraryManager _libraryManager;
|
|
private readonly ILibraryManager _libraryManager;
|
|
private readonly IMediaEncoder _mediaEncoder;
|
|
private readonly IMediaEncoder _mediaEncoder;
|
|
|
|
|
|
@@ -54,6 +55,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|
_userManager = userManager;
|
|
_userManager = userManager;
|
|
_libraryManager = libraryManager;
|
|
_libraryManager = libraryManager;
|
|
_mediaEncoder = mediaEncoder;
|
|
_mediaEncoder = mediaEncoder;
|
|
|
|
+ _userDataManager = userDataManager;
|
|
|
|
|
|
_tvDtoService = new LiveTvDtoService(dtoService, userDataManager, imageProcessor, logger, _itemRepo);
|
|
_tvDtoService = new LiveTvDtoService(dtoService, userDataManager, imageProcessor, logger, _itemRepo);
|
|
}
|
|
}
|
|
@@ -428,7 +430,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|
}
|
|
}
|
|
|
|
|
|
var returnArray = programs
|
|
var returnArray = programs
|
|
- .OrderBy(i => i.ProgramInfo.StartDate)
|
|
|
|
.Select(i =>
|
|
.Select(i =>
|
|
{
|
|
{
|
|
var channel = GetChannel(i);
|
|
var channel = GetChannel(i);
|
|
@@ -450,6 +451,138 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public async Task<QueryResult<ProgramInfoDto>> GetRecommendedPrograms(RecommendedProgramQuery query, CancellationToken cancellationToken)
|
|
|
|
+ {
|
|
|
|
+ IEnumerable<LiveTvProgram> programs = _programs.Values;
|
|
|
|
+
|
|
|
|
+ var user = _userManager.GetUserById(new Guid(query.UserId));
|
|
|
|
+
|
|
|
|
+ // Avoid implicitly captured closure
|
|
|
|
+ var currentUser = user;
|
|
|
|
+ programs = programs.Where(i => i.IsParentalAllowed(currentUser));
|
|
|
|
+
|
|
|
|
+ if (query.IsAiring.HasValue)
|
|
|
|
+ {
|
|
|
|
+ var val = query.IsAiring.Value;
|
|
|
|
+ programs = programs.Where(i => i.IsAiring == val);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (query.HasAired.HasValue)
|
|
|
|
+ {
|
|
|
|
+ var val = query.HasAired.Value;
|
|
|
|
+ programs = programs.Where(i => i.HasAired == val);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var serviceName = ActiveService.Name;
|
|
|
|
+
|
|
|
|
+ var programList = programs.ToList();
|
|
|
|
+
|
|
|
|
+ var genres = programList.SelectMany(i => i.Genres)
|
|
|
|
+ .Distinct(StringComparer.OrdinalIgnoreCase)
|
|
|
|
+ .Select(i => _libraryManager.GetGenre(i))
|
|
|
|
+ .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
|
|
|
|
+
|
|
|
|
+ programs = programList.OrderByDescending(i => GetRecommendationScore(i.ProgramInfo, user.Id, serviceName, genres))
|
|
|
|
+ .ThenBy(i => i.ProgramInfo.StartDate);
|
|
|
|
+
|
|
|
|
+ if (query.Limit.HasValue)
|
|
|
|
+ {
|
|
|
|
+ programs = programs.Take(query.Limit.Value)
|
|
|
|
+ .OrderBy(i => i.ProgramInfo.StartDate);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var returnArray = programs
|
|
|
|
+ .Select(i =>
|
|
|
|
+ {
|
|
|
|
+ var channel = GetChannel(i);
|
|
|
|
+
|
|
|
|
+ var channelName = channel == null ? null : channel.ChannelInfo.Name;
|
|
|
|
+
|
|
|
|
+ return _tvDtoService.GetProgramInfoDto(i, channelName, user);
|
|
|
|
+ })
|
|
|
|
+ .ToArray();
|
|
|
|
+
|
|
|
|
+ await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
|
|
|
|
+
|
|
|
|
+ var result = new QueryResult<ProgramInfoDto>
|
|
|
|
+ {
|
|
|
|
+ Items = returnArray,
|
|
|
|
+ TotalRecordCount = returnArray.Length
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int GetRecommendationScore(ProgramInfo program, Guid userId, string serviceName, Dictionary<string, Genre> genres)
|
|
|
|
+ {
|
|
|
|
+ var score = 0;
|
|
|
|
+
|
|
|
|
+ if (program.IsLive)
|
|
|
|
+ {
|
|
|
|
+ score++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (program.IsSeries && !program.IsRepeat)
|
|
|
|
+ {
|
|
|
|
+ score++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var internalChannelId = _tvDtoService.GetInternalChannelId(serviceName, program.ChannelId);
|
|
|
|
+ var channel = GetInternalChannel(internalChannelId);
|
|
|
|
+
|
|
|
|
+ var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey());
|
|
|
|
+
|
|
|
|
+ if ((channelUserdata.Likes ?? false))
|
|
|
|
+ {
|
|
|
|
+ score += 2;
|
|
|
|
+ }
|
|
|
|
+ else if (!(channelUserdata.Likes ?? true))
|
|
|
|
+ {
|
|
|
|
+ score -= 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (channelUserdata.IsFavorite)
|
|
|
|
+ {
|
|
|
|
+ score += 3;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ score += GetGenreScore(program.Genres, userId, genres);
|
|
|
|
+
|
|
|
|
+ return score;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int GetGenreScore(IEnumerable<string> programGenres, Guid userId, Dictionary<string, Genre> genres)
|
|
|
|
+ {
|
|
|
|
+ return programGenres.Select(i =>
|
|
|
|
+ {
|
|
|
|
+ var score = 0;
|
|
|
|
+
|
|
|
|
+ Genre genre;
|
|
|
|
+
|
|
|
|
+ if (genres.TryGetValue(i, out genre))
|
|
|
|
+ {
|
|
|
|
+ var genreUserdata = _userDataManager.GetUserData(userId, genre.GetUserDataKey());
|
|
|
|
+
|
|
|
|
+ if ((genreUserdata.Likes ?? false))
|
|
|
|
+ {
|
|
|
|
+ score++;
|
|
|
|
+ }
|
|
|
|
+ else if (!(genreUserdata.Likes ?? true))
|
|
|
|
+ {
|
|
|
|
+ score--;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (genreUserdata.IsFavorite)
|
|
|
|
+ {
|
|
|
|
+ score += 2;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return score;
|
|
|
|
+
|
|
|
|
+ }).Sum();
|
|
|
|
+ }
|
|
|
|
+
|
|
private async Task AddRecordingInfo(IEnumerable<ProgramInfoDto> programs, CancellationToken cancellationToken)
|
|
private async Task AddRecordingInfo(IEnumerable<ProgramInfoDto> programs, CancellationToken cancellationToken)
|
|
{
|
|
{
|
|
var timers = await ActiveService.GetTimersAsync(cancellationToken).ConfigureAwait(false);
|
|
var timers = await ActiveService.GetTimersAsync(cancellationToken).ConfigureAwait(false);
|
|
@@ -533,7 +666,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|
|
|
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- var channelPrograms = await service.GetProgramsAsync(currentChannel.ChannelInfo.Id, cancellationToken).ConfigureAwait(false);
|
|
|
|
|
|
+ var start = DateTime.UtcNow;
|
|
|
|
+ var end = start.AddDays(3);
|
|
|
|
+
|
|
|
|
+ var channelPrograms = await service.GetProgramsAsync(currentChannel.ChannelInfo.Id, start, end, cancellationToken).ConfigureAwait(false);
|
|
|
|
|
|
var programTasks = channelPrograms.Select(program => GetProgram(program, currentChannel.ChannelInfo.ChannelType, service.Name, cancellationToken));
|
|
var programTasks = channelPrograms.Select(program => GetProgram(program, currentChannel.ChannelInfo.ChannelType, service.Name, cancellationToken));
|
|
var programEntities = await Task.WhenAll(programTasks).ConfigureAwait(false);
|
|
var programEntities = await Task.WhenAll(programTasks).ConfigureAwait(false);
|