Skip to content

Commit

Permalink
feat: Add DeepL translate connector - EXO-66770 (#44)
Browse files Browse the repository at this point in the history
Add DeepL trasnlate connector
  • Loading branch information
hakermi committed Oct 12, 2023
1 parent 2683179 commit 927868e
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
5 changes: 5 additions & 0 deletions services/impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<artifactId>analytics-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.deepl.api</groupId>
<artifactId>deepl-java</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2023 eXo Platform SAS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.exoplatform.automatic.translation.impl.connectors;

import com.deepl.api.*;
import org.exoplatform.automatic.translation.api.AutomaticTranslationComponentPlugin;
import org.exoplatform.commons.api.settings.SettingService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.util.Locale;

public class DeepLTranslateConnector extends AutomaticTranslationComponentPlugin {

private static final Log LOG = ExoLogger.getLogger(DeepLTranslateConnector.class);

private static final String DEEPL_TRANSLATE_SERVICE = "deepl-translate";

private Translator translator;

private final TextTranslationOptions textTranslationOptions;

public DeepLTranslateConnector(SettingService settingService) {
super(settingService);
textTranslationOptions = new TextTranslationOptions();
textTranslationOptions.setTagHandling("html");
textTranslationOptions.setPreserveFormatting(true);
textTranslationOptions.setSentenceSplittingMode(SentenceSplittingMode.All);
}

@Override
public String translate(String message, Locale targetLocale) {
long startTime = System.currentTimeMillis();
try {
return getDeeplTranslator().translateText(message, null, getLocaleLanguage(targetLocale), textTranslationOptions).getText();
} catch (DeepLException e) {
LOG.error("remote_service={} operation={} parameters=\"message length:{},targetLocale:{}\" status=ko "
+ "duration_ms={} error_msg=\"{}\"",
DEEPL_TRANSLATE_SERVICE,
"translate",
message.length(),
targetLocale.getLanguage(),
System.currentTimeMillis() - startTime,
e.getMessage());
} catch (InterruptedException e) {
LOG.error("DeepL API translation thread has been interrupted", e);
Thread.currentThread().interrupt();
}
return null;
}

private String getLocaleLanguage(Locale locale) {
if (locale.getLanguage().equalsIgnoreCase("en")) {
return "en-US";
} else if (locale.getLanguage().equalsIgnoreCase("pt")) {
return "pt-PT";
} else {
return locale.getLanguage();
}
}

private Translator getDeeplTranslator() {
if (translator == null) {
translator = new Translator(getApiKey());
}
return translator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
<type>org.exoplatform.automatic.translation.impl.connectors.GoogleTranslateConnector</type>
<description>Google Translate</description>
</component-plugin>
<component-plugin>
<name>deepl</name>
<set-method>addConnector</set-method>
<type>org.exoplatform.automatic.translation.impl.connectors.DeepLTranslateConnector</type>
<description>DeepL Translate</description>
</component-plugin>
</external-component-plugins>

<external-component-plugins profiles="analytics">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 eXo Platform SAS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.exoplatform.automatic.translation.impl.connectors;

import com.deepl.api.*;
import org.exoplatform.commons.api.settings.SettingService;
import org.exoplatform.commons.api.settings.SettingValue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Locale;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class DeepLTranslateConnectorTest {

@Mock
private SettingService settingService;

@Mock
private Translator translator;

private DeepLTranslateConnector deepLTranslateConnector;

@Before
public void setUp() {
deepLTranslateConnector = new DeepLTranslateConnector(settingService);
}

@Test
public void translate() throws NoSuchFieldException, IllegalAccessException, DeepLException, InterruptedException {
// Need real auth-key to have a real result
TextTranslationOptions textTranslationOptions = new TextTranslationOptions();
textTranslationOptions.setTagHandling("html");
textTranslationOptions.setPreserveFormatting(true);
textTranslationOptions.setSentenceSplittingMode(SentenceSplittingMode.All);
TextResult textResult = new TextResult("<h1>Hello</h1>", "fr");
Field textTranslationOptionsField = deepLTranslateConnector.getClass().getDeclaredField("textTranslationOptions");
textTranslationOptionsField.setAccessible(true);
textTranslationOptionsField.set(deepLTranslateConnector, textTranslationOptions);
when(translator.translateText("<h1>Bonjour</h1>", null, "en-US", textTranslationOptions)).thenReturn(textResult);
Field field = deepLTranslateConnector.getClass().getDeclaredField("translator");
field.setAccessible(true);
field.set(deepLTranslateConnector, translator);
String text = deepLTranslateConnector.translate("<h1>Bonjour</h1>", new Locale("en"));
assertNotNull(text);
when(translator.translateText("<h1>Bonjour</h1>",
null,
"en-US",
textTranslationOptions)).thenThrow(new DeepLException("error"));
text = deepLTranslateConnector.translate("<h1>Bonjour</h1>", new Locale("en"));
assertNull(text);

}
}

0 comments on commit 927868e

Please sign in to comment.