cleanup for webapi things
This commit is contained in:
12
Torch.API/WebAPI/Plugin/IPluginQuery.cs
Normal file
12
Torch.API/WebAPI/Plugin/IPluginQuery.cs
Normal 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);
|
||||||
|
}
|
81
Torch.API/WebAPI/Plugin/LegacyPluginQuery.cs
Normal file
81
Torch.API/WebAPI/Plugin/LegacyPluginQuery.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
11
Torch.API/WebAPI/Plugin/PluginItem.cs
Normal file
11
Torch.API/WebAPI/Plugin/PluginItem.cs
Normal 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; }
|
||||||
|
}
|
3
Torch.API/WebAPI/Plugin/PluginsResponse.cs
Normal file
3
Torch.API/WebAPI/Plugin/PluginsResponse.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Torch.API.WebAPI.Plugin;
|
||||||
|
|
||||||
|
public record PluginsResponse(PluginItem[] Plugins);
|
6
Torch.API/WebAPI/Plugin/VersionItem.cs
Normal file
6
Torch.API/WebAPI/Plugin/VersionItem.cs
Normal 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);
|
@@ -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);
|
|
||||||
}
|
|
@@ -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
|
||||||
{
|
{
|
@@ -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
|
||||||
{
|
{
|
@@ -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
|
||||||
{
|
{
|
@@ -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);
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user