|
@@ -26,6 +26,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
|
|
|
|
|
|
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
|
|
|
{
|
|
|
+ channelNumber = NormalizeNumber(channelNumber);
|
|
|
+
|
|
|
var url = "https://data.emby.media/service/listings?id=" + info.ListingsId;
|
|
|
|
|
|
// Normalize
|
|
@@ -36,8 +38,100 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
|
|
|
url += "&end=" + endDateUtc.ToString("s", CultureInfo.InvariantCulture) + "Z";
|
|
|
|
|
|
var response = await GetResponse<ListingInfo[]>(url).ConfigureAwait(false);
|
|
|
-
|
|
|
- return new List<ProgramInfo>();
|
|
|
+
|
|
|
+ return response.Where(i => IncludeInResults(i, channelNumber)).Select(GetProgramInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ProgramInfo GetProgramInfo(ListingInfo info)
|
|
|
+ {
|
|
|
+ var showType = info.showType ?? string.Empty;
|
|
|
+
|
|
|
+ var program = new ProgramInfo
|
|
|
+ {
|
|
|
+ Id = info.listingID.ToString(CultureInfo.InvariantCulture),
|
|
|
+ Name = GetStringValue(info.showName),
|
|
|
+ EpisodeTitle = GetStringValue(info.episodeTitle),
|
|
|
+ HomePageUrl = GetStringValue(info.webLink),
|
|
|
+ Overview = info.description,
|
|
|
+ IsHD = info.hd,
|
|
|
+ IsLive = info.live,
|
|
|
+ IsPremiere = info.seasonPremiere || info.seriesPremiere,
|
|
|
+ IsMovie = showType.IndexOf("Movie", StringComparison.OrdinalIgnoreCase) != -1,
|
|
|
+ IsKids = showType.IndexOf("Children", StringComparison.OrdinalIgnoreCase) != -1,
|
|
|
+ IsNews = showType.IndexOf("News", StringComparison.OrdinalIgnoreCase) != -1,
|
|
|
+ IsSports = showType.IndexOf("Sports", StringComparison.OrdinalIgnoreCase) != -1
|
|
|
+ };
|
|
|
+
|
|
|
+ if (!string.IsNullOrWhiteSpace(info.listDateTime))
|
|
|
+ {
|
|
|
+ program.StartDate = DateTime.ParseExact(info.listDateTime, "yyyy'-'MM'-'dd' 'HH':'mm':'ss", CultureInfo.InvariantCulture);
|
|
|
+ program.EndDate = program.StartDate.AddMinutes(info.duration);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info.starRating > 0)
|
|
|
+ {
|
|
|
+ program.CommunityRating = info.starRating*2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!string.IsNullOrWhiteSpace(info.rating))
|
|
|
+ {
|
|
|
+ // They don't have dashes so try to normalize
|
|
|
+ program.OfficialRating = info.rating.Replace("TV", "TV-").Replace("--", "-");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!string.IsNullOrWhiteSpace(info.year))
|
|
|
+ {
|
|
|
+ program.ProductionYear = int.Parse(info.year, CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info.showID > 0)
|
|
|
+ {
|
|
|
+ program.ShowId = info.showID.ToString(CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info.seriesID > 0)
|
|
|
+ {
|
|
|
+ program.SeriesId = info.seriesID.ToString(CultureInfo.InvariantCulture);
|
|
|
+ program.IsSeries = true;
|
|
|
+ program.IsRepeat = info.repeat;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info.starRating > 0)
|
|
|
+ {
|
|
|
+ program.CommunityRating = info.starRating * 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (string.Equals(info.showName, "Movie", StringComparison.OrdinalIgnoreCase))
|
|
|
+ {
|
|
|
+ // Sometimes the movie title will be in here
|
|
|
+ if (!string.IsNullOrWhiteSpace(info.episodeTitle))
|
|
|
+ {
|
|
|
+ program.Name = info.episodeTitle;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return program;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetStringValue(string s)
|
|
|
+ {
|
|
|
+ return string.IsNullOrWhiteSpace(s) ? null : s;
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool IncludeInResults(ListingInfo info, string itemNumber)
|
|
|
+ {
|
|
|
+ if (string.Equals(itemNumber, NormalizeNumber(info.number), StringComparison.OrdinalIgnoreCase))
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ var channelNumber = info.channelNumber.ToString(CultureInfo.InvariantCulture);
|
|
|
+ if (info.subChannelNumber > 0)
|
|
|
+ {
|
|
|
+ channelNumber += "." + info.subChannelNumber.ToString(CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+
|
|
|
+ return string.Equals(channelNumber, itemNumber, StringComparison.OrdinalIgnoreCase);
|
|
|
}
|
|
|
|
|
|
public async Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken)
|
|
@@ -48,18 +142,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
|
|
|
{
|
|
|
var station = response.stations.FirstOrDefault(i =>
|
|
|
{
|
|
|
+ var itemNumber = NormalizeNumber(channel.Number);
|
|
|
+
|
|
|
+ if (string.Equals(itemNumber, NormalizeNumber(i.number), StringComparison.OrdinalIgnoreCase))
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
var channelNumber = i.channelNumber.ToString(CultureInfo.InvariantCulture);
|
|
|
if (i.subChannelNumber > 0)
|
|
|
{
|
|
|
channelNumber += "." + i.subChannelNumber.ToString(CultureInfo.InvariantCulture);
|
|
|
}
|
|
|
|
|
|
- return string.Equals(channelNumber, channel.Number, StringComparison.OrdinalIgnoreCase);
|
|
|
+ return string.Equals(channelNumber, itemNumber, StringComparison.OrdinalIgnoreCase);
|
|
|
});
|
|
|
|
|
|
if (station != null)
|
|
|
{
|
|
|
- channel.Name = station.name;
|
|
|
+ //channel.Name = station.name;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(station.logoFilename))
|
|
|
{
|
|
@@ -70,6 +171,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private string NormalizeNumber(string number)
|
|
|
+ {
|
|
|
+ return number.Replace('-', '.');
|
|
|
+ }
|
|
|
+
|
|
|
public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings)
|
|
|
{
|
|
|
return Task.FromResult(true);
|
|
@@ -108,7 +214,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
|
|
|
return name;
|
|
|
}
|
|
|
|
|
|
- private async Task<T> GetResponse<T>(string url)
|
|
|
+ private async Task<T> GetResponse<T>(string url, Func<string, string> filter = null)
|
|
|
where T : class
|
|
|
{
|
|
|
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
|
@@ -131,12 +237,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
|
|
|
|
|
|
}).ConfigureAwait(false))
|
|
|
{
|
|
|
- return _jsonSerializer.DeserializeFromStream<T>(secondStream);
|
|
|
+ return ParseResponse<T>(secondStream, filter);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private T ParseResponse<T>(Stream response, Func<string,string> filter)
|
|
|
+ {
|
|
|
+ using (var reader = new StreamReader(response))
|
|
|
+ {
|
|
|
+ var json = reader.ReadToEnd();
|
|
|
+
|
|
|
+ if (filter != null)
|
|
|
+ {
|
|
|
+ json = filter(json);
|
|
|
+ }
|
|
|
+
|
|
|
+ return _jsonSerializer.DeserializeFromString<T>(json);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private class LineupInfo
|
|
|
{
|
|
|
public string lineupID { get; set; }
|