Clean up HttpClientManager, LiveTvManager and InstallationManager
This commit is contained in:
parent
0cafd7dfef
commit
a1b96a3135
|
@ -640,15 +640,14 @@ namespace Emby.Server.Implementations
|
||||||
/// Gets the exports.
|
/// Gets the exports.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="manageLiftime">if set to <c>true</c> [manage liftime].</param>
|
/// <param name="manageLifetime">if set to <c>true</c> [manage lifetime].</param>
|
||||||
/// <returns>IEnumerable{``0}.</returns>
|
/// <returns>IEnumerable{``0}.</returns>
|
||||||
public IEnumerable<T> GetExports<T>(bool manageLifetime = true)
|
public IEnumerable<T> GetExports<T>(bool manageLifetime = true)
|
||||||
{
|
{
|
||||||
var parts = GetExportTypes<T>()
|
var parts = GetExportTypes<T>()
|
||||||
.Select(CreateInstanceSafe)
|
.Select(CreateInstanceSafe)
|
||||||
.Where(i => i != null)
|
.Where(i => i != null)
|
||||||
.Cast<T>()
|
.Cast<T>();
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (manageLifetime)
|
if (manageLifetime)
|
||||||
{
|
{
|
||||||
|
@ -703,7 +702,7 @@ namespace Emby.Server.Implementations
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs the startup tasks.
|
/// Runs the startup tasks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task RunStartupTasks()
|
public Task RunStartupTasks()
|
||||||
{
|
{
|
||||||
Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
|
Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false));
|
||||||
|
|
||||||
|
@ -736,6 +735,8 @@ namespace Emby.Server.Implementations
|
||||||
Logger.LogInformation("All entry points have started");
|
Logger.LogInformation("All entry points have started");
|
||||||
|
|
||||||
//LoggerFactory.RemoveConsoleOutput();
|
//LoggerFactory.RemoveConsoleOutput();
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RunEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup)
|
private void RunEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup)
|
||||||
|
|
|
@ -5,18 +5,15 @@ using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Emby.Server.Implementations.IO;
|
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using MediaBrowser.Controller.IO;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.HttpClientManager
|
namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
|
@ -136,9 +133,8 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = CreateWebRequest(url);
|
var request = CreateWebRequest(url);
|
||||||
var httpWebRequest = request as HttpWebRequest;
|
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
if (request is HttpWebRequest httpWebRequest)
|
||||||
{
|
{
|
||||||
AddRequestHeaders(httpWebRequest, options);
|
AddRequestHeaders(httpWebRequest, options);
|
||||||
|
|
||||||
|
@ -159,25 +155,12 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
httpWebRequest.AutomaticDecompression = DecompressionMethods.None;
|
httpWebRequest.AutomaticDecompression = DecompressionMethods.None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
|
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
|
||||||
{
|
|
||||||
if (options.EnableKeepAlive)
|
if (options.EnableKeepAlive)
|
||||||
{
|
{
|
||||||
httpWebRequest.KeepAlive = true;
|
httpWebRequest.KeepAlive = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
request.Method = method;
|
|
||||||
request.Timeout = options.TimeoutMs;
|
|
||||||
|
|
||||||
if (httpWebRequest != null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(options.Host))
|
if (!string.IsNullOrEmpty(options.Host))
|
||||||
{
|
{
|
||||||
httpWebRequest.Host = options.Host;
|
httpWebRequest.Host = options.Host;
|
||||||
|
@ -189,6 +172,11 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
|
||||||
|
|
||||||
|
request.Method = method;
|
||||||
|
request.Timeout = options.TimeoutMs;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(userInfo))
|
if (!string.IsNullOrWhiteSpace(userInfo))
|
||||||
{
|
{
|
||||||
var parts = userInfo.Split(':');
|
var parts = userInfo.Split(':');
|
||||||
|
@ -215,7 +203,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
var hasUserAgent = false;
|
var hasUserAgent = false;
|
||||||
|
|
||||||
foreach (var header in options.RequestHeaders.ToList())
|
foreach (var header in options.RequestHeaders)
|
||||||
{
|
{
|
||||||
if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -340,8 +328,8 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(responseCachePath));
|
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(responseCachePath));
|
||||||
|
|
||||||
using (var responseStream = response.Content)
|
using (var responseStream = response.Content)
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
{
|
{
|
||||||
var memoryStream = new MemoryStream();
|
|
||||||
await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||||
memoryStream.Position = 0;
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
@ -379,10 +367,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO: We can always put this in the options object if needed
|
var bytes = options.RequestContentBytes ?? Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty);
|
||||||
var requestEncoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
var bytes = options.RequestContentBytes ?? requestEncoding.GetBytes(options.RequestContent ?? string.Empty);
|
|
||||||
|
|
||||||
var contentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
|
var contentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
|
@ -392,7 +377,6 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
|
|
||||||
httpWebRequest.ContentType = contentType;
|
httpWebRequest.ContentType = contentType;
|
||||||
|
|
||||||
httpWebRequest.ContentLength = bytes.Length;
|
httpWebRequest.ContentLength = bytes.Length;
|
||||||
(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)).Write(bytes, 0, bytes.Length);
|
(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)).Write(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
@ -409,10 +393,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
|
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < TimeoutSeconds)
|
||||||
{
|
{
|
||||||
if (options.ResourcePool != null)
|
options.ResourcePool?.Release();
|
||||||
{
|
|
||||||
options.ResourcePool.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
||||||
}
|
}
|
||||||
|
@ -455,9 +436,8 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
options.CancellationToken.ThrowIfCancellationRequested();
|
options.CancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (var stream = httpResponse.GetResponseStream())
|
using (var stream = httpResponse.GetResponseStream())
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
{
|
{
|
||||||
var memoryStream = new MemoryStream();
|
|
||||||
|
|
||||||
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||||
|
|
||||||
memoryStream.Position = 0;
|
memoryStream.Position = 0;
|
||||||
|
@ -476,10 +456,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (options.ResourcePool != null)
|
options.ResourcePool?.Release();
|
||||||
{
|
|
||||||
options.ResourcePool.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,13 +465,9 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
var responseInfo = new HttpResponseInfo(disposable)
|
var responseInfo = new HttpResponseInfo(disposable)
|
||||||
{
|
{
|
||||||
Content = content,
|
Content = content,
|
||||||
|
|
||||||
StatusCode = httpResponse.StatusCode,
|
StatusCode = httpResponse.StatusCode,
|
||||||
|
|
||||||
ContentType = httpResponse.ContentType,
|
ContentType = httpResponse.ContentType,
|
||||||
|
|
||||||
ContentLength = contentLength,
|
ContentLength = contentLength,
|
||||||
|
|
||||||
ResponseUrl = httpResponse.ResponseUri.ToString()
|
ResponseUrl = httpResponse.ResponseUri.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -511,11 +484,8 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
var responseInfo = new HttpResponseInfo
|
var responseInfo = new HttpResponseInfo
|
||||||
{
|
{
|
||||||
TempFilePath = tempFile,
|
TempFilePath = tempFile,
|
||||||
|
|
||||||
StatusCode = httpResponse.StatusCode,
|
StatusCode = httpResponse.StatusCode,
|
||||||
|
|
||||||
ContentType = httpResponse.ContentType,
|
ContentType = httpResponse.ContentType,
|
||||||
|
|
||||||
ContentLength = contentLength
|
ContentLength = contentLength
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -619,24 +589,22 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
var contentLength = GetContentLength(httpResponse);
|
var contentLength = GetContentLength(httpResponse);
|
||||||
|
|
||||||
if (!contentLength.HasValue)
|
if (contentLength.HasValue)
|
||||||
{
|
|
||||||
// We're not able to track progress
|
|
||||||
using (var stream = httpResponse.GetResponseStream())
|
|
||||||
{
|
|
||||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
|
||||||
{
|
|
||||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
||||||
{
|
{
|
||||||
await httpResponse.GetResponseStream().CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
await httpResponse.GetResponseStream().CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We're not able to track progress
|
||||||
|
using (var stream = httpResponse.GetResponseStream())
|
||||||
|
using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
|
||||||
|
{
|
||||||
|
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options.Progress.Report(100);
|
options.Progress.Report(100);
|
||||||
|
|
||||||
|
@ -650,10 +618,7 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (options.ResourcePool != null)
|
options.ResourcePool?.Release();
|
||||||
{
|
|
||||||
options.ResourcePool.Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,35 +775,38 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
|
var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
|
||||||
|
|
||||||
if (!isSuccessful)
|
if (isSuccessful)
|
||||||
{
|
{
|
||||||
if (options.LogErrorResponseBody)
|
return;
|
||||||
{
|
}
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var stream = response.GetResponseStream())
|
|
||||||
{
|
|
||||||
if (stream != null)
|
|
||||||
{
|
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
var msg = reader.ReadToEnd();
|
|
||||||
|
|
||||||
_logger.LogError(msg);
|
if (options.LogErrorResponseBody)
|
||||||
}
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var stream = response.GetResponseStream())
|
||||||
|
{
|
||||||
|
if (stream != null)
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
var msg = reader.ReadToEnd();
|
||||||
|
|
||||||
|
_logger.LogError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new HttpException(response.StatusDescription)
|
catch
|
||||||
{
|
{
|
||||||
StatusCode = response.StatusCode
|
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new HttpException(response.StatusDescription)
|
||||||
|
{
|
||||||
|
StatusCode = response.StatusCode
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
|
private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
|
||||||
|
@ -859,13 +827,10 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
private static void TimeoutCallback(object state, bool timedOut)
|
private static void TimeoutCallback(object state, bool timedOut)
|
||||||
{
|
{
|
||||||
if (timedOut)
|
if (timedOut && state != null)
|
||||||
{
|
{
|
||||||
WebRequest request = (WebRequest)state;
|
WebRequest request = (WebRequest)state;
|
||||||
if (state != null)
|
request.Abort();
|
||||||
{
|
|
||||||
request.Abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,13 +845,13 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
|
|
||||||
public void OnError(Task<WebResponse> task)
|
public void OnError(Task<WebResponse> task)
|
||||||
{
|
{
|
||||||
if (task.Exception != null)
|
if (task.Exception == null)
|
||||||
{
|
{
|
||||||
taskCompletion.TrySetException(task.Exception);
|
taskCompletion.TrySetException(Enumerable.Empty<Exception>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
taskCompletion.TrySetException(new List<Exception>());
|
taskCompletion.TrySetException(task.Exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,6 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Extensions;
|
using MediaBrowser.Model.Extensions;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv.Listings
|
namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
@ -32,9 +30,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
private const string ApiUrl = "https://json.schedulesdirect.org/20141201";
|
private const string ApiUrl = "https://json.schedulesdirect.org/20141201";
|
||||||
|
|
||||||
private readonly Dictionary<string, Dictionary<string, ScheduleDirect.Station>> _channelPairingCache =
|
|
||||||
new Dictionary<string, Dictionary<string, ScheduleDirect.Station>>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
public SchedulesDirect(ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IApplicationHost appHost)
|
public SchedulesDirect(ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IApplicationHost appHost)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -74,33 +69,29 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
// Normalize incoming input
|
// Normalize incoming input
|
||||||
channelId = channelId.Replace(".json.schedulesdirect.org", string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart('I');
|
channelId = channelId.Replace(".json.schedulesdirect.org", string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart('I');
|
||||||
|
|
||||||
List<ProgramInfo> programsInfo = new List<ProgramInfo>();
|
|
||||||
|
|
||||||
var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
|
var token = await GetToken(info, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(token))
|
if (string.IsNullOrEmpty(token))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("SchedulesDirect token is empty, returning empty program list");
|
_logger.LogWarning("SchedulesDirect token is empty, returning empty program list");
|
||||||
return programsInfo;
|
|
||||||
|
return Enumerable.Empty<ProgramInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var dates = GetScheduleRequestDates(startDateUtc, endDateUtc);
|
var dates = GetScheduleRequestDates(startDateUtc, endDateUtc);
|
||||||
|
|
||||||
string stationID = channelId;
|
_logger.LogInformation("Channel Station ID is: {ChannelID}", channelId);
|
||||||
|
var requestList = new List<ScheduleDirect.RequestScheduleForChannel>()
|
||||||
_logger.LogInformation("Channel Station ID is: " + stationID);
|
{
|
||||||
List<ScheduleDirect.RequestScheduleForChannel> requestList =
|
new ScheduleDirect.RequestScheduleForChannel()
|
||||||
new List<ScheduleDirect.RequestScheduleForChannel>()
|
|
||||||
{
|
{
|
||||||
new ScheduleDirect.RequestScheduleForChannel()
|
stationID = channelId,
|
||||||
{
|
date = dates
|
||||||
stationID = stationID,
|
}
|
||||||
date = dates
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var requestString = _jsonSerializer.SerializeToString(requestList);
|
var requestString = _jsonSerializer.SerializeToString(requestList);
|
||||||
_logger.LogDebug("Request string for schedules is: " + requestString);
|
_logger.LogDebug("Request string for schedules is: {RequestString}", requestString);
|
||||||
|
|
||||||
var httpOptions = new HttpRequestOptions()
|
var httpOptions = new HttpRequestOptions()
|
||||||
{
|
{
|
||||||
|
@ -109,16 +100,17 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
CancellationToken = cancellationToken,
|
CancellationToken = cancellationToken,
|
||||||
// The data can be large so give it some extra time
|
// The data can be large so give it some extra time
|
||||||
TimeoutMs = 60000,
|
TimeoutMs = 60000,
|
||||||
LogErrorResponseBody = true
|
LogErrorResponseBody = true,
|
||||||
|
RequestContent = requestString
|
||||||
};
|
};
|
||||||
|
|
||||||
httpOptions.RequestHeaders["token"] = token;
|
httpOptions.RequestHeaders["token"] = token;
|
||||||
|
|
||||||
httpOptions.RequestContent = requestString;
|
|
||||||
using (var response = await Post(httpOptions, true, info).ConfigureAwait(false))
|
using (var response = await Post(httpOptions, true, info).ConfigureAwait(false))
|
||||||
|
using (StreamReader reader = new StreamReader(response.Content))
|
||||||
{
|
{
|
||||||
var dailySchedules = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Day>>(response.Content).ConfigureAwait(false);
|
var dailySchedules = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.Day>>(response.Content).ConfigureAwait(false);
|
||||||
_logger.LogDebug("Found {ScheduleCount} programs on {StationID} ScheduleDirect", dailySchedules.Count, stationID);
|
_logger.LogDebug("Found {ScheduleCount} programs on {ChannelID} ScheduleDirect", dailySchedules.Count, channelId);
|
||||||
|
|
||||||
httpOptions = new HttpRequestOptions()
|
httpOptions = new HttpRequestOptions()
|
||||||
{
|
{
|
||||||
|
@ -132,14 +124,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
httpOptions.RequestHeaders["token"] = token;
|
httpOptions.RequestHeaders["token"] = token;
|
||||||
|
|
||||||
List<string> programsID = new List<string>();
|
var programsID = dailySchedules.SelectMany(d => d.programs.Select(s => s.programID)).Distinct();
|
||||||
programsID = dailySchedules.SelectMany(d => d.programs.Select(s => s.programID)).Distinct().ToList();
|
httpOptions.RequestContent = "[\"" + string.Join("\", \"", programsID) + "\"]";
|
||||||
var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]";
|
|
||||||
httpOptions.RequestContent = requestBody;
|
|
||||||
|
|
||||||
double wideAspect = 1.77777778;
|
|
||||||
|
|
||||||
using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false))
|
using (var innerResponse = await Post(httpOptions, true, info).ConfigureAwait(false))
|
||||||
|
using (StreamReader innerReader = new StreamReader(innerResponse.Content))
|
||||||
{
|
{
|
||||||
var programDetails = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ProgramDetails>>(innerResponse.Content).ConfigureAwait(false);
|
var programDetails = await _jsonSerializer.DeserializeFromStreamAsync<List<ScheduleDirect.ProgramDetails>>(innerResponse.Content).ConfigureAwait(false);
|
||||||
var programDict = programDetails.ToDictionary(p => p.programID, y => y);
|
var programDict = programDetails.ToDictionary(p => p.programID, y => y);
|
||||||
|
@ -150,8 +139,8 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
var images = await GetImageForPrograms(info, programIdsWithImages, cancellationToken).ConfigureAwait(false);
|
var images = await GetImageForPrograms(info, programIdsWithImages, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var schedules = dailySchedules.SelectMany(d => d.programs);
|
List<ProgramInfo> programsInfo = new List<ProgramInfo>();
|
||||||
foreach (ScheduleDirect.Program schedule in schedules)
|
foreach (ScheduleDirect.Program schedule in dailySchedules.SelectMany(d => d.programs))
|
||||||
{
|
{
|
||||||
//_logger.LogDebug("Proccesing Schedule for statio ID " + stationID +
|
//_logger.LogDebug("Proccesing Schedule for statio ID " + stationID +
|
||||||
// " which corresponds to channel " + channelNumber + " and program id " +
|
// " which corresponds to channel " + channelNumber + " and program id " +
|
||||||
|
@ -165,15 +154,17 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
{
|
{
|
||||||
var programEntry = programDict[schedule.programID];
|
var programEntry = programDict[schedule.programID];
|
||||||
|
|
||||||
var allImages = (images[imageIndex].data ?? new List<ScheduleDirect.ImageData>()).ToList();
|
var allImages = images[imageIndex].data ?? new List<ScheduleDirect.ImageData>();
|
||||||
var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)).ToList();
|
var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase));
|
||||||
var imagesWithoutText = allImages.Where(i => string.Equals(i.text, "no", StringComparison.OrdinalIgnoreCase)).ToList();
|
var imagesWithoutText = allImages.Where(i => string.Equals(i.text, "no", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
double desiredAspect = 0.666666667;
|
const double desiredAspect = 0.666666667;
|
||||||
|
|
||||||
programEntry.primaryImage = GetProgramImage(ApiUrl, imagesWithText, true, desiredAspect) ??
|
programEntry.primaryImage = GetProgramImage(ApiUrl, imagesWithText, true, desiredAspect) ??
|
||||||
GetProgramImage(ApiUrl, allImages, true, desiredAspect);
|
GetProgramImage(ApiUrl, allImages, true, desiredAspect);
|
||||||
|
|
||||||
|
const double wideAspect = 1.77777778;
|
||||||
|
|
||||||
programEntry.thumbImage = GetProgramImage(ApiUrl, imagesWithText, true, wideAspect);
|
programEntry.thumbImage = GetProgramImage(ApiUrl, imagesWithText, true, wideAspect);
|
||||||
|
|
||||||
// Don't supply the same image twice
|
// Don't supply the same image twice
|
||||||
|
@ -193,18 +184,16 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
programsInfo.Add(GetProgram(channelId, schedule, programDict[schedule.programID]));
|
programsInfo.Add(GetProgram(channelId, schedule, programDict[schedule.programID]));
|
||||||
}
|
}
|
||||||
|
return programsInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return programsInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetSizeOrder(ScheduleDirect.ImageData image)
|
private int GetSizeOrder(ScheduleDirect.ImageData image)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(image.height))
|
if (!string.IsNullOrWhiteSpace(image.height))
|
||||||
{
|
{
|
||||||
int value;
|
if (int.TryParse(image.height, out int value))
|
||||||
if (int.TryParse(image.height, out value))
|
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -225,9 +214,8 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
{
|
{
|
||||||
channelNumber = map.atscMajor + "." + map.atscMinor;
|
channelNumber = map.atscMajor + "." + map.atscMinor;
|
||||||
}
|
}
|
||||||
channelNumber = channelNumber.TrimStart('0');
|
|
||||||
|
|
||||||
return channelNumber;
|
return channelNumber.TrimStart('0');
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsMovie(ScheduleDirect.ProgramDetails programInfo)
|
private bool IsMovie(ScheduleDirect.ProgramDetails programInfo)
|
||||||
|
@ -382,8 +370,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
if (details.movie != null)
|
if (details.movie != null)
|
||||||
{
|
{
|
||||||
int year;
|
if (!string.IsNullOrEmpty(details.movie.year) && int.TryParse(details.movie.year, out int year))
|
||||||
if (!string.IsNullOrEmpty(details.movie.year) && int.TryParse(details.movie.year, out year))
|
|
||||||
{
|
{
|
||||||
info.ProductionYear = year;
|
info.ProductionYear = year;
|
||||||
}
|
}
|
||||||
|
@ -414,18 +401,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetProgramImage(string apiUrl, List<ScheduleDirect.ImageData> images, bool returnDefaultImage, double desiredAspect)
|
private string GetProgramImage(string apiUrl, IEnumerable<ScheduleDirect.ImageData> images, bool returnDefaultImage, double desiredAspect)
|
||||||
{
|
{
|
||||||
string url = null;
|
var match = images
|
||||||
|
.OrderBy(i => Math.Abs(desiredAspect - GetAspectRatio(i)))
|
||||||
var matches = images;
|
|
||||||
|
|
||||||
matches = matches
|
|
||||||
.OrderBy(i => Math.Abs(desiredAspect - GetApsectRatio(i)))
|
|
||||||
.ThenByDescending(GetSizeOrder)
|
.ThenByDescending(GetSizeOrder)
|
||||||
.ToList();
|
.FirstOrDefault();
|
||||||
|
|
||||||
var match = matches.FirstOrDefault();
|
|
||||||
|
|
||||||
if (match == null)
|
if (match == null)
|
||||||
{
|
{
|
||||||
|
@ -434,22 +415,21 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
var uri = match.uri;
|
var uri = match.uri;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(uri))
|
if (string.IsNullOrWhiteSpace(uri))
|
||||||
{
|
{
|
||||||
if (uri.IndexOf("http", StringComparison.OrdinalIgnoreCase) != -1)
|
return null;
|
||||||
{
|
}
|
||||||
url = uri;
|
else if (uri.IndexOf("http", StringComparison.OrdinalIgnoreCase) != -1)
|
||||||
}
|
{
|
||||||
else
|
return uri;
|
||||||
{
|
}
|
||||||
url = apiUrl + "/image/" + uri;
|
else
|
||||||
}
|
{
|
||||||
|
return apiUrl + "/image/" + uri;
|
||||||
}
|
}
|
||||||
//_logger.LogDebug("URL for image is : " + url);
|
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private double GetApsectRatio(ScheduleDirect.ImageData i)
|
private double GetAspectRatio(ScheduleDirect.ImageData i)
|
||||||
{
|
{
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
@ -614,8 +594,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(savedToken.Name) && !string.IsNullOrEmpty(savedToken.Value))
|
if (!string.IsNullOrEmpty(savedToken.Name) && !string.IsNullOrEmpty(savedToken.Value))
|
||||||
{
|
{
|
||||||
long ticks;
|
if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out long ticks))
|
||||||
if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out ticks))
|
|
||||||
{
|
{
|
||||||
// If it's under 24 hours old we can still use it
|
// If it's under 24 hours old we can still use it
|
||||||
if (DateTime.UtcNow.Ticks - ticks < TimeSpan.FromHours(20).Ticks)
|
if (DateTime.UtcNow.Ticks - ticks < TimeSpan.FromHours(20).Ticks)
|
||||||
|
@ -685,8 +664,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newToken = await GetToken(providerInfo, options.CancellationToken).ConfigureAwait(false);
|
options.RequestHeaders["token"] = await GetToken(providerInfo, options.CancellationToken).ConfigureAwait(false);;
|
||||||
options.RequestHeaders["token"] = newToken;
|
|
||||||
return await Post(options, false, providerInfo).ConfigureAwait(false);
|
return await Post(options, false, providerInfo).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,8 +702,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newToken = await GetToken(providerInfo, options.CancellationToken).ConfigureAwait(false);
|
options.RequestHeaders["token"] = await GetToken(providerInfo, options.CancellationToken).ConfigureAwait(false);
|
||||||
options.RequestHeaders["token"] = newToken;
|
|
||||||
return await Get(options, false, providerInfo).ConfigureAwait(false);
|
return await Get(options, false, providerInfo).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,9 +720,9 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
//_logger.LogInformation("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " +
|
//_logger.LogInformation("Obtaining token from Schedules Direct from addres: " + httpOptions.Url + " with body " +
|
||||||
// httpOptions.RequestContent);
|
// httpOptions.RequestContent);
|
||||||
|
|
||||||
using (var responce = await Post(httpOptions, false, null).ConfigureAwait(false))
|
using (var response = await Post(httpOptions, false, null).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(responce.Content).ConfigureAwait(false);
|
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Token>(response.Content).ConfigureAwait(false);
|
||||||
if (root.message == "OK")
|
if (root.message == "OK")
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Authenticated with Schedules Direct token: " + root.token);
|
_logger.LogInformation("Authenticated with Schedules Direct token: " + root.token);
|
||||||
|
@ -828,13 +805,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var httpResponse = await Get(options, false, null).ConfigureAwait(false))
|
using (var httpResponse = await Get(options, false, null).ConfigureAwait(false))
|
||||||
|
using (var response = httpResponse.Content)
|
||||||
{
|
{
|
||||||
using (var response = httpResponse.Content)
|
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Lineups>(response).ConfigureAwait(false);
|
||||||
{
|
|
||||||
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Lineups>(response).ConfigureAwait(false);
|
|
||||||
|
|
||||||
return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
|
return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HttpException ex)
|
catch (HttpException ex)
|
||||||
|
@ -913,54 +888,41 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||||
var list = new List<ChannelInfo>();
|
var list = new List<ChannelInfo>();
|
||||||
|
|
||||||
using (var httpResponse = await Get(httpOptions, true, info).ConfigureAwait(false))
|
using (var httpResponse = await Get(httpOptions, true, info).ConfigureAwait(false))
|
||||||
|
using (var response = httpResponse.Content)
|
||||||
{
|
{
|
||||||
using (var response = httpResponse.Content)
|
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(response).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>();
|
||||||
|
|
||||||
|
foreach (ScheduleDirect.Map map in root.map)
|
||||||
{
|
{
|
||||||
var root = await _jsonSerializer.DeserializeFromStreamAsync<ScheduleDirect.Channel>(response).ConfigureAwait(false);
|
var channelNumber = GetChannelNumber(map);
|
||||||
_logger.LogInformation("Found " + root.map.Count + " channels on the lineup on ScheduleDirect");
|
|
||||||
_logger.LogInformation("Mapping Stations to Channel");
|
|
||||||
|
|
||||||
var allStations = root.stations ?? new List<ScheduleDirect.Station>();
|
var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (station == null)
|
||||||
foreach (ScheduleDirect.Map map in root.map)
|
|
||||||
{
|
{
|
||||||
var channelNumber = GetChannelNumber(map);
|
station = new ScheduleDirect.Station
|
||||||
|
|
||||||
var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
|
||||||
if (station == null)
|
|
||||||
{
|
{
|
||||||
station = new ScheduleDirect.Station
|
stationID = map.stationID
|
||||||
{
|
|
||||||
stationID = map.stationID
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = channelNumber;
|
|
||||||
|
|
||||||
var channelInfo = new ChannelInfo
|
|
||||||
{
|
|
||||||
Number = channelNumber,
|
|
||||||
Name = name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (station != null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(station.name))
|
|
||||||
{
|
|
||||||
channelInfo.Name = station.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
channelInfo.Id = station.stationID;
|
|
||||||
channelInfo.CallSign = station.callsign;
|
|
||||||
|
|
||||||
if (station.logo != null)
|
|
||||||
{
|
|
||||||
channelInfo.ImageUrl = station.logo.URL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list.Add(channelInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var channelInfo = new ChannelInfo
|
||||||
|
{
|
||||||
|
Id = station.stationID,
|
||||||
|
CallSign = station.callsign,
|
||||||
|
Number = channelNumber,
|
||||||
|
Name = string.IsNullOrWhiteSpace(station.name) ? channelNumber : station.name
|
||||||
|
};
|
||||||
|
|
||||||
|
if (station.logo != null)
|
||||||
|
{
|
||||||
|
channelInfo.ImageUrl = station.logo.URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(channelInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,9 +132,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
service.DataSourceChanged += service_DataSourceChanged;
|
service.DataSourceChanged += service_DataSourceChanged;
|
||||||
|
|
||||||
var embyTv = service as EmbyTV.EmbyTV;
|
if (service is EmbyTV.EmbyTV embyTv)
|
||||||
|
|
||||||
if (embyTv != null)
|
|
||||||
{
|
{
|
||||||
embyTv.TimerCreated += EmbyTv_TimerCreated;
|
embyTv.TimerCreated += EmbyTv_TimerCreated;
|
||||||
embyTv.TimerCancelled += EmbyTv_TimerCancelled;
|
embyTv.TimerCancelled += EmbyTv_TimerCancelled;
|
||||||
|
@ -251,18 +249,15 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
mediaSourceId = null;
|
mediaSourceId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSourceInfo info;
|
|
||||||
bool isVideo;
|
|
||||||
ILiveTvService service;
|
|
||||||
ILiveStream liveStream;
|
|
||||||
|
|
||||||
var channel = (LiveTvChannel)_libraryManager.GetItemById(id);
|
var channel = (LiveTvChannel)_libraryManager.GetItemById(id);
|
||||||
isVideo = channel.ChannelType == ChannelType.TV;
|
|
||||||
service = GetService(channel);
|
bool isVideo = channel.ChannelType == ChannelType.TV;
|
||||||
|
ILiveTvService service = GetService(channel);
|
||||||
_logger.LogInformation("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
|
_logger.LogInformation("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId);
|
||||||
|
|
||||||
var supportsManagedStream = service as ISupportsDirectStreamProvider;
|
MediaSourceInfo info;
|
||||||
if (supportsManagedStream != null)
|
ILiveStream liveStream;
|
||||||
|
if (service is ISupportsDirectStreamProvider supportsManagedStream)
|
||||||
{
|
{
|
||||||
liveStream = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, currentLiveStreams, cancellationToken).ConfigureAwait(false);
|
liveStream = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, currentLiveStreams, cancellationToken).ConfigureAwait(false);
|
||||||
info = liveStream.MediaSource;
|
info = liveStream.MediaSource;
|
||||||
|
@ -303,14 +298,12 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = sources.ToList();
|
foreach (var source in sources)
|
||||||
|
|
||||||
foreach (var source in list)
|
|
||||||
{
|
{
|
||||||
Normalize(source, service, baseItem.ChannelType == ChannelType.TV);
|
Normalize(source, service, baseItem.ChannelType == ChannelType.TV);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return sources;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ILiveTvService GetService(LiveTvChannel item)
|
private ILiveTvService GetService(LiveTvChannel item)
|
||||||
|
@ -542,13 +535,11 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
var id = _tvDtoService.GetInternalProgramId(info.Id);
|
var id = _tvDtoService.GetInternalProgramId(info.Id);
|
||||||
|
|
||||||
LiveTvProgram item = null;
|
|
||||||
allExistingPrograms.TryGetValue(id, out item);
|
|
||||||
|
|
||||||
var isNew = false;
|
var isNew = false;
|
||||||
var forceUpdate = false;
|
var forceUpdate = false;
|
||||||
|
|
||||||
if (item == null)
|
LiveTvProgram item;
|
||||||
|
if (!allExistingPrograms.TryGetValue(id, out item))
|
||||||
{
|
{
|
||||||
isNew = true;
|
isNew = true;
|
||||||
item = new LiveTvProgram
|
item = new LiveTvProgram
|
||||||
|
@ -783,11 +774,9 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user);
|
||||||
|
|
||||||
var list = new List<Tuple<BaseItemDto, string, string>>();
|
var list = new List<Tuple<BaseItemDto, string, string>>() {
|
||||||
|
new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, program.ExternalSeriesId)
|
||||||
var externalSeriesId = program.ExternalSeriesId;
|
};
|
||||||
|
|
||||||
list.Add(new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, externalSeriesId));
|
|
||||||
|
|
||||||
await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
|
await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
@ -928,13 +917,11 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
programs = programs.Take(query.Limit.Value);
|
programs = programs.Take(query.Limit.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = new QueryResult<BaseItem>
|
return new QueryResult<BaseItem>
|
||||||
{
|
{
|
||||||
Items = programs.ToArray(),
|
Items = programs.ToArray(),
|
||||||
TotalRecordCount = totalCount
|
TotalRecordCount = totalCount
|
||||||
};
|
};
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryResult<BaseItemDto> GetRecommendedPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken)
|
public QueryResult<BaseItemDto> GetRecommendedPrograms(InternalItemsQuery query, DtoOptions options, CancellationToken cancellationToken)
|
||||||
|
@ -948,17 +935,11 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
var internalResult = GetRecommendedProgramsInternal(query, options, cancellationToken);
|
var internalResult = GetRecommendedProgramsInternal(query, options, cancellationToken);
|
||||||
|
|
||||||
var user = query.User;
|
return new QueryResult<BaseItemDto>
|
||||||
|
{
|
||||||
var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user);
|
Items = _dtoService.GetBaseItemDtos(internalResult.Items, options, query.User),
|
||||||
|
TotalRecordCount = internalResult.TotalRecordCount
|
||||||
var result = new QueryResult<BaseItemDto>
|
};
|
||||||
{
|
|
||||||
Items = returnArray,
|
|
||||||
TotalRecordCount = internalResult.TotalRecordCount
|
|
||||||
};
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetRecommendationScore(LiveTvProgram program, User user, bool factorChannelWatchCount)
|
private int GetRecommendationScore(LiveTvProgram program, User user, bool factorChannelWatchCount)
|
||||||
|
@ -977,28 +958,26 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
var channel = _libraryManager.GetItemById(program.ChannelId);
|
var channel = _libraryManager.GetItemById(program.ChannelId);
|
||||||
|
|
||||||
if (channel != null)
|
if (channel == null)
|
||||||
{
|
{
|
||||||
var channelUserdata = _userDataManager.GetUserData(user, channel);
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
if (channelUserdata.Likes ?? false)
|
var channelUserdata = _userDataManager.GetUserData(user, channel);
|
||||||
{
|
|
||||||
score += 2;
|
|
||||||
}
|
|
||||||
else if (!(channelUserdata.Likes ?? true))
|
|
||||||
{
|
|
||||||
score -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channelUserdata.IsFavorite)
|
if (channelUserdata.Likes.HasValue)
|
||||||
{
|
{
|
||||||
score += 3;
|
score += channelUserdata.Likes.Value ? 2 : -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (factorChannelWatchCount)
|
if (channelUserdata.IsFavorite)
|
||||||
{
|
{
|
||||||
score += channelUserdata.PlayCount;
|
score += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (factorChannelWatchCount)
|
||||||
|
{
|
||||||
|
score += channelUserdata.PlayCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
|
@ -1153,7 +1132,6 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
var parentFolder = GetInternalLiveTvFolder(cancellationToken);
|
var parentFolder = GetInternalLiveTvFolder(cancellationToken);
|
||||||
var parentFolderId = parentFolder.Id;
|
|
||||||
|
|
||||||
foreach (var channelInfo in allChannelsList)
|
foreach (var channelInfo in allChannelsList)
|
||||||
{
|
{
|
||||||
|
@ -1239,30 +1217,11 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
programs.Add(programItem.Id);
|
programs.Add(programItem.Id);
|
||||||
|
|
||||||
if (program.IsMovie)
|
isMovie |= program.IsMovie;
|
||||||
{
|
iSSeries |= program.IsSeries;
|
||||||
isMovie = true;
|
isSports |= program.IsSports;
|
||||||
}
|
isNews |= program.IsNews;
|
||||||
|
isKids |= program.IsKids;
|
||||||
if (program.IsSeries)
|
|
||||||
{
|
|
||||||
iSSeries = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (program.IsSports)
|
|
||||||
{
|
|
||||||
isSports = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (program.IsNews)
|
|
||||||
{
|
|
||||||
isNews = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (program.IsKids)
|
|
||||||
{
|
|
||||||
isKids = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("Channel {0} has {1} new programs and {2} updated programs", currentChannel.Name, newPrograms.Count, updatedPrograms.Count);
|
_logger.LogDebug("Channel {0} has {1} new programs and {2} updated programs", currentChannel.Name, newPrograms.Count, updatedPrograms.Count);
|
||||||
|
@ -1304,8 +1263,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
double percent = numComplete;
|
double percent = numComplete / allChannelsList.Count;
|
||||||
percent /= allChannelsList.Count;
|
|
||||||
|
|
||||||
progress.Report(85 * percent + 15);
|
progress.Report(85 * percent + 15);
|
||||||
}
|
}
|
||||||
|
@ -1320,7 +1278,6 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
{
|
{
|
||||||
IncludeItemTypes = validTypes,
|
IncludeItemTypes = validTypes,
|
||||||
DtoOptions = new DtoOptions(false)
|
DtoOptions = new DtoOptions(false)
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
|
@ -1351,8 +1308,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
}
|
}
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
double percent = numComplete;
|
double percent = numComplete / list.Count;
|
||||||
percent /= list.Count;
|
|
||||||
|
|
||||||
progress.Report(100 * percent);
|
progress.Report(100 * percent);
|
||||||
}
|
}
|
||||||
|
@ -1414,28 +1370,22 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
excludeItemTypes.Add(typeof(Episode).Name);
|
excludeItemTypes.Add(typeof(Episode).Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (query.IsSports.HasValue)
|
if (query.IsSports ?? false)
|
||||||
{
|
{
|
||||||
if (query.IsSports.Value)
|
genres.Add("Sports");
|
||||||
{
|
|
||||||
genres.Add("Sports");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (query.IsKids.HasValue)
|
if (query.IsKids ?? false)
|
||||||
{
|
{
|
||||||
if (query.IsKids.Value)
|
genres.Add("Kids");
|
||||||
{
|
genres.Add("Children");
|
||||||
genres.Add("Kids");
|
genres.Add("Family");
|
||||||
genres.Add("Children");
|
|
||||||
genres.Add("Family");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var limit = query.Limit;
|
var limit = query.Limit;
|
||||||
|
|
||||||
if ((query.IsInProgress ?? false))
|
if (query.IsInProgress ?? false)
|
||||||
{
|
{
|
||||||
limit = (query.Limit ?? 10) * 2;
|
// limit = (query.Limit ?? 10) * 2;
|
||||||
limit = null;
|
limit = null;
|
||||||
|
|
||||||
//var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray();
|
//var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray();
|
||||||
|
@ -1467,7 +1417,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
DtoOptions = dtoOptions
|
DtoOptions = dtoOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
if ((query.IsInProgress ?? false))
|
if (query.IsInProgress ?? false)
|
||||||
{
|
{
|
||||||
result.Items = result
|
result.Items = result
|
||||||
.Items
|
.Items
|
||||||
|
@ -1494,60 +1444,33 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
dto.StartDate = program.StartDate;
|
dto.StartDate = program.StartDate;
|
||||||
dto.EpisodeTitle = program.EpisodeTitle;
|
dto.EpisodeTitle = program.EpisodeTitle;
|
||||||
|
dto.IsRepeat |= program.IsRepeat;
|
||||||
if (program.IsRepeat)
|
dto.IsMovie |= program.IsMovie;
|
||||||
{
|
dto.IsSeries |= program.IsSeries;
|
||||||
dto.IsRepeat = program.IsRepeat;
|
dto.IsSports |= program.IsSports;
|
||||||
}
|
dto.IsLive |= program.IsLive;
|
||||||
if (program.IsMovie)
|
dto.IsNews |= program.IsNews;
|
||||||
{
|
dto.IsKids |= program.IsKids;
|
||||||
dto.IsMovie = program.IsMovie;
|
dto.IsPremiere |= program.IsPremiere;
|
||||||
}
|
|
||||||
if (program.IsSeries)
|
|
||||||
{
|
|
||||||
dto.IsSeries = program.IsSeries;
|
|
||||||
}
|
|
||||||
if (program.IsSports)
|
|
||||||
{
|
|
||||||
dto.IsSports = program.IsSports;
|
|
||||||
}
|
|
||||||
if (program.IsLive)
|
|
||||||
{
|
|
||||||
dto.IsLive = program.IsLive;
|
|
||||||
}
|
|
||||||
if (program.IsNews)
|
|
||||||
{
|
|
||||||
dto.IsNews = program.IsNews;
|
|
||||||
}
|
|
||||||
if (program.IsKids)
|
|
||||||
{
|
|
||||||
dto.IsKids = program.IsKids;
|
|
||||||
}
|
|
||||||
if (program.IsPremiere)
|
|
||||||
{
|
|
||||||
dto.IsPremiere = program.IsPremiere;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasChannelInfo || hasChannelImage)
|
if (hasChannelInfo || hasChannelImage)
|
||||||
{
|
{
|
||||||
var channel = _libraryManager.GetItemById(program.ChannelId) as LiveTvChannel;
|
var channel = _libraryManager.GetItemById(program.ChannelId);
|
||||||
|
|
||||||
if (channel != null)
|
if (channel is LiveTvChannel liveChannel)
|
||||||
{
|
{
|
||||||
dto.ChannelName = channel.Name;
|
dto.ChannelName = liveChannel.Name;
|
||||||
dto.MediaType = channel.MediaType;
|
dto.MediaType = liveChannel.MediaType;
|
||||||
dto.ChannelNumber = channel.Number;
|
dto.ChannelNumber = liveChannel.Number;
|
||||||
|
|
||||||
if (hasChannelImage && channel.HasImage(ImageType.Primary))
|
if (hasChannelImage && liveChannel.HasImage(ImageType.Primary))
|
||||||
{
|
{
|
||||||
dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
|
dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(liveChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var externalSeriesId = program.ExternalSeriesId;
|
programTuples.Add(new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, program.ExternalSeriesId));
|
||||||
|
|
||||||
programTuples.Add(new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, externalSeriesId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddRecordingInfo(programTuples, CancellationToken.None);
|
return AddRecordingInfo(programTuples, CancellationToken.None);
|
||||||
|
@ -2037,19 +1960,13 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
|
|
||||||
private async Task<Tuple<SeriesTimerInfo, ILiveTvService>> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null)
|
private async Task<Tuple<SeriesTimerInfo, ILiveTvService>> GetNewTimerDefaultsInternal(CancellationToken cancellationToken, LiveTvProgram program = null)
|
||||||
{
|
{
|
||||||
var service = program != null ?
|
ILiveTvService service = null;
|
||||||
GetService(program) :
|
|
||||||
null;
|
|
||||||
|
|
||||||
if (service == null)
|
|
||||||
{
|
|
||||||
service = _services.First();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramInfo programInfo = null;
|
ProgramInfo programInfo = null;
|
||||||
|
|
||||||
if (program != null)
|
if(program != null)
|
||||||
{
|
{
|
||||||
|
service = GetService(program);
|
||||||
|
|
||||||
var channel = _libraryManager.GetItemById(program.ChannelId);
|
var channel = _libraryManager.GetItemById(program.ChannelId);
|
||||||
|
|
||||||
programInfo = new ProgramInfo
|
programInfo = new ProgramInfo
|
||||||
|
@ -2079,6 +1996,11 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (service == null)
|
||||||
|
{
|
||||||
|
service = _services.First();
|
||||||
|
}
|
||||||
|
|
||||||
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
|
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
|
||||||
|
|
||||||
info.RecordAnyTime = true;
|
info.RecordAnyTime = true;
|
||||||
|
@ -2147,8 +2069,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
info.Priority = defaultValues.Priority;
|
info.Priority = defaultValues.Priority;
|
||||||
|
|
||||||
string newTimerId = null;
|
string newTimerId = null;
|
||||||
var supportsNewTimerIds = service as ISupportsNewTimerIds;
|
if (service is ISupportsNewTimerIds supportsNewTimerIds)
|
||||||
if (supportsNewTimerIds != null)
|
|
||||||
{
|
{
|
||||||
newTimerId = await supportsNewTimerIds.CreateTimer(info, cancellationToken).ConfigureAwait(false);
|
newTimerId = await supportsNewTimerIds.CreateTimer(info, cancellationToken).ConfigureAwait(false);
|
||||||
newTimerId = _tvDtoService.GetInternalTimerId(newTimerId);
|
newTimerId = _tvDtoService.GetInternalTimerId(newTimerId);
|
||||||
|
@ -2192,8 +2113,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
info.Priority = defaultValues.Priority;
|
info.Priority = defaultValues.Priority;
|
||||||
|
|
||||||
string newTimerId = null;
|
string newTimerId = null;
|
||||||
var supportsNewTimerIds = service as ISupportsNewTimerIds;
|
if (service is ISupportsNewTimerIds supportsNewTimerIds)
|
||||||
if (supportsNewTimerIds != null)
|
|
||||||
{
|
{
|
||||||
newTimerId = await supportsNewTimerIds.CreateSeriesTimer(info, cancellationToken).ConfigureAwait(false);
|
newTimerId = await supportsNewTimerIds.CreateSeriesTimer(info, cancellationToken).ConfigureAwait(false);
|
||||||
newTimerId = _tvDtoService.GetInternalSeriesTimerId(newTimerId).ToString("N");
|
newTimerId = _tvDtoService.GetInternalSeriesTimerId(newTimerId).ToString("N");
|
||||||
|
@ -2354,8 +2274,7 @@ namespace Emby.Server.Implementations.LiveTv
|
||||||
throw new ResourceNotFoundException();
|
throw new ResourceNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var configurable = provider as IConfigurableTunerHost;
|
if (provider is IConfigurableTunerHost configurable)
|
||||||
if (configurable != null)
|
|
||||||
{
|
{
|
||||||
await configurable.Validate(info).ConfigureAwait(false);
|
await configurable.Validate(info).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,13 +549,13 @@ namespace Emby.Server.Implementations.Updates
|
||||||
// Do plugin-specific processing
|
// Do plugin-specific processing
|
||||||
if (isPlugin)
|
if (isPlugin)
|
||||||
{
|
{
|
||||||
if (plugin != null)
|
if (plugin == null)
|
||||||
{
|
{
|
||||||
OnPluginUpdated(plugin, package);
|
OnPluginInstalled(package);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnPluginInstalled(package);
|
OnPluginUpdated(plugin, package);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net
|
namespace MediaBrowser.Common.Net
|
||||||
|
|
Loading…
Reference in New Issue
Block a user