105 lines
4.5 KiB
Java
105 lines
4.5 KiB
Java
package io.gitlab.jfronny.libjf.translate.impl.libretranslate;
|
|
|
|
import io.gitlab.jfronny.commons.http.client.HttpClient;
|
|
import io.gitlab.jfronny.gson.reflect.TypeToken;
|
|
import io.gitlab.jfronny.libjf.translate.api.TranslateException;
|
|
import io.gitlab.jfronny.libjf.translate.impl.AbstractTranslateService;
|
|
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.*;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Type;
|
|
import java.net.URISyntaxException;
|
|
import java.util.*;
|
|
|
|
public class LibreTranslateService extends AbstractTranslateService<LibreTranslateLanguage> {
|
|
public static final String NAME = "LibreTranslate";
|
|
private static final Type languageListType = new TypeToken<List<LibreTranslateLanguage.ApiResult>>(){}.getType();
|
|
private static final Type translateDetectResultListType = new TypeToken<List<LibreTranslateDetectResult>>(){}.getType();
|
|
private static final LibreTranslateLanguage autoDetect = new LibreTranslateLanguage("auto", "AUTO_DETECT");
|
|
private static final Map<String, LibreTranslateService> knownInstances = new HashMap<>();
|
|
|
|
public static LibreTranslateService get(String host) throws TranslateException {
|
|
LibreTranslateService lts;
|
|
if (knownInstances.containsKey(host)) {
|
|
lts = knownInstances.get(host);
|
|
if (lts == null) throw new TranslateException("Translate service previously failed to initialize. Not trying again");
|
|
return lts;
|
|
}
|
|
try {
|
|
lts = new LibreTranslateService(host);
|
|
} catch (TranslateException e) {
|
|
knownInstances.put(host, null);
|
|
throw new TranslateException("Could not instantiate translate service", e);
|
|
}
|
|
knownInstances.put(host, lts);
|
|
return lts;
|
|
}
|
|
|
|
private final String host;
|
|
private final List<LibreTranslateLanguage> knownLanguages;
|
|
private final Map<String, LibreTranslateLanguage> languageById = new HashMap<>();
|
|
private LibreTranslateService(String host) throws TranslateException {
|
|
if (host.endsWith("/")) host = host.substring(0, host.length() - 1);
|
|
this.host = host;
|
|
try {
|
|
ArrayList<LibreTranslateLanguage> langs = new ArrayList<>();
|
|
langs.add(autoDetect);
|
|
for (LibreTranslateLanguage.ApiResult lang : HttpClient.get(host + "/languages").<ArrayList<LibreTranslateLanguage.ApiResult>>sendSerialized(languageListType)) {
|
|
LibreTranslateLanguage langR = lang.toLanguage();
|
|
langs.add(langR);
|
|
languageById.put(lang.code, langR);
|
|
}
|
|
this.knownLanguages = List.copyOf(langs);
|
|
} catch (IOException | URISyntaxException e) {
|
|
throw new TranslateException("Could not get known languages for LibreTranslate backend", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected LibreTranslateLanguage getAutoDetectLang() {
|
|
return autoDetect;
|
|
}
|
|
|
|
@Override
|
|
protected String performTranslate(String textToTranslate, LibreTranslateLanguage translateFrom, LibreTranslateLanguage translateTo) throws Exception {
|
|
LibreTranslateResult result = HttpClient.post(host + "/translate").bodyForm(Map.of(
|
|
"q", textToTranslate,
|
|
"source", translateFrom.getIdentifier(),
|
|
"target", translateTo.getIdentifier()
|
|
)).sendSerialized(LibreTranslateResult.class);
|
|
return result.translatedText;
|
|
}
|
|
|
|
@Override
|
|
public LibreTranslateLanguage detect(String text) throws TranslateException {
|
|
List<LibreTranslateDetectResult> result;
|
|
try {
|
|
result = HttpClient.post(host + "/detect").bodyForm(Map.of("q", text)).sendSerialized(translateDetectResultListType);
|
|
} catch (IOException | URISyntaxException e) {
|
|
throw new TranslateException("Could not detect language", e);
|
|
}
|
|
LibreTranslateDetectResult resCurr = null;
|
|
for (LibreTranslateDetectResult res : result) {
|
|
if (resCurr == null || res.confidence > resCurr.confidence)
|
|
resCurr = res;
|
|
}
|
|
if (resCurr == null) throw new TranslateException("Could not identify any valid language");
|
|
return parseLang(resCurr.language);
|
|
}
|
|
|
|
@Override
|
|
public LibreTranslateLanguage parseLang(String lang) {
|
|
return languageById.get(lang);
|
|
}
|
|
|
|
@Override
|
|
public List<LibreTranslateLanguage> getAvailableLanguages() {
|
|
return knownLanguages;
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return NAME;
|
|
}
|
|
}
|