|
|
|
@ -4,7 +4,6 @@ using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
@ -19,7 +18,6 @@ using MediaBrowser.Model.Cryptography;
|
|
|
|
|
using MediaBrowser.Model.Dto;
|
|
|
|
|
using MediaBrowser.Model.Entities;
|
|
|
|
|
using MediaBrowser.Model.LiveTv;
|
|
|
|
|
using MediaBrowser.Model.Net;
|
|
|
|
|
using MediaBrowser.Model.Serialization;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
|
|
|
@ -36,6 +34,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
private readonly IApplicationHost _appHost;
|
|
|
|
|
private readonly ICryptoProvider _cryptoProvider;
|
|
|
|
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, NameValuePair> _tokens = new ConcurrentDictionary<string, NameValuePair>();
|
|
|
|
|
private DateTime _lastErrorResponse;
|
|
|
|
|
|
|
|
|
|
public SchedulesDirect(
|
|
|
|
|
ILogger<SchedulesDirect> logger,
|
|
|
|
|
IJsonSerializer jsonSerializer,
|
|
|
|
@ -50,8 +51,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
_cryptoProvider = cryptoProvider;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string UserAgent => _appHost.ApplicationUserAgent;
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public string Name => "Schedules Direct";
|
|
|
|
|
|
|
|
|
@ -307,7 +306,8 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
|
|
|
|
|
if (details.contentRating != null && details.contentRating.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
info.OfficialRating = details.contentRating[0].code.Replace("TV", "TV-").Replace("--", "-");
|
|
|
|
|
info.OfficialRating = details.contentRating[0].code.Replace("TV", "TV-", StringComparison.Ordinal)
|
|
|
|
|
.Replace("--", "-", StringComparison.Ordinal);
|
|
|
|
|
|
|
|
|
|
var invalid = new[] { "N/A", "Approved", "Not Rated", "Passed" };
|
|
|
|
|
if (invalid.Contains(info.OfficialRating, StringComparer.OrdinalIgnoreCase))
|
|
|
|
@ -450,7 +450,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
|
|
|
|
|
private async Task<List<ScheduleDirect.ShowImages>> GetImageForPrograms(
|
|
|
|
|
ListingsProviderInfo info,
|
|
|
|
|
List<string> programIds,
|
|
|
|
|
IReadOnlyList<string> programIds,
|
|
|
|
|
CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
if (programIds.Count == 0)
|
|
|
|
@ -458,23 +458,21 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
return new List<ScheduleDirect.ShowImages>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var imageIdString = "[";
|
|
|
|
|
|
|
|
|
|
foreach (var i in programIds)
|
|
|
|
|
StringBuilder str = new StringBuilder("[", 1 + (programIds.Count * 13));
|
|
|
|
|
foreach (ReadOnlySpan<char> i in programIds)
|
|
|
|
|
{
|
|
|
|
|
var imageId = i.Substring(0, 10);
|
|
|
|
|
|
|
|
|
|
if (!imageIdString.Contains(imageId, StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
imageIdString += "\"" + imageId + "\",";
|
|
|
|
|
}
|
|
|
|
|
str.Append('"')
|
|
|
|
|
.Append(i.Slice(0, 10))
|
|
|
|
|
.Append("\",");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imageIdString = imageIdString.TrimEnd(',') + "]";
|
|
|
|
|
// Remove last ,
|
|
|
|
|
str.Length--;
|
|
|
|
|
str.Append(']');
|
|
|
|
|
|
|
|
|
|
using var message = new HttpRequestMessage(HttpMethod.Post, ApiUrl + "/metadata/programs")
|
|
|
|
|
{
|
|
|
|
|
Content = new StringContent(imageIdString, Encoding.UTF8, MediaTypeNames.Application.Json)
|
|
|
|
|
Content = new StringContent(str.ToString(), Encoding.UTF8, MediaTypeNames.Application.Json)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
@ -539,9 +537,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
return lineups;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, NameValuePair> _tokens = new ConcurrentDictionary<string, NameValuePair>();
|
|
|
|
|
private DateTime _lastErrorResponse;
|
|
|
|
|
|
|
|
|
|
private async Task<string> GetToken(ListingsProviderInfo info, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
var username = info.Username;
|
|
|
|
@ -564,8 +559,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NameValuePair savedToken;
|
|
|
|
|
if (!_tokens.TryGetValue(username, out savedToken))
|
|
|
|
|
if (!_tokens.TryGetValue(username, out NameValuePair savedToken))
|
|
|
|
|
{
|
|
|
|
|
savedToken = new NameValuePair();
|
|
|
|
|
_tokens.TryAdd(username, savedToken);
|
|
|
|
@ -653,7 +647,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
|
|
|
|
|
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
|
|
|
|
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(stream).ConfigureAwait(false);
|
|
|
|
|
if (root.message == "OK")
|
|
|
|
|
if (string.Equals(root.message, "OK", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("Authenticated with Schedules Direct token: " + root.token);
|
|
|
|
|
return root.token;
|
|
|
|
@ -777,24 +771,28 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
using var options = new HttpRequestMessage(HttpMethod.Get, ApiUrl + "/lineups/" + listingsId);
|
|
|
|
|
options.Headers.TryAddWithoutValidation("token", token);
|
|
|
|
|
|
|
|
|
|
var list = new List<ChannelInfo>();
|
|
|
|
|
|
|
|
|
|
using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
|
|
|
|
|
await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
|
|
|
|
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(stream).ConfigureAwait(false);
|
|
|
|
|
_logger.LogInformation("Found {ChannelCount} channels on the lineup on ScheduleDirect", root.map.Count);
|
|
|
|
|
_logger.LogInformation("Mapping Stations to Channel");
|
|
|
|
|
|
|
|
|
|
var allStations = root.stations ?? Enumerable.Empty<ScheduleDirect.Station>();
|
|
|
|
|
var allStations = root.stations ?? new List<ScheduleDirect.Station>();
|
|
|
|
|
|
|
|
|
|
foreach (ScheduleDirect.Map map in root.map)
|
|
|
|
|
var map = root.map;
|
|
|
|
|
int len = map.Count;
|
|
|
|
|
var array = new List<ChannelInfo>(len);
|
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
var channelNumber = GetChannelNumber(map);
|
|
|
|
|
var channelNumber = GetChannelNumber(map[i]);
|
|
|
|
|
|
|
|
|
|
var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
var station = allStations.Find(item => string.Equals(item.stationID, map[i].stationID, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
if (station == null)
|
|
|
|
|
{
|
|
|
|
|
station = new ScheduleDirect.Station { stationID = map.stationID };
|
|
|
|
|
station = new ScheduleDirect.Station
|
|
|
|
|
{
|
|
|
|
|
stationID = map[i].stationID
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var channelInfo = new ChannelInfo
|
|
|
|
@ -810,32 +808,10 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
channelInfo.ImageUrl = station.logo.URL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list.Add(channelInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ScheduleDirect.Station GetStation(List<ScheduleDirect.Station> allStations, string channelNumber, string channelName)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(channelName))
|
|
|
|
|
{
|
|
|
|
|
channelName = NormalizeName(channelName);
|
|
|
|
|
|
|
|
|
|
var result = allStations.FirstOrDefault(i => string.Equals(NormalizeName(i.callsign ?? string.Empty), channelName, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
|
|
|
|
if (result != null)
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(channelNumber))
|
|
|
|
|
{
|
|
|
|
|
return allStations.FirstOrDefault(i => string.Equals(NormalizeName(i.stationID ?? string.Empty), channelNumber, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
array[i] = channelInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
return array;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string NormalizeName(string value)
|
|
|
|
@ -1044,7 +1020,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
public class Title
|
|
|
|
|
{
|
|
|
|
|
public string title120 { get; set; }
|
|
|
|
|