diff options
| -rw-r--r-- | Emby.Server.Implementations/ApplicationHost.cs | 12 | ||||
| -rw-r--r-- | Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs | 131 | ||||
| -rw-r--r-- | Emby.Server.Implementations/EntryPoints/UsageReporter.cs | 130 | ||||
| -rw-r--r-- | Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs | 145 | ||||
| -rw-r--r-- | Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs | 196 | ||||
| -rw-r--r-- | Emby.Server.Implementations/LiveTv/LiveTvManager.cs | 249 | ||||
| -rw-r--r-- | Emby.Server.Implementations/News/NewsEntryPoint.cs | 279 | ||||
| -rw-r--r-- | Emby.Server.Implementations/News/NewsService.cs | 77 | ||||
| -rw-r--r-- | Emby.Server.Implementations/Updates/InstallationManager.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Api/StartupWizardService.cs | 29 | ||||
| -rw-r--r-- | MediaBrowser.Common/Net/IHttpClient.cs | 7 | ||||
| -rw-r--r-- | MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Movies/MovieDbProvider.cs | 4 |
13 files changed, 227 insertions, 1040 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 3cc6151f1..80e9b6b50 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -640,15 +640,14 @@ namespace Emby.Server.Implementations /// Gets the exports. /// </summary> /// <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> public IEnumerable<T> GetExports<T>(bool manageLifetime = true) { var parts = GetExportTypes<T>() .Select(CreateInstanceSafe) .Where(i => i != null) - .Cast<T>() - .ToList(); + .Cast<T>(); if (manageLifetime) { @@ -703,7 +702,7 @@ namespace Emby.Server.Implementations /// <summary> /// Runs the startup tasks. /// </summary> - public async Task RunStartupTasks() + public Task RunStartupTasks() { Resolve<ITaskManager>().AddTasks(GetExports<IScheduledTask>(false)); @@ -736,6 +735,8 @@ namespace Emby.Server.Implementations Logger.LogInformation("All entry points have started"); //LoggerFactory.RemoveConsoleOutput(); + + return Task.CompletedTask; } private void RunEntryPoints(IEnumerable<IServerEntryPoint> entryPoints, bool isBeforeStartup) @@ -965,9 +966,6 @@ namespace Emby.Server.Implementations DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LoggerFactory.CreateLogger("DeviceManager"), NetworkManager); RegisterSingleInstance(DeviceManager); - var newsService = new Emby.Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer); - RegisterSingleInstance<INewsService>(newsService); - MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory.CreateLogger("MediaSourceManager"), JsonSerializer, FileSystemManager, UserDataManager, TimerFactory, () => MediaEncoder); RegisterSingleInstance(MediaSourceManager); diff --git a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs deleted file mode 100644 index f7542a5e9..000000000 --- a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ /dev/null @@ -1,131 +0,0 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Model.Extensions; - -namespace Emby.Server.Implementations.EntryPoints -{ - /// <summary> - /// Class UsageEntryPoint - /// </summary> - public class UsageEntryPoint : IServerEntryPoint - { - private readonly IServerApplicationHost _applicationHost; - private readonly IHttpClient _httpClient; - private readonly ILogger _logger; - private readonly ISessionManager _sessionManager; - private readonly IUserManager _userManager; - private readonly IServerConfigurationManager _config; - - private readonly ConcurrentDictionary<Guid, ClientInfo> _apps = new ConcurrentDictionary<Guid, ClientInfo>(); - - public UsageEntryPoint(ILogger logger, IServerApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config) - { - _logger = logger; - _applicationHost = applicationHost; - _httpClient = httpClient; - _sessionManager = sessionManager; - _userManager = userManager; - _config = config; - - _sessionManager.SessionStarted += _sessionManager_SessionStarted; - } - - void _sessionManager_SessionStarted(object sender, SessionEventArgs e) - { - var session = e.SessionInfo; - - if (!string.IsNullOrEmpty(session.Client) && - !string.IsNullOrEmpty(session.DeviceName) && - !string.IsNullOrEmpty(session.DeviceId) && - !string.IsNullOrEmpty(session.ApplicationVersion)) - { - var keys = new List<string> - { - session.Client, - session.DeviceName, - session.DeviceId, - session.ApplicationVersion - }; - - var key = string.Join("_", keys.ToArray()).GetMD5(); - - ClientInfo info; - if (!_apps.TryGetValue(key, out info)) - { - info = new ClientInfo - { - AppName = session.Client, - AppVersion = session.ApplicationVersion, - DeviceName = session.DeviceName, - DeviceId = session.DeviceId - }; - - _apps[key] = info; - - if (_config.Configuration.EnableAnonymousUsageReporting) - { - Task.Run(() => ReportNewSession(info)); - } - } - } - } - - private async Task ReportNewSession(ClientInfo client) - { - try - { - await new UsageReporter(_applicationHost, _httpClient, _logger) - .ReportAppUsage(client, CancellationToken.None) - .ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error sending anonymous usage statistics."); - } - } - - public async void Run() - { - await Task.Delay(5000).ConfigureAwait(false); - OnTimerFired(); - } - - /// <summary> - /// Called when [timer fired]. - /// </summary> - private async void OnTimerFired() - { - if (!_config.Configuration.EnableAnonymousUsageReporting) - { - return; - } - - try - { - await new UsageReporter(_applicationHost, _httpClient, _logger) - .ReportServerUsage(CancellationToken.None) - .ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error sending anonymous usage statistics."); - } - } - - public void Dispose() - { - _sessionManager.SessionStarted -= _sessionManager_SessionStarted; - } - } -} diff --git a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs deleted file mode 100644 index e962bb59b..000000000 --- a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs +++ /dev/null @@ -1,130 +0,0 @@ -using MediaBrowser.Common; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Connect; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller; -using Microsoft.Extensions.Logging; - -namespace Emby.Server.Implementations.EntryPoints -{ - public class UsageReporter - { - private readonly IServerApplicationHost _applicationHost; - private readonly IHttpClient _httpClient; - private readonly ILogger _logger; - private const string MbAdminUrl = "https://www.mb3admin.local/admin/"; - - public UsageReporter(IServerApplicationHost applicationHost, IHttpClient httpClient, ILogger logger) - { - _applicationHost = applicationHost; - _httpClient = httpClient; - _logger = logger; - } - - public async Task ReportServerUsage(CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var data = new Dictionary<string, string> - { - { "feature", _applicationHost.Name }, - { "mac", _applicationHost.SystemId }, - { "serverid", _applicationHost.SystemId }, - { "deviceid", _applicationHost.SystemId }, - { "ver", _applicationHost.ApplicationVersion.ToString() }, - { "platform", _applicationHost.OperatingSystemDisplayName } - }; - - data["plugins"] = string.Join(",", _applicationHost.Plugins.Select(i => i.Id).ToArray()); - - var logErrors = false; -#if DEBUG - logErrors = true; -#endif - var options = new HttpRequestOptions - { - Url = MbAdminUrl + "service/registration/ping", - CancellationToken = cancellationToken, - - // Seeing block length errors - EnableHttpCompression = false, - - LogRequest = false, - LogErrors = logErrors, - BufferContent = false - }; - - options.SetPostData(data); - - using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) - { - - } - } - - public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) - { - if (string.IsNullOrEmpty(app.DeviceId)) - { - throw new ArgumentException("Client info must have a device Id"); - } - - _logger.LogInformation("App Activity: app: {0}, version: {1}, deviceId: {2}, deviceName: {3}", - app.AppName ?? "Unknown App", - app.AppVersion ?? "Unknown", - app.DeviceId, - app.DeviceName ?? "Unknown"); - - cancellationToken.ThrowIfCancellationRequested(); - - var data = new Dictionary<string, string> - { - { "feature", app.AppName ?? "Unknown App" }, - { "serverid", _applicationHost.SystemId }, - { "deviceid", app.DeviceId }, - { "mac", app.DeviceId }, - { "ver", app.AppVersion ?? "Unknown" }, - { "platform", app.DeviceName }, - }; - - var logErrors = false; - -#if DEBUG - logErrors = true; -#endif - var options = new HttpRequestOptions - { - Url = MbAdminUrl + "service/registration/ping", - CancellationToken = cancellationToken, - - // Seeing block length errors - EnableHttpCompression = false, - - LogRequest = false, - LogErrors = logErrors, - BufferContent = false - }; - - options.SetPostData(data); - - using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) - { - - } - } - } - - public class ClientInfo - { - public string AppName { get; set; } - public string AppVersion { get; set; } - public string DeviceName { get; set; } - public string DeviceId { get; set; } - } -} diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index 23dd55b18..d3ba1b683 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -5,18 +5,16 @@ using System.Globalization; using System.IO; using System.Linq; using System.Net; -using System.Net.Sockets; +using System.Net.Cache; using System.Text; using System.Threading; using System.Threading.Tasks; -using Emby.Server.Implementations.IO; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; using MediaBrowser.Model.Net; -using MediaBrowser.Controller.IO; namespace Emby.Server.Implementations.HttpClientManager { @@ -125,59 +123,38 @@ namespace Emby.Server.Implementations.HttpClientManager private WebRequest GetRequest(HttpRequestOptions options, string method) { - var url = options.Url; + string url = options.Url; - var uriAddress = new Uri(url); - var userInfo = uriAddress.UserInfo; + Uri uriAddress = new Uri(url); + string userInfo = uriAddress.UserInfo; if (!string.IsNullOrWhiteSpace(userInfo)) { _logger.LogInformation("Found userInfo in url: {0} ... url: {1}", userInfo, url); url = url.Replace(userInfo + "@", string.Empty); } - var request = CreateWebRequest(url); - var httpWebRequest = request as HttpWebRequest; + WebRequest request = CreateWebRequest(url); - if (httpWebRequest != null) + if (request is HttpWebRequest httpWebRequest) { AddRequestHeaders(httpWebRequest, options); if (options.EnableHttpCompression) { - if (options.DecompressionMethod.HasValue) - { - httpWebRequest.AutomaticDecompression = options.DecompressionMethod.Value == CompressionMethod.Gzip - ? DecompressionMethods.GZip - : DecompressionMethods.Deflate; - } - else + httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate; + if (options.DecompressionMethod.HasValue + && options.DecompressionMethod.Value == CompressionMethod.Gzip) { - httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate; + httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip; } } else { httpWebRequest.AutomaticDecompression = DecompressionMethods.None; } - } - - - - request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache); - - if (httpWebRequest != null) - { - if (options.EnableKeepAlive) - { - httpWebRequest.KeepAlive = true; - } - } - request.Method = method; - request.Timeout = options.TimeoutMs; + httpWebRequest.KeepAlive = options.EnableKeepAlive; - if (httpWebRequest != null) - { if (!string.IsNullOrEmpty(options.Host)) { httpWebRequest.Host = options.Host; @@ -189,6 +166,11 @@ namespace Emby.Server.Implementations.HttpClientManager } } + request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); + + request.Method = method; + request.Timeout = options.TimeoutMs; + if (!string.IsNullOrWhiteSpace(userInfo)) { var parts = userInfo.Split(':'); @@ -215,7 +197,7 @@ namespace Emby.Server.Implementations.HttpClientManager { var hasUserAgent = false; - foreach (var header in options.RequestHeaders.ToList()) + foreach (var header in options.RequestHeaders) { if (string.Equals(header.Key, "Accept", StringComparison.OrdinalIgnoreCase)) { @@ -379,10 +361,7 @@ namespace Emby.Server.Implementations.HttpClientManager { try { - // TODO: We can always put this in the options object if needed - var requestEncoding = Encoding.UTF8; - - var bytes = options.RequestContentBytes ?? requestEncoding.GetBytes(options.RequestContent ?? string.Empty); + var bytes = options.RequestContentBytes ?? Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty); var contentType = options.RequestContentType ?? "application/x-www-form-urlencoded"; @@ -392,7 +371,6 @@ namespace Emby.Server.Implementations.HttpClientManager } httpWebRequest.ContentType = contentType; - httpWebRequest.ContentLength = bytes.Length; (await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)).Write(bytes, 0, bytes.Length); } @@ -409,10 +387,7 @@ namespace Emby.Server.Implementations.HttpClientManager 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 }; } @@ -457,7 +432,6 @@ namespace Emby.Server.Implementations.HttpClientManager using (var stream = httpResponse.GetResponseStream()) { var memoryStream = new MemoryStream(); - await stream.CopyToAsync(memoryStream).ConfigureAwait(false); memoryStream.Position = 0; @@ -476,10 +450,7 @@ namespace Emby.Server.Implementations.HttpClientManager } finally { - if (options.ResourcePool != null) - { - options.ResourcePool.Release(); - } + options.ResourcePool?.Release(); } } @@ -488,13 +459,9 @@ namespace Emby.Server.Implementations.HttpClientManager var responseInfo = new HttpResponseInfo(disposable) { Content = content, - StatusCode = httpResponse.StatusCode, - ContentType = httpResponse.ContentType, - ContentLength = contentLength, - ResponseUrl = httpResponse.ResponseUri.ToString() }; @@ -511,11 +478,8 @@ namespace Emby.Server.Implementations.HttpClientManager var responseInfo = new HttpResponseInfo { TempFilePath = tempFile, - StatusCode = httpResponse.StatusCode, - ContentType = httpResponse.ContentType, - ContentLength = contentLength }; @@ -619,22 +583,20 @@ namespace Emby.Server.Implementations.HttpClientManager 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)) { - using (var fs = _fileSystem.GetFileStream(tempFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true)) - { - await stream.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 httpResponse.GetResponseStream().CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false); + await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false); } } @@ -650,10 +612,7 @@ namespace Emby.Server.Implementations.HttpClientManager } finally { - if (options.ResourcePool != null) - { - options.ResourcePool.Release(); - } + options.ResourcePool?.Release(); } } @@ -810,35 +769,38 @@ namespace Emby.Server.Implementations.HttpClientManager var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299; - if (!isSuccessful) + if (isSuccessful) { - if (options.LogErrorResponseBody) + return; + } + + if (options.LogErrorResponseBody) + { + try { - try + using (var stream = response.GetResponseStream()) { - using (var stream = response.GetResponseStream()) + if (stream != null) { - if (stream != null) + using (var reader = new StreamReader(stream)) { - using (var reader = new StreamReader(stream)) - { - var msg = reader.ReadToEnd(); + var msg = reader.ReadToEnd(); - _logger.LogError(msg); - } + _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) @@ -859,13 +821,10 @@ namespace Emby.Server.Implementations.HttpClientManager private static void TimeoutCallback(object state, bool timedOut) { - if (timedOut) + if (timedOut && state != null) { WebRequest request = (WebRequest)state; - if (state != null) - { - request.Abort(); - } + request.Abort(); } } @@ -880,13 +839,13 @@ namespace Emby.Server.Implementations.HttpClientManager public void OnError(Task<WebResponse> task) { - if (task.Exception != null) + if (task.Exception == null) { - taskCompletion.TrySetException(task.Exception); + taskCompletion.TrySetException(Enumerable.Empty<Exception>()); } else { - taskCompletion.TrySetException(new List<Exception>()); + taskCompletion.TrySetException(task.Exception); } } } diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 60bc38616..e8ffd0caa 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -16,8 +16,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Extensions; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; 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 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) { _logger = logger; @@ -74,33 +69,29 @@ namespace Emby.Server.Implementations.LiveTv.Listings // Normalize incoming input 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); if (string.IsNullOrEmpty(token)) { _logger.LogWarning("SchedulesDirect token is empty, returning empty program list"); - return programsInfo; + + return Enumerable.Empty<ProgramInfo>(); } var dates = GetScheduleRequestDates(startDateUtc, endDateUtc); - string stationID = channelId; - - _logger.LogInformation("Channel Station ID is: " + stationID); - List<ScheduleDirect.RequestScheduleForChannel> requestList = - new List<ScheduleDirect.RequestScheduleForChannel>() + _logger.LogInformation("Channel Station ID is: {ChannelID}", channelId); + var requestList = new List<ScheduleDirect.RequestScheduleForChannel>() + { + new ScheduleDirect.RequestScheduleForChannel() { - new ScheduleDirect.RequestScheduleForChannel() - { - stationID = stationID, - date = dates - } - }; + stationID = channelId, + date = dates + } + }; 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() { @@ -109,16 +100,17 @@ namespace Emby.Server.Implementations.LiveTv.Listings CancellationToken = cancellationToken, // The data can be large so give it some extra time TimeoutMs = 60000, - LogErrorResponseBody = true + LogErrorResponseBody = true, + RequestContent = requestString }; httpOptions.RequestHeaders["token"] = token; - httpOptions.RequestContent = requestString; 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); - _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() { @@ -132,14 +124,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings httpOptions.RequestHeaders["token"] = token; - List<string> programsID = new List<string>(); - programsID = dailySchedules.SelectMany(d => d.programs.Select(s => s.programID)).Distinct().ToList(); - var requestBody = "[\"" + string.Join("\", \"", programsID) + "\"]"; - httpOptions.RequestContent = requestBody; - - double wideAspect = 1.77777778; + var programsID = dailySchedules.SelectMany(d => d.programs.Select(s => s.programID)).Distinct(); + httpOptions.RequestContent = "[\"" + string.Join("\", \"", programsID) + "\"]"; 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 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 schedules = dailySchedules.SelectMany(d => d.programs); - foreach (ScheduleDirect.Program schedule in schedules) + List<ProgramInfo> programsInfo = new List<ProgramInfo>(); + foreach (ScheduleDirect.Program schedule in dailySchedules.SelectMany(d => d.programs)) { //_logger.LogDebug("Proccesing Schedule for statio ID " + stationID + // " which corresponds to channel " + channelNumber + " and program id " + @@ -165,15 +154,17 @@ namespace Emby.Server.Implementations.LiveTv.Listings { var programEntry = programDict[schedule.programID]; - var allImages = (images[imageIndex].data ?? new List<ScheduleDirect.ImageData>()).ToList(); - var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)).ToList(); - var imagesWithoutText = allImages.Where(i => string.Equals(i.text, "no", StringComparison.OrdinalIgnoreCase)).ToList(); + var allImages = images[imageIndex].data ?? new List<ScheduleDirect.ImageData>(); + var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)); + 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) ?? GetProgramImage(ApiUrl, allImages, true, desiredAspect); + const double wideAspect = 1.77777778; + programEntry.thumbImage = GetProgramImage(ApiUrl, imagesWithText, true, wideAspect); // 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])); } + return programsInfo; } } - - return programsInfo; } private int GetSizeOrder(ScheduleDirect.ImageData image) { if (!string.IsNullOrWhiteSpace(image.height)) { - int value; - if (int.TryParse(image.height, out value)) + if (int.TryParse(image.height, out int value)) { return value; } @@ -225,9 +214,8 @@ namespace Emby.Server.Implementations.LiveTv.Listings { channelNumber = map.atscMajor + "." + map.atscMinor; } - channelNumber = channelNumber.TrimStart('0'); - return channelNumber; + return channelNumber.TrimStart('0'); } private bool IsMovie(ScheduleDirect.ProgramDetails programInfo) @@ -382,8 +370,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings if (details.movie != null) { - int year; - if (!string.IsNullOrEmpty(details.movie.year) && int.TryParse(details.movie.year, out year)) + if (!string.IsNullOrEmpty(details.movie.year) && int.TryParse(details.movie.year, out int year)) { info.ProductionYear = year; } @@ -414,18 +401,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings 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 matches = images; - - matches = matches - .OrderBy(i => Math.Abs(desiredAspect - GetApsectRatio(i))) + var match = images + .OrderBy(i => Math.Abs(desiredAspect - GetAspectRatio(i))) .ThenByDescending(GetSizeOrder) - .ToList(); - - var match = matches.FirstOrDefault(); + .FirstOrDefault(); if (match == null) { @@ -434,22 +415,21 @@ namespace Emby.Server.Implementations.LiveTv.Listings var uri = match.uri; - if (!string.IsNullOrWhiteSpace(uri)) + if (string.IsNullOrWhiteSpace(uri)) { - if (uri.IndexOf("http", StringComparison.OrdinalIgnoreCase) != -1) - { - url = uri; - } - else - { - url = apiUrl + "/image/" + uri; - } + return null; + } + else if (uri.IndexOf("http", StringComparison.OrdinalIgnoreCase) != -1) + { + return 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 height = 0; @@ -614,8 +594,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings if (!string.IsNullOrEmpty(savedToken.Name) && !string.IsNullOrEmpty(savedToken.Value)) { - long ticks; - if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out ticks)) + if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out long ticks)) { // If it's under 24 hours old we can still use it 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"] = newToken; + options.RequestHeaders["token"] = await GetToken(providerInfo, options.CancellationToken).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"] = newToken; + options.RequestHeaders["token"] = await GetToken(providerInfo, options.CancellationToken).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 " + // 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") { _logger.LogInformation("Authenticated with Schedules Direct token: " + root.token); @@ -828,13 +805,11 @@ namespace Emby.Server.Implementations.LiveTv.Listings try { 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) @@ -913,54 +888,41 @@ namespace Emby.Server.Implementations.LiveTv.Listings var list = new List<ChannelInfo>(); 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 " + root.map.Count + " channels on the lineup on ScheduleDirect"); - _logger.LogInformation("Mapping Stations to Channel"); - - var allStations = root.stations ?? new List<ScheduleDirect.Station>(); + 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"); - foreach (ScheduleDirect.Map map in root.map) - { - var channelNumber = GetChannelNumber(map); + var allStations = root.stations ?? Enumerable.Empty<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 - }; - } - - var name = channelNumber; + foreach (ScheduleDirect.Map map in root.map) + { + var channelNumber = GetChannelNumber(map); - var channelInfo = new ChannelInfo + var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase)); + if (station == null) + { + station = new ScheduleDirect.Station { - Number = channelNumber, - Name = name + stationID = map.stationID }; + } - 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; - } - } + var channelInfo = new ChannelInfo + { + Id = station.stationID, + CallSign = station.callsign, + Number = channelNumber, + Name = string.IsNullOrWhiteSpace(station.name) ? channelNumber : station.name + }; - list.Add(channelInfo); + if (station.logo != null) + { + channelInfo.ImageUrl = station.logo.URL; } + + list.Add(channelInfo); } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index ee2a9fe4b..a4ffbd2fe 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -132,9 +132,7 @@ namespace Emby.Server.Implementations.LiveTv { service.DataSourceChanged += service_DataSourceChanged; - var embyTv = service as EmbyTV.EmbyTV; - - if (embyTv != null) + if (service is EmbyTV.EmbyTV embyTv) { embyTv.TimerCreated += EmbyTv_TimerCreated; embyTv.TimerCancelled += EmbyTv_TimerCancelled; @@ -251,18 +249,15 @@ namespace Emby.Server.Implementations.LiveTv mediaSourceId = null; } - MediaSourceInfo info; - bool isVideo; - ILiveTvService service; - ILiveStream liveStream; - 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); - var supportsManagedStream = service as ISupportsDirectStreamProvider; - if (supportsManagedStream != null) + MediaSourceInfo info; + ILiveStream liveStream; + if (service is ISupportsDirectStreamProvider supportsManagedStream) { liveStream = await supportsManagedStream.GetChannelStreamWithDirectStreamProvider(channel.ExternalId, mediaSourceId, currentLiveStreams, cancellationToken).ConfigureAwait(false); info = liveStream.MediaSource; @@ -303,14 +298,12 @@ namespace Emby.Server.Implementations.LiveTv throw new NotImplementedException(); } - var list = sources.ToList(); - - foreach (var source in list) + foreach (var source in sources) { Normalize(source, service, baseItem.ChannelType == ChannelType.TV); } - return list; + return sources; } private ILiveTvService GetService(LiveTvChannel item) @@ -542,13 +535,11 @@ namespace Emby.Server.Implementations.LiveTv { var id = _tvDtoService.GetInternalProgramId(info.Id); - LiveTvProgram item = null; - allExistingPrograms.TryGetValue(id, out item); - var isNew = false; var forceUpdate = false; - if (item == null) + LiveTvProgram item; + if (!allExistingPrograms.TryGetValue(id, out item)) { isNew = true; item = new LiveTvProgram @@ -783,11 +774,9 @@ namespace Emby.Server.Implementations.LiveTv var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user); - var list = new List<Tuple<BaseItemDto, string, string>>(); - - var externalSeriesId = program.ExternalSeriesId; - - list.Add(new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, externalSeriesId)); + var list = new List<Tuple<BaseItemDto, string, string>>() { + new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, program.ExternalSeriesId) + }; await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false); @@ -928,13 +917,11 @@ namespace Emby.Server.Implementations.LiveTv programs = programs.Take(query.Limit.Value); } - var result = new QueryResult<BaseItem> - { - Items = programs.ToArray(), - TotalRecordCount = totalCount - }; - - return result; + return new QueryResult<BaseItem> + { + Items = programs.ToArray(), + TotalRecordCount = totalCount + }; } 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 user = query.User; - - var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user); - - var result = new QueryResult<BaseItemDto> - { - Items = returnArray, - TotalRecordCount = internalResult.TotalRecordCount - }; - - return result; + return new QueryResult<BaseItemDto> + { + Items = _dtoService.GetBaseItemDtos(internalResult.Items, options, query.User), + TotalRecordCount = internalResult.TotalRecordCount + }; } private int GetRecommendationScore(LiveTvProgram program, User user, bool factorChannelWatchCount) @@ -977,28 +958,26 @@ namespace Emby.Server.Implementations.LiveTv var channel = _libraryManager.GetItemById(program.ChannelId); - if (channel != null) + if (channel == null) { - var channelUserdata = _userDataManager.GetUserData(user, channel); + return score; + } - if (channelUserdata.Likes ?? false) - { - score += 2; - } - else if (!(channelUserdata.Likes ?? true)) - { - score -= 2; - } + var channelUserdata = _userDataManager.GetUserData(user, channel); - if (channelUserdata.IsFavorite) - { - score += 3; - } + if (channelUserdata.Likes.HasValue) + { + score += channelUserdata.Likes.Value ? 2 : -2; + } - if (factorChannelWatchCount) - { - score += channelUserdata.PlayCount; - } + if (channelUserdata.IsFavorite) + { + score += 3; + } + + if (factorChannelWatchCount) + { + score += channelUserdata.PlayCount; } return score; @@ -1153,7 +1132,6 @@ namespace Emby.Server.Implementations.LiveTv var numComplete = 0; var parentFolder = GetInternalLiveTvFolder(cancellationToken); - var parentFolderId = parentFolder.Id; foreach (var channelInfo in allChannelsList) { @@ -1239,30 +1217,11 @@ namespace Emby.Server.Implementations.LiveTv programs.Add(programItem.Id); - if (program.IsMovie) - { - isMovie = true; - } - - if (program.IsSeries) - { - iSSeries = true; - } - - if (program.IsSports) - { - isSports = true; - } - - if (program.IsNews) - { - isNews = true; - } - - if (program.IsKids) - { - isKids = true; - } + isMovie |= program.IsMovie; + iSSeries |= program.IsSeries; + isSports |= program.IsSports; + isNews |= program.IsNews; + isKids |= program.IsKids; } _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++; - double percent = numComplete; - percent /= allChannelsList.Count; + double percent = numComplete / allChannelsList.Count; progress.Report(85 * percent + 15); } @@ -1320,7 +1278,6 @@ namespace Emby.Server.Implementations.LiveTv { IncludeItemTypes = validTypes, DtoOptions = new DtoOptions(false) - }); var numComplete = 0; @@ -1351,8 +1308,7 @@ namespace Emby.Server.Implementations.LiveTv } numComplete++; - double percent = numComplete; - percent /= list.Count; + double percent = numComplete / list.Count; progress.Report(100 * percent); } @@ -1414,28 +1370,22 @@ namespace Emby.Server.Implementations.LiveTv 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("Family"); - } + genres.Add("Kids"); + genres.Add("Children"); + genres.Add("Family"); } var limit = query.Limit; - if ((query.IsInProgress ?? false)) + if (query.IsInProgress ?? false) { - limit = (query.Limit ?? 10) * 2; + // limit = (query.Limit ?? 10) * 2; limit = null; //var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray(); @@ -1467,7 +1417,7 @@ namespace Emby.Server.Implementations.LiveTv DtoOptions = dtoOptions }); - if ((query.IsInProgress ?? false)) + if (query.IsInProgress ?? false) { result.Items = result .Items @@ -1494,60 +1444,33 @@ namespace Emby.Server.Implementations.LiveTv dto.StartDate = program.StartDate; dto.EpisodeTitle = program.EpisodeTitle; - - if (program.IsRepeat) - { - dto.IsRepeat = program.IsRepeat; - } - if (program.IsMovie) - { - dto.IsMovie = program.IsMovie; - } - 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; - } + dto.IsRepeat |= program.IsRepeat; + dto.IsMovie |= program.IsMovie; + dto.IsSeries |= program.IsSeries; + dto.IsSports |= program.IsSports; + dto.IsLive |= program.IsLive; + dto.IsNews |= program.IsNews; + dto.IsKids |= program.IsKids; + dto.IsPremiere |= program.IsPremiere; 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.MediaType = channel.MediaType; - dto.ChannelNumber = channel.Number; + dto.ChannelName = liveChannel.Name; + dto.MediaType = liveChannel.MediaType; + 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, externalSeriesId)); + programTuples.Add(new Tuple<BaseItemDto, string, string>(dto, program.ExternalId, program.ExternalSeriesId)); } 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) { - var service = program != null ? - GetService(program) : - null; - - if (service == null) - { - service = _services.First(); - } - + ILiveTvService service = null; ProgramInfo programInfo = null; - if (program != null) + if(program != null) { + service = GetService(program); + var channel = _libraryManager.GetItemById(program.ChannelId); programInfo = new ProgramInfo @@ -2077,6 +1994,11 @@ namespace Emby.Server.Implementations.LiveTv Name = program.Name, OfficialRating = program.OfficialRating }; + } + + if (service == null) + { + service = _services.First(); } var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false); @@ -2147,8 +2069,7 @@ namespace Emby.Server.Implementations.LiveTv info.Priority = defaultValues.Priority; string newTimerId = null; - var supportsNewTimerIds = service as ISupportsNewTimerIds; - if (supportsNewTimerIds != null) + if (service is ISupportsNewTimerIds supportsNewTimerIds) { newTimerId = await supportsNewTimerIds.CreateTimer(info, cancellationToken).ConfigureAwait(false); newTimerId = _tvDtoService.GetInternalTimerId(newTimerId); @@ -2192,8 +2113,7 @@ namespace Emby.Server.Implementations.LiveTv info.Priority = defaultValues.Priority; string newTimerId = null; - var supportsNewTimerIds = service as ISupportsNewTimerIds; - if (supportsNewTimerIds != null) + if (service is ISupportsNewTimerIds supportsNewTimerIds) { newTimerId = await supportsNewTimerIds.CreateSeriesTimer(info, cancellationToken).ConfigureAwait(false); newTimerId = _tvDtoService.GetInternalSeriesTimerId(newTimerId).ToString("N"); @@ -2354,8 +2274,7 @@ namespace Emby.Server.Implementations.LiveTv throw new ResourceNotFoundException(); } - var configurable = provider as IConfigurableTunerHost; - if (configurable != null) + if (provider is IConfigurableTunerHost configurable) { await configurable.Validate(info).ConfigureAwait(false); } diff --git a/Emby.Server.Implementations/News/NewsEntryPoint.cs b/Emby.Server.Implementations/News/NewsEntryPoint.cs deleted file mode 100644 index ce6fe6630..000000000 --- a/Emby.Server.Implementations/News/NewsEntryPoint.cs +++ /dev/null @@ -1,279 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using Microsoft.Extensions.Logging; -using MediaBrowser.Model.News; -using MediaBrowser.Model.Notifications; -using MediaBrowser.Model.Serialization; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; -using MediaBrowser.Common.Progress; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Threading; - -namespace Emby.Server.Implementations.News -{ - public class NewsEntryPoint : IServerEntryPoint - { - private ITimer _timer; - private readonly IHttpClient _httpClient; - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - private readonly IJsonSerializer _json; - - private readonly INotificationManager _notifications; - private readonly IUserManager _userManager; - - private readonly TimeSpan _frequency = TimeSpan.FromHours(24); - private readonly ITimerFactory _timerFactory; - - public NewsEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IJsonSerializer json, INotificationManager notifications, IUserManager userManager, ITimerFactory timerFactory) - { - _httpClient = httpClient; - _appPaths = appPaths; - _fileSystem = fileSystem; - _logger = logger; - _json = json; - _notifications = notifications; - _userManager = userManager; - _timerFactory = timerFactory; - } - - public void Run() - { - _timer = _timerFactory.Create(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); - } - - /// <summary> - /// Called when [timer fired]. - /// </summary> - /// <param name="state">The state.</param> - private async void OnTimerFired(object state) - { - var path = Path.Combine(_appPaths.CachePath, "news.json"); - - try - { - await DownloadNews(path).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error downloading news"); - } - } - - private async Task DownloadNews(string path) - { - DateTime? lastUpdate = null; - - if (_fileSystem.FileExists(path)) - { - lastUpdate = _fileSystem.GetLastWriteTimeUtc(path); - } - - var requestOptions = new HttpRequestOptions - { - Url = "https://github.com/jellyfin/jellyfin", - Progress = new SimpleProgress<double>(), - UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36", - BufferContent = false - }; - - using (var response = await _httpClient.SendAsync(requestOptions, "GET").ConfigureAwait(false)) - { - using (var stream = response.Content) - { - using (var reader = XmlReader.Create(stream)) - { - var news = ParseRssItems(reader).ToList(); - - _json.SerializeToFile(news, path); - - await CreateNotifications(news, lastUpdate, CancellationToken.None).ConfigureAwait(false); - } - } - } - } - - private Task CreateNotifications(List<NewsItem> items, DateTime? lastUpdate, CancellationToken cancellationToken) - { - if (lastUpdate.HasValue) - { - items = items.Where(i => i.Date.ToUniversalTime() >= lastUpdate.Value) - .ToList(); - } - - var tasks = items.Select(i => _notifications.SendNotification(new NotificationRequest - { - Date = i.Date, - Name = i.Title, - Description = i.Description, - Url = i.Link, - UserIds = _userManager.Users.Select(u => u.Id).ToArray() - - }, cancellationToken)); - - return Task.WhenAll(tasks); - } - - private IEnumerable<NewsItem> ParseRssItems(XmlReader reader) - { - reader.MoveToContent(); - reader.Read(); - - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "channel": - { - if (!reader.IsEmptyElement) - { - using (var subReader = reader.ReadSubtree()) - { - return ParseFromChannelNode(subReader); - } - } - else - { - reader.Read(); - } - break; - } - default: - { - reader.Skip(); - break; - } - } - } - else - { - reader.Read(); - } - } - - return new List<NewsItem>(); - } - - private IEnumerable<NewsItem> ParseFromChannelNode(XmlReader reader) - { - var list = new List<NewsItem>(); - - reader.MoveToContent(); - reader.Read(); - - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "item": - { - if (!reader.IsEmptyElement) - { - using (var subReader = reader.ReadSubtree()) - { - list.Add(ParseItem(subReader)); - } - } - else - { - reader.Read(); - } - break; - } - default: - { - reader.Skip(); - break; - } - } - } - else - { - reader.Read(); - } - } - - return list; - } - - private NewsItem ParseItem(XmlReader reader) - { - var item = new NewsItem(); - - reader.MoveToContent(); - reader.Read(); - - while (!reader.EOF && reader.ReadState == ReadState.Interactive) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "title": - { - item.Title = reader.ReadElementContentAsString(); - break; - } - case "link": - { - item.Link = reader.ReadElementContentAsString(); - break; - } - case "description": - { - item.DescriptionHtml = reader.ReadElementContentAsString(); - item.Description = item.DescriptionHtml.StripHtml(); - break; - } - case "pubDate": - { - var date = reader.ReadElementContentAsString(); - DateTime parsedDate; - - if (DateTime.TryParse(date, out parsedDate)) - { - item.Date = parsedDate; - } - break; - } - default: - { - reader.Skip(); - break; - } - } - } - else - { - reader.Read(); - } - } - - return item; - } - - public void Dispose() - { - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } - } - } -} diff --git a/Emby.Server.Implementations/News/NewsService.cs b/Emby.Server.Implementations/News/NewsService.cs deleted file mode 100644 index 80e799634..000000000 --- a/Emby.Server.Implementations/News/NewsService.cs +++ /dev/null @@ -1,77 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Model.News; -using MediaBrowser.Model.Querying; -using MediaBrowser.Model.Serialization; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Emby.Server.Implementations.News -{ - public class NewsService : INewsService - { - private readonly IApplicationPaths _appPaths; - private readonly IJsonSerializer _json; - - public NewsService(IApplicationPaths appPaths, IJsonSerializer json) - { - _appPaths = appPaths; - _json = json; - } - - public QueryResult<NewsItem> GetProductNews(NewsQuery query) - { - try - { - return GetProductNewsInternal(query); - } - catch (FileNotFoundException) - { - // No biggie - return new QueryResult<NewsItem> - { - Items = new NewsItem[] { } - }; - } - catch (IOException) - { - // No biggie - return new QueryResult<NewsItem> - { - Items = new NewsItem[] { } - }; - } - } - - private QueryResult<NewsItem> GetProductNewsInternal(NewsQuery query) - { - var path = Path.Combine(_appPaths.CachePath, "news.json"); - - var items = GetNewsItems(path).OrderByDescending(i => i.Date); - - var itemsArray = items.ToArray(); - var count = itemsArray.Length; - - if (query.StartIndex.HasValue) - { - itemsArray = itemsArray.Skip(query.StartIndex.Value).ToArray(); - } - - if (query.Limit.HasValue) - { - itemsArray = itemsArray.Take(query.Limit.Value).ToArray(); - } - - return new QueryResult<NewsItem> - { - Items = itemsArray, - TotalRecordCount = count - }; - } - - private IEnumerable<NewsItem> GetNewsItems(string path) - { - return _json.DeserializeFromFile<List<NewsItem>>(path); - } - } -} diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index b4d18b69c..27741863b 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -549,13 +549,13 @@ namespace Emby.Server.Implementations.Updates // Do plugin-specific processing if (isPlugin) { - if (plugin != null) + if (plugin == null) { - OnPluginUpdated(plugin, package); + OnPluginInstalled(package); } else { - OnPluginInstalled(package); + OnPluginUpdated(plugin, package); } } } diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 7fccbcc9b..0ddc1e1dd 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -68,35 +68,6 @@ namespace MediaBrowser.Api _config.Configuration.IsStartupWizardCompleted = true; _config.SetOptimalValues(); _config.SaveConfiguration(); - - Task.Run(UpdateStats); - } - - private async Task UpdateStats() - { - try - { - var url = string.Format("http://www.mb3admin.local/admin/service/package/installed?mac={0}&product=MBServer&operation=Install&version={1}", - _appHost.SystemId, - _appHost.ApplicationVersion.ToString()); - - using (var response = await _httpClient.SendAsync(new HttpRequestOptions - { - - Url = url, - CancellationToken = CancellationToken.None, - LogErrors = false, - LogRequest = false - - }, "GET").ConfigureAwait(false)) - { - - } - } - catch - { - - } } public object Get(GetStartupConfiguration request) diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs index cf5511965..f88cfbb2b 100644 --- a/MediaBrowser.Common/Net/IHttpClient.cs +++ b/MediaBrowser.Common/Net/IHttpClient.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; +using System.IO; using System.Threading.Tasks; namespace MediaBrowser.Common.Net @@ -56,4 +53,4 @@ namespace MediaBrowser.Common.Net /// <returns>Task{HttpResponseInfo}.</returns> Task<HttpResponseInfo> GetTempFileResponse(HttpRequestOptions options); } -}
\ No newline at end of file +} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 5effba26b..09b783587 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -175,7 +175,6 @@ namespace MediaBrowser.Model.Configuration public int SchemaVersion { get; set; } - public bool EnableAnonymousUsageReporting { get; set; } public bool EnableFolderView { get; set; } public bool EnableGroupingIntoCollections { get; set; } public bool DisplaySpecialsWithinSeasons { get; set; } @@ -221,7 +220,6 @@ namespace MediaBrowser.Model.Configuration HttpsPortNumber = DefaultHttpsPort; EnableHttps = true; EnableDashboardResponseCaching = true; - EnableAnonymousUsageReporting = false; EnableCaseSensitiveItemIds = true; EnableAutomaticRestart = true; diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index d967d7b62..1ebf56e23 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -146,7 +146,7 @@ namespace MediaBrowser.Providers.Movies return _tmdbSettings; } - using (var response = await GetMovieDbResponse(new HttpRequestOptions + using (HttpResponseInfo response = await GetMovieDbResponse(new HttpRequestOptions { Url = string.Format(TmdbConfigUrl, ApiKey), CancellationToken = cancellationToken, @@ -154,7 +154,7 @@ namespace MediaBrowser.Providers.Movies }).ConfigureAwait(false)) { - using (var json = response.Content) + using (Stream json = response.Content) { _tmdbSettings = await _jsonSerializer.DeserializeFromStreamAsync<TmdbSettingsResult>(json).ConfigureAwait(false); |
