Seite 1 von 2

Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 26.10.2017 11:34
von RSBasic
Guten Morgen,

ich bin mit Deepl.com sehr zufrieden.
Meine WinAPI Library wird in vier Sprachen angeboten und die Texte wurden mit Google Translator automatisiert übersetzt. Aufgrund der vielen Beispielcodes (1138 Codes) ist das manuelle Übersetzen sehr zeitaufwendig.
Da ich Deepl.com sehr gut finde, würde ich die Texte mit Deepl.com erneut übersetzen lassen.
Um das Übersetzen automatisieren zu können, brauche ich eine Schnittstelle (HTTP-Request oder JSON-API), damit ich die Texte nicht einzeln manuell einfügen muss.

Auf der folgenden Seite gibt es eine Lösung mit PowerShell, um die Texte per JSON an die Website zu senden: https://psvmware.wordpress.com/2017/09/ ... owershell/

Den Code der Funktion kann man in einer PowerShell-Datei (*.ps1) speichern und diese mit der CMD-Konsole aufrufen.
Ich habe den Code leicht modifiziert, damit man Parameter an die Funktion übergeben kann (Man kann es bestimmt besser lösen, aber so gut bin ich noch nicht in PowerShell.):

Code: Alles auswählen

function get-DeepLtranslation ($sentence, $fromLang, $toLang)
{
#Languages available: PL,EN,NL,ES,IT,FR
$url = "https://www.deepl.com/jsonrpc"
$call = '{"jsonrpc":"2.0","method":"LMT_handle_jobs","params":{"jobs":[{"kind":"default","raw_en_sentence":"'+$sentence+'"}],"lang":{"user_preferred_langs":["EN","PL","NL"],"source_lang_user_selected":"'+$fromLang+'","target_lang":"'+$toLang+'"},"priority":-1},"id":15}'
$bytes = [System.Text.Encoding]::ASCII.GetBytes($call)
$web = [System.Net.WebRequest]::Create($url)
$web.Method = "POST"
$web.ContentLength = $bytes.Length
$web.ContentType = "application/x-www-form-urlencoded"
$stream = $web.GetRequestStream()
$stream.Write($bytes,0,$bytes.Length)
$stream.close()
$reader = New-Object System.IO.Streamreader -ArgumentList $web.GetResponse().GetResponseStream()
$answer = ($reader.ReadToEnd()|ConvertFrom-Json).result.translations.beams | select -ExpandProperty 'postprocessed_sentence'
$reader.Close()
return $answer
}
get-DeepLtranslation -sentence $args[0] -fromLang $args[1] -toLang $args[2]
Und jetzt der PB-Code zum Aufrufen dieser ps1-Datei zum Übersetzen:

Code: Alles auswählen

EnableExplicit

Define Program

Define PSFile$ = "C:\...\File.ps1"
Define Sentence$ = "Hallo Welt"
Define FromLang$ = "DE"
Define ToLang$ = "EN"

