Jump to content

Google translate workflow

Recommended Posts

  • 1 month later...
  • 2 weeks later...
  • 8 months later...

Although i this workflow, I wonder if it is possible to translate bigger chunks of text? It seems like the first period sign "." terminates the translation. I do a lot of research in academic papers for my master thesis, and use Alfred to do a quick translation of chunks of text (typically a paragraph or three) that I use as citations in my paper. I have successfully made it work by removing the punctuation manually before pasting it into this wf, but that removes the beauty of it.




Edit: I fidgeted around with periods a little. Not only are periods escaping the query, but the result from a "I say hello." returns (the translated equivalent of) "I say hello ." - mind the gap between hello and the period. Would love it if someone smarter than me would have a look at this!

Edited by bonka
Link to comment

What actually happens is that Google returns each sentence as a separate result, but the workflow throws away all but the first.
To get multi-sentence results, open the workflow in Finder and edit the translate script in it to read as follows. This will show all the sentences in a translation. Because Alfred can't show much text in its results, I've added copy text and large type. Hit CMD+C on a result to copy the translation to the clipboard and CMD+L to show the full translation in Alfred's large type window.

# Set locale and normalize unicode composition for international support.
export LC_CTYPE="UTF-8"
query="$(echo "${@:3}" | iconv -s -f UTF-8-Mac -t UTF-8)"

# Retrieve and parse Google Translate answer.
response="$(curl -G --data-urlencode "text=$query" --data 'client=p' --data 'sl=auto' --data "tl=$1" --silent --user-agent 'Mozilla/5.0' 'http://translate.google.com/translate_a/t' | python -c 'import sys, json; print("".join([d.get("trans", "<UNTRANSLATED>") for d in json.loads(sys.stdin.read())["sentences"]]).encode("utf-8"))')"
[[ -z "$response" ]] && translation="No translation found" || translation="$response"

# Write feedback.
echo '<?xml version="1.0" encoding="UTF-8"?><items>
  <item uid="translation">
	<text type="copy"><![CDATA['"$translation"']]></text>
	<text type="largetype"><![CDATA['"$translation"']]></text>
	<subtitle>”'"$query"'” in '$2'.</subtitle>
Link to comment


What actually happens is that Google returns each sentence as a separate result, but the workflow throws away all but the first.


You know, I noticed this when I was writing my version of this workflow, but I lost track / got distracted and forgot to continue looking into it. I should go fix mine.

Link to comment

The important bit is setting the client URL parameter to something other than t. That way you get valid, comprehensible JSON instead of some weird crap.


I was just working on this, and, well, I took the other route to make the json valid. Basically, it seems that for a null value, Google just sends back nothing, so I added a while loop to look for two commas in a row and replace them with `,null,`. But your solution seems much, much better.

Link to comment
  • 2 weeks later...
  • 2 weeks later...

Oh my god. That is so lame. Lets start a Facebook page.


Edit: Is this API pricing page on Google Cloud Services new?


I don't think it is new. The endpoint that this (and my) workflow used was unofficial, and the paid translation API has been around for quite a while. So, these just used a sort of backdoor that Google had left open. Now, the URL leads to a redirect captcha challenge that redirects nowhere.


It's a pity that they closed the endpoint, but we can't be too mad because it was never official to begin with.

Link to comment

Okay. It can work. I just updated mine.


The endpoint has changed slightly, so the URL needs to be corrected. Also, the trick to get good JSON that Dean pointed out a few posts back no longer works, so you have to scrub the data. Next, the keys seem to have changed in that they're all just numeric arrays.


Here's what I did (it is truly an inelegant hack, but I just wanted to get it working again), so you can crib from it to get this one working again.

foreach ( $languages as $code => $name ) :
	$query =  "http://translate.google.com/translate_a/single?client=json&ie=UTF-8&oe=UTF-8";
	$query .= "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at";
	$query .= "&q=" . urlencode( $text );
	$query .= "&hl=en&sl=auto&";
	$query .= "tl=" . $code;

	$trans = file_get_contents( $query );
	while ( false !== strpos( $trans, '[,' ) ) :
		$trans = str_replace( '[,', '[null,', $trans );
	while ( false !== strpos( $trans, ',,' ) ) :
		$trans = str_replace( ',,', ',null,', $trans );
  $trans = json_decode( $trans, true );
	$string = '';
	foreach ( $trans[0] as $t ) :
		$string .= trim( $t[0] ) . ' ';
	$w->result( '', $string, $string, "$name: $text", "icons/$code.png", 'yes', '' );

(Note: mine lets you use multiple languages at once, so that's why there is the big foreach loop. I haven't updated this to use Alphred yet, so it still uses David's Workflows library)


The while loops scrub the response into something that json_decode can read.

Edited by Shawn Rice
Link to comment

from what I gather the state of this workflow is this workflow, not counting the most recent fix:




with this substitution in the 'translate' file:




what's next?


(I use a modified version of the workflow for single language translations (da>en) with a hotkey and instant paste, perhaps I should just hack mr. Rice' in the same way workflow and let this one deprecate)

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...