diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
index 36f082b02c..3f8fc639f1 100644
--- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
@@ -150,7 +150,22 @@ namespace MediaBrowser.Controller.LiveTv
///
/// The production year.
public int? ProductionYear { get; set; }
-
+ ///
+ /// Gets or sets the home page URL.
+ ///
+ /// The home page URL.
+ public string HomePageUrl { get; set; }
+ ///
+ /// Gets or sets the series identifier.
+ ///
+ /// The series identifier.
+ public string SeriesId { get; set; }
+ ///
+ /// Gets or sets the show identifier.
+ ///
+ /// The show identifier.
+ public string ShowId { get; set; }
+
public ProgramInfo()
{
Genres = new List();
diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
index e5817d390d..42064cf50d 100644
--- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
@@ -185,7 +185,11 @@ namespace MediaBrowser.Controller.LiveTv
///
/// null if [has image] contains no value, true if [has image]; otherwise, false.
public bool? HasImage { get; set; }
-
+ ///
+ /// Gets or sets the show identifier.
+ ///
+ /// The show identifier.
+ public string ShowId { get; set; }
public RecordingInfo()
{
diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs
index 1be6549ff8..2d79473f00 100644
--- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs
@@ -94,6 +94,12 @@ namespace MediaBrowser.Controller.LiveTv
///
/// true if this instance is post padding required; otherwise, false.
public bool IsPostPaddingRequired { get; set; }
+
+ ///
+ /// Gets or sets the series identifier.
+ ///
+ /// The series identifier.
+ public string SeriesId { get; set; }
public SeriesTimerInfo()
{
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index c90b9eacb8..cf294997b7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -295,6 +295,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
RecordAnyTime = false,
RecordNewOnly = false
};
+
+ if (program != null)
+ {
+ defaults.SeriesId = program.SeriesId;
+ defaults.ProgramId = program.Id;
+ }
+
return Task.FromResult(defaults);
}
@@ -515,8 +522,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
OriginalAirDate = info.OriginalAirDate,
Status = RecordingStatus.Scheduled,
Overview = info.Overview,
- SeriesTimerId = info.Id.Substring(0, 10),
- TimerId = timer.Id
+ SeriesTimerId = timer.SeriesTimerId,
+ TimerId = timer.Id,
+ ShowId = info.ShowId
};
_recordingProvider.Add(recording);
}
@@ -624,7 +632,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
allPrograms = GetProgramsForSeries(seriesTimer, allPrograms);
- allPrograms = allPrograms.Where(epg => currentRecordings.All(r => r.ProgramId.Substring(0, 14) != epg.Id.Substring(0, 14))); //filtered recordings already running
+ var recordingShowIds = currentRecordings.Select(i => i.ShowId).ToList();
+
+ allPrograms = allPrograms.Where(epg => !recordingShowIds.Contains(epg.ShowId, StringComparer.OrdinalIgnoreCase));
return allPrograms.Select(i => RecordingHelper.CreateTimer(i, seriesTimer));
}
@@ -638,7 +648,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
if (seriesTimer.RecordNewOnly)
{
- allPrograms = allPrograms.Where(epg => !epg.IsRepeat); //Filtered by New only
+ allPrograms = allPrograms.Where(epg => !epg.IsRepeat);
}
if (!seriesTimer.RecordAnyChannel)
@@ -648,8 +658,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
allPrograms = allPrograms.Where(epg => seriesTimer.Days.Contains(epg.StartDate.DayOfWeek));
- // TODO: This assumption will require review once additional listing providers are added
- return allPrograms.Where(epg => epg.Id.StartsWith(seriesTimer.ProgramId, StringComparison.OrdinalIgnoreCase));
+ return allPrograms.Where(epg => string.Equals(epg.SeriesId, seriesTimer.SeriesId, StringComparison.OrdinalIgnoreCase));
}
private string GetChannelEpgCachePath(string channelId)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs
index 641505e381..6c1cc5506f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs
@@ -26,6 +26,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby
public async Task> 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(url).ConfigureAwait(false);
-
- return new List();
+
+ 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 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 GetResponse(string url)
+ private async Task GetResponse(string url, Func 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(secondStream);
+ return ParseResponse(secondStream, filter);
}
}
}
}
+ private T ParseResponse(Stream response, Func filter)
+ {
+ using (var reader = new StreamReader(response))
+ {
+ var json = reader.ReadToEnd();
+
+ if (filter != null)
+ {
+ json = filter(json);
+ }
+
+ return _jsonSerializer.DeserializeFromString(json);
+ }
+ }
+
private class LineupInfo
{
public string lineupID { get; set; }
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 02ca7f0f6d..331f421851 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -622,6 +622,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.ProviderImageUrl = info.ImageUrl;
item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks;
item.StartDate = info.StartDate;
+ item.HomePageUrl = info.HomePageUrl;
item.ProductionYear = info.ProductionYear;
item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate;