Check-in [cfa194ff57]
Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | test and fix systran and deepl, jettison deepl pro/api split (now decided on key suffix) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
cfa194ff57da0e7441a0772de824173e |
User & Date: | mario 2022-10-21 04:49:03 |
Context
2022-10-21
| ||
06:20 | basic system tests check-in: 66f8ffe0f8 user: mario tags: trunk | |
04:49 | test and fix systran and deepl, jettison deepl pro/api split (now decided on key suffix) check-in: cfa194ff57 user: mario tags: trunk | |
04:47 | shorten ctx usage, but inject to pt_dialogs check-in: ab7fa5386f user: mario tags: trunk | |
Changes
Changes to OptionsDialog.xdl.
︙ | ︙ | |||
16 17 18 19 20 21 22 | <dlg:textfield dlg:id="email" dlg:tab-index="6" dlg:left="169" dlg:top="42" dlg:width="75" dlg:height="10" dlg:help-text="MyMemory asks for an email addres (does not require it)" dlg:help-url="HIDID"/> <dlg:fixedline dlg:id="FixedLine1" dlg:tab-index="6" dlg:left="5" dlg:top="75" dlg:width="117" dlg:height="9" dlg:value="Options"/> <dlg:fixedline dlg:id="FixedLine3" dlg:tab-index="7" dlg:left="5" dlg:top="5" dlg:width="117" dlg:height="7" dlg:value="Service"/> <dlg:fixedline dlg:id="FixedLine2" dlg:tab-index="8" dlg:left="131" dlg:top="5" dlg:width="115" dlg:height="8" dlg:value="Parameters"/> <dlg:fixedline dlg:id="Label1" dlg:tab-index="9" dlg:left="137" dlg:top="20" dlg:width="23" dlg:height="8" dlg:value="API key "/> <dlg:fixedline dlg:id="Label2" dlg:tab-index="10" dlg:left="137" dlg:top="42" dlg:width="28" dlg:height="8" dlg:printable="false" dlg:value="Email adr "/> <dlg:fixedline dlg:id="Label3" dlg:tab-index="11" dlg:left="137" dlg:top="64" dlg:width="30" dlg:height="8" dlg:value="Command "/> | | | | < | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <dlg:textfield dlg:id="email" dlg:tab-index="6" dlg:left="169" dlg:top="42" dlg:width="75" dlg:height="10" dlg:help-text="MyMemory asks for an email addres (does not require it)" dlg:help-url="HIDID"/> <dlg:fixedline dlg:id="FixedLine1" dlg:tab-index="6" dlg:left="5" dlg:top="75" dlg:width="117" dlg:height="9" dlg:value="Options"/> <dlg:fixedline dlg:id="FixedLine3" dlg:tab-index="7" dlg:left="5" dlg:top="5" dlg:width="117" dlg:height="7" dlg:value="Service"/> <dlg:fixedline dlg:id="FixedLine2" dlg:tab-index="8" dlg:left="131" dlg:top="5" dlg:width="115" dlg:height="8" dlg:value="Parameters"/> <dlg:fixedline dlg:id="Label1" dlg:tab-index="9" dlg:left="137" dlg:top="20" dlg:width="23" dlg:height="8" dlg:value="API key "/> <dlg:fixedline dlg:id="Label2" dlg:tab-index="10" dlg:left="137" dlg:top="42" dlg:width="28" dlg:height="8" dlg:printable="false" dlg:value="Email adr "/> <dlg:fixedline dlg:id="Label3" dlg:tab-index="11" dlg:left="137" dlg:top="64" dlg:width="30" dlg:height="8" dlg:value="Command "/> <dlg:menulist dlg:id="backend" dlg:tab-index="12" dlg:left="10" dlg:top="20" dlg:width="105" dlg:height="14" dlg:help-text="Which translation service to use. Some might require an API key, or email address. Google Ajax, DuckDuckGo, PONS Web, or Argos Translate are recommended defaults. For sensitive documents, DeepL, SysTran, or a Microsoft subscription might be more suitable." dlg:spin="true" dlg:linecount="20"> <dlg:menupopup> <dlg:menuitem dlg:value="Google Translate"/> <dlg:menuitem dlg:value="GoogleApis Ajax Translate"/> <dlg:menuitem dlg:value="MyMemory"/> <dlg:menuitem dlg:value="PONS Text Translation"/> <dlg:menuitem dlg:value="DuckDuckGo"/> <dlg:menuitem dlg:value="command line tool"/> <dlg:menuitem dlg:value="ArgosTranslate (OpenNMT)"/> <dlg:menuitem dlg:value="LibreTranslate"/> <dlg:menuitem dlg:value="LibreLocal http://localhost:5000/translate"/> <dlg:menuitem dlg:value="DeepL web interface"/> <dlg:menuitem dlg:value="DeepL Pro/Free API"/> <dlg:menuitem dlg:value="SYSTRAN translate Pro API"/> <dlg:menuitem dlg:value="DT: QCRI Machine Translation"/> <dlg:menuitem dlg:value="DT: Yandex Translation"/> <dlg:menuitem dlg:value="DT: Papago Web Translator"/> <dlg:menuitem dlg:value="DT: Pons Dictionary"/> <dlg:menuitem dlg:value="DT: Linguee Dictionary"/> <dlg:menuitem dlg:value="DT: Microsoft Translator"/> |
︙ | ︙ |
Changes to pythonpath/translationbackends.py.
︙ | ︙ | |||
226 227 228 229 230 231 232 | # # · calls mobile page http://translate.google.com/m?hl=en&sl=auto&q=TRANSLATE # · iterates over each 1900 characters # class GoogleWeb(BackendUtils): """ broadest language support (130) """ | | > | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | # # · calls mobile page http://translate.google.com/m?hl=en&sl=auto&q=TRANSLATE # · iterates over each 1900 characters # class GoogleWeb(BackendUtils): """ broadest language support (130) """ match = r"^google$ | ^google [\s\-_]* (translate|web)$" raises_error = False requires_key = False lang_detect = "auto" is_tested = 1.0 # main backend, well tested max_len = 1900 # request text translation from google def fetch(self, text): dst_lang = self.params["lang"] src_lang = self.params["from"] # "auto" works # fetch translation page url = "https://translate.google.com/m?tl=%s&hl=%s&sl=%s&q=%s" % ( |
︙ | ︙ | |||
261 262 263 264 265 266 267 268 269 270 271 272 273 274 | """ alternative/faster interface """ match = r"^google.*ajax" raises_error = False requires_key = False lang_detect = "auto" is_tested = 0.9 # main backend # request text translation from google def fetch(self, text): resp = http.get( url="https://translate.googleapis.com/translate_a/single", params={ "client": "gtx", | > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | """ alternative/faster interface """ match = r"^google.*ajax" raises_error = False requires_key = False lang_detect = "auto" is_tested = 0.9 # main backend max_len = 1900 # request text translation from google def fetch(self, text): resp = http.get( url="https://translate.googleapis.com/translate_a/single", params={ "client": "gtx", |
︙ | ︙ | |||
465 466 467 468 469 470 471 | raise ConnectionRefusedError(resp, resp.content) # DeepL online translator # · will easily yield HTTP 429 Too many requests, # so probably not useful for multi-paragraph translation anyway (just text selections) # · a convoluted json-rpc interface (but hints at context-sensitive language recognition) | | < < < < < < < < < < < < < < < < < < | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | raise ConnectionRefusedError(resp, resp.content) # DeepL online translator # · will easily yield HTTP 429 Too many requests, # so probably not useful for multi-paragraph translation anyway (just text selections) # · a convoluted json-rpc interface (but hints at context-sensitive language recognition) # · mostly here for testing if DeepL yields better results for your text documents # class DeeplWeb(BackendUtils): """ 15 langs, screen scraping access """ match = r"^deepl [\s_\-]* web" requires_key = False raises_error = True |
︙ | ︙ | |||
621 622 623 624 625 626 627 | # DeepL API # # So, there's a free API and the pro API now. This might make the _web scraping # dancearound redundant. The free API is certainly more enticing for testing. # In general, DeepL provides a more streamlined translation than GoogleWeb. | | | | > > > > > > < < > | > < < < < < < < < < < < < < < < < < < < < < < | 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 | # DeepL API # # So, there's a free API and the pro API now. This might make the _web scraping # dancearound redundant. The free API is certainly more enticing for testing. # In general, DeepL provides a more streamlined translation than GoogleWeb. # It's mostly in here because the API is quite simple. (Rudimentarily tested) # class DeeplApi(DeeplWeb): """ High quality AI translation, 15 langs""" match = r"^deepl (free|translate|api|pro[\s/_-])*" requires_key = True raises_error = True lang_detect = "auto" is_tested = 0.1 # only free ever tested max_len = 50000 api_url = "https://api.deepl.com/v2/translate" api_free = "https://api-free.deepl.com/v2/translate" headers = {} def __init__(self, **params): DeeplWeb.__init__(self, **params) self.headers = { "Authorization": "DeepL-Auth-Key " + self.params["api_key"], } # confirmed: if key ends in :fx - https://www.deepl.com/docs-api/api-access/general-information/ if re.search(r":fx\s*$", self.params["api_key"], re.I): self.api_url = self.api_free def translate(self, text, preserve=0): # pylint: disable=arguments-differ # https://www.deepl.com/docs-api/translating-text/request/ params = { "text": text, "target_lang": self.params["lang"], "source_lang": self.non_auto_lang(None), # from if not 'auto' "split_sentences": "1", "preserve_formatting": str(preserve), "formality": "default", #"tag_handling": "xml|html", } self.log.debug("p=%s h=%s", params, self.headers) resp = http.post( self.api_url, data=params, headers=self.headers, ) self.log.debug(resp) if resp.status_code == 200: resp = resp.json().get("translations") if resp: return resp[0]["text"] else: self.log.error(repr(resp)) if resp.status_code == 403: resp.status = "Authorization/API key invalid" if not hasattr(resp, "status"): resp.status = "???" raise ConnectionRefusedError(resp.status_code, resp.status, resp.headers) return text def linebreakwise(self, text): return self.translate(text, preserve=1) # deep-translator # requires `pip install deep-translator` # · more backends than pytranslate, # though PONS+Linguee are just dictionaries # → https://github.com/nidhaloff/deep-translator # |
︙ | ︙ | |||
894 895 896 897 898 899 900 | if re.match(r"""^["']?[\{%$]""" + key + r"""[\}%$]?["']?$""", arg): return value return arg # SYSTRAN Translate API # · https://docs.systran.net/translateAPI/translation/ | | | | | < | | < < | | | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 | if re.match(r"""^["']?[\{%$]""" + key + r"""[\}%$]?["']?$""", arg): return value return arg # SYSTRAN Translate API # · https://docs.systran.net/translateAPI/translation/ # · also requires an API key (trial subscriptions are working meanwhile) # class SysTran(BackendUtils): """ professional service, 50 languages """ match = r"^systran" requires_key = True raises_error = True lang_detect = "auto" is_tested = 0.2 # actually tested now max_len = 10000 api_url = "https://api-translate.systran.net/translation/text/translate" def fetch(self, text): resp = http.post( url=self.api_url, data={ "input": text, "target": self.params["lang"], "source": self.params["from"], }, headers={ "Authorization": "Key " + self.params["api_key"] } ) data = resp.json() # if not JSON response, we probably ran into a HTTP/API error if resp.status_code != 200: raise Exception(data, resp.headers) # nested result structure return data["outputs"][0]["output"] # ArgosTranslate # # · offline translation package (OpenNMT) |
︙ | ︙ |
Changes to tk_translate/__init__.py.
1 2 3 4 5 6 7 8 | #!/usr/bin/env python3 # encoding: utf-8 # fmt: off # api: pysimplegui # type: gui # title: standalone PageTranslate # description: Utilizes translationbackends in trivial from→to texteditor # category: transform | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #!/usr/bin/env python3 # encoding: utf-8 # fmt: off # api: pysimplegui # type: gui # title: standalone PageTranslate # description: Utilizes translationbackends in trivial from→to texteditor # category: transform # version: 0.3 # state: beta # license: MITL # config: - # priority: optional # depends: python >= 3.8, python:PySimpleGUI >= 4.37, python:requests # pack: pythonpath/*.py=gui/ # architecture: all # classifiers: translation # keywords: translation # url: https://fossil.include-once.org/pagetranslate/ # doc-format: text/markdown # # **tk-translate** is a PySimpleGUI variant of # [PageTranslate](https://fossil.include-once.org/pagetranslate/). # It provides a terse GUI to get some text translated using one of the various # services from PT or Deep-Translator. Albeit it has no config dialog, thus # won't pacify API-key requirements. It's mostly just meant for testing. # # ![🗔](https://fossil.include-once.org/pagetranslate/raw/24ddd787008?m=image/png) # # Presents two input boxes, some buttons, for plain text translations. # Usage: # # * Insert text into left input # * Select backend # * Change target language |
︙ | ︙ | |||
105 106 107 108 109 110 111 | "Linguee Dict", "PONS Dict", "dingonyms --merriam {text}", "LibreTranslate ⚿", "SysTRAN ⚿", "QCRI ⚿", "Yandex ⚿", | < | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | "Linguee Dict", "PONS Dict", "dingonyms --merriam {text}", "LibreTranslate ⚿", "SysTRAN ⚿", "QCRI ⚿", "Yandex ⚿", "DeepL Free/Pro API ⚿", "DeepL Web ⛼", "Microsoft ⚿", "DeepTransApi: Google", "DeepTransApi: MyMemory", "deep_translator -trans 'google' -src 'auto' -tg {lang} -txt {text}", "argos-translate --from-lang {from} --to-lang {lang} {text}", "trans -sl {from} {text} {lang}", |
︙ | ︙ |