Hello community, here is the log from the commit of package translate-shell for openSUSE:Factory checked in at 2016-05-30 09:58:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/translate-shell (Old) and /work/SRC/openSUSE:Factory/.translate-shell.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "translate-shell" Changes: -------- --- /work/SRC/openSUSE:Factory/translate-shell/translate-shell.changes 2016-03-16 10:36:23.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.translate-shell.new/translate-shell.changes 2016-05-30 09:58:20.000000000 +0200 @@ -1,0 +2,6 @@ +Sat May 28 15:43:12 UTC 2016 - [email protected] + +- Update to version 0.9.4: + * No changelog available. + +------------------------------------------------------------------- Old: ---- translate-shell-0.9.3.2.tar.gz New: ---- translate-shell-0.9.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ translate-shell.spec ++++++ --- /var/tmp/diff_new_pack.4k7Lal/_old 2016-05-30 09:58:21.000000000 +0200 +++ /var/tmp/diff_new_pack.4k7Lal/_new 2016-05-30 09:58:21.000000000 +0200 @@ -17,7 +17,7 @@ Name: translate-shell -Version: 0.9.3.2 +Version: 0.9.4 Release: 0 Summary: Google Translate to serve as a command-line tool License: Unlicense ++++++ translate-shell-0.9.3.2.tar.gz -> translate-shell-0.9.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/Makefile new/translate-shell-0.9.4/Makefile --- old/translate-shell-0.9.3.2/Makefile 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/Makefile 2016-05-18 05:26:56.000000000 +0200 @@ -30,8 +30,9 @@ [ "`$(BUILDDIR)/$(COMMAND) -no-init -D -b 忍者`" = 'Ninja' ] &&\ [ "`$(BUILDDIR)/$(COMMAND) -no-init -D -b 'hello world'`" = 'hello world' ] -install: - @install -D $(BUILDDIR)/$(COMMAND) $(PREFIX)/bin/$(COMMAND) &&\ +install: build + @mkdir -p $(PREFIX)/bin &&\ + install $(BUILDDIR)/$(COMMAND) $(PREFIX)/bin/$(COMMAND) &&\ mkdir -p $(PREFIX)/share/man/man1 &&\ cp $(MANDIR)/$(COMMAND).1 $(PREFIX)/share/man/man1/$(COMMAND).1 &&\ echo "[OK] $(NAME) installed." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/README.md new/translate-shell-0.9.4/README.md --- old/translate-shell-0.9.3.2/README.md 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/README.md 2016-05-18 05:26:56.000000000 +0200 @@ -1,12 +1,12 @@ # Translate Shell -[](http://www.soimort.org/translate-shell) +[](https://www.soimort.org/translate-shell) [](https://travis-ci.org/soimort/translate-shell) [](https://github.com/soimort/translate-shell/releases) -[](http://www.soimort.org/translate-shell/trans) +[](https://www.soimort.org/translate-shell/trans) [](https://gitter.im/soimort/translate-shell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -**[Translate Shell](http://www.soimort.org/translate-shell)** (formerly _Google Translate CLI_) is a command-line translator powered by **[Google Translate](https://translate.google.com/)** (default), **[Bing Translator](https://www.bing.com/translator)**, and **[Yandex.Translate](https://translate.yandex.com/)**. It gives you easy access to one of these translation engines your terminal: +**[Translate Shell](https://www.soimort.org/translate-shell)** (formerly _Google Translate CLI_) is a command-line translator powered by **[Google Translate](https://translate.google.com/)** (default), **[Bing Translator](https://www.bing.com/translator)**, **[Yandex.Translate](https://translate.yandex.com/)** and **[Apertium](https://www.apertium.org/)**. It gives you easy access to one of these translation engines your terminal: ``` $ trans 'Saluton, Mondo!' @@ -104,29 +104,21 @@ $ wget git.io/trans $ chmod +x ./trans -There is a [GPG signature](http://www.soimort.org/translate-shell/trans.sig). +There is a [GPG signature](https://www.soimort.org/translate-shell/trans.sig). ### Option #2. From A Package Manager -#### Using [Antigen](http://antigen.sharats.me/) +#### Using [Antigen](https://github.com/zsh-users/antigen) (Recommended for Zsh users) Add the following line to your `.zshrc`: antigen bundle soimort/translate-shell -#### Using [Homebrew](http://brew.sh/) - - $ brew install translate-shell - -On Linux with [Linuxbrew](https://github.com/Homebrew/linuxbrew), you may ignore its dependencies (e.g. gawk) if you already have them in your system: - - $ brew install --ignore-dependencies translate-shell - #### Using your favorite package manager See **[wiki: Distros](https://github.com/soimort/translate-shell/wiki/Distros)** on how to install from a specific package manager on your distro. -### Option #3. From Git +### Option #3. From Git (Recommended for seasoned hackers) $ git clone https://github.com/soimort/translate-shell $ cd translate-shell/ @@ -141,7 +133,7 @@ $ [sudo] make PREFIX=/usr install -## Introduction by Examples +## Getting Started by Examples ### Translate a Word @@ -323,7 +315,7 @@ ## Usage -For more details on command-line options, see the man page **[trans(1)](http://www.soimort.org/translate-shell/trans.1.html)** or use `trans -M` in a terminal. +For more details on command-line options, see the man page **[trans(1)](https://www.soimort.org/translate-shell/trans.1.html)** or use `trans -M` in a terminal. ``` Usage: trans [OPTIONS] [SOURCE]:[TARGETS] [TEXT]... @@ -507,6 +499,7 @@ * **[Text Editor Integration](https://github.com/soimort/translate-shell/wiki/Text-Editor-Integration)** * **[Configuration](https://github.com/soimort/translate-shell/wiki/Configuration)** * **[Themes](https://github.com/soimort/translate-shell/wiki/Themes)** +* **[AppleScript](https://github.com/soimort/translate-shell/wiki/AppleScript)** Find out whether your Linux distribution has included **Translate Shell** in its official repository. If not, contribute one: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/README.template.md new/translate-shell-0.9.4/README.template.md --- old/translate-shell-0.9.3.2/README.template.md 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/README.template.md 2016-05-18 05:26:56.000000000 +0200 @@ -1,12 +1,12 @@ # Translate Shell -[](http://www.soimort.org/translate-shell) +[](https://www.soimort.org/translate-shell) [](https://travis-ci.org/soimort/translate-shell) [](https://github.com/soimort/translate-shell/releases) -[](http://www.soimort.org/translate-shell/trans) +[](https://www.soimort.org/translate-shell/trans) [](https://gitter.im/soimort/translate-shell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -**[Translate Shell](http://www.soimort.org/translate-shell)** (formerly _Google Translate CLI_) is a command-line translator powered by **[Google Translate](https://translate.google.com/)** (default), **[Bing Translator](https://www.bing.com/translator)**, and **[Yandex.Translate](https://translate.yandex.com/)**. It gives you easy access to one of these translation engines your terminal: +**[Translate Shell](https://www.soimort.org/translate-shell)** (formerly _Google Translate CLI_) is a command-line translator powered by **[Google Translate](https://translate.google.com/)** (default), **[Bing Translator](https://www.bing.com/translator)**, **[Yandex.Translate](https://translate.yandex.com/)** and **[Apertium](https://www.apertium.org/)**. It gives you easy access to one of these translation engines your terminal: ``` $ trans 'Saluton, Mondo!' @@ -104,29 +104,21 @@ $ wget git.io/trans $ chmod +x ./trans -There is a [GPG signature](http://www.soimort.org/translate-shell/trans.sig). +There is a [GPG signature](https://www.soimort.org/translate-shell/trans.sig). ### Option #2. From A Package Manager -#### Using [Antigen](https://github.com/zsh-users/antigen) +#### Using [Antigen](https://github.com/zsh-users/antigen) (Recommended for Zsh users) Add the following line to your `.zshrc`: antigen bundle soimort/translate-shell -#### Using [Homebrew](https://github.com/Homebrew/homebrew) - - $ brew install https://www.soimort.org/translate-shell/translate-shell.rb - -On Linux with [Linuxbrew](https://github.com/Homebrew/linuxbrew), you may ignore its dependencies (e.g. gawk) if you already have them in your system: - - $ brew install --ignore-dependencies https://www.soimort.org/translate-shell/translate-shell.rb - #### Using your favorite package manager See **[wiki: Distros](https://github.com/soimort/translate-shell/wiki/Distros)** on how to install from a specific package manager on your distro. -### Option #3. From Git +### Option #3. From Git (Recommended for seasoned hackers) $ git clone https://github.com/soimort/translate-shell $ cd translate-shell/ @@ -141,7 +133,7 @@ $ [sudo] make PREFIX=/usr install -## Introduction by Examples +## Getting Started by Examples ### Translate a Word @@ -323,7 +315,7 @@ ## Usage -For more details on command-line options, see the man page **[trans(1)](http://www.soimort.org/translate-shell/trans.1.html)** or use `trans -M` in a terminal. +For more details on command-line options, see the man page **[trans(1)](https://www.soimort.org/translate-shell/trans.1.html)** or use `trans -M` in a terminal. ``` $usage$ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/build.awk new/translate-shell-0.9.4/build.awk --- old/translate-shell-0.9.3.2/build.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/build.awk 2016-05-18 05:26:56.000000000 +0200 @@ -22,7 +22,6 @@ PagesPath = "gh-pages/" BadgeDownload = PagesPath "images/badge-download" BadgeRelease = PagesPath "images/badge-release" - HomebrewFormula = PagesPath "translate-shell.rb" Index = PagesPath "index.md" ReadmePath = "./" @@ -249,17 +248,6 @@ writeTo(text, BadgeDownload) system("save-to-png " BadgeDownload) - d("Updating gh-pages/translate-shell.rb ...") - # Update gh-pages/translate-shell.rb - system("git archive --format=tar.gz --prefix=translate-shell-"Version"/ v"Version" >"PagesPath"/v"Version".tar.gz") - ("sha256sum " PagesPath"/v"Version".tar.gz") | getline temp - split(temp, group) - sha256 = group[1] - text = readFrom(HomebrewFormula ".temp") - gsub(/\$sha256\$/, sha256, text) - gsub(/\$Version\$/, Version, text) - writeTo(text, HomebrewFormula) - d("Updating gh-pages/index.md ...") # Update gh-pages/index.md ("sha1sum " Trans) | getline temp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Languages.awk new/translate-shell-0.9.4/include/Languages.awk --- old/translate-shell-0.9.3.2/include/Languages.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Languages.awk 2016-05-18 05:26:56.000000000 +0200 @@ -1681,6 +1681,20 @@ Locale["tt"]["glotto"] = "tata1255" Locale["tt"]["script"] = "Cyrl" + #? Udmurt + Locale["udm"]["support"] = "yandex-only" + Locale["udm"]["name"] = "Udmurt" + Locale["udm"]["endonym"] = "удмурт" + #Locale["udm"]["translations-of"] + #Locale["udm"]["definitions-of"] + #Locale["udm"]["synonyms"] + #Locale["udm"]["examples"] + #Locale["udm"]["see-also"] + Locale["udm"]["family"] = "Uralic" + Locale["udm"]["iso"] = "udm" + Locale["udm"]["glotto"] = "udmu1245" + Locale["udm"]["script"] = "Cyrl" + #? Uyghur Locale["ug"]["support"] = "unstable" Locale["ug"]["name"] = "Uyghur" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Parser.awk new/translate-shell-0.9.4/include/Parser.awk --- old/translate-shell-0.9.3.2/include/Parser.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Parser.awk 2016-05-18 05:26:56.000000000 +0200 @@ -265,16 +265,19 @@ for (i = 0; i < length(tokens); i++) { token = tokens[i] - if (belongsTo(token, arrayStartTokens)) + if (belongsTo(token, arrayStartTokens)) { stack[++p] = 0 - else if (belongsTo(token, objectStartTokens)) + } else if (belongsTo(token, objectStartTokens)) { stack[++p] = NULLSTR - else if (belongsTo(token, objectEndTokens) || - belongsTo(token, arrayEndTokens)) + flag = 0 # ready to read key + } else if (belongsTo(token, objectEndTokens) || + belongsTo(token, arrayEndTokens)) { --p - else if (belongsTo(token, commas)) { + } else if (belongsTo(token, commas)) { if (isnum(stack[p])) # array stack[p]++ # increase index + else # object + flag = 0 # ready to read key } else if (belongsTo(token, colons)) { flag = 1 # ready to read value } else if (isnum(stack[p]) || flag) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Script.awk new/translate-shell-0.9.4/include/Script.awk --- old/translate-shell-0.9.3.2/include/Script.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Script.awk 2016-05-18 05:26:56.000000000 +0200 @@ -60,7 +60,7 @@ if (newerVersion(newVersion, Version)) { w("Current version: \t" Version) w("New version available: \t" newVersion) - w("Download from: \t" "http://www.soimort.org/translate-shell/trans") + w("Download from: \t" "https://www.soimort.org/translate-shell/trans") } else { w("Current version: \t" Version) w("Already up-to-date.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Translate.awk new/translate-shell-0.9.4/include/Translate.awk --- old/translate-shell-0.9.3.2/include/Translate.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Translate.awk 2016-05-18 05:26:56.000000000 +0200 @@ -84,7 +84,7 @@ return text } -# Send an HTTP request and get response from an online translator. +# Send an HTTP GET request and get response from an online translator. function getResponse(text, sl, tl, hl, content, header, isBody, url) { url = _RequestUrl(text, sl, tl, hl) @@ -93,6 +93,8 @@ "Connection: close\n" if (Option["user-agent"]) header = header "User-Agent: " Option["user-agent"] "\n" + if (Cookie) + header = header "Cookie: " Cookie "\n" content = NULLSTR; isBody = 0 print header |& HttpService diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Translators/*.awk new/translate-shell-0.9.4/include/Translators/*.awk --- old/translate-shell-0.9.3.2/include/Translators/*.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Translators/*.awk 2016-05-18 05:26:56.000000000 +0200 @@ -1,3 +1,4 @@ @include "include/Translators/GoogleTranslate" @include "include/Translators/BingTranslator" @include "include/Translators/YandexTranslate" +@include "include/Translators/Apertium" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Translators/Apertium.awk new/translate-shell-0.9.4/include/Translators/Apertium.awk --- old/translate-shell-0.9.3.2/include/Translators/Apertium.awk 1970-01-01 01:00:00.000000000 +0100 +++ new/translate-shell-0.9.4/include/Translators/Apertium.awk 2016-05-18 05:26:56.000000000 +0200 @@ -0,0 +1,124 @@ +#################################################################### +# Apertium.awk # +#################################################################### +# +# Last Updated: 14 Mar 2016 +BEGIN { provides("apertium") } + +function apertiumInit() { + HttpProtocol = "http://" + HttpHost = "www.apertium.org" + HttpPort = 80 +} + +function apertiumRequestUrl(text, sl, tl, hl) { + return HttpPathPrefix "/apy/translate?" \ + "langpair=" preprocess(sl) "|" preprocess(tl) \ + "&q=" preprocess(text) +} + +function apertiumTTSUrl(text, tl, narrator) { + # Not implemented +} + +function apertiumWebTranslateUrl(uri, sl, tl, hl) { + # Not implemented +} + +# Get the translation of a string. +function apertiumTranslate(text, sl, tl, hl, + isVerbose, toSpeech, returnPlaylist, returnIl, + #### + r, + content, tokens, ast, + _sl, _tl, _hl, il, + translation, + wShowOriginal, wShowTranslation, wShowLanguages, + group, temp) { + if (!getCode(tl)) { + # Check if target language is supported + w("[WARNING] Unknown target language code: " tl) + } else if (isRTL(tl)) { + # Check if target language is R-to-L + if (!FriBidi) + w("[WARNING] " getName(tl) " is a right-to-left language, but FriBidi is not found.") + } + _sl = getCode(sl); if (!_sl) _sl = sl + _tl = getCode(tl); if (!_tl) _tl = tl + _hl = getCode(hl); if (!_hl) _hl = hl + + # Quick hack: Apertium doesn't have an "auto" language code + _sl = "auto" == _sl ? "en" : _sl + + content = getResponse(text, _sl, _tl, _hl) + tokenize(tokens, content) + parseJson(ast, tokens) + + l(content, "content", 1, 1) + l(tokens, "tokens", 1, 0, 1) + l(ast, "ast") + if (!isarray(ast) || !anything(ast)) { + e("[ERROR] Oops! Something went wrong and I can't translate it for you :(") + ExitCode = 1 + return + } + + translation = unparameterize(ast[0 SUBSEP "responseData" SUBSEP]) + + returnIl[0] = il = _sl + if (Option["verbose"] < 0) + return getList(il) + + # Generate output + if (!isVerbose) { + # Brief mode + r = translation + + } else { + # Verbose mode + wShowOriginal = Option["show-original"] + wShowTranslation = Option["show-translation"] + wShowLanguages = Option["show-languages"] + + if (wShowOriginal) { + # Display: original text + if (r) r = r RS RS + r = r m("-- display original text") + r = r prettify("original", s(text, il)) + } + + if (wShowTranslation) { + # Display: major translation + if (r) r = r RS RS + r = r m("-- display major translation") + r = r prettify("translation", s(translation, tl)) + } + + if (wShowLanguages) { + # Display: source language -> target language + if (r) r = r RS RS + r = r m("-- display source language -> target language") + temp = Option["fmt-languages"] + if (!temp) temp = "[ %s -> %t ]" + split(temp, group, /(%s|%S|%t|%T)/) + r = r prettify("languages", group[1]) + if (temp ~ /%s/) + r = r prettify("languages-sl", getDisplay(il)) + if (temp ~ /%S/) + r = r prettify("languages-sl", getName(il)) + r = r prettify("languages", group[2]) + if (temp ~ /%t/) + r = r prettify("languages-tl", getDisplay(tl)) + if (temp ~ /%T/) + r = r prettify("languages-tl", getName(tl)) + r = r prettify("languages", group[3]) + } + } + + if (toSpeech) { + returnPlaylist[0]["text"] = translation + returnPlaylist[0]["tl"] = tl + } + + return r +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Translators/BingTranslator.awk new/translate-shell-0.9.4/include/Translators/BingTranslator.awk --- old/translate-shell-0.9.3.2/include/Translators/BingTranslator.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Translators/BingTranslator.awk 2016-05-18 05:26:56.000000000 +0200 @@ -2,76 +2,47 @@ # BingTranslator.awk # #################################################################### # -# Last Updated: 11 Mar 2016 -# http://ssl.microsofttranslator.com/dynamic/226010/js/LandingPage.js +# Last Updated: 18 May 2016 BEGIN { provides("bing") } -function genRTTAppId( content, group, header, isBody) { +function bingInit() { HttpProtocol = "http://" - HttpHost = "ssl.microsofttranslator.com" + HttpHost = "www.bing.com" HttpPort = 80 - LandingPage = "/dynamic/226010/js/LandingPage.js" +} - if (Option["proxy"]) { - match(Option["proxy"], /^(http:\/*)?([^\/]*):([^\/:]*)/, HttpProxySpec) - HttpService = "/inet/tcp/0/" HttpProxySpec[2] "/" HttpProxySpec[3] - HttpPathPrefix = HttpProtocol HttpHost - } else { - HttpService = "/inet/tcp/0/" HttpHost "/" HttpPort - HttpPathPrefix = "" - } +# Retrieve the Cookie needed. +function bingSetCookie( cookie, group, header, url) { + url = HttpPathPrefix "/translator" - header = "GET " LandingPage " HTTP/1.1\n" \ + header = "GET " url " HTTP/1.1\n" \ "Host: " HttpHost "\n" \ "Connection: close\n" if (Option["user-agent"]) header = header "User-Agent: " Option["user-agent"] "\n" - content = NULLSTR; isBody = 0 + cookie = NULLSTR print header |& HttpService - while ((HttpService |& getline) > 0) { - if (isBody) - content = content ? content "\n" $0 : $0 - else if (length($0) <= 1) - isBody = 1 + while ((HttpService |& getline) > 0 && length($0) > 1) { + match($0, /Set-Cookie: ([^;]*);/, group) + if (group[1]) { + cookie = cookie (cookie ? "; " : NULLSTR) group[1] + } l(sprintf("%4s bytes > %s", length($0), length($0) < 1024 ? $0 : "...")) } close(HttpService) - - match(content, /rttAppId:"([^"]+)"/, group) - if (group[1]) { - RTTAppId = group[1] - } else { - e("[ERROR] Oops! Something went wrong and I can't translate it for you :(") - exit 1 - } -} - -function bingInit() { - genRTTAppId() # generate a one-time key - - HttpProtocol = "http://" - HttpHost = "api.microsofttranslator.com" - HttpPort = 80 -} - -function bingRequestUrl(text, sl, tl, hl) { - # Quick hack: Bing doesn't have an "auto" language code - if (sl == "auto") sl = NULLSTR - - return HttpPathPrefix "/v2/ajax.svc/TranslateArray2?" \ - "appId=" preprocess(parameterize(RTTAppId, "\"")) \ - "&from=" preprocess(parameterize(sl, "\"")) \ - "&to=" preprocess(parameterize(tl, "\"")) \ - "&texts=" preprocess("[" parameterize(text, "\"") "]") + Cookie = cookie } +# TTS -- FIXME! function bingTTSUrl(text, tl, narrator) { narrator = Option["narrator"] ~ /^[AFaf]/ ? "female" : "male" - - return HttpProtocol HttpHost "/v2/http.svc/speak?" "appId=" RTTAppId \ - "&language=" tl "&text=" preprocess(text) \ - "&format=audio/mp3" "&options=MinSize|" narrator + # FIXME: + # 1. use digraphia code (en-US) as Alpha-2 code alone doen't work + # 2. how to pass cookies to an external player? + return HttpProtocol HttpHost "/translator/api/language/Speak?" \ + "locale=" tl "&text=" preprocess(text) \ + "&gender=" narrator "&media=audio/mp3" } function bingWebTranslateUrl(uri, sl, tl, hl) { @@ -79,6 +50,47 @@ "from=" sl "&to=" tl "&a=" uri } +# Send an HTTP POST request and get response from Bing Translator. +function bingPost(text, sl, tl, hl, + #### + content, contentLength, group, + header, isBody, reqBody, url) { + reqBody = "[{" parameterize("text") ":" parameterize(text) "}]" + contentLength = dump(reqBody, group) + + url = HttpPathPrefix "/translator/api/Translate/TranslateArray?" \ + "from=" sl "&to=" tl + + header = "POST " url " HTTP/1.1\n" \ + "Host: " HttpHost "\n" \ + "Connection: close\n" \ + "Content-Length: " contentLength "\n" \ + "Content-Type: application/json\n" # must! + if (Option["user-agent"]) + header = header "User-Agent: " Option["user-agent"] "\n" + if (Cookie) + header = header "Cookie: " Cookie "\n" # must! + + content = NULLSTR; isBody = 0 + print (header "\n" reqBody) |& HttpService + while ((HttpService |& getline) > 0) { + if (isBody) + content = content ? content "\n" $0 : $0 + else if (length($0) <= 1) + isBody = 1 + l(sprintf("%4s bytes > %s", length($0), $0)) + } + close(HttpService) + + return assert(content, "[ERROR] Null response.") +} + +# Dictionary API (via HTTP GET). +function bingRequestUrl(text, sl, tl, hl) { + return HttpPathPrefix "/translator/api/Dictionary/Lookup?" \ + "from=" sl "&to=" tl "&text=" preprocess(text) +} + # Get the translation of a string. function bingTranslate(text, sl, tl, hl, isVerbose, toSpeech, returnPlaylist, returnIl, @@ -101,19 +113,19 @@ _tl = getCode(tl); if (!_tl) _tl = tl _hl = getCode(hl); if (!_hl) _hl = hl - content = getResponse(text, _sl, _tl, _hl) - # Strip the content and get a valid JSON string - match(content, /(\[.*\])$/, group) - if (!group[0]) { - # Display the error message - match(content, /"(.*)"$/, group) - gsub(/\\u000d/, "\r", group[1]) - gsub(/\\u000a/, "\n", group[1]) - e("[ERROR] " group[1]) - ExitCode = 1 - return - } - content = group[1] + # Hot-patches for Bing's own translator language codes + # See: <https://msdn.microsoft.com/en-us/library/hh456380.aspx> + if (_sl == "auto") _sl = "-" + if (_sl == "bs") _sl = "bs-Latn" # 'bs' is not recognized as valid code + if (_sl == "zh-CN") _sl = "zh-CHS" + if (_sl == "zh-TW") _sl = "zh-CHT" + if (_tl == "bs") _tl = "bs-Latn" + if (_tl == "zh-CN") _tl = "zh-CHS" + if (_tl == "zh-TW") _tl = "zh-CHT" + + bingSetCookie() # must! + + content = bingPost(text, _sl, _tl, _hl) tokenize(tokens, content) parseJson(ast, tokens) @@ -124,11 +136,16 @@ e("[ERROR] Oops! Something went wrong and I can't translate it for you :(") ExitCode = 1 return + } else if (ast[0 SUBSEP "Message"]) { + e("[ERROR] " unparameterize(ast[0 SUBSEP "Message"])) + e("[ERROR] " unparameterize(ast[0 SUBSEP "Details" SUBSEP 0])) + ExitCode = 1 + return } - translation = unparameterize(ast[0 SUBSEP 0 SUBSEP "TranslatedText"]) + translation = unparameterize(ast[0 SUBSEP "items" SUBSEP 0 SUBSEP "text"]) - returnIl[0] = il = unparameterize(ast[0 SUBSEP 0 SUBSEP "From"]) + returnIl[0] = il = unparameterize(ast[0 SUBSEP "from"]) if (Option["verbose"] < 0) return getList(il) @@ -139,9 +156,11 @@ } else { # Verbose mode + wShowOriginal = Option["show-original"] wShowTranslation = Option["show-translation"] wShowLanguages = Option["show-languages"] + wShowDictionary = Option["show-dictionary"] if (wShowOriginal) { # Display: original text @@ -176,6 +195,22 @@ r = r prettify("languages-tl", getName(tl)) r = r prettify("languages", group[3]) } + + if (wShowDictionary && false) { # FIXME! + # Dictionary API + # Note: source language must be identified + dicContent = getResponse(text, il, _tl, _hl) + tokenize(dicTokens, dicContent) + parseJson(dicAst, dicTokens) # FIXME: inefficient parser + + if (anything(dicAst)) { + # Display: dictionary entries + if (r) r = r RS + r = r m("-- display dictionary entries") + + # TODO + } + } } if (toSpeech) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Translators/GoogleTranslate.awk new/translate-shell-0.9.4/include/Translators/GoogleTranslate.awk --- old/translate-shell-0.9.3.2/include/Translators/GoogleTranslate.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Translators/GoogleTranslate.awk 2016-05-18 05:26:56.000000000 +0200 @@ -48,21 +48,21 @@ function googleInit() { HttpProtocol = "http://" - HttpHost = "translate.google.com" + HttpHost = "translate.googleapis.com" HttpPort = 80 } function googleRequestUrl(text, sl, tl, hl) { - return HttpPathPrefix "/translate_a/single?client=t" \ + return HttpPathPrefix "/translate_a/single?client=gtx" \ "&ie=UTF-8&oe=UTF-8" \ "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at" \ "&sl=" sl "&tl=" tl "&hl=" hl \ - "&tk=" genTK(text) "&q=" preprocess(text) + "&q=" preprocess(text) } function googleTTSUrl(text, tl) { - return HttpProtocol HttpHost "/translate_tts?ie=UTF-8&client=t" \ - "&tl=" tl "&tk=" genTK(text) "&q=" preprocess(text) + return HttpProtocol HttpHost "/translate_tts?ie=UTF-8&client=gtx" \ + "&tl=" tl "&q=" preprocess(text) } function googleWebTranslateUrl(uri, sl, tl, hl) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/include/Translators/YandexTranslate.awk new/translate-shell-0.9.4/include/Translators/YandexTranslate.awk --- old/translate-shell-0.9.3.2/include/Translators/YandexTranslate.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/include/Translators/YandexTranslate.awk 2016-05-18 05:26:56.000000000 +0200 @@ -2,7 +2,7 @@ # YandexTranslate.awk # #################################################################### # -# Last Updated: 11 Mar 2016 +# Last Updated: 16 May 2016 BEGIN { provides("yandex") } function genSID( content, group, temp) { @@ -33,10 +33,39 @@ split(tl, group, "-"); tl = group[1] return HttpPathPrefix "/api/v1/tr.json/translate?" \ - "id=" SID "&srv=tr-text" \ + "id=" SID "-0-0&srv=tr-text" \ "&text=" preprocess(text) "&lang=" (sl == "auto" ? tl : sl "-" tl) } +function yandexGetDictionaryResponse(text, sl, tl, hl, content, header, isBody, url) { + # Quick hack: Yandex doesn't support digraphia code (yet) + split(sl, group, "-"); sl = group[1] + split(tl, group, "-"); tl = group[1] + + url = HttpPathPrefix "/dicservice.json/lookup?" \ + "sid=" SID \ + "&text=" preprocess(text) "&lang=" (sl == "auto" ? tl : sl "-" tl) + + header = "GET " url " HTTP/1.1\n" \ + "Host: " "dictionary.yandex.net" "\n" \ + "Connection: close\n" + if (Option["user-agent"]) + header = header "User-Agent: " Option["user-agent"] "\n" + + content = NULLSTR; isBody = 0 + print header |& HttpService + while ((HttpService |& getline) > 0) { + if (isBody) + content = content ? content "\n" $0 : $0 + else if (length($0) <= 1) + isBody = 1 + l(sprintf("%4s bytes > %s", length($0), $0)) + } + close(HttpService) + + return assert(content, "[ERROR] Null response.") +} + function yandexTTSUrl(text, tl) { switch (tl) { # List of available TTS language codes case "ar": tl = "ar_AE"; break @@ -78,6 +107,8 @@ _sl, _tl, _hl, il, translation, wShowOriginal, wShowTranslation, wShowLanguages, + wShowDictionary, dicContent, dicTokens, dicAst, + i, syn, mean, group, temp) { if (!getCode(tl)) { # Check if target language is supported @@ -123,9 +154,11 @@ } else { # Verbose mode + wShowOriginal = Option["show-original"] wShowTranslation = Option["show-translation"] wShowLanguages = Option["show-languages"] + wShowDictionary = Option["show-dictionary"] if (wShowOriginal) { # Display: original text @@ -160,6 +193,66 @@ r = r prettify("languages-tl", getName(tl)) r = r prettify("languages", group[3]) } + + if (wShowDictionary) { + # Dictionary API + dicContent = yandexGetDictionaryResponse(text, _sl, _tl, _hl) + tokenize(dicTokens, dicContent) + parseJson(dicAst, dicTokens) + + if (anything(dicAst)) { + # Display: dictionary entries + if (r) r = r RS + r = r m("-- display dictionary entries") + + saveSortedIn = PROCINFO["sorted_in"] + PROCINFO["sorted_in"] = "@ind_num_asc" + for (i in dicAst) { + if (i ~ "^0" SUBSEP "def" SUBSEP "[[:digit:]]+" SUBSEP \ + "pos$") { + r = r RS prettify("dictionary-word-class", s((literal(dicAst[i])), hl)) + syn = mean = "" + } + + # TODO: ex, gen, ... + + if (i ~ "^0" SUBSEP "def" SUBSEP "[[:digit:]]+" SUBSEP \ + "tr" SUBSEP "[[:digit:]]+" SUBSEP \ + "mean" SUBSEP "[[:digit:]]+" SUBSEP "text") { + if (mean) { + mean = mean prettify("dictionary-explanation", ", ") \ + prettify("dictionary-explanation-item", s((literal(dicAst[i])), sl)) + } else { + mean = prettify("dictionary-explanation-item", s((literal(dicAst[i])), sl)) + } + } + + if (i ~ "^0" SUBSEP "def" SUBSEP "[[:digit:]]+" SUBSEP \ + "tr" SUBSEP "[[:digit:]]+" SUBSEP \ + "syn" SUBSEP "[[:digit:]]+" SUBSEP "text") { + if (syn) { + syn = syn prettify("dictionary-explanation", ", ") \ + prettify("dictionary-word", s((literal(dicAst[i])), il)) + } else { + syn = prettify("dictionary-word", s((literal(dicAst[i])), il)) + } + } + + if (i ~ "^0" SUBSEP "def" SUBSEP "[[:digit:]]+" SUBSEP \ + "tr" SUBSEP "[[:digit:]]+" SUBSEP "text$") { + text = prettify("dictionary-word", s((literal(dicAst[i])), il)) + if (syn) { + r = r RS ins(1, text prettify("dictionary-explanation", ", ") syn) + } else { + r = r RS ins(1, text) + } + r = r RS ins(2, mean) + syn = mean = "" + } + } + PROCINFO["sorted_in"] = saveSortedIn + } + } } if (toSpeech) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/man/trans.1 new/translate-shell-0.9.4/man/trans.1 --- old/translate-shell-0.9.3.2/man/trans.1 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/man/trans.1 2016-05-18 05:26:56.000000000 +0200 @@ -1,6 +1,6 @@ -.\" Automatically generated by Pandoc 1.16 +.\" Automatically generated by Pandoc 1.17.0.3 .\" -.TH "TRANS" "1" "2016\-03\-11" "0.9.3.2" "" +.TH "TRANS" "1" "2016\-05\-18" "0.9.4" "" .hy .SH NAME .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/man/trans.1.md new/translate-shell-0.9.4/man/trans.1.md --- old/translate-shell-0.9.3.2/man/trans.1.md 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/man/trans.1.md 2016-05-18 05:26:56.000000000 +0200 @@ -1,6 +1,6 @@ -% TRANS(1) 0.9.3.2 +% TRANS(1) 0.9.4 % Mort Yao <[email protected]> -% 2016-03-11 +% 2016-05-18 # NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/metainfo.awk new/translate-shell-0.9.4/metainfo.awk --- old/translate-shell-0.9.3.2/metainfo.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/metainfo.awk 2016-05-18 05:26:56.000000000 +0200 @@ -1,8 +1,8 @@ BEGIN { Name = "Translate Shell" Description = "Command-line translator using Google Translate, Bing Translator, Yandex.Translate, etc." - Version = "0.9.3.2" - ReleaseDate = "2016-03-11" + Version = "0.9.4" + ReleaseDate = "2016-05-18" Command = "trans" EntryPoint = "translate.awk" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/translate-shell-0.9.3.2/test/TestParser.awk new/translate-shell-0.9.4/test/TestParser.awk --- old/translate-shell-0.9.3.2/test/TestParser.awk 2016-03-11 21:05:18.000000000 +0100 +++ new/translate-shell-0.9.4/test/TestParser.awk 2016-05-18 05:26:56.000000000 +0200 @@ -71,7 +71,7 @@ assertEqual(tokens, expected) } - T("parseJson()", 5) + T("parseJson()", 10) { delete tokens; delete ast; delete expected tokenize(tokens, "0") @@ -105,6 +105,36 @@ expected[0 SUBSEP "answer" SUBSEP 0] = 42 expected[0 SUBSEP "Answer"] = "null" assertEqual(ast, expected) + + delete tokens; delete ast; delete expected + tokenize(tokens, "{\"answer\": {\"everything\": 42}}") + parseJson(ast, tokens) + expected[0 SUBSEP "answer" SUBSEP "everything"] = "42" + assertEqual(ast, expected) + + delete tokens; delete ast; delete expected + tokenize(tokens, "{\"answer\": {\"everything\": [42]}}") + parseJson(ast, tokens) + expected[0 SUBSEP "answer" SUBSEP "everything" SUBSEP 0] = "42" + assertEqual(ast, expected) + + # empty object - what is the "correct" parsing result? + + delete tokens; delete ast; delete expected + tokenize(tokens, "{}") + parseJson(ast, tokens) + assertEqual(ast, expected) + + delete tokens; delete ast; delete expected + tokenize(tokens, "{\"answer\": {}}") + parseJson(ast, tokens) + assertEqual(ast, expected) + + delete tokens; delete ast; delete expected + tokenize(tokens, "{\"answer\": {}, \"Answer\": null}") + parseJson(ast, tokens) + expected[0 SUBSEP "Answer"] = "null" + assertEqual(ast, expected) } T("parseList()", 1)
