Initial commit to new repository
This commit is contained in:
180
.decompiledproj/AxCopilot/Handlers/JsonSkillHandler.cs
Normal file
180
.decompiledproj/AxCopilot/Handlers/JsonSkillHandler.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AxCopilot.SDK;
|
||||
using AxCopilot.Services;
|
||||
|
||||
namespace AxCopilot.Handlers;
|
||||
|
||||
public class JsonSkillHandler : IActionHandler
|
||||
{
|
||||
private readonly JsonSkillDefinition _def;
|
||||
|
||||
private readonly HttpClient _http = new HttpClient();
|
||||
|
||||
private List<LauncherItem>? _cache;
|
||||
|
||||
private DateTime _cacheExpiry = DateTime.MinValue;
|
||||
|
||||
public string? Prefix => _def.Prefix;
|
||||
|
||||
public PluginMetadata Metadata => new PluginMetadata(_def.Id, _def.Name, _def.Version, "JSON Skill");
|
||||
|
||||
public JsonSkillHandler(JsonSkillDefinition def)
|
||||
{
|
||||
_def = def;
|
||||
_http.Timeout = TimeSpan.FromSeconds(3.0);
|
||||
if (def.Credential?.Type == "bearer_token")
|
||||
{
|
||||
string token = CredentialManager.GetToken(def.Credential.CredentialKey);
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
||||
{
|
||||
if (_cache != null && DateTime.Now < _cacheExpiry)
|
||||
{
|
||||
return _cache;
|
||||
}
|
||||
if (_def.Request == null || _def.Response == null)
|
||||
{
|
||||
return Enumerable.Empty<LauncherItem>();
|
||||
}
|
||||
try
|
||||
{
|
||||
string url = _def.Request.Url.Replace("{{INPUT}}", Uri.EscapeDataString(query));
|
||||
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri parsedUrl) || (parsedUrl.Scheme != Uri.UriSchemeHttp && parsedUrl.Scheme != Uri.UriSchemeHttps))
|
||||
{
|
||||
LogService.Error("[" + _def.Name + "] 유효하지 않은 URL: " + url);
|
||||
return new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("설정 오류", "스킬 URL이 유효하지 않습니다 (http/https만 허용)", null, null));
|
||||
}
|
||||
string text = _def.Request.Method.ToUpper();
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
HttpResponseMessage httpResponseMessage = ((!(text == "POST")) ? (await _http.GetAsync(url, ct)) : (await _http.PostAsync(url, BuildBody(query), ct)));
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
HttpResponseMessage response = httpResponseMessage;
|
||||
response.EnsureSuccessStatusCode();
|
||||
List<LauncherItem> items = ParseResults(await response.Content.ReadAsStringAsync(ct));
|
||||
JsonSkillCache? cache = _def.Cache;
|
||||
if (cache != null && cache.Ttl > 0)
|
||||
{
|
||||
_cache = items;
|
||||
_cacheExpiry = DateTime.Now.AddSeconds(_def.Cache.Ttl);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
if (_cache != null)
|
||||
{
|
||||
LogService.Warn("[" + _def.Name + "] API 타임아웃, 캐시 반환");
|
||||
return _cache;
|
||||
}
|
||||
return new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("네트워크 오류", "연결을 확인하세요", null, null));
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
LogService.Error("[" + _def.Name + "] API 호출 실패: " + ex2.Message);
|
||||
return new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("오류: " + ex2.Message, _def.Name, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
||||
{
|
||||
if (item.ActionUrl != null && Uri.TryCreate(item.ActionUrl, UriKind.Absolute, out Uri result) && (result.Scheme == Uri.UriSchemeHttp || result.Scheme == Uri.UriSchemeHttps))
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(item.ActionUrl)
|
||||
{
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private HttpContent BuildBody(string query)
|
||||
{
|
||||
string content = JsonSerializer.Serialize(_def.Request?.Body).Replace("\"{{INPUT}}\"", "\"" + query + "\"");
|
||||
return new StringContent(content, Encoding.UTF8, "application/json");
|
||||
}
|
||||
|
||||
private List<LauncherItem> ParseResults(string json)
|
||||
{
|
||||
List<LauncherItem> list = new List<LauncherItem>();
|
||||
try
|
||||
{
|
||||
JsonNode jsonNode = JsonNode.Parse(json);
|
||||
if (jsonNode == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
JsonNode jsonNode2 = NavigatePath(jsonNode, _def.Response.ResultsPath);
|
||||
if (!(jsonNode2 is JsonArray source))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
foreach (JsonNode item in source.Take(10))
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
string title = NavigatePath(item, _def.Response.TitleField)?.ToString() ?? "(제목 없음)";
|
||||
string subtitle = ((_def.Response.SubtitleField == null) ? "" : (NavigatePath(item, _def.Response.SubtitleField)?.ToString() ?? ""));
|
||||
string actionUrl = ((_def.Response.ActionUrl == null) ? null : NavigatePath(item, _def.Response.ActionUrl)?.ToString());
|
||||
list.Add(new LauncherItem(title, subtitle, null, item, actionUrl, "\ue82d"));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("[" + _def.Name + "] 응답 파싱 실패: " + ex.Message);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static JsonNode? NavigatePath(JsonNode root, string path)
|
||||
{
|
||||
string[] array = path.Split('.');
|
||||
JsonNode jsonNode = root;
|
||||
string[] array2 = array;
|
||||
foreach (string text in array2)
|
||||
{
|
||||
if (jsonNode == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int num = text.IndexOf('[');
|
||||
if (num >= 0)
|
||||
{
|
||||
int num2 = text.IndexOf(']');
|
||||
if (num2 < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string propertyName = text.Substring(0, num);
|
||||
int num3 = num + 1;
|
||||
int index = int.Parse(text.Substring(num3, num2 - num3));
|
||||
jsonNode = jsonNode[propertyName]?[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonNode = jsonNode[text];
|
||||
}
|
||||
}
|
||||
return jsonNode;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user