|
|
@ -1,7 +1,9 @@
|
|
|
|
using System.IO.Compression;
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
|
|
|
using System.Net;
|
|
|
|
using System.Text;
|
|
|
|
using System.Text;
|
|
|
|
using System.Text.Encodings.Web;
|
|
|
|
using System.Text.Encodings.Web;
|
|
|
|
using System.Text.Json;
|
|
|
|
using System.Text.Json;
|
|
|
|
|
|
|
|
using System.Text.Json.Nodes;
|
|
|
|
using System.Text.Json.Serialization;
|
|
|
|
using System.Text.Json.Serialization;
|
|
|
|
|
|
|
|
|
|
|
|
namespace STranslateDLL;
|
|
|
|
namespace STranslateDLL;
|
|
|
@ -10,7 +12,20 @@ public static class LocalMode
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private static long _nextId;
|
|
|
|
private static long _nextId;
|
|
|
|
|
|
|
|
|
|
|
|
private static bool _hasInit = false;
|
|
|
|
private static bool _hasInit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly Dictionary<bool, string> TextTypeDic = new()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
{ true, "richtext" },
|
|
|
|
|
|
|
|
{ false, "plaintext" }
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static JsonSerializerOptions GetOptions =>
|
|
|
|
|
|
|
|
new()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
|
|
|
|
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
private static void Initial()
|
|
|
|
private static void Initial()
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -23,39 +38,122 @@ public static class LocalMode
|
|
|
|
|
|
|
|
|
|
|
|
public static async Task<string> ExecuteAsync(
|
|
|
|
public static async Task<string> ExecuteAsync(
|
|
|
|
string content,
|
|
|
|
string content,
|
|
|
|
string? sourceLang = null,
|
|
|
|
string sourceLang = "auto",
|
|
|
|
string targetLang = "ZH",
|
|
|
|
string targetLang = "ZH",
|
|
|
|
CancellationToken? token = null
|
|
|
|
CancellationToken? token = null
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!_hasInit)
|
|
|
|
if (!_hasInit) Initial();
|
|
|
|
|
|
|
|
var getToken = token ?? CancellationToken.None;
|
|
|
|
|
|
|
|
var splitResult = await SplitTextAsync(content, getToken);
|
|
|
|
|
|
|
|
//TODO: Error handling
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var splitObj = JsonSerializer.Deserialize<JsonObject>(splitResult);
|
|
|
|
|
|
|
|
if (sourceLang.Equals("auto", StringComparison.CurrentCultureIgnoreCase) || sourceLang.Equals(""))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Initial();
|
|
|
|
sourceLang = splitObj?["result"]?["lang"]?["detected"]?.ToString()?.ToUpper() ?? "auto";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var getToken = token ?? CancellationToken.None;
|
|
|
|
|
|
|
|
var timeSpan = GenerateTimestamp(content);
|
|
|
|
var jobs = new List<Job>();
|
|
|
|
|
|
|
|
var chunks = splitObj?["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
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
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 = targetLang;
|
|
|
|
|
|
|
|
var targetLangParts = targetLang.Split("-");
|
|
|
|
|
|
|
|
if (targetLangParts.Length > 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
targetLangCode = targetLangParts[0];
|
|
|
|
|
|
|
|
hasRegionalVariant = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var id = CreateId();
|
|
|
|
var id = CreateId();
|
|
|
|
var reqStr = GenerateRequestStr(content, sourceLang, targetLang, timeSpan, id);
|
|
|
|
var reqData = new DeepLRequest
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Jsonrpc = "2.0",
|
|
|
|
|
|
|
|
Method = "LMT_handle_jobs",
|
|
|
|
|
|
|
|
Id = id,
|
|
|
|
|
|
|
|
Params = new ReqParams
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CommonJobParams = new ReqParamsCommonJobParams
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Mode = "translate",
|
|
|
|
|
|
|
|
RegionalVariant = hasRegionalVariant ? targetLang : null
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Lang = new ReqParamsLang
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// SourceLangUserSelected = sourceLang,
|
|
|
|
|
|
|
|
SourceLangComputed = sourceLang.ToUpper(),
|
|
|
|
|
|
|
|
TargetLang = targetLangCode.ToUpper()
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Jobs = jobs.ToArray(),
|
|
|
|
|
|
|
|
Priority = 1,
|
|
|
|
|
|
|
|
Timestamp = GenerateTimestamp(content)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var json = JsonSerializer.Serialize(reqData, GetOptions);
|
|
|
|
|
|
|
|
json = AdjustJsonContent(json, id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using var client = new HttpClient();
|
|
|
|
using var client = new HttpClient();
|
|
|
|
var request = new HttpRequestMessage(HttpMethod.Post, "https://www2.deepl.com/jsonrpc")
|
|
|
|
var request = new HttpRequestMessage(HttpMethod.Post,
|
|
|
|
|
|
|
|
"https://www2.deepl.com/jsonrpc?client=chrome-extension,1.28.0&method=LMT_handle_jobs")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Content = new StringContent(reqStr, Encoding.UTF8, "application/json")
|
|
|
|
Content = new StringContent(json, Encoding.UTF8, "application/json")
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Add headers to the request
|
|
|
|
|
|
|
|
request.Headers.Add("User-Agent", "DeepL-iOS/2.4.0 iOS 15.7.1 (iPhone14,2)");
|
|
|
|
|
|
|
|
request.Headers.Add("Accept", "*/*");
|
|
|
|
request.Headers.Add("Accept", "*/*");
|
|
|
|
request.Headers.Add("x-app-os-name", "IOS");
|
|
|
|
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("x-app-os-version", "15.7.1");
|
|
|
|
request.Headers.Add("Authorization", "None");
|
|
|
|
request.Headers.Add("Accept-Language", "en-US,en;q=0.9");
|
|
|
|
request.Headers.Add("Cache-Control", "no-cache");
|
|
|
|
request.Headers.Add("Accept-Encoding", "gzip,deflate,br");
|
|
|
|
// request.Headers.Add("Content-Type", "application/json");
|
|
|
|
//request.Headers.Add("Content-Type", "application/json");
|
|
|
|
request.Headers.Add("DNT", "1");
|
|
|
|
request.Headers.Add("x-app-device", "iPhone14,2");
|
|
|
|
request.Headers.Add("Origin", "chrome-extension://cofdbpoegempjloogbagkncekinflcnj");
|
|
|
|
request.Headers.Add("x-app-build", "353");
|
|
|
|
request.Headers.Add("Pragma", "no-cache");
|
|
|
|
request.Headers.Add("x-app-version", "2.4");
|
|
|
|
request.Headers.Add("Priority", "u=1, i");
|
|
|
|
request.Headers.Add("Referer", "https://www.deepl.com/");
|
|
|
|
request.Headers.Add("Referer", "https://www.deepl.com/");
|
|
|
|
request.Headers.Add("Connection", "keep-alive");
|
|
|
|
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);
|
|
|
|
var resp = await client.SendAsync(request, getToken);
|
|
|
|
//resp.EnsureSuccessStatusCode();
|
|
|
|
//resp.EnsureSuccessStatusCode();
|
|
|
@ -77,93 +175,138 @@ public static class LocalMode
|
|
|
|
responseBody = await resp.Content.ReadAsStringAsync(getToken);
|
|
|
|
responseBody = await resp.Content.ReadAsStringAsync(getToken);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var deeplResp = JsonSerializer.Deserialize<DeepLResponse>(responseBody);
|
|
|
|
var jNode = JsonNode.Parse(responseBody);
|
|
|
|
|
|
|
|
var data = jNode?["result"]?["translations"]?[0]?["beams"]?[0]?["sentences"]?[0]?["text"]?.ToString();
|
|
|
|
|
|
|
|
// data = UnicodeToString(data);
|
|
|
|
|
|
|
|
|
|
|
|
var response = new Response { Code = resp.StatusCode.GetHashCode() };
|
|
|
|
var errorMsg = jNode?["error"]?["message"]?.ToString();
|
|
|
|
|
|
|
|
var detailsMsg = jNode?["error"]?["data"]?["what"]?.ToString();
|
|
|
|
|
|
|
|
var error = $"Error: {errorMsg}\nDetails: {detailsMsg}";
|
|
|
|
|
|
|
|
|
|
|
|
string defaultMessage =
|
|
|
|
var response = new Response
|
|
|
|
resp.StatusCode == System.Net.HttpStatusCode.OK
|
|
|
|
{
|
|
|
|
? "Empty Result"
|
|
|
|
Code = resp.StatusCode.GetHashCode(),
|
|
|
|
: "Empty Error Message";
|
|
|
|
Data = data ?? error
|
|
|
|
response.Data =
|
|
|
|
};
|
|
|
|
deeplResp?.Result?.Texts?.FirstOrDefault()?.Text
|
|
|
|
|
|
|
|
?? deeplResp?.Error?.Message
|
|
|
|
|
|
|
|
?? defaultMessage;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return JsonSerializer.Serialize(response, GetOptions);
|
|
|
|
return JsonSerializer.Serialize(response, GetOptions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static long GenerateTimestamp(string texts)
|
|
|
|
private static async Task<string> SplitTextAsync(string text, CancellationToken? token)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
long iCount = texts.Split('i').Length - 1;
|
|
|
|
var id = CreateId();
|
|
|
|
var ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
|
|
var getToken = token ?? CancellationToken.None;
|
|
|
|
return iCount != 0 ? ts - ts % (iCount + 1) + (iCount + 1) : ts;
|
|
|
|
var requestData = new DeepLRequest
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static long CreateId()
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return Interlocked.Increment(ref _nextId);
|
|
|
|
Jsonrpc = "2.0",
|
|
|
|
|
|
|
|
Method = "LMT_split_text",
|
|
|
|
|
|
|
|
Id = id,
|
|
|
|
|
|
|
|
Params = new ReqParams
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
CommonJobParams = new ReqParamsCommonJobParams
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Mode = "translate"
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Lang = new ReqParamsLang
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SourceLangUserSelected = "auto"
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Texts = [text],
|
|
|
|
|
|
|
|
TextType = TextTypeDic[ /*tagHandling*/false || IsRichText(text)]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
private static string AdjustJsonContent(string json, long id)
|
|
|
|
var json = JsonSerializer.Serialize(requestData, GetOptions);
|
|
|
|
|
|
|
|
json = 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")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
string method;
|
|
|
|
Content = new StringContent(json, Encoding.UTF8, "application/json")
|
|
|
|
if ((id + 3) % 13 == 0 || (id + 5) % 29 == 0)
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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"))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
method = "\"method\" : \"";
|
|
|
|
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
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
method = "\"method\": \"";
|
|
|
|
responseBody = await resp.Content.ReadAsStringAsync(getToken);
|
|
|
|
}
|
|
|
|
|
|
|
|
return json.Replace("\"method\":\"", method);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static JsonSerializerOptions GetOptions =>
|
|
|
|
return responseBody;
|
|
|
|
new()
|
|
|
|
}
|
|
|
|
{
|
|
|
|
|
|
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
|
|
|
|
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static string GenerateRequestStr(
|
|
|
|
private static string? UnicodeToString(string? srcText)
|
|
|
|
string text,
|
|
|
|
|
|
|
|
string? sourceLang,
|
|
|
|
|
|
|
|
string targetLang,
|
|
|
|
|
|
|
|
long timeSpan,
|
|
|
|
|
|
|
|
long id
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var req = new DeepLRequest
|
|
|
|
if (srcText == null) return default;
|
|
|
|
|
|
|
|
var dst = "";
|
|
|
|
|
|
|
|
var src = srcText;
|
|
|
|
|
|
|
|
var len = srcText.Length / 6;
|
|
|
|
|
|
|
|
for (var i = 0; i <= len - 1; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Jsonrpc = "2.0",
|
|
|
|
var str = "";
|
|
|
|
Method = "LMT_handle_texts",
|
|
|
|
str = src[..6][2..];
|
|
|
|
Params = new ReqParams
|
|
|
|
src = src[6..];
|
|
|
|
{
|
|
|
|
var bytes = new byte[2];
|
|
|
|
Texts = [new ReqParamsTexts { Text = text, RequestAlternatives = 0 }],
|
|
|
|
bytes[1] = byte.Parse(int.Parse(str[..2], System.Globalization.NumberStyles.HexNumber).ToString());
|
|
|
|
Splitting = "newlines",
|
|
|
|
bytes[0] = byte.Parse(int.Parse(str.Substring(2, 2), System.Globalization.NumberStyles.HexNumber).ToString());
|
|
|
|
Lang = new ReqParamsLang
|
|
|
|
dst += Encoding.Unicode.GetString(bytes);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static bool IsRichText(string text)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SourceLangUserSelected = sourceLang,
|
|
|
|
return text.Contains('<') && text.Contains('>');
|
|
|
|
TargetLang = targetLang
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
Timestamp = timeSpan,
|
|
|
|
private static long GenerateTimestamp(string texts)
|
|
|
|
CommonJobParams = new ReqParamsCommonJobParams
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WasSpoken = false,
|
|
|
|
long iCount = texts.Split('i').Length - 1;
|
|
|
|
TranscribeAS = ""
|
|
|
|
var ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
|
|
|
|
|
|
return iCount != 0 ? ts - ts % (iCount + 1) + iCount + 1 : ts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
Id = id
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var json = JsonSerializer.Serialize(req, GetOptions);
|
|
|
|
private static long CreateId()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return Interlocked.Increment(ref _nextId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var count = json.Length > 300 ? 0 : 3;
|
|
|
|
private static string AdjustJsonContent(string json, long id)
|
|
|
|
req.Params.Texts.First().RequestAlternatives = count;
|
|
|
|
{
|
|
|
|
json = JsonSerializer.Serialize(req, GetOptions);
|
|
|
|
string method;
|
|
|
|
json = AdjustJsonContent(json, id);
|
|
|
|
if ((id + 3) % 13 == 0 || (id + 5) % 29 == 0)
|
|
|
|
return json;
|
|
|
|
method = "\"method\" : \"";
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
method = "\"method\": \"";
|
|
|
|
|
|
|
|
return json.Replace("\"method\":\"", method);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -173,46 +316,34 @@ public class Response
|
|
|
|
public string Data { get; set; } = "";
|
|
|
|
public string Data { get; set; } = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Request
|
|
|
|
|
|
|
|
|
|
|
|
public class DeepLRequest
|
|
|
|
public class DeepLRequest
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[JsonPropertyName("jsonrpc")]
|
|
|
|
[JsonPropertyName("jsonrpc")] public string Jsonrpc { get; set; } = "";
|
|
|
|
public string Jsonrpc { get; set; } = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("method")]
|
|
|
|
[JsonPropertyName("method")] public string Method { get; set; } = "";
|
|
|
|
public string Method { get; set; } = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("params")]
|
|
|
|
[JsonPropertyName("params")] public ReqParams? Params { get; set; }
|
|
|
|
public ReqParams? Params { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("id")]
|
|
|
|
[JsonPropertyName("id")] public long Id { get; set; }
|
|
|
|
public long Id { get; set; }
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class ReqParams
|
|
|
|
public class ReqParams
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[JsonPropertyName("texts")]
|
|
|
|
[JsonPropertyName("commonJobParams")] public ReqParamsCommonJobParams? CommonJobParams { get; set; }
|
|
|
|
public ReqParamsTexts[]? Texts { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("splitting")]
|
|
|
|
[JsonPropertyName("lang")] public ReqParamsLang? Lang { get; set; }
|
|
|
|
public string Splitting { get; set; } = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("lang")]
|
|
|
|
[JsonPropertyName("texts")] public string[]? Texts { get; set; }
|
|
|
|
public ReqParamsLang? Lang { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("timestamp")]
|
|
|
|
[JsonPropertyName("textType")] public string? TextType { get; set; }
|
|
|
|
public long Timestamp { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("commonJobParams")]
|
|
|
|
[JsonPropertyName("jobs")] public Job[]? Jobs { get; set; }
|
|
|
|
public ReqParamsCommonJobParams? CommonJobParams { get; set; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class ReqParamsTexts
|
|
|
|
[JsonPropertyName("priority")] public int Priority { get; set; }
|
|
|
|
{
|
|
|
|
|
|
|
|
[JsonPropertyName("text")]
|
|
|
|
|
|
|
|
public string Text { get; set; } = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("requestAlternatives")]
|
|
|
|
[JsonPropertyName("timestamp")] public long Timestamp { get; set; }
|
|
|
|
public int RequestAlternatives { get; set; }
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class ReqParamsLang
|
|
|
|
public class ReqParamsLang
|
|
|
@ -220,94 +351,50 @@ public class ReqParamsLang
|
|
|
|
[JsonPropertyName("source_lang_user_selected")]
|
|
|
|
[JsonPropertyName("source_lang_user_selected")]
|
|
|
|
public string? SourceLangUserSelected { get; set; }
|
|
|
|
public string? SourceLangUserSelected { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("target_lang")]
|
|
|
|
[JsonPropertyName("source_lang_computed")]
|
|
|
|
public string TargetLang { get; set; } = "";
|
|
|
|
public string? SourceLangComputed { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("target_lang")] public string TargetLang { get; set; } = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class ReqParamsCommonJobParams
|
|
|
|
public class ReqParamsCommonJobParams
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[JsonPropertyName("wasSpoken")]
|
|
|
|
[JsonPropertyName("mode")] public string Mode { get; set; } = "";
|
|
|
|
public bool WasSpoken { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("transcribe_as")]
|
|
|
|
[JsonPropertyName("regionalVariant")] public string? RegionalVariant { get; set; }
|
|
|
|
public string? TranscribeAS { get; set; }
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class DeepLResponse
|
|
|
|
public class Job
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[JsonPropertyName("jsonrpc")]
|
|
|
|
[JsonPropertyName("kind")] public string Kind { get; set; } = "";
|
|
|
|
public string Jsonrpc { get; set; } = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("id")]
|
|
|
|
[JsonPropertyName("preferred_num_beams")]
|
|
|
|
public long Id { get; set; }
|
|
|
|
public int PreferredNumBeams { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("result")]
|
|
|
|
[JsonPropertyName("raw_en_context_before")]
|
|
|
|
public RespResult? Result { get; set; }
|
|
|
|
public string[]? RawEnContextBefore { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("error")]
|
|
|
|
[JsonPropertyName("raw_en_context_after")]
|
|
|
|
public RespError? Error { get; set; }
|
|
|
|
public string[]? RawEnContextAfter { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("sentences")] public Sentence[]? Sentences { get; set; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class RespResult
|
|
|
|
public class Sentence
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[JsonPropertyName("texts")]
|
|
|
|
[JsonPropertyName("id")] public int Id { get; set; }
|
|
|
|
public RespResultText[]? Texts { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("lang")]
|
|
|
|
|
|
|
|
public string Lang { get; set; } = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("lang_is_confident")]
|
|
|
|
[JsonPropertyName("prefix")] public string Prefix { get; set; } = "";
|
|
|
|
public bool LangIsConfident { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("detectedLanguages")]
|
|
|
|
[JsonPropertyName("text")] public string Text { get; set; } = "";
|
|
|
|
public RespResultDetectedLanguages? DetectedLanguages { get; set; }
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class RespResultText
|
|
|
|
#endregion
|
|
|
|
{
|
|
|
|
|
|
|
|
[JsonPropertyName("alternatives")]
|
|
|
|
|
|
|
|
public object[]? Alternatives { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("text")]
|
|
|
|
|
|
|
|
public string Text { get; set; } = "";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class RespResultDetectedLanguages
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
public float EN { get; set; }
|
|
|
|
|
|
|
|
public float DE { get; set; }
|
|
|
|
|
|
|
|
public float FR { get; set; }
|
|
|
|
|
|
|
|
public float ES { get; set; }
|
|
|
|
|
|
|
|
public float PT { get; set; }
|
|
|
|
|
|
|
|
public float IT { get; set; }
|
|
|
|
|
|
|
|
public float NL { get; set; }
|
|
|
|
|
|
|
|
public float PL { get; set; }
|
|
|
|
|
|
|
|
public float RU { get; set; }
|
|
|
|
|
|
|
|
public float ZH { get; set; }
|
|
|
|
|
|
|
|
public float JA { get; set; }
|
|
|
|
|
|
|
|
public float BG { get; set; }
|
|
|
|
|
|
|
|
public float CS { get; set; }
|
|
|
|
|
|
|
|
public float DA { get; set; }
|
|
|
|
|
|
|
|
public float EL { get; set; }
|
|
|
|
|
|
|
|
public float ET { get; set; }
|
|
|
|
|
|
|
|
public float FI { get; set; }
|
|
|
|
|
|
|
|
public float HU { get; set; }
|
|
|
|
|
|
|
|
public float LT { get; set; }
|
|
|
|
|
|
|
|
public float LV { get; set; }
|
|
|
|
|
|
|
|
public float RO { get; set; }
|
|
|
|
|
|
|
|
public float SK { get; set; }
|
|
|
|
|
|
|
|
public float SL { get; set; }
|
|
|
|
|
|
|
|
public float SV { get; set; }
|
|
|
|
|
|
|
|
public float TR { get; set; }
|
|
|
|
|
|
|
|
public float ID { get; set; }
|
|
|
|
|
|
|
|
public float Unsupported { get; set; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class RespError
|
|
|
|
public class RespError
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[JsonPropertyName("code")]
|
|
|
|
[JsonPropertyName("code")] public int Code { get; set; }
|
|
|
|
public int Code { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("message")]
|
|
|
|
[JsonPropertyName("message")] public string Message { get; set; } = "";
|
|
|
|
public string Message { get; set; } = "";
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|