Skip to content

Commit

Permalink
resolve theopenconversationkit#1606 [Translator] : init Deepl integra…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
charles_moulhaud committed May 17, 2024
1 parent d4b28e5 commit 543b9bf
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 0 deletions.
58 changes: 58 additions & 0 deletions translator/deepl-translate/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (C) 2017/2021 e-voyageurs technologies
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ai.tock</groupId>
<artifactId>tock-translator</artifactId>
<version>23.9.3-SNAPSHOT</version>
</parent>

<artifactId>tock-deepl-translate</artifactId>
<name>Tock Deepl Translator</name>
<description>Deepl translator implementation</description>

<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<dependency>
<groupId>ai.tock</groupId>
<artifactId>tock-translator-core</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.squareup.moshi</groupId>
<artifactId>moshi</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>com.squareup.moshi</groupId>
<artifactId>moshi-kotlin</artifactId>
<version>1.12.0</version>
</dependency>
</dependencies>

</project>
65 changes: 65 additions & 0 deletions translator/deepl-translate/src/main/kotlin/DeeplClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2017/2021 e-voyageurs technologies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ai.tock
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import java.io.IOException

data class TranslationResponse(
val translations: List<Translation>
)

data class Translation(
val text: String
)

val DEEPL_URL_API = "https://api.deepl.com/v2/translate"

class DeeplClient(private val apiKey: String) {
private val client = OkHttpClient()
private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
private val jsonAdapter = moshi.adapter(TranslationResponse::class.java)

fun translate(text: String, sourceLang: String,targetLang: String): String? {
// TODO Pass placeholders options in parameters
val textWithTags = text.replace("{", "<x>").replace("}", "</x>")

val requestBody = """
text=$textWithTags&source_lang=$sourceLang&target_lang=$targetLang&tag_handling=xml&non_translatable_tags=x
""".trimIndent().toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())

val request = Request.Builder()
.url(DEEPL_URL_API)
.addHeader("Authorization", "DeepL-Auth-Key $apiKey")
.post(requestBody)
.build()

client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")

val responseBody = response.body?.string()
val translationResponse = jsonAdapter.fromJson(responseBody!!)

val translatedText = translationResponse?.translations?.firstOrNull()?.text
return translatedText?.replace("<x>", "{")?.replace("</x>", "}")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2017/2021 e-voyageurs technologies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ai.tock

import ai.tock.shared.property
import ai.tock.translator.TranslatorEngine
import org.apache.commons.text.StringEscapeUtils
import java.util.Locale

internal object DeeplTranslatorEngine : TranslatorEngine {

private val deeplClient = DeeplClient(property ("tock_deepl_api_key", "default"))
override val supportAdminTranslation: Boolean = true

override fun translate(text: String, source: Locale, target: Locale): String {
val translatedText = deeplClient.translate(text, source.language, target.language)
return StringEscapeUtils.unescapeHtml4(translatedText)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import ai.tock.DeeplTranslatorEngine
import org.junit.jupiter.api.Test
import java.util.Locale
import kotlin.test.assertEquals

/*
* Copyright (C) 2017/2021 e-voyageurs technologies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

class DeeplTranslateIntegrationTest {
@Test
fun simpleTest() {
val result = DeeplTranslatorEngine.translate("Bonjour, je voudrais me rendre à New-York Mardi prochain", Locale.FRENCH, Locale.ENGLISH)
assertEquals("Hello, I would like to go to New York next Tuesday.",result)
}

@Test
fun testWithParameters() {
val result = DeeplTranslatorEngine.translate("Bonjour, je voudrais me rendre à {:city} {:date}", Locale.FRENCH, Locale.GERMAN)
assertEquals("Hallo, ich möchte nach {:city} {:date} reisen",result)
}
}

0 comments on commit 543b9bf

Please sign in to comment.