diff --git a/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java b/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java index f30309f..b783d39 100644 --- a/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java +++ b/src/main/java/cn/octopusyan/dmt/translate/TranslateApi.java @@ -12,6 +12,7 @@ import lombok.Getter; public enum TranslateApi { FREE_BAIDU("free_baidu", "百度", false), FREE_GOOGLE("free_google", "谷歌", false), + FREE_MICROSOFT("free_microsoft", "微软", false), BAIDU("baidu", "百度(需认证)", true), ; diff --git a/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java b/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java index 9951c64..e11c30b 100644 --- a/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java +++ b/src/main/java/cn/octopusyan/dmt/translate/factory/TranslateFactoryImpl.java @@ -3,10 +3,7 @@ package cn.octopusyan.dmt.translate.factory; import cn.octopusyan.dmt.model.WordItem; import cn.octopusyan.dmt.translate.DelayWord; import cn.octopusyan.dmt.translate.TranslateApi; -import cn.octopusyan.dmt.translate.processor.AbstractTranslateProcessor; -import cn.octopusyan.dmt.translate.processor.BaiduTranslateProcessor; -import cn.octopusyan.dmt.translate.processor.FreeBaiduTranslateProcessor; -import cn.octopusyan.dmt.translate.processor.FreeGoogleTranslateProcessor; +import cn.octopusyan.dmt.translate.processor.*; import lombok.extern.slf4j.Slf4j; import java.util.*; @@ -38,6 +35,7 @@ public class TranslateFactoryImpl implements TranslateFactory { private void initProcessor() { processorList.addAll(Arrays.asList( new FreeGoogleTranslateProcessor(), + new FreeMicrosoftTranslateProcessor(), new FreeBaiduTranslateProcessor(), new BaiduTranslateProcessor() )); diff --git a/src/main/java/cn/octopusyan/dmt/translate/processor/FreeMicrosoftTranslateProcessor.java b/src/main/java/cn/octopusyan/dmt/translate/processor/FreeMicrosoftTranslateProcessor.java new file mode 100644 index 0000000..d435856 --- /dev/null +++ b/src/main/java/cn/octopusyan/dmt/translate/processor/FreeMicrosoftTranslateProcessor.java @@ -0,0 +1,89 @@ +package cn.octopusyan.dmt.translate.processor; + + +import cn.hutool.core.date.DateUtil; +import cn.octopusyan.dmt.common.util.JsonUtil; +import cn.octopusyan.dmt.translate.TranslateApi; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import tools.jackson.databind.JsonNode; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 微软 免费翻译接口 + * + * @author octopus_yan@foxmail.com + */ +public class FreeMicrosoftTranslateProcessor extends AbstractTranslateProcessor { + + private String token; + + public FreeMicrosoftTranslateProcessor() { + super(TranslateApi.FREE_MICROSOFT); + } + + @Override + public String url() { + return "https://api.cognitive.microsofttranslator.com/translate"; + } + + /** + * 翻译处理 + * + * @param source 待翻译单词 + * @return 翻译结果 + */ + @Override + public String customTranslate(String source) throws IOException, InterruptedException { + + Map form = new HashMap<>(); + form.put("api-version", "3.0"); + form.put("to", "zh-Hans"); + form.put("textType", "plain"); + + Map header = new HashMap<>(); + header.put("Authorization", STR."Bearer \{oauth()}"); + + String body = STR.""" + [ + { + "Text": "\{source}" + } + ] + """; + + StringBuilder retStr = new StringBuilder(); + + String resp = httpUtil.postForm(url(), JsonUtil.parseJsonObject(header), JsonUtil.parseJsonObject(form), JsonUtil.parseJsonObject(body)); + JsonNode json = JsonUtil.parseJsonObject(resp); + + for (JsonNode o : json.get(0)) { + retStr.append(o.get(0).asString()); + } + + return retStr.toString(); + } + + private synchronized String oauth() throws IOException, InterruptedException { + if (token == null) { + token = httpUtil.get("https://edge.microsoft.com/translate/auth", null, null); + } else { + // 解析,对应的签名或者加密方式 + Claims claims = Jwts.parser() +// .verifyWith(key) // 指定用于验证的密钥 +// .decryptWith(key) // 加密方式,指定用于解密的密钥。 + .build() + .parseSignedClaims(token) // 签名方式 +// .parseEncryptedClaims(token) // 加密方式,对 JWT 进行解密,并获取其声明部分。 + .getPayload(); // 获取解密后的声明(claims)内容。 + if(DateUtil.compare(DateUtil.date(), claims.getExpiration()) > 0) { + token = null; + return oauth(); + } + } + return token; + } +}