mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-26 17:40:30 +01:00
added IHasImages and IHasUserData
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
@@ -21,18 +22,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public ChannelImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem)
|
||||
public ChannelImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem, IHttpClient httpClient)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_liveTvManager = liveTvManager;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Channel;
|
||||
return item is LiveTvChannel;
|
||||
}
|
||||
|
||||
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
|
||||
@@ -48,21 +51,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return true;
|
||||
}
|
||||
|
||||
var channel = (Channel)item;
|
||||
|
||||
if (channel.HasProviderImage ?? true)
|
||||
try
|
||||
{
|
||||
try
|
||||
await DownloadImage((LiveTvChannel)item, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
// Don't fail the provider on a 404
|
||||
if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound)
|
||||
{
|
||||
await DownloadImage(item, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
// Don't fail the provider on a 404
|
||||
if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,20 +68,55 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task DownloadImage(BaseItem item, CancellationToken cancellationToken)
|
||||
private async Task DownloadImage(LiveTvChannel item, CancellationToken cancellationToken)
|
||||
{
|
||||
var channel = (Channel)item;
|
||||
var channelInfo = item.ChannelInfo;
|
||||
|
||||
var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, channel.ServiceName, StringComparison.OrdinalIgnoreCase));
|
||||
Stream imageStream = null;
|
||||
string contentType = null;
|
||||
|
||||
if (service != null)
|
||||
if (!string.IsNullOrEmpty(channelInfo.ImagePath))
|
||||
{
|
||||
var response = await service.GetChannelImageAsync(channel.ChannelId, cancellationToken).ConfigureAwait(false);
|
||||
contentType = "image/" + Path.GetExtension(channelInfo.ImagePath).ToLower();
|
||||
imageStream = _fileSystem.GetFileStream(channelInfo.ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(channelInfo.ImageUrl))
|
||||
{
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = channelInfo.ImageUrl
|
||||
};
|
||||
|
||||
var response = await _httpClient.GetResponse(options).ConfigureAwait(false);
|
||||
|
||||
if (!response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException("Provider did not return an image content type.");
|
||||
}
|
||||
|
||||
imageStream = response.Content;
|
||||
contentType = response.ContentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, item.ServiceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (service != null)
|
||||
{
|
||||
var response = await service.GetChannelImageAsync(channelInfo.Id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
imageStream = response.Stream;
|
||||
contentType = response.MimeType;
|
||||
}
|
||||
}
|
||||
|
||||
if (imageStream != null)
|
||||
{
|
||||
// Dummy up the original url
|
||||
var url = channel.ServiceName + channel.ChannelId;
|
||||
var url = item.ServiceName + channelInfo.Id;
|
||||
|
||||
await _providerManager.SaveImage(channel, response.Stream, response.MimeType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false);
|
||||
await _providerManager.SaveImage(item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,11 +135,29 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public RecordingInfoDto GetRecordingInfoDto(RecordingInfo info, ILiveTvService service, User user = null)
|
||||
/// <summary>
|
||||
/// Convert the provider 0-5 scale to our 0-10 scale
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
/// <returns></returns>
|
||||
private float? GetClientCommunityRating(float? val)
|
||||
{
|
||||
if (!val.HasValue)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return val.Value * 2;
|
||||
}
|
||||
|
||||
public RecordingInfoDto GetRecordingInfoDto(LiveTvRecording recording, ILiveTvService service, User user = null)
|
||||
{
|
||||
var info = recording.RecordingInfo;
|
||||
|
||||
var dto = new RecordingInfoDto
|
||||
{
|
||||
Id = GetInternalRecordingId(service.Name, info.Id).ToString("N"),
|
||||
Type = recording.GetClientTypeName(),
|
||||
ChannelName = info.ChannelName,
|
||||
Overview = info.Overview,
|
||||
EndDate = info.EndDate,
|
||||
@@ -154,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
EpisodeTitle = info.EpisodeTitle,
|
||||
ChannelType = info.ChannelType,
|
||||
MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video,
|
||||
CommunityRating = info.CommunityRating,
|
||||
CommunityRating = GetClientCommunityRating(info.CommunityRating),
|
||||
OfficialRating = info.OfficialRating,
|
||||
Audio = info.Audio,
|
||||
IsHD = info.IsHD,
|
||||
@@ -162,9 +180,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
Url = info.Url
|
||||
};
|
||||
|
||||
var imageTag = GetImageTag(recording);
|
||||
|
||||
if (imageTag.HasValue)
|
||||
{
|
||||
dto.ImageTags[ImageType.Primary] = imageTag.Value;
|
||||
}
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
//dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey()));
|
||||
dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, recording.GetUserDataKey()));
|
||||
}
|
||||
|
||||
var duration = info.EndDate - info.StartDate;
|
||||
@@ -184,18 +209,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
/// <param name="info">The info.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>ChannelInfoDto.</returns>
|
||||
public ChannelInfoDto GetChannelInfoDto(Channel info, User user = null)
|
||||
public ChannelInfoDto GetChannelInfoDto(LiveTvChannel info, User user = null)
|
||||
{
|
||||
var channelInfo = info.ChannelInfo;
|
||||
|
||||
var dto = new ChannelInfoDto
|
||||
{
|
||||
Name = info.Name,
|
||||
ServiceName = info.ServiceName,
|
||||
ChannelType = info.ChannelType,
|
||||
Number = info.ChannelNumber,
|
||||
Type = info.GetType().Name,
|
||||
ChannelType = channelInfo.ChannelType,
|
||||
Number = channelInfo.Number,
|
||||
Type = info.GetClientTypeName(),
|
||||
Id = info.Id.ToString("N"),
|
||||
MediaType = info.MediaType,
|
||||
ExternalId = info.ChannelId
|
||||
ExternalId = channelInfo.Id
|
||||
};
|
||||
|
||||
if (user != null)
|
||||
@@ -203,7 +230,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey()));
|
||||
}
|
||||
|
||||
var imageTag = GetLogoImageTag(info);
|
||||
var imageTag = GetImageTag(info);
|
||||
|
||||
if (imageTag.HasValue)
|
||||
{
|
||||
@@ -213,7 +240,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return dto;
|
||||
}
|
||||
|
||||
public ProgramInfoDto GetProgramInfoDto(ProgramInfo program, Channel channel, User user = null)
|
||||
public ProgramInfoDto GetProgramInfoDto(ProgramInfo program, LiveTvChannel channel, User user = null)
|
||||
{
|
||||
var dto = new ProgramInfoDto
|
||||
{
|
||||
@@ -230,7 +257,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
IsHD = program.IsHD,
|
||||
OriginalAirDate = program.OriginalAirDate,
|
||||
Audio = program.Audio,
|
||||
CommunityRating = program.CommunityRating,
|
||||
CommunityRating = GetClientCommunityRating(program.CommunityRating),
|
||||
AspectRatio = program.AspectRatio,
|
||||
IsRepeat = program.IsRepeat,
|
||||
EpisodeTitle = program.EpisodeTitle,
|
||||
@@ -248,7 +275,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return dto;
|
||||
}
|
||||
|
||||
private Guid? GetLogoImageTag(Channel info)
|
||||
private Guid? GetImageTag(BaseItem info)
|
||||
{
|
||||
var path = info.PrimaryImagePath;
|
||||
|
||||
@@ -263,7 +290,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting channel image info for {0}", ex, info.Name);
|
||||
_logger.ErrorException("Error getting image info for {0}", ex, info.Name);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -273,7 +300,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
var name = serviceName + externalId + channelName;
|
||||
|
||||
return name.ToLower().GetMBId(typeof(Channel));
|
||||
return name.ToLower().GetMBId(typeof(LiveTvChannel));
|
||||
}
|
||||
|
||||
public Guid GetInternalTimerId(string serviceName, string externalId)
|
||||
@@ -314,41 +341,53 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
Name = dto.Name,
|
||||
StartDate = dto.StartDate,
|
||||
Status = dto.Status,
|
||||
SeriesTimerId = dto.ExternalSeriesTimerId,
|
||||
PrePaddingSeconds = dto.PrePaddingSeconds,
|
||||
PostPaddingSeconds = dto.PostPaddingSeconds,
|
||||
IsPostPaddingRequired = dto.IsPostPaddingRequired,
|
||||
IsPrePaddingRequired = dto.IsPrePaddingRequired,
|
||||
Priority = dto.Priority
|
||||
Priority = dto.Priority,
|
||||
SeriesTimerId = dto.ExternalSeriesTimerId,
|
||||
ProgramId = dto.ExternalProgramId,
|
||||
ChannelId = dto.ExternalChannelId,
|
||||
Id = dto.ExternalId
|
||||
};
|
||||
|
||||
// Convert internal server id's to external tv provider id's
|
||||
if (!isNew && !string.IsNullOrEmpty(dto.Id))
|
||||
if (!isNew && !string.IsNullOrEmpty(dto.Id) && string.IsNullOrEmpty(info.Id))
|
||||
{
|
||||
var timer = await liveTv.GetTimer(dto.Id, cancellationToken).ConfigureAwait(false);
|
||||
var timer = await liveTv.GetSeriesTimer(dto.Id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.Id = timer.ExternalId;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.SeriesTimerId))
|
||||
{
|
||||
var timer = await liveTv.GetSeriesTimer(dto.SeriesTimerId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.SeriesTimerId = timer.ExternalId;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.ChannelId))
|
||||
if (!string.IsNullOrEmpty(dto.ChannelId) && string.IsNullOrEmpty(info.ChannelId))
|
||||
{
|
||||
var channel = await liveTv.GetChannel(dto.ChannelId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.ChannelId = channel.ExternalId;
|
||||
if (channel != null)
|
||||
{
|
||||
info.ChannelId = channel.ExternalId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.ProgramId))
|
||||
if (!string.IsNullOrEmpty(dto.ProgramId) && string.IsNullOrEmpty(info.ProgramId))
|
||||
{
|
||||
var program = await liveTv.GetProgram(dto.ProgramId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.ProgramId = program.ExternalId;
|
||||
if (program != null)
|
||||
{
|
||||
info.ProgramId = program.ExternalId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.SeriesTimerId) && string.IsNullOrEmpty(info.SeriesTimerId))
|
||||
{
|
||||
var timer = await liveTv.GetSeriesTimer(dto.SeriesTimerId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (timer != null)
|
||||
{
|
||||
info.SeriesTimerId = timer.ExternalId;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
@@ -371,29 +410,38 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
Priority = dto.Priority,
|
||||
RecordAnyChannel = dto.RecordAnyChannel,
|
||||
RecordAnyTime = dto.RecordAnyTime,
|
||||
RecordNewOnly = dto.RecordNewOnly
|
||||
RecordNewOnly = dto.RecordNewOnly,
|
||||
ProgramId = dto.ExternalProgramId,
|
||||
ChannelId = dto.ExternalChannelId,
|
||||
Id = dto.ExternalId
|
||||
};
|
||||
|
||||
// Convert internal server id's to external tv provider id's
|
||||
if (!isNew && !string.IsNullOrEmpty(dto.Id))
|
||||
if (!isNew && !string.IsNullOrEmpty(dto.Id) && string.IsNullOrEmpty(info.Id))
|
||||
{
|
||||
var timer = await liveTv.GetSeriesTimer(dto.Id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.Id = timer.ExternalId;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.ChannelId))
|
||||
if (!string.IsNullOrEmpty(dto.ChannelId) && string.IsNullOrEmpty(info.ChannelId))
|
||||
{
|
||||
var channel = await liveTv.GetChannel(dto.ChannelId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.ChannelId = channel.ExternalId;
|
||||
if (channel != null)
|
||||
{
|
||||
info.ChannelId = channel.ExternalId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.ProgramId))
|
||||
if (!string.IsNullOrEmpty(dto.ProgramId) && string.IsNullOrEmpty(info.ProgramId))
|
||||
{
|
||||
var program = await liveTv.GetProgram(dto.ProgramId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
info.ProgramId = program.ExternalId;
|
||||
if (program != null)
|
||||
{
|
||||
info.ProgramId = program.ExternalId;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
|
||||
private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
|
||||
|
||||
private List<Channel> _channels = new List<Channel>();
|
||||
private List<LiveTvChannel> _channels = new List<LiveTvChannel>();
|
||||
private List<ProgramInfoDto> _programs = new List<ProgramInfoDto>();
|
||||
|
||||
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, ILocalizationManager localization, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager)
|
||||
@@ -77,18 +77,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
|
||||
IEnumerable<Channel> channels = _channels;
|
||||
IEnumerable<LiveTvChannel> channels = _channels;
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
channels = channels.Where(i => i.IsParentalAllowed(user, _localization))
|
||||
channels = channels
|
||||
.Where(i => i.IsParentalAllowed(user, _localization))
|
||||
.OrderBy(i =>
|
||||
{
|
||||
double number = 0;
|
||||
|
||||
if (!string.IsNullOrEmpty(i.ChannelNumber))
|
||||
if (!string.IsNullOrEmpty(i.ChannelInfo.Number))
|
||||
{
|
||||
double.TryParse(i.ChannelNumber, out number);
|
||||
double.TryParse(i.ChannelInfo.Number, out number);
|
||||
}
|
||||
|
||||
return number;
|
||||
@@ -100,9 +101,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
double number = 0;
|
||||
|
||||
if (!string.IsNullOrEmpty(i.ChannelNumber))
|
||||
if (!string.IsNullOrEmpty(i.ChannelInfo.Number))
|
||||
{
|
||||
double.TryParse(i.ChannelNumber, out number);
|
||||
double.TryParse(i.ChannelInfo.Number, out number);
|
||||
}
|
||||
|
||||
return number;
|
||||
@@ -120,14 +121,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public Channel GetChannel(string id)
|
||||
public LiveTvChannel GetInternalChannel(string id)
|
||||
{
|
||||
var guid = new Guid(id);
|
||||
|
||||
return _channels.FirstOrDefault(i => i.Id == guid);
|
||||
}
|
||||
|
||||
private async Task<Channel> GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken)
|
||||
public async Task<LiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken)
|
||||
{
|
||||
var service = ActiveService;
|
||||
|
||||
var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var recording = recordings.FirstOrDefault(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id));
|
||||
|
||||
return await GetRecording(recording, service.Name, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(serviceName), _fileSystem.GetValidFilename(channelInfo.Name));
|
||||
|
||||
@@ -150,26 +162,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
|
||||
var id = _tvDtoService.GetInternalChannelId(serviceName, channelInfo.Id, channelInfo.Name);
|
||||
|
||||
var item = _itemRepo.RetrieveItem(id) as Channel;
|
||||
var item = _itemRepo.RetrieveItem(id) as LiveTvChannel;
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
item = new Channel
|
||||
item = new LiveTvChannel
|
||||
{
|
||||
Name = channelInfo.Name,
|
||||
Id = id,
|
||||
DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo),
|
||||
DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo),
|
||||
Path = path,
|
||||
ChannelId = channelInfo.Id,
|
||||
ChannelNumber = channelInfo.Number,
|
||||
ServiceName = serviceName,
|
||||
HasProviderImage = channelInfo.HasImage
|
||||
Path = path
|
||||
};
|
||||
|
||||
isNew = true;
|
||||
}
|
||||
|
||||
item.ChannelInfo = channelInfo;
|
||||
item.ServiceName = serviceName;
|
||||
|
||||
// Set this now so we don't cause additional file system access during provider executions
|
||||
item.ResetResolveArgs(fileInfo);
|
||||
|
||||
@@ -178,6 +189,35 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return item;
|
||||
}
|
||||
|
||||
private async Task<LiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var isNew = false;
|
||||
|
||||
var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);
|
||||
|
||||
var item = _itemRepo.RetrieveItem(id) as LiveTvRecording;
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
item = new LiveTvRecording
|
||||
{
|
||||
Name = info.Name,
|
||||
Id = id,
|
||||
DateCreated = DateTime.UtcNow,
|
||||
DateModified = DateTime.UtcNow
|
||||
};
|
||||
|
||||
isNew = true;
|
||||
}
|
||||
|
||||
item.RecordingInfo = info;
|
||||
item.ServiceName = serviceName;
|
||||
|
||||
await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public Task<ProgramInfoDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
|
||||
{
|
||||
var program = _programs.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
|
||||
@@ -225,7 +265,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
var allChannels = await GetChannels(service, cancellationToken).ConfigureAwait(false);
|
||||
var allChannelsList = allChannels.ToList();
|
||||
|
||||
var list = new List<Channel>();
|
||||
var list = new List<LiveTvChannel>();
|
||||
var programs = new List<ProgramInfoDto>();
|
||||
|
||||
var numComplete = 0;
|
||||
@@ -271,26 +311,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
|
||||
public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var service = ActiveService;
|
||||
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
|
||||
var list = new List<RecordingInfoDto>();
|
||||
var list = new List<RecordingInfo>();
|
||||
|
||||
if (ActiveService != null)
|
||||
{
|
||||
var recordings = await ActiveService.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var dtos = recordings.Select(i => _tvDtoService.GetRecordingInfoDto(i, ActiveService, user));
|
||||
|
||||
list.AddRange(dtos);
|
||||
}
|
||||
var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
|
||||
list.AddRange(recordings);
|
||||
|
||||
if (!string.IsNullOrEmpty(query.ChannelId))
|
||||
{
|
||||
list = list.Where(i => string.Equals(i.ChannelId, query.ChannelId))
|
||||
list = list
|
||||
.Where(i => _tvDtoService.GetInternalChannelId(service.Name, i.ChannelId, i.ChannelName) == new Guid(query.ChannelId))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
var returnArray = list.OrderByDescending(i => i.StartDate)
|
||||
if (!string.IsNullOrEmpty(query.Id))
|
||||
{
|
||||
list = list
|
||||
.Where(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(query.Id))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
var entities = await GetEntities(list, service.Name, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var returnArray = entities
|
||||
.Select(i => _tvDtoService.GetRecordingInfoDto(i, ActiveService, user))
|
||||
.OrderByDescending(i => i.StartDate)
|
||||
.ToArray();
|
||||
|
||||
return new QueryResult<RecordingInfoDto>
|
||||
@@ -300,6 +348,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
};
|
||||
}
|
||||
|
||||
private Task<LiveTvRecording[]> GetEntities(IEnumerable<RecordingInfo> recordings, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var tasks = recordings.Select(i => GetRecording(i, serviceName, cancellationToken));
|
||||
|
||||
return Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private IEnumerable<ILiveTvService> GetServices(string serviceName, string channelId)
|
||||
{
|
||||
IEnumerable<ILiveTvService> services = _services;
|
||||
@@ -404,11 +459,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
var results = await GetRecordings(new RecordingQuery
|
||||
{
|
||||
UserId = user == null ? null : user.Id.ToString("N")
|
||||
UserId = user == null ? null : user.Id.ToString("N"),
|
||||
Id = id
|
||||
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture));
|
||||
return results.Items.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken)
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
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;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
public class ProgramImageProvider : BaseMetadataProvider
|
||||
{
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public ProgramImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem, IHttpClient httpClient)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_liveTvManager = liveTvManager;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is LiveTvProgram;
|
||||
}
|
||||
|
||||
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
|
||||
{
|
||||
return !item.HasImage(ImageType.Primary);
|
||||
}
|
||||
|
||||
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
if (item.HasImage(ImageType.Primary))
|
||||
{
|
||||
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await DownloadImage((LiveTvProgram)item, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
// Don't fail the provider on a 404
|
||||
if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task DownloadImage(LiveTvProgram item, CancellationToken cancellationToken)
|
||||
{
|
||||
var programInfo = item.ProgramInfo;
|
||||
|
||||
Stream imageStream = null;
|
||||
string contentType = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(programInfo.ImagePath))
|
||||
{
|
||||
contentType = "image/" + Path.GetExtension(programInfo.ImagePath).ToLower();
|
||||
imageStream = _fileSystem.GetFileStream(programInfo.ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(programInfo.ImageUrl))
|
||||
{
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = programInfo.ImageUrl
|
||||
};
|
||||
|
||||
var response = await _httpClient.GetResponse(options).ConfigureAwait(false);
|
||||
|
||||
if (!response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException("Provider did not return an image content type.");
|
||||
}
|
||||
|
||||
imageStream = response.Content;
|
||||
contentType = response.ContentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, item.ServiceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (service != null)
|
||||
{
|
||||
var response = await service.GetProgramImageAsync(programInfo.Id, programInfo.ChannelId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
imageStream = response.Stream;
|
||||
contentType = response.MimeType;
|
||||
}
|
||||
}
|
||||
|
||||
if (imageStream != null)
|
||||
{
|
||||
// Dummy up the original url
|
||||
var url = item.ServiceName + programInfo.Id;
|
||||
|
||||
await _providerManager.SaveImage(item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override MetadataProviderPriority Priority
|
||||
{
|
||||
get { return MetadataProviderPriority.Second; }
|
||||
}
|
||||
|
||||
public override ItemUpdateType ItemUpdateType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ItemUpdateType.ImageUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
public class RecordingImageProvider : BaseMetadataProvider
|
||||
{
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IHttpClient _httpClient;
|
||||
|
||||
public RecordingImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem, IHttpClient httpClient)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_liveTvManager = liveTvManager;
|
||||
_providerManager = providerManager;
|
||||
_fileSystem = fileSystem;
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is LiveTvRecording;
|
||||
}
|
||||
|
||||
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
|
||||
{
|
||||
return !item.HasImage(ImageType.Primary);
|
||||
}
|
||||
|
||||
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
if (item.HasImage(ImageType.Primary))
|
||||
{
|
||||
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await DownloadImage((LiveTvRecording)item, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
// Don't fail the provider on a 404
|
||||
if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task DownloadImage(LiveTvRecording item, CancellationToken cancellationToken)
|
||||
{
|
||||
var recordingInfo = item.RecordingInfo;
|
||||
|
||||
Stream imageStream = null;
|
||||
string contentType = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(recordingInfo.ImagePath))
|
||||
{
|
||||
contentType = "image/" + Path.GetExtension(recordingInfo.ImagePath).ToLower();
|
||||
imageStream = _fileSystem.GetFileStream(recordingInfo.ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(recordingInfo.ImageUrl))
|
||||
{
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = recordingInfo.ImageUrl
|
||||
};
|
||||
|
||||
var response = await _httpClient.GetResponse(options).ConfigureAwait(false);
|
||||
|
||||
if (!response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException("Provider did not return an image content type.");
|
||||
}
|
||||
|
||||
imageStream = response.Content;
|
||||
contentType = response.ContentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, item.ServiceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (service != null)
|
||||
{
|
||||
var response = await service.GetRecordingImageAsync(recordingInfo.Id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
imageStream = response.Stream;
|
||||
contentType = response.MimeType;
|
||||
}
|
||||
}
|
||||
|
||||
if (imageStream != null)
|
||||
{
|
||||
// Dummy up the original url
|
||||
var url = item.ServiceName + recordingInfo.Id;
|
||||
|
||||
await _providerManager.SaveImage(item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override MetadataProviderPriority Priority
|
||||
{
|
||||
get { return MetadataProviderPriority.Second; }
|
||||
}
|
||||
|
||||
public override ItemUpdateType ItemUpdateType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ItemUpdateType.ImageUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user