Skip to content

Commit 7ebe67a

Browse files
author
xiaoqunLiu
committed
translate
1 parent d963cb2 commit 7ebe67a

File tree

674 files changed

+508
-115938
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

674 files changed

+508
-115938
lines changed

docs-core/src/main/java/com/sismics/docs/core/constant/ConfigType.java

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,77 @@ public enum ConfigType {
99
/**
1010
* Lucene directory storage type.
1111
*/
12-
LUCENE_DIRECTORY_STORAGE,
12+
LUCENE_DIRECTORY_STORAGE("lucene_directory_storage"),
1313
/**
1414
* Theme configuration.
1515
*/
16-
THEME,
16+
THEME("theme"),
1717

1818
/**
1919
* Guest login.
2020
*/
21-
GUEST_LOGIN,
21+
GUEST_LOGIN("guest_login"),
2222

2323
/**
2424
* OCR enabled.
2525
*/
26-
OCR_ENABLED,
26+
OCR_ENABLED("ocr_enabled"),
2727

2828
/**
2929
* Default language.
3030
*/
31-
DEFAULT_LANGUAGE,
31+
DEFAULT_LANGUAGE("default_language"),
3232

3333
/**
3434
* SMTP server configuration.
3535
*/
36-
SMTP_HOSTNAME,
37-
SMTP_PORT,
38-
SMTP_FROM,
39-
SMTP_USERNAME,
40-
SMTP_PASSWORD,
36+
SMTP_HOSTNAME("smtp_hostname"),
37+
SMTP_PORT("smtp_port"),
38+
SMTP_FROM("smtp_from"),
39+
SMTP_USERNAME("smtp_username"),
40+
SMTP_PASSWORD("smtp_password"),
4141

4242
/**
4343
* Inbox scanning configuration.
4444
*/
45-
INBOX_ENABLED,
46-
INBOX_HOSTNAME,
47-
INBOX_PORT,
48-
INBOX_STARTTLS,
49-
INBOX_USERNAME,
50-
INBOX_PASSWORD,
51-
INBOX_FOLDER,
52-
INBOX_TAG,
53-
INBOX_AUTOMATIC_TAGS,
54-
INBOX_DELETE_IMPORTED,
45+
INBOX_ENABLED("inbox_enabled"),
46+
INBOX_HOSTNAME("inbox_hostname"),
47+
INBOX_PORT("inbox_port"),
48+
INBOX_STARTTLS("inbox_starttls"),
49+
INBOX_USERNAME("inbox_username"),
50+
INBOX_PASSWORD("inbox_password"),
51+
INBOX_FOLDER("inbox_folder"),
52+
INBOX_TAG("inbox_tag"),
53+
INBOX_AUTOMATIC_TAGS("inbox_automatic_tags"),
54+
INBOX_DELETE_IMPORTED("inbox_delete_imported"),
5555

5656
/**
5757
* LDAP connection.
5858
*/
59-
LDAP_ENABLED,
60-
LDAP_HOST,
61-
LDAP_PORT,
62-
LDAP_USESSL,
63-
LDAP_ADMIN_DN,
64-
LDAP_ADMIN_PASSWORD,
65-
LDAP_BASE_DN,
66-
LDAP_FILTER,
67-
LDAP_DEFAULT_EMAIL,
68-
LDAP_DEFAULT_STORAGE
59+
LDAP_ENABLED("ldap_enabled"),
60+
LDAP_HOST("ldap_host"),
61+
LDAP_PORT("ldap_port"),
62+
LDAP_USESSL("ldap_usessl"),
63+
LDAP_ADMIN_DN("ldap_admin_dn"),
64+
LDAP_ADMIN_PASSWORD("ldap_admin_password"),
65+
LDAP_BASE_DN("ldap_base_dn"),
66+
LDAP_FILTER("ldap_filter"),
67+
LDAP_DEFAULT_EMAIL("ldap_default_email"),
68+
LDAP_DEFAULT_STORAGE("ldap_default_storage"),
69+
70+
/**
71+
* Youdao Translation API configuration.
72+
*/
73+
YOUDAO_APP_KEY("youdao.app_key"),
74+
YOUDAO_APP_SECRET("youdao.app_secret");
75+
76+
private final String key;
77+
78+
ConfigType(String key) {
79+
this.key = key;
80+
}
81+
82+
public String getKey() {
83+
return key;
84+
}
6985
}

