Initial commit to new repository
This commit is contained in:
163
.decompiledproj/AxCopilot/Handlers/WebSearchHandler.cs
Normal file
163
.decompiledproj/AxCopilot/Handlers/WebSearchHandler.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AxCopilot.SDK;
|
||||
using AxCopilot.Services;
|
||||
|
||||
namespace AxCopilot.Handlers;
|
||||
|
||||
public class WebSearchHandler : IActionHandler
|
||||
{
|
||||
private readonly SettingsService _settings;
|
||||
|
||||
private static readonly string _iconDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".", "Assets", "SearchEngines");
|
||||
|
||||
private static readonly Dictionary<string, (string Name, string UrlTemplate, string Icon)> _engines = new Dictionary<string, (string, string, string)>
|
||||
{
|
||||
["g"] = ("Google", "https://www.google.com/search?q={0}", "google"),
|
||||
["n"] = ("Naver", "https://search.naver.com/search.naver?query={0}", "naver"),
|
||||
["y"] = ("YouTube", "https://www.youtube.com/results?search_query={0}", "youtube"),
|
||||
["gh"] = ("GitHub", "https://github.com/search?q={0}", "github"),
|
||||
["d"] = ("DuckDuckGo", "https://duckduckgo.com/?q={0}", "duckduckgo"),
|
||||
["w"] = ("Wikipedia", "https://ko.wikipedia.org/w/index.php?search={0}", "wikipedia"),
|
||||
["nm"] = ("Naver Map", "https://map.naver.com/p/search/{0}", "navermap"),
|
||||
["nw"] = ("나무위키", "https://namu.wiki/Special:Search?query={0}", "namuwiki"),
|
||||
["ni"] = ("Naver 이미지", "https://search.naver.com/search.naver?where=image&query={0}", "naver"),
|
||||
["gi"] = ("Google 이미지", "https://www.google.com/search?tbm=isch&q={0}", "google")
|
||||
};
|
||||
|
||||
private const string SecurityWarn = "⚠ 검색어가 외부로 전송됩니다 — 기밀 데이터 입력 금지";
|
||||
|
||||
public string? Prefix => "?";
|
||||
|
||||
public PluginMetadata Metadata => new PluginMetadata("WebSearch", "웹 검색 — ? 뒤에 검색어 또는 URL 입력", "1.0", "AX");
|
||||
|
||||
private string DefaultEngineKey => _settings.Settings.Launcher.WebSearchEngine ?? "g";
|
||||
|
||||
private (string Name, string UrlTemplate, string Icon) DefaultEngine
|
||||
{
|
||||
get
|
||||
{
|
||||
(string, string, string) value;
|
||||
return _engines.TryGetValue(DefaultEngineKey, out value) ? value : _engines["g"];
|
||||
}
|
||||
}
|
||||
|
||||
public WebSearchHandler(SettingsService settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
private static string? GetIconPath(string engineKey)
|
||||
{
|
||||
if (!_engines.TryGetValue(engineKey, out (string, string, string) value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string text = Path.Combine(_iconDir, value.Item3 + ".png");
|
||||
return File.Exists(text) ? text : null;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
string iconPath = GetIconPath(DefaultEngineKey);
|
||||
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("검색어를 입력하세요", "예: ? 오늘 날씨 · ?g python · ?y 음악 · ?n 뉴스 | ⚠ 검색어가 외부로 전송됩니다 — 기밀 데이터 입력 금지", iconPath, null, null, "\ue774")));
|
||||
}
|
||||
List<LauncherItem> list = new List<LauncherItem>();
|
||||
string text = query.Trim();
|
||||
if (IsUrl(text))
|
||||
{
|
||||
string text2 = (text.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? text : ("https://" + text));
|
||||
string faviconPathForUrl = GetFaviconPathForUrl(text2);
|
||||
list.Add(new LauncherItem("열기: " + text, text2 + " | ⚠ 검색어가 외부로 전송됩니다 — 기밀 데이터 입력 금지", faviconPathForUrl, text2, null, "\ue774"));
|
||||
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
||||
}
|
||||
string[] array = text.Split(' ', 2);
|
||||
string text3 = array[0].ToLowerInvariant();
|
||||
if (array.Length == 2 && _engines.TryGetValue(text3, out (string, string, string) value))
|
||||
{
|
||||
string text4 = array[1].Trim();
|
||||
if (!string.IsNullOrWhiteSpace(text4))
|
||||
{
|
||||
string data = string.Format(value.Item2, Uri.EscapeDataString(text4));
|
||||
list.Add(new LauncherItem(value.Item1 + "에서 '" + text4 + "' 검색", "⚠ 검색어가 외부로 전송됩니다 — 기밀 데이터 입력 금지", GetIconPath(text3), data, null, "\ue774"));
|
||||
}
|
||||
}
|
||||
string defaultEngineKey = DefaultEngineKey;
|
||||
(string, string, string) defaultEngine = DefaultEngine;
|
||||
string data2 = string.Format(defaultEngine.Item2, Uri.EscapeDataString(text));
|
||||
list.Add(new LauncherItem(defaultEngine.Item1 + "에서 '" + text + "' 검색", "⚠ 검색어가 외부로 전송됩니다 — 기밀 데이터 입력 금지", GetIconPath(defaultEngineKey), data2, null, "\ue774"));
|
||||
if (text.Length <= 2)
|
||||
{
|
||||
foreach (var (text6, tuple2) in _engines)
|
||||
{
|
||||
list.Add(new LauncherItem("?" + text6 + " — " + tuple2.Item1, $"예: ?{text6} {text} | {"⚠ 검색어가 외부로 전송됩니다 — 기밀 데이터 입력 금지"}", GetIconPath(text6), null, null, "\ue774"));
|
||||
}
|
||||
}
|
||||
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
||||
{
|
||||
if (item.Data is string text && !string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(text)
|
||||
{
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Warn("웹 검색 열기 실패: " + ex.Message);
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static bool IsUrl(string input)
|
||||
{
|
||||
if (input.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || input.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!input.Contains(' ') && input.Contains('.') && input.Length > 3)
|
||||
{
|
||||
string text = input.Split('/')[0];
|
||||
string[] array = text.Split('.');
|
||||
return array.Length >= 2 && array[^1].Length >= 2 && array[^1].Length <= 6 && array[^1].All(char.IsLetter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string? GetFaviconPathForUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
url = "https://" + url;
|
||||
}
|
||||
string text = new Uri(url).Host.ToLowerInvariant();
|
||||
string text2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "favicons", text + ".png");
|
||||
if (File.Exists(text2))
|
||||
{
|
||||
return text2;
|
||||
}
|
||||
FaviconService.GetFavicon(url);
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user