Difference between revisions of "Using Google Translate"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting)
(Updated information on Google Translate params and better examples using unit fpjson)
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
 +
{{Using_Google_Translate}}
 +
 +
__TOC__
 +
 
==Overview==
 
==Overview==
Google Translate has several front ends. If you want to translate many texts you have to pay and get a key.  
+
There are at least two way to access Google Translate:
 +
* A free but metered way.
 +
* Using the OAuth2 authenticated API.
  
https://developers.google.com/translate/v2/getting_started
+
This is a usage example of the former.
  
==Simple example for casual translations==
+
For information on the latter please consult: [https://developers.google.com/translate/v2/getting_started Google Translate Getting Started]
  
This example demonstrats how to query the translator via the TFPHTTPClient and parsing the first array of the returned JSON. Even though this example is written using Lazarus, it can be easily adapted for use with FPC.
+
==Info on the params==
 +
According to an answer on Stack Overflow ([https://stackoverflow.com/a/29537590/8167 What is the meaning of Google Translate query params?]) here's a list of the params to the HTTP GET call:
 +
* sl - source language code (auto for auto detection)
 +
* tl - translation language
 +
* q - source text / word
 +
* ie - input encoding (a guess)
 +
* oe - output encoding (a guess)
 +
* dt - may be included more than once and specifies what to return in the reply
 +
* dj - JSON response with names instead of only arrays (dj=1)
 +
 
 +
Here are some value for dt:
 +
* t - translation of source text
 +
* at - alternate translations
 +
* rm - transcription / transliteration of source and translated texts
 +
* bd - dictionary, in case source text is one word (you get translations with articles, reverse translations, etc.)
 +
* md - definitions of source text, if it's one word
 +
* ss - synonyms of source text, if it's one word
 +
* ex - examples
 +
* rw - See also list
 +
 
 +
 
 +
==Contacting Google==
 +
This function will return the JSON response.
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
uses
 
uses
   lazlogger, fpjson, fphttpclient, HTTPDefs;
+
   {...}, fpjson, fphttpclient, opensslsockets, {...}
  
function DownloadText(const URL: string): TStrings;
+
function CallGoogleTranslate(AURL: String): TJSONStringType;
 
var
 
var
 
   client: TFPHTTPClient;
 
   client: TFPHTTPClient;
 
   doc: TStringList;
 
   doc: TStringList;
 
begin
 
begin
   Result:=nil;
+
   Result:= EmptyStr;
 
   doc:=TStringList.Create;
 
   doc:=TStringList.Create;
 
   client:=TFPHTTPClient.Create(nil);
 
   client:=TFPHTTPClient.Create(nil);
 
   try
 
   try
     client.Get(URL,doc);
+
     client.Get(AURL,doc);
     Result:=doc;
+
     Result:=doc.Text;
    doc:=nil;
 
 
   finally
 
   finally
 
     doc.Free;
 
     doc.Free;
Line 29: Line 56:
 
   end;
 
   end;
 
end;
 
end;
 +
</syntaxhighlight>
 +
 +
==Parsing the JSON Array based response==
 +
<syntaxhighlight lang="pascal">
 +
uses
 +
  {...}, fpjson, jsonparser, HTTPDefs, {...}
 +
 +
const
 +
  cArrayShortLanguages: Array [0..7] of String = (
 +
    'auto',
 +
    'en',
 +
    'pt',
 +
    'pl',
 +
    'fr',
 +
    'es',
 +
    'it',
 +
    'ru'
 +
  );
  
function AskGoogleTranslate(OriginalText, SourceLang, TargetLang: string;
+
procedure ParseArraysTranslate;
  out TranslatedText, ErrorMessage: string): boolean;
 
 
var
 
var
  doc: TStrings;
 
 
   URL: String;
 
   URL: String;
   JSON: String;
+
   Index: integer;
   p: PChar;
+
   strResponse: TJSONStringType;
  i: Integer;
+
   jdResponse, jdTranslation, jdTranslationArray: TJSONData;
   StartPos: PChar;
+
   jaTranslation, jaTranslationArray: TJSONArray;
  Line: TJSONStringType;
 
   Level: Integer;
 
 
begin
 
begin
  Result:=false;
 
  ErrorMessage:='';
 
  TranslatedText:='';
 
  if (SourceLang='') or (TargetLang='') then begin
 
    ErrorMessage:='missing language parameter';
 
    exit;
 
  end;
 
  if OriginalText='' then exit;
 
  
  // download JSON
+
   URL:='https://translate.googleapis.com/translate_a/single?client=gtx'
   URL:='http://translate.google.com/translate_a/t?client=t'
+
     +'&q='+HTTPEncode({** PUT TEXT TO TRANSLATE HERE **})
     +'&text='+HTTPEncode(OriginalText)
+
     +'&sl='+cArrayShortLanguages[0] // Auto Detect
     +'&sl='+SourceLang
+
     +'&tl='+cArrayShortLanguages[1] // English
     +'&tl='+TargetLang
+
     +'&dt=t'
    +'&sc=1'
 
     +'&ssel=0&tsel=0'
 
 
     +'&ie=UTF-8&oe=UTF-8'
 
     +'&ie=UTF-8&oe=UTF-8'
 
     ;
 
     ;
 +
 +
  strResponse:= CallGoogleTranslate(URL);
 
   try
 
   try
     doc:=DownloadText(URL);
+
     jdResponse:= GetJSON(strResponse);
  except
+
 
     on E: Exception do begin
+
     jdTranslation:= jdResponse.FindPath('[0]');
      debugln(['AskGoogleTranslate failed URL=',URL,' Error=',E.Message]);
+
     if (jdTranslation <> nil) and (jdTranslation.JSONType = jtArray) then
      ErrorMessage:='query failed: '+E.Message;
+
     begin
      exit;
+
      jaTranslation:= TJSONArray(jdTranslation);
     end;
+
      for index:= 0 to Pred(jaTranslation.Count) do
  end;
+
       begin
  try
+
        jdTranslationArray:= jaTranslation[Index];
    // parse JSON
+
         if (jdTranslationArray <> nil) and (jdTranslationArray.JSONType = jtArray) then
    // For example:
 
    //  [[["Erster Satz . ","First sentence.","",""],["Zweiter Satz . ","Second sentence.","",""]],
 
     JSON:=doc.Text;
 
    p:=PChar(JSON);
 
    Level:=0;
 
    i:=0;
 
    repeat
 
       case p^ of
 
      #0: break;
 
      '[':
 
         begin
 
          inc(Level);
 
          i:=0;
 
        end;
 
      ']':
 
 
         begin
 
         begin
           dec(Level);
+
           jaTranslationArray:= TJSONArray(jdTranslationArray);
          if Level=1 then break;
+
           WriteLN(Trim(jaTranslationArray[0].AsString));
        end;
 
      ',':
 
        inc(i);
 
      '"':
 
        begin
 
          inc(p);
 
           StartPos:=p;
 
          repeat
 
            case p^ of
 
            #0,'"': break;
 
            '\':
 
              begin
 
                inc(p);
 
                if p^=#0 then break;
 
              end;
 
            end;
 
            inc(p);
 
          until false;
 
          if i=0 then begin
 
            Line:=JSONStringToString(copy(JSON,StartPos-PChar(JSON)+1,p-StartPos));
 
            TranslatedText:=TranslatedText+Line;
 
          end;
 
          if p^=#0 then break;
 
 
         end;
 
         end;
 
       end;
 
       end;
      inc(p);
+
     end;
     until false;
 
 
   finally
 
   finally
     doc.Free;
+
     jdResponse.Free;
 
   end;
 
   end;
  Result:=true;
 
 
end;
 
end;
 +
</syntaxhighlight>
  
// here is an example how to translate English(en) to German(de)
+
==Parsing the JSON Object based response==
procedure TForm1.Button1Click(Sender: TObject);
+
<syntaxhighlight lang="pascal">
 +
uses
 +
  {...}, fpjson, jsonparser, HTTPDefs, {...}
 +
 
 +
const
 +
  cArrayShortLanguages: Array [0..7] of String = (
 +
    'auto',
 +
    'en',
 +
    'pt',
 +
    'pl',
 +
    'fr',
 +
    'es',
 +
    'it',
 +
    'ru'
 +
  );
 +
  cJSONSentences = 'sentences';
 +
  cJSONTranslation = 'trans';
 +
  cJSONSource = 'src';
 +
 
 +
procedure ParseObjectTranslate;
 
var
 
var
   ErrorMessage: string;
+
   URL: String;
   TranslatedText: string;
+
   Index: integer;
 +
  strResponse: TJSONStringType;
 +
  jdResponse: TJSONData;
 +
  joTranslation, joSentence: TJSONObject;
 +
  jaSentencesArray: TJSONArray;
 
begin
 
begin
   if not AskGoogleTranslate('First sentence. Second sentence.','en','de',TranslatedText,ErrorMessage)
+
   Application.ProcessMessages;
  then begin
+
    URL:='https://translate.googleapis.com/translate_a/single?client=gtx'
    debugln(['AskGoogleTranslate failed: ',ErrorMessage]);
+
      +'&q='+HTTPEncode({** PUT TEXT TO TRANSLATE HERE **})
  end else begin
+
      +'&sl='+cArrayShortLanguages[0] // Auto Detect
    debugln(['TForm1.FormCreate Translation: ',TranslatedText]);
+
      +'&tl='+cArrayShortLanguages[1] // English
  end;
+
      +'&dt=t&dj=1' // dj=1 makes the response be a JSON Object
 +
      +'&ie=UTF-8&oe=UTF-8'
 +
      ;
 +
 
 +
    strResponse:= CallGoogleTranslate(URL);
 +
    try
 +
      jdResponse:= GetJSON(strResponse);
 +
 
 +
      if (jdResponse <> nil) and (jdResponse.JSONType = jtObject) then
 +
      begin
 +
        joTranslation:= TJSONObject(jdResponse);
 +
        jaSentencesArray:= TJSONArray(joTranslation.FindPath(cJSONSentences));
 +
        for Index:=0 to Pred(jaSentencesArray.Count) do
 +
        begin
 +
          joSentence:= TJSONObject(jaSentencesArray[Index]);
 +
          WriteLN(Trim(joSentence.Get(cJSONTranslation,'')));
 +
        end;
 +
      end;
 +
    finally
 +
      jdResponse.Free;
 +
    end;
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
[[Category:FPC]]
+
==External Links==
[[Category:Lazarus]]
+
[https://github.com/gcarreno/TestGoogleTranslate Test Google Translate] - A [https://github.com GitHub] repository which demonstrates this example.
[[Category:Networking]]
 

Latest revision as of 07:13, 16 December 2021

English (en) français (fr) português (pt)

Overview

There are at least two way to access Google Translate:

  • A free but metered way.
  • Using the OAuth2 authenticated API.

This is a usage example of the former.

For information on the latter please consult: Google Translate Getting Started

Info on the params

According to an answer on Stack Overflow (What is the meaning of Google Translate query params?) here's a list of the params to the HTTP GET call:

  • sl - source language code (auto for auto detection)
  • tl - translation language
  • q - source text / word
  • ie - input encoding (a guess)
  • oe - output encoding (a guess)
  • dt - may be included more than once and specifies what to return in the reply
  • dj - JSON response with names instead of only arrays (dj=1)

Here are some value for dt:

  • t - translation of source text
  • at - alternate translations
  • rm - transcription / transliteration of source and translated texts
  • bd - dictionary, in case source text is one word (you get translations with articles, reverse translations, etc.)
  • md - definitions of source text, if it's one word
  • ss - synonyms of source text, if it's one word
  • ex - examples
  • rw - See also list


Contacting Google

This function will return the JSON response.

uses
  {...}, fpjson, fphttpclient, opensslsockets, {...}

function CallGoogleTranslate(AURL: String): TJSONStringType;
var
  client: TFPHTTPClient;
  doc: TStringList;
begin
  Result:= EmptyStr;
  doc:=TStringList.Create;
  client:=TFPHTTPClient.Create(nil);
  try
    client.Get(AURL,doc);
    Result:=doc.Text;
  finally
    doc.Free;
    client.Free;
  end;
end;

Parsing the JSON Array based response

uses
  {...}, fpjson, jsonparser, HTTPDefs, {...}

const
  cArrayShortLanguages: Array [0..7] of String = (
    'auto',
    'en',
    'pt',
    'pl',
    'fr',
    'es',
    'it',
    'ru'
  );

procedure ParseArraysTranslate;
var
  URL: String;
  Index: integer;
  strResponse: TJSONStringType;
  jdResponse, jdTranslation, jdTranslationArray: TJSONData;
  jaTranslation, jaTranslationArray: TJSONArray;
begin

  URL:='https://translate.googleapis.com/translate_a/single?client=gtx'
    +'&q='+HTTPEncode({** PUT TEXT TO TRANSLATE HERE **})
    +'&sl='+cArrayShortLanguages[0] // Auto Detect
    +'&tl='+cArrayShortLanguages[1] // English
    +'&dt=t'
    +'&ie=UTF-8&oe=UTF-8'
    ;

  strResponse:= CallGoogleTranslate(URL);
  try
    jdResponse:= GetJSON(strResponse);

    jdTranslation:= jdResponse.FindPath('[0]');
    if (jdTranslation <> nil) and (jdTranslation.JSONType = jtArray) then
    begin
      jaTranslation:= TJSONArray(jdTranslation);
      for index:= 0 to Pred(jaTranslation.Count) do
      begin
        jdTranslationArray:= jaTranslation[Index];
        if (jdTranslationArray <> nil) and (jdTranslationArray.JSONType = jtArray) then
        begin
          jaTranslationArray:= TJSONArray(jdTranslationArray);
          WriteLN(Trim(jaTranslationArray[0].AsString));
        end;
      end;
    end;
  finally
    jdResponse.Free;
  end;
end;

Parsing the JSON Object based response

uses
  {...}, fpjson, jsonparser, HTTPDefs, {...}

const
  cArrayShortLanguages: Array [0..7] of String = (
    'auto',
    'en',
    'pt',
    'pl',
    'fr',
    'es',
    'it',
    'ru'
  );
  cJSONSentences = 'sentences';
  cJSONTranslation = 'trans';
  cJSONSource = 'src';

procedure ParseObjectTranslate;
var
  URL: String;
  Index: integer;
  strResponse: TJSONStringType;
  jdResponse: TJSONData;
  joTranslation, joSentence: TJSONObject;
  jaSentencesArray: TJSONArray;
begin
  Application.ProcessMessages;
    URL:='https://translate.googleapis.com/translate_a/single?client=gtx'
      +'&q='+HTTPEncode({** PUT TEXT TO TRANSLATE HERE **})
      +'&sl='+cArrayShortLanguages[0] // Auto Detect
      +'&tl='+cArrayShortLanguages[1] // English
      +'&dt=t&dj=1' // dj=1 makes the response be a JSON Object
      +'&ie=UTF-8&oe=UTF-8'
      ;

    strResponse:= CallGoogleTranslate(URL);
    try
      jdResponse:= GetJSON(strResponse);

      if (jdResponse <> nil) and (jdResponse.JSONType = jtObject) then
      begin
        joTranslation:= TJSONObject(jdResponse);
        jaSentencesArray:= TJSONArray(joTranslation.FindPath(cJSONSentences));
        for Index:=0 to Pred(jaSentencesArray.Count) do
        begin
          joSentence:= TJSONObject(jaSentencesArray[Index]);
          WriteLN(Trim(joSentence.Get(cJSONTranslation,'')));
        end;
      end;
    finally
      jdResponse.Free;
    end;
end;

External Links

Test Google Translate - A GitHub repository which demonstrates this example.