docs-core/src/main/java/com/sismics/docs/core/util/ConfigUtil.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,25 @@ public class ConfigUtil {
1919
* @throws IllegalStateException Configuration parameter undefined
2020
*/
2121
public static String getConfigStringValue(ConfigType configType) {
22+
// First try to get from ResourceBundle
23+
try {
24+
ResourceBundle bundle = getConfigBundle();
25+
String key = configType.name().toLowerCase();
26+
// Special case for Youdao API keys
27+
if (configType == ConfigType.YOUDAO_APP_KEY) {
28+
key = "youdao.app_key";
29+
} else if (configType == ConfigType.YOUDAO_APP_SECRET) {
30+
key = "youdao.app_secret";
31+
}
32+
String value = bundle.getString(key);
33+
if (value != null && !value.isEmpty()) {
34+
return value;
35+
}
36+
} catch (Exception e) {
37+
// Ignore and try database
38+
}
39+
40+
// If not found in ResourceBundle, try database
2241
ConfigDao configDao = new ConfigDao();
2342
Config config = configDao.getById(configType);
2443
if (config == null) {

docs-web/pom.xml

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,29 @@
144144
<scope>test</scope>
145145
</dependency>
146146

147+
<dependency>
148+
<groupId>org.apache.httpcomponents</groupId>
149+
<artifactId>httpclient</artifactId>
150+
<version>4.5.13</version>
151+
</dependency>
152+
153+
<dependency>
154+
<groupId>org.json</groupId>
155+
<artifactId>json</artifactId>
156+
<version>20231013</version>
157+
</dependency>
158+
147159
</dependencies>
148160

149161
<build>
150162
<resources>
151163
<resource>
152164
<directory>src/main/resources</directory>
165+
<filtering>false</filtering>
166+
</resource>
167+
<resource>
168+
<directory>src/dev/resources</directory>
169+
<filtering>false</filtering>
153170
</resource>
154171
</resources>
155172
</build>
@@ -171,16 +188,6 @@
171188
<resource>
172189
<directory>src/dev/resources</directory>
173190
<filtering>false</filtering>
174-
<excludes>
175-
<exclude>**/config.properties</exclude>
176-
</excludes>
177-
</resource>
178-
<resource>
179-
<directory>src/dev/resources</directory>
180-
<filtering>true</filtering>
181-
<includes>
182-
<include>**/config.properties</include>
183-
</includes>
184191
</resource>
185192
</resources>
186193

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
api.current_version=${project.version}
22
api.min_version=1.0
33
db.version=31
4+
5+
# Youdao Translation API Configuration
6+
youdao.app_key=0f3412892b569a09
7+
youdao.app_secret=zyR0MubRGQIqfDmAa8YbeYNocHdO8cqW
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.sismics.docs.core.constant;
2+
3+
/**
4+
* Configuration types.
5+
*/
6+
public enum ConfigType {
7+
DEFAULT_LANGUAGE("default_language"),
8+
GUEST_LOGIN("guest_login"),
9+
OCR_ENABLED("ocr_enabled"),
10+
SMTP_HOSTNAME("smtp_hostname"),
11+
SMTP_PORT("smtp_port"),
12+
SMTP_USERNAME("smtp_username"),
13+
SMTP_PASSWORD("smtp_password"),
14+
SMTP_FROM("smtp_from"),
15+
INBOX_ENABLED("inbox_enabled"),
16+
INBOX_AUTOMATIC_TAGS("inbox_automatic_tags"),
17+
INBOX_DELETE_IMPORTED("inbox_delete_imported"),
18+
INBOX_HOSTNAME("inbox_hostname"),
19+
INBOX_PORT("inbox_port"),
20+
INBOX_STARTTLS("inbox_starttls"),
21+
INBOX_USERNAME("inbox_username"),
22+
INBOX_PASSWORD("inbox_password"),
23+
INBOX_FOLDER("inbox_folder"),
24+
INBOX_TAG("inbox_tag"),
25+
LDAP_ENABLED("ldap_enabled"),
26+
LDAP_HOST("ldap_host"),
27+
LDAP_PORT("ldap_port"),
28+
LDAP_USESSL("ldap_usessl"),
29+
LDAP_ADMIN_DN("ldap_admin_dn"),
30+
LDAP_ADMIN_PASSWORD("ldap_admin_password"),
31+
LDAP_BASE_DN("ldap_base_dn"),
32+
LDAP_FILTER("ldap_filter"),
33+
LDAP_DEFAULT_EMAIL("ldap_default_email"),
34+
LDAP_DEFAULT_STORAGE("ldap_default_storage"),
35+
THEME("theme"),
36+
LUCENE_DIRECTORY_STORAGE("lucene_directory_storage"),
37+
YOUDAO_APP_KEY("youdao.app_key"),
38+
YOUDAO_APP_SECRET("youdao.app_secret");
39+
40+
private final String key;
41+
42+
ConfigType(String key) {
43+
this.key = key;
44+
}
45+
46+
public String getKey() {
47+
return key;
48+
}
49+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package com.sismics.docs.core.service;
2+
3+
import com.google.common.base.Strings;
4+
import com.sismics.docs.core.util.ConfigUtil;
5+
import com.sismics.docs.core.constant.ConfigType;
6+
import com.sismics.util.context.ThreadLocalContext;
7+
import org.apache.commons.codec.digest.DigestUtils;
8+
import org.apache.http.HttpEntity;
9+
import org.apache.http.client.methods.CloseableHttpResponse;
10+
import org.apache.http.client.methods.HttpPost;
11+
import org.apache.http.entity.StringEntity;
12+
import org.apache.http.impl.client.CloseableHttpClient;
13+
import org.apache.http.impl.client.HttpClients;
14+
import org.apache.http.util.EntityUtils;
15+
import org.json.JSONObject;
16+
17+
import java.io.IOException;
18+
import java.nio.charset.StandardCharsets;
19+
import java.util.UUID;
20+
21+
/**
22+
* Translation service using Youdao API.
23+
*/
24+
public class TranslationService {
25+
private static final String YOUDAO_API_URL = "https://openapi.youdao.com/api";
26+
private static final String YOUDAO_APP_KEY = ConfigUtil.getConfigStringValue(ConfigType.YOUDAO_APP_KEY);
27+
private static final String YOUDAO_APP_SECRET = ConfigUtil.getConfigStringValue(ConfigType.YOUDAO_APP_SECRET);
28+
29+
public TranslationService() {
30+
// System.out.println("[TranslationService] YOUDAO_APP_KEY=" + YOUDAO_APP_KEY);
31+
// System.out.println("[TranslationService] YOUDAO_APP_SECRET=" + YOUDAO_APP_SECRET);
32+
System.out.println("[TranslationService] TranslationService initialized");
33+
}
34+
35+
/**
36+
* Translate text using Youdao API.
37+
*
38+
* @param content Text to translate
39+
* @param from Source language
40+
* @param to Target language
41+
* @return Translated text
42+
* @throws IOException If an error occurs during translation
43+
*/
44+
public String translate(String content, String from, String to) throws IOException {
45+
if (content == null || content.isEmpty()) {
46+
throw new IOException("Content is empty");
47+
}
48+
int maxLen = 4000;
49+
StringBuilder translated = new StringBuilder();
50+
int start = 0;
51+
while (start < content.length()) {
52+
int end = Math.min(start + maxLen, content.length());
53+
String part = content.substring(start, end);
54+
String partResult = translateSingle(part, from, to);
55+
translated.append(partResult);
56+
start = end;
57+
}
58+
return translated.toString();
59+
}
60+
61+
// 单段调用
62+
private String translateSingle(String content, String from, String to) throws IOException {
63+
if (Strings.isNullOrEmpty(content)) {
64+
return content;
65+
}
66+
67+
String salt = UUID.randomUUID().toString();
68+
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
69+
String sign = DigestUtils.sha256Hex(YOUDAO_APP_KEY + truncate(content) + salt + curtime + YOUDAO_APP_SECRET);
70+
71+
// 使用 application/x-www-form-urlencoded 方式提交参数
72+
java.util.List<org.apache.http.NameValuePair> params = new java.util.ArrayList<>();
73+
params.add(new org.apache.http.message.BasicNameValuePair("q", content));
74+
params.add(new org.apache.http.message.BasicNameValuePair("from", from));
75+
params.add(new org.apache.http.message.BasicNameValuePair("to", to));
76+
params.add(new org.apache.http.message.BasicNameValuePair("appKey", YOUDAO_APP_KEY));
77+
params.add(new org.apache.http.message.BasicNameValuePair("salt", salt));
78+
params.add(new org.apache.http.message.BasicNameValuePair("sign", sign));
79+
params.add(new org.apache.http.message.BasicNameValuePair("signType", "v3"));
80+
params.add(new org.apache.http.message.BasicNameValuePair("curtime", curtime));
81+
82+
try (org.apache.http.impl.client.CloseableHttpClient httpClient = org.apache.http.impl.client.HttpClients.createDefault()) {
83+
org.apache.http.client.methods.HttpPost httpPost = new org.apache.http.client.methods.HttpPost(YOUDAO_API_URL);
84+
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
85+
httpPost.setEntity(new org.apache.http.client.entity.UrlEncodedFormEntity(params, java.nio.charset.StandardCharsets.UTF_8));
86+
87+
try (org.apache.http.client.methods.CloseableHttpResponse response = httpClient.execute(httpPost)) {
88+
org.apache.http.HttpEntity entity = response.getEntity();
89+
if (entity != null) {
90+
String result = org.apache.http.util.EntityUtils.toString(entity);
91+
org.json.JSONObject jsonResponse = new org.json.JSONObject(result);
92+
93+
// 输出完整响应
94+
// System.out.println("[Youdao API] response: " + jsonResponse.toString());
95+
96+
// 检查 errorCode
97+
if (jsonResponse.has("errorCode") && !"0".equals(jsonResponse.getString("errorCode"))) {
98+
throw new IOException("Translation failed, errorCode=" + jsonResponse.getString("errorCode")
99+
+ ", msg=" + jsonResponse.optString("msg"));
100+
}
101+
102+
if (jsonResponse.has("translation") && jsonResponse.getJSONArray("translation").length() > 0) {
103+
return jsonResponse.getJSONArray("translation").getString(0);
104+
}
105+
}
106+
}
107+
}
108+
109+
throw new IOException("Translation failed: empty response or no translation field");
110+
}
111+
112+
/**
113+
* Truncate text to 20 characters for Youdao API.
114+
*/
115+
private String truncate(String text) {
116+
if (text.length() <= 20) {
117+
return text;
118+
}
119+
return text.substring(0, 10) + text.length() + text.substring(text.length() - 10);
120+
}
121+
}

0 commit comments

Comments
 (0)