From 2bd364c36c3f067ba1b09affb302705e4f45991d Mon Sep 17 00:00:00 2001 From: zggsong Date: Tue, 5 Nov 2024 16:10:50 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=95=B4=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- STranslateDLL/Program.cs | 227 ++++++++++++----------------- STranslateDLL/Utilities.cs | 6 +- STranslateDLLTests/ProgramTests.cs | 2 +- 3 files changed, 101 insertions(+), 134 deletions(-) diff --git a/STranslateDLL/Program.cs b/STranslateDLL/Program.cs index ec7b3f0..1d20220 100644 --- a/STranslateDLL/Program.cs +++ b/STranslateDLL/Program.cs @@ -1,6 +1,5 @@ using System.IO.Compression; using System.Text; -using System.Text.Json; using System.Text.Json.Nodes; namespace STranslateDLL; @@ -15,64 +14,23 @@ public static class Program ) { Utilities.Initial(); - var getToken = token ?? CancellationToken.None; var splitResult = await SplitTextAsync(content, getToken); var splitData = JsonNode.Parse(splitResult); var splitError = splitData?["error"]?["message"]?.ToString(); if (splitError != null) - { return Utilities.Serialize(new Response { Code = 500, Data = splitError }); - } - - if (sourceLang.Equals("auto", StringComparison.CurrentCultureIgnoreCase) || sourceLang.Equals("")) - sourceLang = splitData?["result"]?["lang"]?["detected"]?.ToString()?.ToUpper() ?? "auto"; - var jobs = new List(); - 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(); - var contextAfter = Array.Empty(); - if (i > 0) contextBefore = [chunkArray[i - 1]?["sentences"]?[0]?["text"]?.ToString() ?? ""]; - - if (i < chunkArray.Count - 1) - contextAfter = [chunkArray[i + 1]?["sentences"]?[0]?["text"]?.ToString() ?? ""]; + sourceLang = GetSourceLang(sourceLang, splitData); - var job = new Job - { - 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 jobs = CreateJobs(splitData); - var hasRegionalVariant = false; - var targetLangCode = targetLang; - var targetLangParts = targetLang.Split("-"); - if (targetLangParts.Length > 1) - { - targetLangCode = targetLangParts[0]; - hasRegionalVariant = true; - } + var targetLangCode = GetTargetLangCode(targetLang, out var hasRegionalVariant); var id = Utilities.CreateId(); var reqData = new DeepLRequest @@ -89,7 +47,6 @@ public static class Program }, Lang = new ReqParamsLang { - // SourceLangUserSelected = sourceLang, SourceLangComputed = sourceLang.ToUpper(), TargetLang = targetLangCode.ToUpper() }, @@ -102,19 +59,95 @@ public static class Program var json = Utilities.Serialize(reqData); 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 CreateJobs(JsonNode? splitData) + { + var jobs = new List(); + 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(); + var contextAfter = i < chunkArray.Count - 1 + ? new[] { chunkArray[i + 1]?["sentences"]?[0]?["text"]?.ToString() ?? "" } + : Array.Empty(); + + 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 SendRequestAsync(string json, CancellationToken token, string method) + { using var client = new HttpClient(); - var request = new HttpRequestMessage(HttpMethod.Post, - "https://www2.deepl.com/jsonrpc?client=chrome-extension,1.28.0&method=LMT_handle_jobs") + var uri = $"{Utilities.Url}?client=chrome-extension,1.28.0&method={method}"; + var request = new HttpRequestMessage(HttpMethod.Post, uri) { 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-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"); @@ -126,52 +159,26 @@ public static class Program 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); - //resp.EnsureSuccessStatusCode(); - - 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); - } - - 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 - }; + private static async Task GetResponseBodyAsync(HttpResponseMessage resp, CancellationToken token) + { + if (!resp.Content.Headers.ContentEncoding.Contains("br")) + return await resp.Content.ReadAsStringAsync(token); - 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 SplitTextAsync(string text, CancellationToken? token) + private static async Task SplitTextAsync(string text, CancellationToken token) { var id = Utilities.CreateId(); - var getToken = token ?? CancellationToken.None; var requestData = new DeepLRequest { Jsonrpc = "2.0", - Method = "LMT_split_text2", + Method = "LMT_split_text", Id = id, Params = new ReqParams { @@ -183,55 +190,13 @@ public static class Program { SourceLangUserSelected = "auto" }, - Texts = [text], - TextType = Utilities.TextTypeDic[ /*tagHandling*/false || Utilities.IsRichText(text)] + Texts = new[] { text }, + TextType = Utilities.TextTypeDic[Utilities.IsRichText(text)] } }; var json = Utilities.Serialize(requestData); json = Utilities.AdjustJsonContent(json, id); - using var client = new HttpClient(); - 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; + return await SendRequestAsync(json, token, "LMT_split_text"); } } \ No newline at end of file diff --git a/STranslateDLL/Utilities.cs b/STranslateDLL/Utilities.cs index 0fd3ef1..ed58009 100644 --- a/STranslateDLL/Utilities.cs +++ b/STranslateDLL/Utilities.cs @@ -6,6 +6,7 @@ namespace STranslateDLL; public static class Utilities { + public const string Url = "https://www2.deepl.com/jsonrpc"; private static long _nextId; private static bool _hasInit; @@ -15,11 +16,12 @@ public static class Utilities { false, "plaintext" } }; - private static JsonSerializerOptions GetOptions => + private static readonly JsonSerializerOptions GetOptions = new() { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault, + WriteIndented = true }; public static string Serialize(object data) diff --git a/STranslateDLLTests/ProgramTests.cs b/STranslateDLLTests/ProgramTests.cs index b7aec03..595b83d 100644 --- a/STranslateDLLTests/ProgramTests.cs +++ b/STranslateDLLTests/ProgramTests.cs @@ -13,7 +13,7 @@ public class ProgramTests(ITestOutputHelper testOutputHelper) try { 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); } catch (Exception ex)