LibJF/libjf-translate-v1/src/main/java/io/gitlab/jfronny/libjf/translate/impl/libretranslate/LibreTranslateService.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;
}
}