fix: 修复文件列表为空时的返回值处理并添加图像处理相关依赖

This commit is contained in:
Megghy
2025-09-29 13:41:32 +08:00
parent 7abe753401
commit 360cc79e18
12 changed files with 1913 additions and 0 deletions

177
Modules/ProxyManager.cs Normal file
View File

@@ -0,0 +1,177 @@
using System.Net;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Caching.Memory;
namespace MegghysAPI.Modules
{
/// <summary>
/// 代理IP管理器
/// </summary>
public static class ProxyManager
{
// 用于获取代理IP的客户端不使用代理
private static readonly HttpClient ProxyApiHttpClient = new();
// 缓存代理IP的响应
private static readonly MemoryCache ProxyResponseCache = new(new MemoryCacheOptions());
// 缓存配置了代理的HttpClient
private static readonly MemoryCache HttpClientCache = new(new MemoryCacheOptions());
private const string BaseUrl = "https://share.proxy.qg.net/get";
private const string DefaultKey = "9IK2T3XL";
private const string DefaultPassword = "04BC86C88CDB";
/// <summary>
/// 获取配置了代理的 HttpClient带缓存和自动释放功能
/// </summary>
/// <param name="proxyAddress">可选的代理地址。如果为空,则自动获取。</param>
/// <param name="key">代理用户名</param>
/// <param name="password">代理密码</param>
/// <returns>配置好代理的 HttpClient</returns>
public static async Task<HttpClient> GetHttpClientAsync(string? proxyAddress = null, string key = DefaultKey, string password = DefaultPassword)
{
// 如果未提供代理地址则从API获取
if (string.IsNullOrWhiteSpace(proxyAddress))
{
var proxyResponse = await GetProxyAsync(key: key);
var proxyIp = proxyResponse?.Data?.FirstOrDefault();
if (proxyIp?.Server == null || proxyIp.Deadline == null)
{
// 如果无法获取有效代理返回一个不带代理的普通HttpClient
return new HttpClient();
}
// 检查缓存中是否已有此代理的HttpClient
if (HttpClientCache.TryGetValue(proxyIp.Server, out HttpClient? cachedClient))
{
return cachedClient!;
}
// 创建新的HttpClient并配置缓存
var client = CreateConfiguredHttpClient(proxyIp.Server, key, password);
var deadline = DateTime.Parse(proxyIp.Deadline);
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(deadline)
.RegisterPostEvictionCallback((cacheKey, value, reason, state) =>
{
(value as HttpClient)?.Dispose();
});
HttpClientCache.Set(proxyIp.Server, client, cacheEntryOptions);
return client;
}
else
{
// 如果用户手动提供了代理地址,我们无法知道其过期时间,因此不进行缓存
return CreateConfiguredHttpClient(proxyAddress, key, password);
}
}
private static HttpClient CreateConfiguredHttpClient(string proxyAddress, string key, string password)
{
var handler = new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.All,
Proxy = new WebProxy(proxyAddress, false)
{
Credentials = new NetworkCredential(key, password)
},
UseProxy = true
};
var client = new HttpClient(handler, disposeHandler: true);
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36");
return client;
}
/// <summary>
/// 异步获取代理IP, 带缓存功能
/// </summary>
public static async Task<ProxyResponse?> GetProxyAsync(string key = DefaultKey, string? area = null, string? areaEx = null, int? isp = null, int? num = null, bool? distinct = null)
{
var queryParams = new Dictionary<string, string?>
{
{ "key", key },
{ "area", area },
{ "area_ex", areaEx },
{ "isp", isp?.ToString() },
{ "num", num?.ToString() },
{ "distinct", distinct?.ToString().ToLower() }
};
var queryString = string.Join("&", queryParams
.Where(kvp => !string.IsNullOrEmpty(kvp.Value))
.Select(kvp => $"{kvp.Key}={Uri.EscapeDataString(kvp.Value!)}"));
var cacheKey = $"ProxyResponse_{queryString}";
if (ProxyResponseCache.TryGetValue(cacheKey, out ProxyResponse? cachedResponse))
{
return cachedResponse;
}
var requestUrl = $"{BaseUrl}?{queryString}";
try
{
var response = await ProxyApiHttpClient.GetAsync(requestUrl);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var proxyResponse = JsonSerializer.Deserialize<ProxyResponse>(json);
if (proxyResponse?.Code == "SUCCESS" && proxyResponse.Data?.Any() == true)
{
// 使用代理的过期时间作为缓存的过期时间
var deadline = DateTime.Parse(proxyResponse.Data.First().Deadline!);
ProxyResponseCache.Set(cacheKey, proxyResponse, deadline);
}
return proxyResponse;
}
catch (HttpRequestException e)
{
Console.WriteLine($"请求代理IP时发生错误: {e.Message}");
return null;
}
}
}
/// <summary>
/// 代理IP接口响应
/// </summary>
public class ProxyResponse
{
[JsonPropertyName("code")]
public string? Code { get; set; }
[JsonPropertyName("data")]
public List<ProxyIp>? Data { get; set; }
[JsonPropertyName("request_id")]
public string? RequestId { get; set; }
}
/// <summary>
/// 代理IP信息
/// </summary>
public class ProxyIp
{
[JsonPropertyName("proxy_ip")]
public string? ProxyIpAddress { get; set; }
[JsonPropertyName("server")]
public string? Server { get; set; }
[JsonPropertyName("area")]
public string? Area { get; set; }
[JsonPropertyName("isp")]
public string? Isp { get; set; }
[JsonPropertyName("deadline")]
public string? Deadline { get; set; }
}
}