Translate plugin
-
@A-Notepad-User
@PeterJones said in Translate plugin:If you were able to find a translation API that was free-to-use, if it had a REST-style API, you could probably use the RestApiToText plugin in Notepad++ to try it out, and then either write a PythonScript-based wrapper, or
… or, just use “mine”:
https://community.notepad-plus-plus.org/topic/24389/little-dialog-wrapper-for-pythonscript/31
Cheers.
-
Ooh, nice, I had forgotten you had shared that.
A word to anyone wanting to use it: in case you don’t see it higher in the conversation:
- You need to have at least PythonScript 3.0.16 installed (the Plugins Admin doesn’t install the PS 3.x versions, so you will have to manually install the beta version).
- You need to install the “Little Dialog Wrapper” that @Ekopalypse shared in the first post in that Topic.
-
Moving the
translate.py
specific question to this Topic, rather than the Little Dialog Wrapper conversation…Like happened with the
dictionary
script in the other Topic, thetranslate
script relies on therequests
library, which I don’t have. I tried to follow @rdipardo’s changes for thedictionary
in the analogous locations int hetranslate
, but I’m having difficulty.#import requests #### per @rdipardo's updates on Michael's other script import json import urllib.request as requests import urllib.parse ... def on_translate(self): ... ###r = requests.get(f"http://mymemory.translated.net/api/get?q={text_encoded}&langpair={langpair}") r = requests.urlopen(requests.Request(f"http://mymemory.translated.net/api/get?q={text_encoded}&langpair={langpair}")) ###response = r.json()['responseData']['translatedText'] console.writeError(f"r.status: {r.status}\nr.read: {r.read().decode('utf8')}"); return; ###### exit here, because the next line gives an error response = json.loads(r.read().decode('utf8'))['responseData']['translatedText'] # Set return translation if response is not None: self.ret.trans = response else: self.ret.trans = "(no translation found)" self.trans.setText(self.ret.trans) # Set return text self.ret.text = self.text.getText()
When I run that with the console.writeError, I get:
r.status: 200 r.read: can't open file
Any ideas what I’m doing wrong? Or has the translation API changed?
----
update: printing the URL it is trying to access usingconsole.writeError(f"\n\nhttp://mymemory.translated.net/api/get?q={text_encoded}&langpair={langpair}\n");
shows
http://mymemory.translated.net/api/get?q=Hello&langpair=en|de
If I paste that URL into my browser, I get valid JSON for the translation:
{"responseData":{"translatedText":"Hallo","match":1},"quotaFinished":false,"mtLangSupported":null,"responseDetails":"","responseStatus":200,"responderId":"45","exception_code":null,"matches":[{"id":"758976106","segment":"Hello","translation":"Hallo","source":"en-GB","target":"de-DE","quality":"74","reference":null,"usage-count":93,"subject":"All","created-by":"MateCat","last-updated-by":"MateCat","create-date":"2022-10-06 13:45:27","last-update-date":"2022-10-06 13:45:27","match":1},{"id":"757809118","segment":"Hello","translation":"Hello","source":"en-GB","target":"de-DE","quality":"74","reference":null,"usage-count":2,"subject":"All","created-by":"MateCat","last-updated-by":"MateCat","create-date":"2022-09-16 12:45:34","last-update-date":"2022-09-16 12:45:34","match":0.98999999999999999}]}
So why is that URL working for browser but not for API?
-
@PeterJones said in Translate plugin:
Any ideas what I’m doing wrong? Or has the translation API changed?
Not off hand. Pressed for time now, can look at it later. In the meantime, here is my updated full script. It may have other dependencies I’m overlooking, but at least you can see my non-
requests
version:import json import urllib.request as requests import urllib.parse from enum import Enum from Npp import editor from WinDialog import Button, ComboBox, DefaultButton, Dialog, Label, TextBox from WinDialog.win_helper import WindowStyle as WS TITLE = "Translate" DEFAULTLANG = "English" class Languages(Enum): """Translated language options.""" Chinese = "zh" English = "en" French = "fr" German = "de" Italian = "it" Japanese = "ja" Portuguese = "pt" Russian = "ru" Spanish = "es" class Returns(object): """The input / output for the Translator service.""" def __init__(self, text="", srclang=DEFAULTLANG, dstlang=DEFAULTLANG): self.text = text self.trans = "" self.srclang = srclang self.dstlang = dstlang class Translator(Dialog): """A Translator dialog interface.""" def __init__(self, ret=Returns()): super().__init__( title=TITLE , center = True , size=(290, 165) ) self.translate = DefaultButton( title='&Translate' , position=(120, 145), size=(50, 11) ) self.label1 = Label( title='Text:' , position=(10, 12) , size=(35, 11) ) self.text = TextBox( position=(45, 10) , size=(235, 55) ) self.swapt = Button( title='^&v' , position=(45, 67) , size=(20, 14) ) self.srclang = ComboBox( position=(75, 68) , size=(80, 14) ) self.swapl = Button( title='<&=>' , position=(165, 67) , size=(20, 14) ) self.dstlang = ComboBox( position=(200, 68) , size=(80, 14) ) self.label2 = Label( title='Translated:' , position=(10, 84) , size=(35, 11) ) self.trans = TextBox( position=(45, 82) , size=(235, 55) ) self.replace = Button( title='&Replace' , position=(175, 145), size=(50, 11) ) self.close = Button( title='&Close' , position=(230, 145), size=(50, 11) ) self.ret = ret self.onIdOk = self._on_translate self.translate.onClick = self._on_translate self.swapt.onClick = self._on_swapt self.swapl.onClick = self._on_swapl self.srclang.onSelEndOk = self._on_translate self.dstlang.onSelEndOk = self._on_translate self.replace.onClick = self._on_replace self.close.onClick = self._on_close self.srclang.style = self.srclang.style | WS.TABSTOP self.dstlang.style = self.dstlang.style | WS.TABSTOP self.text.style = self.text.style | WS.VSCROLL # | WS.HSCROLL self.trans.style = self.trans.style | WS.VSCROLL # | WS.HSCROLL self.show() def initialize(self): """Initialize the dialog.""" self.text.setText(self.ret.text) self._init_langs() if self.ret.srclang != self.ret.dstlang and self.ret.text != "": self._on_translate() def _init_langs(self): srclang = list(n.name for n in Languages) if self.ret.srclang in srclang: srclang.insert(0, self.ret.srclang) self.srclang.set(srclang) dstlang = list(n.name for n in Languages) if self.ret.dstlang in dstlang: dstlang.insert(0, self.ret.dstlang) self.dstlang.set(dstlang) def _on_translate(self): """Translate the text.""" if self.text.getText() == "": return text_encoded = urllib.parse.quote(self.text.getText()) srclang = Languages[self.srclang.getSelectedItemText()] dstlang = Languages[self.dstlang.getSelectedItemText()] if srclang == dstlang: return # Set return languages self.ret.srclang = srclang.name self.ret.dstlang = dstlang.name srccode = srclang.value dstcode = dstlang.value # EXAMPLE: LANGPAIR=EN|IT USING 2 LETTER ISO OR RFC3066 LIKE ZH-CN langpair = f"{srccode}|{dstcode}" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"} r = requests.urlopen(requests.Request(url=f"http://mymemory.translated.net/api/get?q={text_encoded}&langpair={langpair}", headers=headers)) if r.status != 200: return ret = r.read() response = json.loads(ret.decode('utf8'))['responseData']['translatedText'] # Set return translation if response is not None: self.ret.trans = response else: self.ret.trans = "(no translation found)" self.trans.setText(self.ret.trans) # Set return text self.ret.text = self.text.getText() def _on_swapl(self): """Swap languages.""" self.ret.dstlang = self.srclang.getSelectedItemText() self.ret.srclang = self.dstlang.getSelectedItemText() self._init_langs() self._on_translate() def _on_swapt(self): """Swap texts.""" self.ret.trans = self.text.getText() self.ret.text = self.trans.getText() self.text.setText(self.ret.text) self.trans.setText(self.ret.trans) self._on_swapl() def _on_replace(self): """Replace text with translation in document.""" if self.ret.trans != "": editor.replaceSel(self.ret.trans) self.terminate() def _on_close(self): self.terminate() class Translate(): """A translator service.""" def __init__(self): self.srclang = DEFAULTLANG self.dstlang = DEFAULTLANG def _editor_getWordAtCaretOrSelection(self): retval = '' (sel_start, sel_end) = (editor.getSelectionStart(), editor.getSelectionEnd()) if editor.getSelections() == 1 and sel_start != sel_end: retval = editor.getTextRange(sel_start, sel_end) else: start_of_word_pos = editor.wordStartPosition(editor.getCurrentPos(), True) end_of_word_pos = editor.wordEndPosition(start_of_word_pos, True) if start_of_word_pos != end_of_word_pos: retval = editor.getTextRange(start_of_word_pos, end_of_word_pos) editor.setSelection(end_of_word_pos, start_of_word_pos) return retval def translate(self): text = "" if editor.getSelectionEmpty(): sel = self._editor_getWordAtCaretOrSelection() if len(sel) > 0: text = sel else: text = editor.getSelText() ret = Returns(text, self.srclang, self.dstlang) Translator(ret) self.srclang = ret.srclang self.dstlang = ret.dstlang Translate().translate()
Cheers.
-
@Michael-Vincent said in Translate plugin:
In the meantime, here is my updated full script.
That one works for me. My guess is that it’s your User-Agent headers allowing it to work.
update: yes, adding the headers to my edits makes mine work
Thank you.
-
Hello, how are you?
Could someone show me a Translate plugin that works on the latest version of Notpad++ and explain how to install it?
-
As was said above, the Translate Plugin does work with the latest version of Notepad++ : you just have to use the 32bit Notepad++ (of which there is still a latest version). If you have 32bit Notepad++, you can just use the Plugins Admin to install the Translate Plugin. And job’s done. (All that could have been gleaned by reading my response from last July.)
If you choose not to use the 32bit Notepad++, then that original “Translate Plugin” isn’t available for you. (However, if you want to use 64bit Notepad++ most of the time, and just use 32bit Notepad++ for the Translation Plugin, then you could download a “portable” copy of the 32bit Notepad++ of the most recent version using the official downloads page, and unzip that portable 32bit, and use that portable copy to install the old Translate Plugin and see how it works. (Warning: it’s possible that the translation service that Translate Plugin links to costs money; I haven’t investigated, but most translation services do.)
However, as @databird announced in February of this year, there is a 64bit translation plugin available under the search terms described in that reply, with more-full installation instructions in the replies immediately below – but unfortunately, it requires paying for the translation service. in general, automated translation is not free (even Google translate won’t let you access their free translation service from some other application; you can enter text manually, but if you want an API so it can be automated from some other tool like Notepad++, you’d have to pay for it.) But I believe that the original 32bit Translate Plugin also requires payment (though I’m not sure), so I don’t think the 64bit plugin is any different to the 32bit plugin, in that regard (again, I could be mistaken).
The third is to use a script in the PythonScript plugin, as described in the subsequent discussion. So the steps would be
- Install the PythonScript 3 plugin. Unfortunately, you cannot use the Plugins Admin tool to install that. But our FAQ: How to install and run a script in PythonScript has a section on how to install the PythonScript 3 version of the plugin. I will not repeat those instructions here.
- Install the WinDialog library, which is the library mentioned in the other topic you replied to. You can get from its github repo here – that repo page also has the instructions as to how to install the WinDialog library in PythonScript 3. So follow those instructions for how to do that.
- Copy the
translate.py
script from @Michael-Vincent’s March 29 post in this conversation. The FAQ I linked you to in step1 tells you what to do with a script once you’ve copied it from a post, in order to install and run the script; so follow those instructions. - Run the script, as described in the FAQ from step 1.
-
@PeterJones
Is it possible to add Ukrainian language? -
@HEPBHbIU_KAPJICOH said in Translate plugin:
Is it possible to add Ukrainian language?
The Translate plugin is not maintained any more by its original author, so it’s presumably not taking feature requests. So “no”, it’s not possible to add any new language to that plugin.
And whether or not it supported Ukrainian is probably up to the external translation engine, not just the plugin author, so even if it was still taking feature requests, they might not be able to support it.
-
@HEPBHbIU_KAPJICOH said in Translate plugin:
Is it possible to add Ukrainian language?
Looks like it already does include Ukrainian: https://sourceforge.net/p/npptranslate/code/HEAD/tree/nppTranslateCS/MyMemoryTranslateEngine.cs#l102
There’s also a slightly updated 64-bit version on GitHub with all the same languages: https://github.com/databird/npptranslate64/releases