diff --git a/src/Ombi.Api/Api.cs b/src/Ombi.Api/Api.cs index 764da5a13..7a8e7678b 100644 --- a/src/Ombi.Api/Api.cs +++ b/src/Ombi.Api/Api.cs @@ -16,14 +16,14 @@ namespace Ombi.Api { public class Api : IApi { - public Api(ILogger log, IOmbiHttpClient client) + public Api(ILogger log, HttpClient client) { Logger = log; _client = client; } private ILogger Logger { get; } - private readonly IOmbiHttpClient _client; + private readonly HttpClient _client; public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings { diff --git a/src/Ombi.Api/IOmbiHttpClient.cs b/src/Ombi.Api/IOmbiHttpClient.cs deleted file mode 100644 index 1f6ff9514..000000000 --- a/src/Ombi.Api/IOmbiHttpClient.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Ombi.Api -{ - public interface IOmbiHttpClient - { - Task SendAsync(HttpRequestMessage request); - Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); - Task GetStringAsync(Uri requestUri); - } -} \ No newline at end of file diff --git a/src/Ombi.Api/Ombi.Api.csproj b/src/Ombi.Api/Ombi.Api.csproj index 98da29c2a..91821c83b 100644 --- a/src/Ombi.Api/Ombi.Api.csproj +++ b/src/Ombi.Api/Ombi.Api.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Ombi.Api/OmbiHttpClient.cs b/src/Ombi.Api/OmbiHttpClient.cs deleted file mode 100644 index 978476cf7..000000000 --- a/src/Ombi.Api/OmbiHttpClient.cs +++ /dev/null @@ -1,110 +0,0 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2017 Jamie Rees -// File: OmbiHttpClient.cs -// Created By: Jamie Rees -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// ************************************************************************/ -#endregion - -using System; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Ombi.Core.Settings; -using Ombi.Helpers; -using Ombi.Settings.Settings.Models; - -namespace Ombi.Api -{ - /// - /// The purpose of this class is simple, keep one instance of the HttpClient in play. - /// There are many articles related to when using multiple HttpClient's keeping the socket in a WAIT state - /// https://blogs.msdn.microsoft.com/alazarev/2017/12/29/disposable-finalizers-and-httpclient/ - /// https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ - /// - public class OmbiHttpClient : IOmbiHttpClient - { - public OmbiHttpClient(ICacheService cache, ISettingsService s) - { - _cache = cache; - _settings = s; - _runtimeVersion = AssemblyHelper.GetRuntimeVersion(); - } - - private static HttpClient _client; - private static HttpMessageHandler _handler; - - private readonly ICacheService _cache; - private readonly ISettingsService _settings; - private readonly string _runtimeVersion; - - - public async Task SendAsync(HttpRequestMessage request) - { - await Setup(); - return await _client.SendAsync(request); - } - - public async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - await Setup(); - return await _client.SendAsync(request, cancellationToken); - } - - public async Task GetStringAsync(Uri requestUri) - { - await Setup(); - return await _client.GetStringAsync(requestUri); - } - - private async Task Setup() - { - if (_client == null) - { - if (_handler == null) - { - // Get the handler - _handler = await GetHandler(); - } - _client = new HttpClient(_handler); - _client.DefaultRequestHeaders.Add("User-Agent", $"Ombi/{_runtimeVersion} (https://ombi.io/)"); - } - } - - private async Task GetHandler() - { - if (_cache == null) - { - return new HttpClientHandler(); - } - var settings = await _cache.GetOrAdd(CacheKeys.OmbiSettings, async () => await _settings.GetSettingsAsync(), DateTime.Now.AddHours(1)); - if (settings.IgnoreCertificateErrors) - { - return new HttpClientHandler - { - ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true, - }; - } - return new HttpClientHandler(); - } - } -} \ No newline at end of file diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index ef9c9230c..73a69203a 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -23,7 +23,6 @@ using Ombi.Notifications; using Ombi.Schedule; using Ombi.Schedule.Jobs; using Ombi.Settings.Settings; -using Ombi.Store.Context; using Ombi.Store.Repository; using Ombi.Notifications.Agents; using Ombi.Schedule.Jobs.Radarr; @@ -68,6 +67,8 @@ using Ombi.Api.MusicBrainz; using Ombi.Api.Twilio; using Ombi.Api.CloudService; using Ombi.Api.RottenTomatoes; +using System.Net.Http; +using Microsoft.Extensions.Logging; namespace Ombi.DependencyInjection { @@ -119,14 +120,24 @@ namespace Ombi.DependencyInjection public static void RegisterHttp(this IServiceCollection services) { + var runtimeVersion = AssemblyHelper.GetRuntimeVersion(); services.AddSingleton(); services.AddScoped(sp => sp.GetService().HttpContext.User); + services.AddHttpClient("OmbiClient", client => + { + client.DefaultRequestHeaders.Add("User-Agent", $"Ombi/{runtimeVersion} (https://ombi.io/)"); + }).ConfigurePrimaryHttpMessageHandler(() => + { + var httpClientHandler = new HttpClientHandler(); + httpClientHandler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true; + + return httpClientHandler; + }); } public static void RegisterApi(this IServiceCollection services) { - services.AddScoped(); - services.AddScoped(); // https://blogs.msdn.microsoft.com/alazarev/2017/12/29/disposable-finalizers-and-httpclient/ + services.AddScoped(s => new Api.Api(s.GetRequiredService>(), s.GetRequiredService().CreateClient("OmbiClient"))); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj index ed1e9e4a2..49d1dd194 100644 --- a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj +++ b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs index 85765b6c6..4c856c9cd 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs @@ -5,6 +5,6 @@ namespace Ombi.Schedule.Jobs.Ombi public interface IOmbiAutomaticUpdater : IBaseJob { string[] GetVersion(); - Task UpdateAvailable(string branch, string currentVersion); + Task UpdateAvailable(string currentVersion); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs index e44728698..c2cf42441 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs @@ -49,10 +49,10 @@ namespace Ombi.Schedule.Jobs.Ombi var productArray = productVersion.Split('-'); return productArray; } - public async Task UpdateAvailable(string branch, string currentVersion) + public async Task UpdateAvailable(string currentVersion) { - var updates = await Processor.Process(branch); + var updates = await Processor.Process(); var serverVersion = updates.UpdateVersionString; return !serverVersion.Equals(currentVersion, StringComparison.CurrentCultureIgnoreCase); @@ -88,7 +88,7 @@ namespace Ombi.Schedule.Jobs.Ombi Logger.LogDebug(LoggingEvents.Updater, "Looking for updates now"); //TODO this fails because the branch = featureupdater when it should be feature/updater - var updates = await Processor.Process(branch); + var updates = await Processor.Process(); Logger.LogDebug(LoggingEvents.Updater, "Updates: {0}", updates); diff --git a/src/Ombi.Schedule/Processor/AppVeyor.cs b/src/Ombi.Schedule/Processor/AppVeyor.cs index 6bb4e001c..5a760c50c 100644 --- a/src/Ombi.Schedule/Processor/AppVeyor.cs +++ b/src/Ombi.Schedule/Processor/AppVeyor.cs @@ -109,8 +109,8 @@ namespace Ombi.Core.Processor public string UpdateVersionString { get; set; } public int UpdateVersion { get; set; } public DateTime UpdateDate { get; set; } - - public List ChangeLogs { get; set; } + public bool UpdateAvailable { get; set; } + public string ChangeLogs { get; set; } public List Downloads { get; set; } } diff --git a/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs b/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs index a34bd89e1..89a6519e6 100644 --- a/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs +++ b/src/Ombi.Schedule/Processor/ChangeLogProcessor.cs @@ -16,94 +16,41 @@ namespace Ombi.Schedule.Processor { public class ChangeLogProcessor : IChangeLogProcessor { - public ChangeLogProcessor(IApi api, IOmbiHttpClient client) + public ChangeLogProcessor(IApi api, IHttpClientFactory client) { _api = api; - _client = client; + _client = client.CreateClient("OmbiClient"); } private readonly IApi _api; - private readonly IOmbiHttpClient _client; + private readonly HttpClient _client; private const string _changeLogUrl = "https://raw.githubusercontent.com/tidusjar/Ombi/{0}/CHANGELOG.md"; private const string AppveyorApiUrl = "https://ci.appveyor.com/api"; private string ChangeLogUrl(string branch) => string.Format(_changeLogUrl, branch); - public async Task Process(string branch) + public async Task Process() { - var masterBranch = branch.Equals("master", StringComparison.CurrentCultureIgnoreCase); - string githubChangeLog; - - githubChangeLog = await _client.GetStringAsync(new Uri(ChangeLogUrl(branch))); - - - var html = Markdown.ToHtml(githubChangeLog); - - - var doc = new HtmlDocument(); - doc.LoadHtml(html); - - HtmlNode latestRelease; - if (masterBranch) - { - latestRelease = doc.DocumentNode.Descendants("h2") - .FirstOrDefault(x => x.InnerText != "(unreleased)"); - } - else - { - latestRelease = doc.DocumentNode.Descendants("h2") - .FirstOrDefault(x => x.InnerText == "(unreleased)"); - - if (latestRelease == null) - { - latestRelease = doc.DocumentNode.Descendants("h2") - .FirstOrDefault(x => x.InnerText != "(unreleased)"); - } - } - - var newFeatureList = latestRelease.NextSibling.NextSibling.NextSibling.NextSibling; - var featuresString = newFeatureList.ChildNodes.Where(x => x.Name != "#text").Select(x => x.InnerText.Replace("\\n", "")).ToList(); - var fixes = newFeatureList.NextSibling.NextSibling.NextSibling.NextSibling; - var fixesString = fixes.ChildNodes.Where(x => x.Name != "#text").Select(x => x.InnerText.Replace("\\n", "")).ToList(); - - // Cleanup - var featuresList = featuresString.Distinct().ToList(); - var fixesList = fixesString.Distinct().ToList(); - - // Get release var release = new Release { - Version = latestRelease.InnerText, - Features = featuresList, - Fixes = fixesList, Downloads = new List() }; - if (masterBranch) - { - var releaseTag = latestRelease.InnerText.Substring(0, 9); - await GetGitubRelease(release, releaseTag); - } - else - { - // Get AppVeyor - await GetAppVeyorRelease(release, branch); - } - - - return TransformUpdate(release,!masterBranch); - + await GetGitubRelease(release); + + return TransformUpdate(release); } - private UpdateModel TransformUpdate(Release release, bool develop) + private UpdateModel TransformUpdate(Release release) { var newUpdate = new UpdateModel { - UpdateVersionString = develop ? release.Version : release.Version.Substring(1,8), - UpdateVersion = release.Version == "(unreleased)" ? 0 : int.Parse(release.Version.Substring(1, 5).Replace(".", "")), + UpdateVersionString = release.Version, + UpdateVersion = int.Parse(release.Version.Substring(1, 5).Replace(".", "")), UpdateDate = DateTime.Now, - ChangeLogs = new List(), - Downloads = new List() - }; + ChangeLogs = release.Description, + Downloads = new List(), + UpdateAvailable = release.Version != AssemblyHelper.GetRuntimeVersion() + }; foreach (var dl in release.Downloads) { @@ -114,75 +61,16 @@ namespace Ombi.Schedule.Processor }); } - foreach (var f in release.Features) - { - var change = new ChangeLog - { - Descripion = f, - Type = "New", - }; - - newUpdate.ChangeLogs.Add(change); - } - - foreach (var f in release.Fixes) - { - var change = new ChangeLog - { - Descripion = f, - Type = "Fixed", - }; - - newUpdate.ChangeLogs.Add(change); - } - return newUpdate; } - private async Task GetAppVeyorRelease(Release release, string branch) + private async Task GetGitubRelease(Release release) { - var request = new Request($"/projects/tidusjar/requestplex/branch/{branch}", AppVeyorApi.AppveyorApiUrl, HttpMethod.Get); - request.ApplicationJsonContentType(); + var client = new GitHubClient(Octokit.ProductHeaderValue.Parse("OmbiV4")); - var builds = await _api.Request(request); - var jobId = builds.build.jobs.FirstOrDefault()?.jobId ?? string.Empty; + var releases = await client.Repository.Release.GetAll("ombi-app", "ombi"); + var latest = releases.OrderByDescending(x => x.CreatedAt).FirstOrDefault(); - if (builds.build.finished == DateTime.MinValue || builds.build.status.Equals("failed")) - { - return; - } - release.Version = builds.build.version; - // get the artifacts - request = new Request($"/buildjobs/{jobId}/artifacts", AppVeyorApi.AppveyorApiUrl, HttpMethod.Get); - request.ApplicationJsonContentType(); - - var artifacts = await _api.Request>(request); - - foreach (var item in artifacts) - { - var d = new Downloads - { - Name = item.fileName, - Url = $"{AppveyorApiUrl}/buildjobs/{jobId}/artifacts/{item.fileName}" - }; - release.Downloads.Add(d); - } - } - - private async Task GetGitubRelease(Release release, string releaseTag) - { - var client = new GitHubClient(Octokit.ProductHeaderValue.Parse("OmbiV3")); - - var releases = await client.Repository.Release.GetAll("tidusjar", "ombi"); - var latest = releases.FirstOrDefault(x => x.TagName.Equals(releaseTag, StringComparison.InvariantCultureIgnoreCase)); - if (latest.Name.Contains("V2", CompareOptions.IgnoreCase)) - { - latest = null; - } - if (latest == null) - { - latest = releases.OrderByDescending(x => x.CreatedAt).FirstOrDefault(); - } foreach (var item in latest.Assets) { var d = new Downloads @@ -192,6 +80,8 @@ namespace Ombi.Schedule.Processor }; release.Downloads.Add(d); } + release.Description = Markdown.ToHtml(latest.Body); + release.Version = latest.TagName; } } public class Release @@ -199,8 +89,7 @@ namespace Ombi.Schedule.Processor public string Version { get; set; } public string CheckinVersion { get; set; } public List Downloads { get; set; } - public List Features { get; set; } - public List Fixes { get; set; } + public string Description { get; set; } } public class Downloads diff --git a/src/Ombi.Schedule/Processor/IChangeLogProcessor.cs b/src/Ombi.Schedule/Processor/IChangeLogProcessor.cs index 97780245f..434faedd2 100644 --- a/src/Ombi.Schedule/Processor/IChangeLogProcessor.cs +++ b/src/Ombi.Schedule/Processor/IChangeLogProcessor.cs @@ -4,6 +4,6 @@ namespace Ombi.Core.Processor { public interface IChangeLogProcessor { - Task Process(string branch); + Task Process(); } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/Models/OmbiSettings.cs b/src/Ombi.Settings/Settings/Models/OmbiSettings.cs index 36b540026..6c622f2ce 100644 --- a/src/Ombi.Settings/Settings/Models/OmbiSettings.cs +++ b/src/Ombi.Settings/Settings/Models/OmbiSettings.cs @@ -6,7 +6,6 @@ public bool CollectAnalyticData { get; set; } public bool Wizard { get; set; } public string ApiKey { get; set; } - public bool IgnoreCertificateErrors { get; set; } public bool DoNotSendNotificationsForAutoApprove { get; set; } public bool HideRequestsUsers { get; set; } public bool DisableHealthChecks { get; set; } diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts index c5b29adff..7fa710248 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts @@ -12,7 +12,6 @@ export interface IOmbiSettings extends ISettings { collectAnalyticData: boolean; wizard: boolean; apiKey: string; - ignoreCertificateErrors: boolean; doNotSendNotificationsForAutoApprove: boolean; hideRequestsUsers: boolean; defaultLanguageCode: string; @@ -285,3 +284,19 @@ export interface ITheMovieDbSettings extends ISettings { showAdultMovies: boolean; excludedKeywordIds: number[]; } + +export interface IUpdateModel +{ + updateVersionString: string; + updateVersion: number; + updateDate: Date, + updateAvailable: boolean; + changeLogs: string; + downloads: IUpdateDonloads[]; +} + +export interface IUpdateDonloads +{ + name: string; + url: string +} diff --git a/src/Ombi/ClientApp/src/app/services/update.service.ts b/src/Ombi/ClientApp/src/app/services/update.service.ts new file mode 100644 index 000000000..d1e84cfaf --- /dev/null +++ b/src/Ombi/ClientApp/src/app/services/update.service.ts @@ -0,0 +1,18 @@ +import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; +import { Injectable, Inject } from "@angular/core"; + +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; + +import { ServiceHelpers } from "./service.helpers"; +import { IUpdateModel } from "../interfaces"; + +@Injectable() +export class UpdateService extends ServiceHelpers { + constructor(http: HttpClient, @Inject(APP_BASE_HREF) href:string) { + super(http, "/api/v1/Update/", href); + } + public checkForUpdate(): Observable { + return this.http.get(`${this.url}`, {headers: this.headers}); + } +} diff --git a/src/Ombi/ClientApp/src/app/settings/about/about.component.html b/src/Ombi/ClientApp/src/app/settings/about/about.component.html index e6eb05cb4..f4872eda7 100644 --- a/src/Ombi/ClientApp/src/app/settings/about/about.component.html +++ b/src/Ombi/ClientApp/src/app/settings/about/about.component.html @@ -13,8 +13,8 @@
Version
-
{{about.version}} (New Update Available)
+
{{about.version}} (New Update Available)