Program = RunProgram("cmd.exe", "/c PowerShell.exe -Command " + Chr(34) + PSFile$ + Chr(34) + " '" + Sentence$ + "' '" + FromLang$ + "' '" + ToLang$ + "'", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
If Program
  While ProgramRunning(Program)
    If AvailableProgramOutput(Program)
      Debug ReadProgramString(Program)
      ;Break;Falls man nur die erste Zeile auslesen möchte
    EndIf
  Wend
  
  CloseProgram(Program)
EndIf
Ich hoffe, es ist für euch nützlich. Den Code könnt ihr gerne verbessern und hier posten.

\\Edit:
Man könnte es wahrscheinlich auch komplett in PB machen, aber das fiel mir erst später ein und bin jetzt zu faul dafür, den Code nach PB zu übersetzen. Aber wenn jemand einen kompletten PB-Code schreiben möchte, dann wäre der Code noch besser.

Re: Deepl.com - Automatisierte Übersetzung

Verfasst: 26.10.2017 13:07
von NicTheQuick
Könnte man mit ReceiveHTTPMemory() auch POST-Request senden, wäre das ein Kinderspiel. Aber bei Purebasic wird ja leider viel zu häufig alles nur halbherzig implementiert. Weil es dann auch noch HTTPS ist, kann man es nicht mal mit der normalen Network-Library simulieren.

Man bräuchte also eine externe Librarie dafür, wodurch Plattformkompatibilität wiederum schwierig wird. Aber Powershell ist ja auch nicht plattformunabhängig. Aber bestimmt hat hier jemand trotzdem Lust das zu machen, so wie ich unsere User hier kenne. :-D

Re: Deepl.com - Automatisierte Übersetzung

Verfasst: 26.10.2017 13:11
von Kiffi
NicTheQuick hat geschrieben:Aber bestimmt hat hier jemand trotzdem Lust das zu machen, so wie ich unsere User hier kenne. :-D
ehrlich gesagt habe ich vor ein paar Tagen auch so was ähnliches wie Ray gebastelt. Als mir dann klar wurde, dass es dann via HTTPS Post gesendet werden muss (und welchen Aufwand das in PB bedeutet), habe ich ganz schnell die Finger davon gelassen.

Grüße ... Peter

Re: Deepl.com - Automatisierte Übersetzung

Verfasst: 26.10.2017 15:00
von TroaX
NicTheQuick hat geschrieben:Aber Powershell ist ja auch nicht plattformunabhängig. Aber bestimmt hat hier jemand trotzdem Lust das zu machen, so wie ich unsere User hier kenne. :-D
Normalerweise bin ich bei HTTP/S-Sauereien gerne dabei. Aber nicht mit PureBasic. Man könnte es ja mit LibCURL machen. Aber wenn der Include mit einer neueren Version von PB nicht mehr läuft bzw. das Include mit einer neueren Version von cURL inkompatibel ist, dann ist das Gebastel wieder groß. Und darauf habe ich kein Nerv.

Re: Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 05.01.2018 21:43
von HeX0R
Irgendwie wollen die Umlaute nicht?!

Code: Alles auswählen

EnableExplicit

Define Program

Define PSFile$ = "...\deepl.ps1"
Define Sentence$ = "Pretty World"
Define FromLang$ = "EN"
Define ToLang$ = "DE"
Define a$

Debug Sentence$
Program = RunProgram("cmd.exe", "/c PowerShell.exe -Command " + Chr(34) + PSFile$ + Chr(34) + " '" + Sentence$ + "' '" + FromLang$ + "' '" + ToLang$ + "'", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
If Program
  While ProgramRunning(Program)
    If AvailableProgramOutput(Program)
    	a$ = ReadProgramString(Program)
    	Debug a$
      ;Break;Falls man nur die erste Zeile auslesen möchte
    EndIf
  Wend
 
  CloseProgram(Program)
EndIf
Oder geht das bei Dir?

Re: Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 05.01.2018 22:15
von RSBasic
Bei mir auch nicht. Ich habs mit verschiedenen Zeichensätzen (sowohl in der ps1-Datei bei System.Text.Encoding, als auch bei RunProgram() und ReadProgramString()) ausprobiert, aber irgendwie komme ich gerade nicht auf die Lösung.
Vielleicht hat jemand von euch eine Lösung?

Re: Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 06.01.2018 00:22
von HeX0R
Das liegt auf jeden Fall an dem ConvertFrom-Json, der Server schickt das als \u00fc (für ü), aber dieses powershell bekommt das nicht umgewandelt und macht ein FFFD (also einen REPLACEMENT CHARACTER) draus.
Das bekommst Du hinterher natürlich nicht mehr zurückentschlüsselt.

Und ich kenne mich mit dem furchtbaren powershell scripting Mist nicht aus.

Habe es jetzt ein wenig umständlich gelöst (wofür haben wir denn JSON features in PB), aber Funktion ist bekanntlich alles :)
deepl.ps1:

Code: Alles auswählen

function get-DeepLtranslation ($sentence, $fromLang, $toLang)
{
#Languages available: PL,EN,NL,ES,IT,FR
$url = "https://www.deepl.com/jsonrpc"
$call = '{"jsonrpc":"2.0","method":"LMT_handle_jobs","params":{"jobs":[{"kind":"default","raw_en_sentence":"'+$sentence+'"}],"lang":{"user_preferred_langs":["EN","PL","NL"],"source_lang_user_selected":"'+$fromLang+'","target_lang":"'+$toLang+'"},"priority":-1},"id":15}'
$bytes = [System.Text.Encoding]::UTF8.GetBytes($call)
$web = [System.Net.WebRequest]::Create($url)
$web.Method = "POST"
$web.ContentLength = $bytes.Length
$web.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"
$stream = $web.GetRequestStream()
$stream.Write($bytes,0,$bytes.Length)
$stream.close()
$reader = New-Object System.IO.Streamreader -ArgumentList $web.GetResponse().GetResponseStream()
$answer = $reader.ReadToEnd()
$reader.Close()
return $answer
}
get-DeepLtranslation -sentence $args[0] -fromLang $args[1] -toLang $args[2]
PB-Code:

Code: Alles auswählen

Structure _JSON_OBJ4_
	num_symbols.i
	totalLogProb.i
	score.i
	postprocessed_sentence.s
EndStructure

Structure _JSON_OBJ3_
	timeAfterPreprocessing.i
	timeReceivedFromEndpoint.i
	List beams._JSON_OBJ4_()
	total_time_endpoint.i
	timeSentToEndpoint.i
EndStructure

Structure _JSON_OBJ2_
	source_lang.s
	target_lang.s
	List translations._JSON_OBJ3_()
	ource_lang_is_confident.i
EndStructure

Structure _JSON_OBJ_
	jsonrpc.s
	id.i
	result._JSON_OBJ2_
EndStructure

Procedure.s Translate(Sentence$, FromLang$, ToLang$)
	Protected Program, s.s, Result.s, NumCR
	Protected PSFile$   = "...deepl.ps1"
	Protected R._JSON_OBJ_
	
	Sentence$ = ReplaceString(Sentence$, "\n", #ESC$)
	
	Program = RunProgram("cmd.exe", "/c PowerShell.exe -Command " + Chr(34) + PSFile$ + Chr(34) + " '" + Sentence$ + "' '" + FromLang$ + "' '" + ToLang$ + "'", "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
	If Program
		While ProgramRunning(Program)
			If AvailableProgramOutput(Program)
				s = ReadProgramString(Program)
				If ParseJSON(0, s)
					ExtractJSONStructure(JSONValue(0), @R, _JSON_OBJ_)
					If FirstElement(R\result\translations()) And FirstElement(R\result\translations()\beams())
						Result = R\result\translations()\beams()\postprocessed_sentence
					EndIf
				EndIf
				Break
			EndIf
		Wend
		CloseProgram(Program)
	EndIf
	
	Result = ReplaceString(Result, #ESC$, "\n")

	
	ProcedureReturn Result
EndProcedure

Debug Translate("pretty world", "EN", "DE")
Brauchst Du mehr Ergebnisse, einfach durch R\result\translations()\beams() iterieren.

Re: Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 06.01.2018 01:53
von HeX0R
Hier noch ein Beispiel mit curl (command line, habs von hier ), dann muss man dieses hässliche Powershell Ding nicht mehr nehmen.

curl.exe sollte im gleichen Verzeichnis liegen, dann wird alles gut :)

Code: Alles auswählen

Structure _JSON_OBJ4_
   num_symbols.i
   totalLogProb.i
   score.i
   postprocessed_sentence.s
EndStructure

Structure _JSON_OBJ3_
   timeAfterPreprocessing.i
   timeReceivedFromEndpoint.i
   List beams._JSON_OBJ4_()
   total_time_endpoint.i
   timeSentToEndpoint.i
EndStructure

Structure _JSON_OBJ2_
   source_lang.s
   target_lang.s
   List translations._JSON_OBJ3_()
   ource_lang_is_confident.i
EndStructure

Structure _JSON_OBJ_
   jsonrpc.s
   id.i
   result._JSON_OBJ2_
EndStructure

Procedure.s Translate(Sentence$, FromLang$, ToLang$)
   Protected Program, s.s, Result.s, NumCR
   Protected CurlOptions.s, Curl$ = "curl.exe"
   Protected R._JSON_OBJ_
   
   Sentence$   = ReplaceString(Sentence$, "\n", #ESC$)
   
   CurlOptions = "-X POST --insecure -d " + #DQUOTE$ + "{\" + #DQUOTE$ + "jsonrpc\" + #DQUOTE$ + ":\" + #DQUOTE$ + "2.0\" + #DQUOTE$ + ",\" + #DQUOTE$ + 
                 "method\" + #DQUOTE$ + ":\" + #DQUOTE$ + "LMT_handle_jobs\" + #DQUOTE$ + ",\" + #DQUOTE$ + "params\" + #DQUOTE$ + ":{\" + #DQUOTE$ +
                 "jobs\" + #DQUOTE$ + ":[{\" + #DQUOTE$ + "kind\" + #DQUOTE$ + ":\" + #DQUOTE$ + "default\" + #DQUOTE$ + ",\" + #DQUOTE$ + "raw_en_sentence\" + #DQUOTE$ +
                 ":\" + #DQUOTE$ + Sentence$ + "\" + #DQUOTE$ + "}],\" + #DQUOTE$ + "lang\" + #DQUOTE$ + ":{\" + #DQUOTE$ + "user_preferred_langs\" + #DQUOTE$ + 
                 ":[\" + #DQUOTE$ + "EN\" + #DQUOTE$ + ",\" + #DQUOTE$ + "DE\" + #DQUOTE$ + ",\" + #DQUOTE$ + "FR\" + #DQUOTE$ + "]" +
                 ",\" + #DQUOTE$ + "source_lang_user_selected\" + #DQUOTE$ + ":\" + #DQUOTE$ + FromLang$ + "\" + #DQUOTE$ + ",\" + #DQUOTE$ + "target_lang\" + #DQUOTE$ + 
                 ":\" + #DQUOTE$ + ToLang$ + "\" + #DQUOTE$ + "},\" + #DQUOTE$ + "priority\" + #DQUOTE$ + ":-1},\" + #DQUOTE$ + "id\" + #DQUOTE$ + ":15}" + #DQUOTE$ + " "
   CurlOptions + "https://www.deepl.com/jsonrpc"
   Program = RunProgram(GetPathPart(ProgramFilename()) + Curl$, CurlOptions, "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)

   If Program
      While ProgramRunning(Program)
         If AvailableProgramOutput(Program)
            s = ReadProgramString(Program)
            If ParseJSON(0, s)
               ExtractJSONStructure(JSONValue(0), @R, _JSON_OBJ_)
               If FirstElement(R\result\translations()) And FirstElement(R\result\translations()\beams())
                  Result = R\result\translations()\beams()\postprocessed_sentence
               EndIf
            EndIf
            Break
         EndIf
      Wend
      CloseProgram(Program)
   EndIf
   
   Result = ReplaceString(Result, #ESC$, "\n")

   
   ProcedureReturn Result
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
	Debug Translate("pretty world", "EN", "DE")
CompilerEndIf

Re: Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 06.01.2018 12:44
von RSBasic
Danke HeX0R für die Lösung und für den Zusatzcode mit curl. :allright:

Re: Deepl.com - Automatisierte Übersetzung (Windows)

Verfasst: 06.01.2018 13:12
von tft
Hallo,

ich würde auch gerne sagen COOLLL ... aber bei mir läufts nicht. Muss ich noch etwas installieren?

Gruss TFT