cleanup for webapi things

This commit is contained in:
zznty
2022-12-02 15:44:38 +07:00
parent ead8e3a4fc
commit 8478ee3752
14 changed files with 125 additions and 112 deletions

View File

@@ -0,0 +1,12 @@
using System;
using System.Threading.Tasks;
namespace Torch.API.WebAPI.Plugin;
public interface IPluginQuery
{
Task<PluginsResponse> QueryAll();
Task<PluginItem> QueryOne(Guid guid);
Task<bool> DownloadPlugin(Guid guid, string path = null);
Task<bool> DownloadPlugin(PluginItem item, string path = null);
}

View File

@@ -0,0 +1,81 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using NLog;
namespace Torch.API.WebAPI.Plugin;
public class LegacyPluginQuery : IPluginQuery
{
private const string BASE_URL = "https://torchapi.com/api/plugins/";
private readonly HttpClient _client;
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private LegacyPluginQuery()
{
_client = new()
{
BaseAddress = new(BASE_URL)
};
}
public static LegacyPluginQuery Instance { get; } = new();
public async Task<PluginsResponse> QueryAll()
{
return await _client.GetFromJsonAsync<PluginsResponse>("/", CancellationToken.None);
}
public async Task<PluginItem> QueryOne(Guid guid)
{
using var res = await _client.GetAsync($"/search/{guid}");
if (!res.IsSuccessStatusCode)
return null;
return await res.Content.ReadFromJsonAsync<PluginItem>();
}
public async Task<bool> DownloadPlugin(Guid guid, string path = null)
{
var item = await QueryOne(guid);
if (item is null) return false;
return await DownloadPlugin(item, path);
}
public async Task<bool> DownloadPlugin(PluginItem item, string path = null)
{
try
{
path ??= Path.Combine(AppContext.BaseDirectory, "Plugins", $"{item.Name}.zip");
if (item.Versions.Length == 0)
{
Log.Error($"Selected plugin {item.Name} does not have any versions to download!");
return false;
}
var version = item.Versions.FirstOrDefault(v => v.Version == item.LatestVersion);
if (version is null)
{
Log.Error($"Could not find latest version for selected plugin {item.Name}");
return false;
}
var s = await _client.GetStreamAsync(version.Url);
if(File.Exists(path))
File.Delete(path);
await using var f = File.Create(path);
await s.CopyToAsync(f);
}
catch (Exception ex)
{
Log.Error(ex, "Failed to download plugin!");
return false;
}
return true;
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Text.Json.Serialization;
namespace Torch.API.WebAPI.Plugin;
public record PluginItem(Guid Id, string Name, string Author, string Description, string LatestVersion,
VersionItem[] Versions)
{
[JsonIgnore]
public bool Installed { get; set; }
}

View File

@@ -0,0 +1,3 @@
namespace Torch.API.WebAPI.Plugin;
public record PluginsResponse(PluginItem[] Plugins);

View File

@@ -0,0 +1,6 @@
using System.Text.Json.Serialization;
namespace Torch.API.WebAPI.Plugin;
public record VersionItem(string Version, string Note, [property: JsonPropertyName("is_beta")] bool IsBeta,
string Url);

View File

@@ -1,104 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using NLog;
namespace Torch.API.WebAPI
{
public class PluginQuery
{
private const string ALL_QUERY = "https://torchapi.com/api/plugins/";
private const string PLUGIN_QUERY = "https://torchapi.com/api/plugins/search/{0}";
private readonly HttpClient _client;
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private static PluginQuery _instance;
public static PluginQuery Instance => _instance ??= new();
private PluginQuery()
{
_client = new();
}
public async Task<PluginsResponse> QueryAll()
{
return (PluginsResponse) await _client.GetFromJsonAsync(ALL_QUERY, typeof(PluginsResponse), CancellationToken.None);
}
public Task<PluginItem> QueryOne(Guid guid)
{
return QueryOne(guid.ToString());
}
public async Task<PluginItem> QueryOne(string guid)
{
using var res = await _client.GetAsync(string.Format(PLUGIN_QUERY, guid));
if (!res.IsSuccessStatusCode)
return null;
return await res.Content.ReadFromJsonAsync<PluginItem>();
}
public Task<bool> DownloadPlugin(Guid guid, string path = null)
{
return DownloadPlugin(guid.ToString(), path);
}
public async Task<bool> DownloadPlugin(string guid, string path = null)
{
var item = await QueryOne(guid);
if (item is null) return false;
return await DownloadPlugin(item, path);
}
public async Task<bool> DownloadPlugin(PluginItem item, string path = null)
{
try
{
path ??= Path.Combine(AppContext.BaseDirectory, "Plugins", $"{item.Name}.zip");
if (item.Versions.Length == 0)
{
Log.Error($"Selected plugin {item.Name} does not have any versions to download!");
return false;
}
var version = item.Versions.FirstOrDefault(v => v.Version == item.LatestVersion);
if (version is null)
{
Log.Error($"Could not find latest version for selected plugin {item.Name}");
return false;
}
var s = await _client.GetStreamAsync(version.Url);
if(File.Exists(path))
File.Delete(path);
await using var f = File.Create(path);
await s.CopyToAsync(f);
}
catch (Exception ex)
{
Log.Error(ex, "Failed to download plugin!");
}
return true;
}
}
public record PluginsResponse(PluginItem[] Plugins);
public record PluginItem(Guid Id, string Name, string Author, string Description, string LatestVersion,
VersionItem[] Versions)
{
[JsonIgnore]
public bool Installed { get; set; }
}
public record VersionItem(string Version, string Note, [property: JsonPropertyName("is_beta")] bool IsBeta,
string Url);
}

View File

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
using JorgeSerrano.Json; using JorgeSerrano.Json;
using Version = SemanticVersioning.Version; using Version = SemanticVersioning.Version;
namespace Torch.API.WebAPI; namespace Torch.API.WebAPI.Update;
public class GithubQuery : IUpdateQuery public class GithubQuery : IUpdateQuery
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Torch.API.WebAPI; namespace Torch.API.WebAPI.Update;
public interface IUpdateQuery : IDisposable public interface IUpdateQuery : IDisposable
{ {

View File

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
using Torch.API.Utils; using Torch.API.Utils;
using Version = SemanticVersioning.Version; using Version = SemanticVersioning.Version;
namespace Torch.API.WebAPI namespace Torch.API.WebAPI.Update
{ {
public class JenkinsQuery : IUpdateQuery public class JenkinsQuery : IUpdateQuery
{ {

View File

@@ -1,5 +1,5 @@
using SemanticVersioning; using SemanticVersioning;
namespace Torch.API.WebAPI; namespace Torch.API.WebAPI.Update;
public record UpdateRelease(Version Version, string ArtifactUrl); public record UpdateRelease(Version Version, string ArtifactUrl);

View File

@@ -22,6 +22,7 @@ using Torch.Collections;
using Torch.Server.Annotations; using Torch.Server.Annotations;
using Torch.Managers; using Torch.Managers;
using Torch.API.Managers; using Torch.API.Managers;
using Torch.API.WebAPI.Plugin;
namespace Torch.Server.Views namespace Torch.Server.Views
{ {
@@ -60,7 +61,7 @@ namespace Torch.Server.Views
{ {
try try
{ {
var res = await PluginQuery.Instance.QueryAll(); var res = await LegacyPluginQuery.Instance.QueryAll();
foreach (var item in res.Plugins.OrderBy(i => i.Name)) { foreach (var item in res.Plugins.OrderBy(i => i.Name)) {
lock (_syncLock) lock (_syncLock)
{ {

View File

@@ -14,6 +14,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Shapes; using System.Windows.Shapes;
using System.ComponentModel; using System.ComponentModel;
using Torch.API.WebAPI.Plugin;
namespace Torch.Server.Views namespace Torch.Server.Views
{ {
@@ -50,7 +51,7 @@ namespace Torch.Server.Views
var PercentChangeOnDownload = 100 / PluginsToDownload.Count; var PercentChangeOnDownload = 100 / PluginsToDownload.Count;
foreach (PluginItem PluginItem in PluginsToDownload) { foreach (PluginItem PluginItem in PluginsToDownload) {
if (!PluginQuery.Instance.DownloadPlugin(PluginItem.Id).Result) { if (!LegacyPluginQuery.Instance.DownloadPlugin(PluginItem.Id).Result) {
failedDownloads++; failedDownloads++;
DownloadProgress += PercentChangeOnDownload; DownloadProgress += PercentChangeOnDownload;
(sender as BackgroundWorker).ReportProgress(DownloadProgress); (sender as BackgroundWorker).ReportProgress(DownloadProgress);

View File

@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using NLog; using NLog;
using Torch.API; using Torch.API;
using Torch.API.WebAPI; using Torch.API.WebAPI;
using Torch.API.WebAPI.Update;
namespace Torch.Managers namespace Torch.Managers
{ {

View File

@@ -16,6 +16,7 @@ using Torch.API.Managers;
using Torch.API.Plugins; using Torch.API.Plugins;
using Torch.API.Session; using Torch.API.Session;
using Torch.API.WebAPI; using Torch.API.WebAPI;
using Torch.API.WebAPI.Plugin;
using Torch.Collections; using Torch.Collections;
using Torch.Commands; using Torch.Commands;
using Torch.Plugins; using Torch.Plugins;
@@ -306,7 +307,7 @@ namespace Torch.Managers
return; return;
} }
item.Manifest.Version.TryExtractVersion(out Version currentVersion); item.Manifest.Version.TryExtractVersion(out Version currentVersion);
var latest = await PluginQuery.Instance.QueryOne(item.Manifest.Guid); var latest = await LegacyPluginQuery.Instance.QueryOne(item.Manifest.Guid);
if (latest?.LatestVersion == null) if (latest?.LatestVersion == null)
{ {
@@ -329,7 +330,7 @@ namespace Torch.Managers
} }
_log.Info($"Updating plugin '{item.Manifest.Name}' from {currentVersion} to {newVersion}."); _log.Info($"Updating plugin '{item.Manifest.Name}' from {currentVersion} to {newVersion}.");
await PluginQuery.Instance.DownloadPlugin(latest, item.Path); await LegacyPluginQuery.Instance.DownloadPlugin(latest, item.Path);
Interlocked.Increment(ref count); Interlocked.Increment(ref count);
} }
catch (Exception e) catch (Exception e)