Sun, 31 Dec 2017 16:52:09 +0100
Updated copyright for 2018.
# -*- coding: utf-8 -*- # Copyright (c) 2017 - 2018 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the DeepL translation engine. """ from __future__ import unicode_literals try: str = unicode except NameError: pass import json import re from PyQt5.QtCore import QUrl, QByteArray from .TranslationEngine import TranslationEngine class DeepLEngine(TranslationEngine): """ Class implementing the translation engine for the DeepL translation service. """ TranslatorUrl = "https://deepl.com/jsonrpc" MaxTranslationTextLen = 5000 def __init__(self, plugin, parent=None): """ Constructor @param plugin reference to the plugin object @type TranslatorPlugin @param parent reference to the parent object @type QObject """ super(DeepLEngine, self).__init__(plugin, parent) self.__splitPattern = re.compile(r"([^\.!\?;]+[\.!\?;]*)") def engineName(self): """ Public method to return the name of the engine. @return engine name @rtype str """ return "deepl" def supportedLanguages(self): """ Public method to get the supported languages. @return list of supported language codes @rtype list of str """ return ["de", "en", "es", "fr", "it", "nl", "pl", ] def getTranslation(self, requestObject, text, originalLanguage, translationLanguage): """ Public method to translate the given text. @param requestObject reference to the request object (TranslatorRequest) @param text text to be translated (string) @param originalLanguage language code of the original (string) @param translationLanguage language code of the translation (string) @return tuple of translated text (string) and flag indicating success (boolean) """ if len(text) > self.MaxTranslationTextLen: return self.tr( "Text to be translated exceeds the translation limit of {0}" " characters.").format(self.MaxTranslationTextLen), False sentences = [s for s in self.__splitPattern.split(text) if len(s) > 0] if originalLanguage in self.supportedLanguages(): originalLanguageU = originalLanguage.upper() else: originalLanguageU = "auto" payload = { "jsonrpc": "2.0", "method": "LMT_handle_jobs", "id": 1, "params": { "jobs": [ {"kind": "default", "raw_en_sentence": s} for s in sentences ], "lang": { "user_preferred_langs": [ originalLanguage.upper(), translationLanguage.upper(), ], "source_lang_user_selected": originalLanguageU, "target_lang": translationLanguage.upper() }, "priority": 1, } } request = QByteArray(json.dumps(payload).encode("utf-8")) response, ok = requestObject.post(QUrl(self.TranslatorUrl), request, "json") if ok: try: responseDict = json.loads(response) except ValueError: return self.tr("Invalid response received from DeepL"), False if "error" in responseDict: return self.tr("DeepL reported an error.\nMessage: {0}")\ .format(responseDict["error"]["message"]), False if "result" not in responseDict: return self.tr("DeepL call returned an unknown result"), False if not responseDict["result"]["source_lang"] or \ not responseDict["result"]["target_lang"]: return self.tr( "Unsupported language code given (source: {0}," " target: {1}).").format( originalLanguage, translationLanguage), False translations = responseDict["result"]["translations"] if len(translations) == 0: return self.tr("<p>No translation found</p>"), True # show sentence by sentence separated by a line translationStrings = [] for translation in translations: translationStrings.append( "<br/>".join( [ s["postprocessed_sentence"] for s in sorted( translation["beams"], key=lambda b: -1 * b["score"]) ] ) ) result = "<p>" + "<hr/>".join(translationStrings) + "</p>" else: result = response return result, ok