115 lines
5.2 KiB
Java
115 lines
5.2 KiB
Java
package io.gitlab.jfronny.libjf.translate.impl.libretranslate;
|
|
|
|
import com.google.common.reflect.TypeToken;
|
|
import io.gitlab.jfronny.libjf.HttpUtils;
|
|
import io.gitlab.jfronny.libjf.translate.api.TranslateException;
|
|
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
|
|
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateDetectResult;
|
|
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateLanguage;
|
|
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateRequest;
|
|
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateResult;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Type;
|
|
import java.net.URISyntaxException;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
public class LibreTranslateService implements TranslateService<LibreTranslateLanguage> {
|
|
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 : HttpUtils.get(host + "/languages").<ArrayList<LibreTranslateLanguage.ApiResult>>sendJson(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
|
|
public String translate(String textToTranslate, LibreTranslateLanguage translateFrom, LibreTranslateLanguage translateTo) throws TranslateException {
|
|
if (textToTranslate == null) throw new TranslateException("textToTranslate must not be null");
|
|
if (translateFrom == null) translateFrom = autoDetect;
|
|
if (translateTo == null) throw new TranslateException("translateTo must not be null");
|
|
LibreTranslateRequest.Translate request = new LibreTranslateRequest.Translate();
|
|
request.q = textToTranslate;
|
|
request.source = translateFrom.getIdentifier();
|
|
request.target = translateTo.getIdentifier();
|
|
LibreTranslateResult result = null;
|
|
try {
|
|
result = HttpUtils.post(host + "/translate").bodyJson(request).sendJson(LibreTranslateResult.class);
|
|
} catch (IOException | URISyntaxException e) {
|
|
throw new TranslateException("Could not translate text", e);
|
|
}
|
|
return result.translatedText;
|
|
}
|
|
|
|
@Override
|
|
public LibreTranslateLanguage detect(String text) throws TranslateException {
|
|
LibreTranslateRequest request = new LibreTranslateRequest();
|
|
request.q = text;
|
|
List<LibreTranslateDetectResult> result;
|
|
try {
|
|
result = HttpUtils.post(host + "/detect").bodyJson(request).sendJson(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 "LibreTranslate";
|
|
}
|
|
}
|