Skip to content

Commit dd622e2

Browse files
committed
添加项目文件。
1 parent 52cbd1f commit dd622e2

File tree

11 files changed

+666
-0
lines changed

11 files changed

+666
-0
lines changed
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
//https://github.com/sangyuxiaowu/Sang.Baidu.TranslateAPI/blob/main/Sang.Baidu.TranslateAPI/BaiduTranslator.cs
2+
3+
using System.Net.Http.Json;
4+
using System.Text.Json;
5+
using System.Text.Json.Serialization;
6+
using System.Text;
7+
using System.Security.Cryptography;
8+
9+
namespace Pixeval.Extensions.Translators.Baidu.Client;
10+
#nullable disable
11+
/// <summary>
12+
/// 文档:https://fanyi-api.baidu.com/doc/21
13+
/// </summary>
14+
public class BaiduTranslatorClient
15+
{
16+
/// <summary>
17+
/// APPID
18+
/// </summary>
19+
private string _appId;
20+
21+
/// <summary>
22+
/// 密钥
23+
/// </summary>
24+
private string _secretKey;
25+
26+
/// <summary>
27+
/// 翻译服务终结点
28+
/// </summary>
29+
private readonly string _endpoint;
30+
31+
/// <summary>
32+
/// HttpClient
33+
/// </summary>
34+
private readonly HttpClient _httpClient;
35+
36+
37+
/// <summary>
38+
/// 构造函数
39+
/// </summary>
40+
/// <param name="appId">APPID</param>
41+
/// <param name="secretKey">密钥</param>
42+
/// <param name="endpoint">翻译服务终结点</param>
43+
public BaiduTranslatorClient(string appId, string secretKey, string endpoint = "https://fanyi-api.baidu.com/api/trans/vip/translate")
44+
{
45+
_appId = appId;
46+
_secretKey = secretKey;
47+
_endpoint = endpoint;
48+
_httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(10) }; // 设置超时时间
49+
}
50+
51+
/// <summary>
52+
/// 构造函数
53+
/// </summary>
54+
/// <param name="appId">APPID</param>
55+
/// <param name="secretKey">密钥</param>
56+
/// <param name="httpClient">HttpClient</param>
57+
/// <param name="endpoint">翻译服务终结点</param>
58+
public BaiduTranslatorClient(string appId, string secretKey, HttpClient httpClient, string endpoint = "https://fanyi-api.baidu.com/api/trans/vip/translate")
59+
{
60+
_appId = appId;
61+
_secretKey = secretKey;
62+
_endpoint = endpoint;
63+
_httpClient = httpClient;
64+
}
65+
66+
/// <summary>
67+
/// 重新设置appId 和 secretKey
68+
/// </summary>
69+
/// <param name="appId">APPID</param>
70+
/// <param name="secretKey">密钥</param>
71+
public void SetAppIdAndSecretKey(string appId, string secretKey)
72+
{
73+
_appId = appId;
74+
_secretKey = secretKey;
75+
}
76+
77+
/// <summary>
78+
/// 翻译
79+
/// </summary>
80+
/// <param name="text">请求翻译文本,长度控制在 6000 bytes以内(汉字约为输入参数 2000 个)</param>
81+
/// <param name="toLanguage">翻译目标语言</param>
82+
/// <returns></returns>
83+
public async Task<BaiduTranslateResult> Translate(string text, string toLanguage)
84+
{
85+
return await Translate(text, toLanguage, "auto");
86+
}
87+
88+
/// <summary>
89+
/// 翻译
90+
/// </summary>
91+
/// <param name="text">请求翻译文本,长度控制在 6000 bytes以内(汉字约为输入参数 2000 个)</param>
92+
/// <param name="toLanguage">翻译目标语言</param>
93+
/// <param name="fromLanguage">翻译源语言,可为auto,自动检测</param>
94+
/// <param name="salt">设置后将使用传入的随机数</param>
95+
/// <param name="sign">设置后将使用传入的签名结果</param>
96+
/// <returns></returns>
97+
public async Task<BaiduTranslateResult> Translate(string text, string toLanguage, string fromLanguage = "auto", string salt = "", string sign = "")
98+
{
99+
// 使用时间戳
100+
if (string.IsNullOrWhiteSpace(salt))
101+
{
102+
salt = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
103+
}
104+
// 使用MD5加密
105+
if (string.IsNullOrWhiteSpace(sign))
106+
{
107+
sign = (_appId + text + salt + _secretKey).MD5();
108+
}
109+
// 拼接URL
110+
string url = $"{_endpoint}?q={text}&from={fromLanguage}&to={toLanguage}&appid={_appId}&salt={salt}&sign={sign}";
111+
// 发送请求
112+
try
113+
{
114+
#if NET6_0_OR_GREATER
115+
//return await _httpClient.GetFromJsonAsync<BaiduTranslateResult>(url);
116+
var response = await _httpClient.GetAsync(url);
117+
var options = new JsonSerializerOptions
118+
{
119+
TypeInfoResolver = SourceGenerationContext.Default,
120+
};
121+
if (response.IsSuccessStatusCode)
122+
{
123+
var str = await response.Content.ReadAsStringAsync();
124+
var result = JsonSerializer.Deserialize<BaiduTranslateResult>(
125+
str, SourceGenerationContext.Default.BaiduTranslateResult);
126+
return result;
127+
}
128+
return new BaiduTranslateResult { Error_Code = response.StatusCode.ToString(), Error_Msg = response.ReasonPhrase };
129+
#else
130+
var response = await _httpClient.GetAsync(url);
131+
if (response.IsSuccessStatusCode)
132+
{
133+
var result = await response.Content.ReadAsStringAsync();
134+
var json = JsonDocument.Parse(result);
135+
var root = json.RootElement;
136+
137+
// 是否存在错误码
138+
if (root.TryGetProperty("error_code", out var errorCode))
139+
{
140+
return new BaiduTranslateResult { Error_Code = errorCode.GetString(), Error_Msg = root.GetProperty("error_msg").GetString() };
141+
}
142+
143+
var from = root.GetProperty("from").GetString();
144+
var to = root.GetProperty("to").GetString();
145+
146+
var transResult = new List<TransResult>();
147+
for (int i = 0; i < root.GetProperty("trans_result").GetArrayLength(); i++)
148+
{
149+
var item = root.GetProperty("trans_result")[i];
150+
transResult.Add(new TransResult
151+
{
152+
Src = item.GetProperty("src").GetString(),
153+
Dst = item.GetProperty("dst").GetString()
154+
});
155+
}
156+
157+
return new BaiduTranslateResult
158+
{
159+
From = from,
160+
To = to,
161+
Trans_Result = transResult
162+
};
163+
}
164+
return new BaiduTranslateResult { Error_Code = response.StatusCode.ToString(), Error_Msg = response.ReasonPhrase };
165+
#endif
166+
}
167+
catch (Exception ex)
168+
{
169+
return new BaiduTranslateResult { Error_Code = "Exception", Error_Msg = ex.Message };
170+
}
171+
}
172+
173+
/// <summary>
174+
/// 释放资源
175+
/// </summary>
176+
public void Dispose()
177+
{
178+
_httpClient?.Dispose();
179+
}
180+
181+
}
182+
[JsonSerializable(typeof(BaiduTranslateResult))]
183+
[JsonSerializable(typeof(List<TransResult>))]
184+
[JsonSerializable(typeof(TransResult))]
185+
[JsonSerializable(typeof(bool))]
186+
[JsonSerializable(typeof(string))]
187+
internal partial class SourceGenerationContext : JsonSerializerContext
188+
{
189+
}
190+
191+
public class BaiduTranslateResult
192+
{
193+
/// <summary>
194+
/// 是否成功
195+
/// </summary>
196+
public bool Success => Error_Code == null;
197+
/// <summary>
198+
/// 翻译源语言
199+
/// </summary>
200+
[JsonPropertyName("from")]
201+
public string From { get; set; }
202+
/// <summary>
203+
/// 翻译目标语言
204+
/// </summary>
205+
[JsonPropertyName("to")]
206+
public string To { get; set; }
207+
/// <summary>
208+
/// 翻译结果
209+
/// </summary>
210+
[JsonPropertyName("trans_result")]
211+
public List<TransResult> Trans_Result { get; set; }
212+
/// <summary>
213+
/// 错误码
214+
/// </summary>
215+
[JsonPropertyName("error_code")]
216+
public string Error_Code { get; set; }
217+
/// <summary>
218+
/// 错误信息
219+
/// </summary>
220+
221+
[JsonPropertyName("error_msg")]
222+
public string Error_Msg { get; set; }
223+
224+
/// <summary>
225+
/// 获取翻译结果
226+
/// </summary>
227+
/// <returns></returns>
228+
public string GetResult()
229+
{
230+
return Trans_Result != null && Trans_Result.Count > 0 ? Trans_Result[0].Dst : null;
231+
}
232+
233+
}
234+
235+
/// <summary>
236+
/// 翻译结果
237+
/// </summary>
238+
public class TransResult
239+
{
240+
/// <summary>
241+
/// 原文
242+
/// </summary>
243+
[JsonPropertyName("src")]
244+
public string Src { get; set; }
245+
/// <summary>
246+
/// 译文
247+
/// </summary>
248+
[JsonPropertyName("dst")]
249+
public string Dst { get; set; }
250+
}
251+
public static class Cryptography
252+
{
253+
254+
/// <summary>
255+
/// MD5 计算
256+
/// </summary>
257+
/// <param name="str">待计算字符</param>
258+
/// <param name="isUpper">是否是大写</param>
259+
/// <param name="isBig">是否是32位,否则为16位</param>
260+
/// <returns>计算结果</returns>
261+
public static string MD5(this string str, bool isUpper = false, bool isBig = true)
262+
{
263+
using (var md5 = System.Security.Cryptography.MD5.Create())
264+
{
265+
var result = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
266+
var strResult = isBig ? BitConverter.ToString(result) : BitConverter.ToString(result, 4, 8);
267+
return isUpper ? strResult.Replace("-", "") : strResult.Replace("-", "").ToLower();
268+
}
269+
}
270+
271+
/// <summary>
272+
/// SHA1 计算
273+
/// </summary>
274+
/// <param name="str">待计算字符</param>
275+
/// <param name="isUpper">是否是大写</param>
276+
/// <returns>计算结果</returns>
277+
public static string SHA1(this string str, bool isUpper = false)
278+
{
279+
using (var sha1 = System.Security.Cryptography.SHA1.Create())
280+
{
281+
var result = sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
282+
var strResult = BitConverter.ToString(result);
283+
return isUpper ? strResult.Replace("-", "") : strResult.Replace("-", "").ToLower();
284+
}
285+
}
286+
287+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Globalization;
2+
using System.Runtime.InteropServices;
3+
using System.Runtime.InteropServices.Marshalling;
4+
using Pixeval.Extensions.Common;
5+
using Pixeval.Extensions.SDK;
6+
using Pixeval.Extensions.Translators.Baidu.Settings;
7+
using Pixeval.Extensions.Translators.Baidu.Translators;
8+
9+
namespace Pixeval.Extensions.Translators.Baidu;
10+
11+
[GeneratedComClass]
12+
public partial class ExtensionsHost:ExtensionsHostBase
13+
{
14+
public static string TempDirectory { get; private set; } = "";
15+
16+
public static string ExtensionDirectory { get; private set; } = "";
17+
18+
public override string ExtensionName => "百度翻译";
19+
20+
public override string AuthorName => "Betta_Fish";
21+
22+
public override string ExtensionLink => "https://github.com/zxbmmmmmmmmm";
23+
24+
public override string HelpLink => "https://github.com/zxbmmmmmmmmm";
25+
26+
public override string Description => "百度翻译插件,需要手动输入API Key";
27+
28+
public override byte[]? Icon
29+
{
30+
get
31+
{
32+
var stream = typeof(ExtensionsHost).Assembly.GetManifestResourceStream("logo");
33+
if (stream is null)
34+
return null;
35+
var array = new byte[stream.Length];
36+
_ = stream.Read(array);
37+
return array;
38+
}
39+
}
40+
41+
public override string Version => "1.0.0";
42+
public static ExtensionsHost Current { get; } = new();
43+
44+
[UnmanagedCallersOnly(EntryPoint = nameof(DllGetExtensionsHost))]
45+
private static unsafe int DllGetExtensionsHost(void** ppv)
46+
{
47+
return DllGetExtensionsHost(ppv, Current);
48+
}
49+
public override IExtension[] Extensions { get; }
50+
51+
public BaiduTranslator Translator { get; set; }
52+
public override void Initialize(string cultureName, string tempDirectory, string extensionDirectory)
53+
{
54+
TempDirectory = tempDirectory;
55+
ExtensionDirectory = extensionDirectory;
56+
CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = new(cultureName);
57+
Translator.TargetLanguage = cultureName.Split('-').First();
58+
}
59+
public ExtensionsHost()
60+
{
61+
Translator = new BaiduTranslator();
62+
Extensions = [Translator,new AppIdSettingsExtension(),new ApiKeySettingsExtension()];
63+
}
64+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
8+
<PublishAot>true</PublishAot>
9+
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
10+
</PropertyGroup>
11+
12+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
13+
<IsAotCompatible>True</IsAotCompatible>
14+
</PropertyGroup>
15+
16+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
17+
<IsAotCompatible>True</IsAotCompatible>
18+
</PropertyGroup>
19+
20+
<ItemGroup>
21+
<PackageReference Include="Pixeval.Extensions.Common" Version="4.3.4.1" />
22+
<PackageReference Include="Pixeval.Extensions.SDK" Version="4.3.4.1" />
23+
</ItemGroup>
24+
25+
</Project>

0 commit comments

Comments
 (0)