Plugins/UiExtensionPlugins/Translator/TranslatorEngines/DeepLEngine.py

changeset 6018
1c858879d3d0
child 6026
4773c9469880
equal deleted inserted replaced
6017:dab01678626d 6018:1c858879d3d0
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the DeepL translation engine.
8 """
9
10 from __future__ import unicode_literals
11 try:
12 str = unicode
13 except NameError:
14 pass
15
16 import json
17 import re
18
19 from PyQt5.QtCore import QUrl, QByteArray
20
21 from .TranslationEngine import TranslationEngine
22
23
24 class DeepLEngine(TranslationEngine):
25 """
26 Class implementing the translation engine for the DeepL
27 translation service.
28 """
29 TranslatorUrl = "https://deepl.com/jsonrpc"
30 MaxTranslationTextLen = 5000
31
32 def __init__(self, plugin, parent=None):
33 """
34 Constructor
35
36 @param plugin reference to the plugin object
37 @type TranslatorPlugin
38 @param parent reference to the parent object
39 @type QObject
40 """
41 super(DeepLEngine, self).__init__(plugin, parent)
42
43 self.__splitPattern = re.compile(r"([^\.!\?;]+[\.!\?;]*)")
44
45 def engineName(self):
46 """
47 Public method to return the name of the engine.
48
49 @return engine name
50 @rtype str
51 """
52 return "deepl"
53
54 def supportedLanguages(self):
55 """
56 Public method to get the supported languages.
57
58 @return list of supported language codes
59 @rtype list of str
60 """
61 return ["de", "en", "es", "fr", "it", "nl", "pl",]
62
63 def getTranslation(self, requestObject, text, originalLanguage,
64 translationLanguage):
65 """
66 Public method to translate the given text.
67
68 @param requestObject reference to the request object
69 (TranslatorRequest)
70 @param text text to be translated (string)
71 @param originalLanguage language code of the original (string)
72 @param translationLanguage language code of the translation (string)
73 @return tuple of translated text (string) and flag indicating
74 success (boolean)
75 """
76 if len(text) > self.MaxTranslationTextLen:
77 return self.tr(
78 "Text to be translated exceeds the translation limit of {0}"
79 " characters.").format(self.MaxTranslationTextLen), False
80
81 sentences = [s for s in self.__splitPattern.split(text) if len(s) > 0]
82 if originalLanguage in self.supportedLanguages():
83 originalLanguageU = originalLanguage.upper()
84 else:
85 originalLanguageU = "auto"
86 payload = {
87 "jsonrpc": "2.0",
88 "method": "LMT_handle_jobs",
89 "id": 1,
90 "params": {
91 "jobs": [{"kind": "default", "raw_en_sentence": s}
92 for s in sentences
93 ],
94 "lang": {
95 "user_preferred_langs": [
96 originalLanguage.upper(),
97 translationLanguage.upper(),
98 ],
99 "source_lang_user_selected": originalLanguageU,
100 "target_lang": translationLanguage.upper()
101 },
102 "priority": 1,
103 }
104 }
105 request = QByteArray(json.dumps(payload).encode("utf-8"))
106 response, ok = requestObject.post(QUrl(self.TranslatorUrl), request,
107 "json")
108 if ok:
109 try:
110 responseDict = json.loads(response)
111 except ValueError:
112 return self.tr("Invalid response received from DeepL"), False
113
114 if "error" in responseDict:
115 return self.tr("DeepL reported an error.\nMessage: {0}")\
116 .format(responseDict["error"]["message"]), False
117
118 if "result" not in responseDict:
119 return self.tr("DeepL call returned an unknown result"), False
120
121 if not responseDict["result"]["source_lang"] or \
122 not responseDict["result"]["target_lang"]:
123 return self.tr(
124 "Unsupported language code given (source: {0},"
125 " target: {1}).").format(
126 originalLanguage, translationLanguage), False
127
128 translations = responseDict["result"]["translations"]
129 if len(translations) == 0:
130 return self.tr("<p>No translation found</p>"), True
131
132 # show sentence by sentence separated by a line
133 translationStrings = []
134 for translation in translations:
135 translationStrings.append(
136 "<br/>".join(
137 [s["postprocessed_sentence"] for s in sorted(
138 translation["beams"],
139 key=lambda b: -1 * b["score"])
140 ]
141 )
142 )
143 result = "<p>" + "<hr/>".join(translationStrings) + "</p>"
144
145 else:
146 result = response
147 return result, ok

eric ide

mercurial