perf: 整理代码

main
zggsong 3 weeks ago
parent 970e408aa9
commit 2bd364c36c

@ -1,6 +1,5 @@
using System.IO.Compression; using System.IO.Compression;
using System.Text; using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
namespace STranslateDLL; namespace STranslateDLL;
@ -15,64 +14,23 @@ public static class Program
) )
{ {
Utilities.Initial(); Utilities.Initial();
var getToken = token ?? CancellationToken.None; var getToken = token ?? CancellationToken.None;
var splitResult = await SplitTextAsync(content, getToken); var splitResult = await SplitTextAsync(content, getToken);
var splitData = JsonNode.Parse(splitResult); var splitData = JsonNode.Parse(splitResult);
var splitError = splitData?["error"]?["message"]?.ToString(); var splitError = splitData?["error"]?["message"]?.ToString();
if (splitError != null) if (splitError != null)
{
return Utilities.Serialize(new Response return Utilities.Serialize(new Response
{ {
Code = 500, Code = 500,
Data = splitError Data = splitError
}); });
}
if (sourceLang.Equals("auto", StringComparison.CurrentCultureIgnoreCase) || sourceLang.Equals(""))
sourceLang = splitData?["result"]?["lang"]?["detected"]?.ToString()?.ToUpper() ?? "auto";
var jobs = new List<Job>(); sourceLang = GetSourceLang(sourceLang, splitData);
var chunks = splitData?["result"]?["texts"]?[0]?["chunks"];
if (chunks is JsonArray chunkArray)
for (var i = 0; i < chunkArray.Count; i++)
{
var sentence = chunkArray[i]?["sentences"]?[0];
var contextBefore = Array.Empty<string>();
var contextAfter = Array.Empty<string>();
if (i > 0) contextBefore = [chunkArray[i - 1]?["sentences"]?[0]?["text"]?.ToString() ?? ""];
if (i < chunkArray.Count - 1)
contextAfter = [chunkArray[i + 1]?["sentences"]?[0]?["text"]?.ToString() ?? ""];
var job = new Job var jobs = CreateJobs(splitData);
{
Kind = "default",
PreferredNumBeams = 4,
RawEnContextBefore = contextBefore,
RawEnContextAfter = contextAfter,
Sentences =
[
new Sentence
{
Prefix = sentence?["prefix"]?.ToString() ?? "",
Text = sentence?["text"]?.ToString() ?? "",
Id = i + 1
}
]
};
jobs.Add(job);
}
var hasRegionalVariant = false; var targetLangCode = GetTargetLangCode(targetLang, out var hasRegionalVariant);
var targetLangCode = targetLang;
var targetLangParts = targetLang.Split("-");
if (targetLangParts.Length > 1)
{
targetLangCode = targetLangParts[0];
hasRegionalVariant = true;
}
var id = Utilities.CreateId(); var id = Utilities.CreateId();
var reqData = new DeepLRequest var reqData = new DeepLRequest
@ -89,7 +47,6 @@ public static class Program
}, },
Lang = new ReqParamsLang Lang = new ReqParamsLang
{ {
// SourceLangUserSelected = sourceLang,
SourceLangComputed = sourceLang.ToUpper(), SourceLangComputed = sourceLang.ToUpper(),
TargetLang = targetLangCode.ToUpper() TargetLang = targetLangCode.ToUpper()
}, },
@ -102,19 +59,95 @@ public static class Program
var json = Utilities.Serialize(reqData); var json = Utilities.Serialize(reqData);
json = Utilities.AdjustJsonContent(json, id); json = Utilities.AdjustJsonContent(json, id);
var responseBody = await SendRequestAsync(json, getToken, "LMT_handle_jobs");
var jNode = JsonNode.Parse(responseBody);
var data = jNode?["result"]?["translations"]?[0]?["beams"]?[0]?["sentences"]?[0]?["text"]?.ToString();
var errorMsg = jNode?["error"]?["message"]?.ToString();
var detailsMsg = jNode?["error"]?["data"]?["what"]?.ToString();
var error = $"Error: {errorMsg}\nDetails: {detailsMsg}";
return Utilities.Serialize(new Response
{
Code = data != null ? 200 : 500,
Data = data ?? error
});
}
private static string GetSourceLang(string sourceLang, JsonNode? splitData)
{
if (sourceLang.Equals("auto", StringComparison.CurrentCultureIgnoreCase) || sourceLang.Equals(""))
sourceLang = splitData?["result"]?["lang"]?["detected"]?.ToString().ToUpper() ?? "auto";
return sourceLang;
}
private static List<Job> CreateJobs(JsonNode? splitData)
{
var jobs = new List<Job>();
var chunks = splitData?["result"]?["texts"]?[0]?["chunks"];
if (chunks is JsonArray chunkArray)
for (var i = 0; i < chunkArray.Count; i++)
{
var sentence = chunkArray[i]?["sentences"]?[0];
var contextBefore = i > 0
? new[] { chunkArray[i - 1]?["sentences"]?[0]?["text"]?.ToString() ?? "" }
: Array.Empty<string>();
var contextAfter = i < chunkArray.Count - 1
? new[] { chunkArray[i + 1]?["sentences"]?[0]?["text"]?.ToString() ?? "" }
: Array.Empty<string>();
var job = new Job
{
Kind = "default",
PreferredNumBeams = 4,
RawEnContextBefore = contextBefore,
RawEnContextAfter = contextAfter,
Sentences = new[]
{
new Sentence
{
Prefix = sentence?["prefix"]?.ToString() ?? "",
Text = sentence?["text"]?.ToString() ?? "",
Id = i + 1
}
}
};
jobs.Add(job);
}
return jobs;
}
private static string GetTargetLangCode(string targetLang, out bool hasRegionalVariant)
{
var targetLangCode = targetLang;
var targetLangParts = targetLang.Split("-");
hasRegionalVariant = targetLangParts.Length > 1;
if (hasRegionalVariant) targetLangCode = targetLangParts[0];
return targetLangCode;
}
private static async Task<string> SendRequestAsync(string json, CancellationToken token, string method)
{
using var client = new HttpClient(); using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, var uri = $"{Utilities.Url}?client=chrome-extension,1.28.0&method={method}";
"https://www2.deepl.com/jsonrpc?client=chrome-extension,1.28.0&method=LMT_handle_jobs") var request = new HttpRequestMessage(HttpMethod.Post, uri)
{ {
Content = new StringContent(json, Encoding.UTF8, "application/json") Content = new StringContent(json, Encoding.UTF8, "application/json")
}; };
AddRequestHeaders(request);
var resp = await client.SendAsync(request, token);
return await GetResponseBodyAsync(resp, token);
}
private static void AddRequestHeaders(HttpRequestMessage request)
{
request.Headers.Add("Accept", "*/*"); request.Headers.Add("Accept", "*/*");
request.Headers.Add("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh-HK;q=0.6,zh;q=0.5"); request.Headers.Add("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh-HK;q=0.6,zh;q=0.5");
request.Headers.Add("Authorization", "None"); request.Headers.Add("Authorization", "None");
request.Headers.Add("Cache-Control", "no-cache"); request.Headers.Add("Cache-Control", "no-cache");
// request.Headers.Add("Content-Type", "application/json");
request.Headers.Add("DNT", "1"); request.Headers.Add("DNT", "1");
request.Headers.Add("Origin", "chrome-extension://cofdbpoegempjloogbagkncekinflcnj"); request.Headers.Add("Origin", "chrome-extension://cofdbpoegempjloogbagkncekinflcnj");
request.Headers.Add("Pragma", "no-cache"); request.Headers.Add("Pragma", "no-cache");
@ -126,52 +159,26 @@ public static class Program
request.Headers.Add("Sec-GPC", "1"); request.Headers.Add("Sec-GPC", "1");
request.Headers.Add("User-Agent", request.Headers.Add("User-Agent",
"DeepLBrowserExtension/1.28.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"); "DeepLBrowserExtension/1.28.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36");
}
var resp = await client.SendAsync(request, getToken); private static async Task<string> GetResponseBodyAsync(HttpResponseMessage resp, CancellationToken token)
//resp.EnsureSuccessStatusCode(); {
if (!resp.Content.Headers.ContentEncoding.Contains("br"))
string responseBody; return await resp.Content.ReadAsStringAsync(token);
if (resp.Content.Headers.ContentEncoding.Contains("br"))
{
await using var responseStream = await resp.Content.ReadAsStreamAsync(getToken);
await using var decompressionStream = new BrotliStream(
responseStream,
CompressionMode.Decompress
);
using var streamReader = new StreamReader(decompressionStream);
responseBody = await streamReader.ReadToEndAsync(getToken);
}
else
{
responseBody = await resp.Content.ReadAsStringAsync(getToken);
}
var jNode = JsonNode.Parse(responseBody);
var data = jNode?["result"]?["translations"]?[0]?["beams"]?[0]?["sentences"]?[0]?["text"]?.ToString();
// data = UnicodeToString(data);
var errorMsg = jNode?["error"]?["message"]?.ToString();
var detailsMsg = jNode?["error"]?["data"]?["what"]?.ToString();
var error = $"Error: {errorMsg}\nDetails: {detailsMsg}";
var response = new Response
{
Code = resp.StatusCode.GetHashCode(),
Data = data ?? error
};
return Utilities.Serialize(response); await using var responseStream = await resp.Content.ReadAsStreamAsync(token);
await using var decompressionStream = new BrotliStream(responseStream, CompressionMode.Decompress);
using var streamReader = new StreamReader(decompressionStream);
return await streamReader.ReadToEndAsync(token);
} }
private static async Task<string> SplitTextAsync(string text, CancellationToken? token) private static async Task<string> SplitTextAsync(string text, CancellationToken token)
{ {
var id = Utilities.CreateId(); var id = Utilities.CreateId();
var getToken = token ?? CancellationToken.None;
var requestData = new DeepLRequest var requestData = new DeepLRequest
{ {
Jsonrpc = "2.0", Jsonrpc = "2.0",
Method = "LMT_split_text2", Method = "LMT_split_text",
Id = id, Id = id,
Params = new ReqParams Params = new ReqParams
{ {
@ -183,55 +190,13 @@ public static class Program
{ {
SourceLangUserSelected = "auto" SourceLangUserSelected = "auto"
}, },
Texts = [text], Texts = new[] { text },
TextType = Utilities.TextTypeDic[ /*tagHandling*/false || Utilities.IsRichText(text)] TextType = Utilities.TextTypeDic[Utilities.IsRichText(text)]
} }
}; };
var json = Utilities.Serialize(requestData); var json = Utilities.Serialize(requestData);
json = Utilities.AdjustJsonContent(json, id); json = Utilities.AdjustJsonContent(json, id);
using var client = new HttpClient(); return await SendRequestAsync(json, token, "LMT_split_text");
var request = new HttpRequestMessage(HttpMethod.Post,
"https://www2.deepl.com/jsonrpc?client=chrome-extension,1.28.0&method=LMT_split_text")
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
// Add headers to the request
request.Headers.Add("Accept", "*/*");
request.Headers.Add("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh-HK;q=0.6,zh;q=0.5");
request.Headers.Add("Authorization", "None");
request.Headers.Add("Cache-Control", "no-cache");
// request.Headers.Add("Content-Type", "application/json");
request.Headers.Add("DNT", "1");
request.Headers.Add("Origin", "chrome-extension://cofdbpoegempjloogbagkncekinflcnj");
request.Headers.Add("Pragma", "no-cache");
request.Headers.Add("Priority", "u=1, i");
request.Headers.Add("Referer", "https://www.deepl.com/");
request.Headers.Add("Sec-Fetch-Dest", "empty");
request.Headers.Add("Sec-Fetch-Mode", "cors");
request.Headers.Add("Sec-Fetch-Site", "none");
request.Headers.Add("Sec-GPC", "1");
request.Headers.Add("User-Agent",
"DeepLBrowserExtension/1.28.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36");
var resp = await client.SendAsync(request, getToken);
string responseBody;
if (resp.Content.Headers.ContentEncoding.Contains("br"))
{
await using var responseStream = await resp.Content.ReadAsStreamAsync(getToken);
await using var decompressionStream = new BrotliStream(
responseStream,
CompressionMode.Decompress
);
using var streamReader = new StreamReader(decompressionStream);
responseBody = await streamReader.ReadToEndAsync(getToken);
}
else
{
responseBody = await resp.Content.ReadAsStringAsync(getToken);
}
return responseBody;
} }
} }

@ -6,6 +6,7 @@ namespace STranslateDLL;
public static class Utilities public static class Utilities
{ {
public const string Url = "https://www2.deepl.com/jsonrpc";
private static long _nextId; private static long _nextId;
private static bool _hasInit; private static bool _hasInit;
@ -15,11 +16,12 @@ public static class Utilities
{ false, "plaintext" } { false, "plaintext" }
}; };
private static JsonSerializerOptions GetOptions => private static readonly JsonSerializerOptions GetOptions =
new() new()
{ {
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
WriteIndented = true
}; };
public static string Serialize(object data) public static string Serialize(object data)

@ -13,7 +13,7 @@ public class ProgramTests(ITestOutputHelper testOutputHelper)
try try
{ {
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
var ret = await Program.ExecuteAsync("Hello World", "EN", "ZH", cts.Token); var ret = await Program.ExecuteAsync("Hello World", "auto", "ZH", cts.Token);
testOutputHelper.WriteLine(ret); testOutputHelper.WriteLine(ret);
} }
catch (Exception ex) catch (Exception ex)

Loading…
Cancel
Save