diff --git a/extensions/devtoolsdeepltranslate.cpp b/extensions/devtoolsdeepltranslate.cpp index 57b1116..7f3a67d 100644 --- a/extensions/devtoolsdeepltranslate.cpp +++ b/extensions/devtoolsdeepltranslate.cpp @@ -41,7 +41,7 @@ std::pair Translate(const std::wstring& text, DevTools* devt QString qtext = S(text); qtext.remove(QString(12288)); // japanese space (no need for translator) - // Check quotes + // Remove quotes bool checkquote = false; if ((qtext.front() == QString(12300) && qtext.back() == QString(12301)) // japanese quotation marks || (qtext.front() == "\"" && qtext.back() == "\"")) @@ -51,18 +51,18 @@ std::pair Translate(const std::wstring& text, DevTools* devt qtext.chop(1); } - if (qtext == QString(12387)) // if text consists of only one sokuon, add exclamation mark for correct translation - { - qtext += "!"; - } - - // Check ellipsis + // Check specific cases (sentence has only one japanese symbol or consists of ellipsis) int count = qtext.count(QString(8230)); // ellipsis if (count == qtext.length() || (count == (qtext.length() - 1) && qtext.back() == QString(12290))) // japanese end of a sentence { return { true, text }; } + if (count == (qtext.length() - 1)) + { + qtext.remove(QString(8230)); + qtext += QString(12290) + QString(8230); // add the end symbol for correct translation + } // Put quotes back if (checkquote) @@ -87,79 +87,69 @@ std::pair Translate(const std::wstring& text, DevTools* devt pageenabled = -1; useragentflag = -1; update = -1; + callnumber = 0; } - // Erase tags and reduce the number of ellipsis for better translation + // Remove tags and reduce the number of ellipsis for correct translation qtext.remove(QRegExp("<[^>]*>")); qtext.replace(QRegExp("(" + QString(8230) + ")+"), " " + QString(8230)); // Enable page feedback QJsonObject root; + int errorcode = 0; if (pageenabled == -1) { if (!devtools->SendRequest("Page.enable", {}, root)) - { - return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; - } - pageenabled = 1; + errorcode = 1; + else + pageenabled = 1; } // Change user-agent if in headless mode - if (useragentflag == -1) + if (useragentflag == -1 && errorcode == 0) { QString useragent = devtools->getUserAgent(); if (!useragent.isEmpty()) { useragent.replace("HeadlessChrome", "Chrome"); if (!devtools->SendRequest("Network.setUserAgentOverride", { {"userAgent", useragent} }, root)) - { - return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; - } + errorcode = 1; + else + useragentflag = 1; } - useragentflag = 1; } + // Increase queue counter and wait until previous calls are done float timer = 0; int timer_stop = 10; long calltag = ++callnumber; callqueue.insert(callqueue.begin(), calltag); - while (callqueue.back() != calltag && timer < 2 * timer_stop) + while (errorcode == 0 && callqueue.back() != calltag && timer < 2 * timer_stop) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); timer += 0.1; } if (timer >= timer_stop) - { - callqueue.pop_back(); - return { false, FormatString(L"%s: %d ", ERROR_GOT_TIMEOUT, 2 * timer_stop) }; - } + errorcode = 5; + + // Set methods to receive long navigate = devtools->methodToReceive("Page.navigatedWithinDocument"); long target = devtools->methodToReceive("DOM.attributeModified", { { "value" , "lmt__mobile_share_container" } }); if (update == -1) - { update = devtools->methodToReceive("DOM.documentUpdated"); - } - // Navigate to site + // Navigate to site and wait until it is loaded QString fullurl = URL + "#ja/" + S(translateTo.Copy()) + "/" + qtext; - if (!devtools->SendRequest("Page.navigate", { {"url", fullurl} }, root)) - { - callqueue.pop_back(); - return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; - } - - // Wait until page is loaded + if (errorcode == 0 && !devtools->SendRequest("Page.navigate", { {"url", fullurl} }, root)) + errorcode = 1; timer = 0; - while (!devtools->checkMethod(navigate) && timer < timer_stop) + while (errorcode == 0 && !devtools->checkMethod(navigate) && timer < timer_stop) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); timer += 0.1; } if (timer >= timer_stop) - { - callqueue.pop_back(); - return { false, FormatString(L"%s: %d ", ERROR_GOT_TIMEOUT, timer_stop) }; - } + errorcode = 2; // Check if document is outdated if (devtools->checkMethod(update)) @@ -170,86 +160,99 @@ std::pair Translate(const std::wstring& text, DevTools* devt } // Get document - if (docfound == -1) + if (docfound == -1 && errorcode == 0) { if (!devtools->SendRequest("DOM.getDocument", {}, root)) - { - callqueue.pop_back(); - return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; - } - docfound = root.value("result").toObject().value("root").toObject().value("nodeId").toInt(); + errorcode = 1; + else + docfound = root.value("result").toObject().value("root").toObject().value("nodeId").toInt(); } // Get target selector - if (targetNodeId == -1) + if (targetNodeId == -1 && errorcode == 0) { if (!devtools->SendRequest("DOM.querySelector", { {"nodeId", docfound}, {"selector", "textarea.lmt__target_textarea"} }, root) || root.value("result").toObject().value("nodeId").toInt() == 0) { docfound = -1; - callqueue.pop_back(); - return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; + errorcode = 1; } - targetNodeId = root.value("result").toObject().value("nodeId").toInt(); + else + targetNodeId = root.value("result").toObject().value("nodeId").toInt(); } - // Wait for translation to appear on the web page + // Wait for the translation to appear on the web page timer = 0; - while (!devtools->checkMethod(target) && timer < timer_stop) + while (errorcode == 0 && !devtools->checkMethod(target) && timer < timer_stop) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); timer += 0.1; } // Catch the translation - if (!devtools->SendRequest("DOM.getOuterHTML", { {"nodeId", targetNodeId + 1} }, root)) + QString OuterHTML; + if (errorcode == 0 && !devtools->SendRequest("DOM.getOuterHTML", { {"nodeId", targetNodeId + 1} }, root)) { - docfound = -1; targetNodeId = -1; - callqueue.pop_back(); - return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; + errorcode = 1; + } + else + { + OuterHTML = root.value("result").toObject().value("outerHTML").toString(); } - QString OuterHTML = root.value("result").toObject().value("outerHTML").toString(); - callqueue.pop_back(); if (OuterHTML == "
") { // Try to catch the notification int noteNodeId = -1; - if (!devtools->SendRequest("DOM.querySelector", { {"nodeId", docfound}, {"selector", "div.lmt__system_notification"} }, root) + if (errorcode == 0 && !devtools->SendRequest("DOM.querySelector", { {"nodeId", docfound}, {"selector", "div.lmt__system_notification"} }, root) || root.value("result").toObject().value("nodeId").toInt() == 0) { - return { false, FormatString(L"%s: %d ", ERROR_GOT_TIMEOUT, timer_stop) }; + errorcode = 2; } - noteNodeId = root.value("result").toObject().value("nodeId").toInt(); - - if (devtools->SendRequest("DOM.getOuterHTML", { {"nodeId", noteNodeId} }, root)) + else { - OuterHTML = root.value("result").toObject().value("outerHTML").toString(); + noteNodeId = root.value("result").toObject().value("nodeId").toInt(); + if (errorcode == 0 && devtools->SendRequest("DOM.getOuterHTML", { {"nodeId", noteNodeId} }, root)) + { + OuterHTML = root.value("result").toObject().value("outerHTML").toString(); + } + errorcode = 3; } - OuterHTML.remove(QRegExp("<[^>]*>")); - OuterHTML = OuterHTML.trimmed(); - - return { false, FormatString(L"%s: %s", ERROR_NOTE, S(OuterHTML)) }; } OuterHTML.remove(QRegExp("<[^>]*>")); OuterHTML = OuterHTML.trimmed(); // Check if the translator output language does not match the selected language - if (devtools->SendRequest("DOM.getAttributes", { {"nodeId", targetNodeId} }, root)) + QString targetlang; + if (errorcode == 0 && devtools->SendRequest("DOM.getAttributes", { {"nodeId", targetNodeId} }, root)) { - QJsonObject result = root.value("result").toObject(); - QJsonArray attributes = result.value("attributes").toArray(); + QJsonArray attributes = root.value("result").toObject().value("attributes").toArray(); for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i].toString() == "lang") { - QString targetlang = attributes[i + 1].toString().mid(0, 2); + targetlang = attributes[i + 1].toString().mid(0, 2); if (targetlang != S(translateTo.Copy())) { - return { false, FormatString(L"%s (%s): %s", ERROR_LANGUAGE, S(targetlang), S(OuterHTML)) }; + errorcode = 4; } } } } - return { true, S(OuterHTML) }; + + callqueue.pop_back(); + if (errorcode == 0) + return { true, S(OuterHTML) }; + else if (errorcode == 1) + return { false, FormatString(L"%s", ERROR_COMMAND_FAIL) }; + else if (errorcode == 2) + return { false, FormatString(L"%s: %d", ERROR_GOT_TIMEOUT, timer_stop) }; + else if (errorcode == 3) + return { false, FormatString(L"%s: %s", ERROR_NOTE, S(OuterHTML)) }; + else if (errorcode == 4) + return { false, FormatString(L"%s (%s): %s", ERROR_LANGUAGE, S(targetlang), S(OuterHTML)) }; + else if (errorcode == 5) + return { false, FormatString(L"%s: %d", ERROR_GOT_TIMEOUT, 2*timer_stop) }; + else + return { false, FormatString(L"%s", TRANSLATION_ERROR) }; } \ No newline at end of file