Skip to content

Commit 500e972

Browse files
committed
Improve HTTP POST requests in translations
1 parent 8f93031 commit 500e972

File tree

2 files changed

+87
-115
lines changed

2 files changed

+87
-115
lines changed

common/src/main/kotlin/xyz/bluspring/unitytranslate/translator/LibreTranslateInstance.kt

Lines changed: 33 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import net.minecraft.util.random.Weight
99
import net.minecraft.util.random.WeightedEntry
1010
import xyz.bluspring.unitytranslate.Language
1111
import xyz.bluspring.unitytranslate.UnityTranslate
12+
import xyz.bluspring.unitytranslate.util.HttpHelper
1213
import java.io.OutputStreamWriter
1314
import java.net.HttpURLConnection
1415
import java.net.URL
@@ -72,101 +73,38 @@ open class LibreTranslateInstance(val url: String, private var weight: Int, val
7273
}
7374

7475
open fun detectLanguage(text: String): Language? {
75-
val url = URL("$url/detect")
76-
val httpConn = url.openConnection() as HttpURLConnection
77-
httpConn.requestMethod = "POST"
78-
httpConn.setRequestProperty("accept", "application/json")
79-
httpConn.setRequestProperty("Content-Type", "application/json")
80-
httpConn.doOutput = true
81-
82-
val writer = OutputStreamWriter(httpConn.outputStream, "UTF-8")
83-
84-
writer.write(JsonObject().apply {
76+
val detected = HttpHelper.post("$url/detect", JsonObject().apply {
8577
addProperty("q", text)
8678

8779
if (authKey?.isNotBlank() == true)
8880
addProperty("api_key", authKey)
89-
}.toString())
90-
91-
writer.flush()
92-
writer.close()
93-
httpConn.outputStream.close()
94-
if (httpConn.responseCode / 100 != 2) {
95-
throw Exception("Failed to load ${this.url}/detect (code ${httpConn.responseCode})")
96-
} else {
97-
val responseStream = httpConn.inputStream
98-
val s = Scanner(responseStream, "UTF-8").useDelimiter("\\A")
99-
val response = if (s.hasNext()) s.next() else ""
100-
101-
val detected = JsonParser.parseString(response).asJsonArray.sortedByDescending { it.asJsonObject.get("confidence").asDouble }
102-
val langCode = detected.firstOrNull()?.asJsonObject?.get("language")?.asString ?: return null
103-
val lang = Language.findLibreLang(langCode)
104-
105-
if (lang == null) {
106-
UnityTranslate.logger.error("Failed to find language for LibreTranslate code $langCode!")
107-
}
81+
}).asJsonArray.sortedByDescending { it.asJsonObject.get("confidence").asDouble }
82+
83+
val langCode = detected.firstOrNull()?.asJsonObject?.get("language")?.asString ?: return null
84+
val lang = Language.findLibreLang(langCode)
10885

109-
httpConn.disconnect()
110-
s.close()
111-
return lang
86+
if (lang == null) {
87+
UnityTranslate.logger.error("Failed to find language for LibreTranslate code $langCode!")
11288
}
89+
90+
return lang
11391
}
11492

11593
open fun batchTranslate(from: String, to: String, request: List<String>): List<String> {
116-
val url = URL("$url/translate")
117-
val httpConn = url.openConnection() as HttpURLConnection
118-
httpConn.requestMethod = "POST"
119-
httpConn.setRequestProperty("accept", "application/json")
120-
httpConn.setRequestProperty("Content-Type", "application/json")
121-
httpConn.doOutput = true
122-
123-
val writer = OutputStreamWriter(httpConn.outputStream, "UTF-8")
124-
125-
try {
126-
writer.write(JsonObject().apply {
127-
addProperty("source", from)
128-
addProperty("target", to)
129-
add("q", JsonArray().apply {
130-
for (s in request) {
131-
this.add(s)
132-
}
133-
})
134-
135-
if (authKey?.isNotBlank() == true)
136-
addProperty("api_key", authKey)
137-
}.toString())
138-
139-
writer.flush()
140-
writer.close()
141-
httpConn.outputStream.close()
142-
if (httpConn.responseCode / 100 != 2) {
143-
httpConn.disconnect()
144-
throw Exception("Failed to load ${this.url}/translate (code ${httpConn.responseCode})")
145-
} else {
146-
val responseStream = httpConn.inputStream
147-
val s = Scanner(responseStream, "UTF-8").useDelimiter("\\A")
148-
149-
try {
150-
val response = if (s.hasNext()) s.next() else ""
151-
152-
val translated = JsonParser.parseString(response).asJsonObject.get("translatedText").asJsonArray
153-
154-
httpConn.disconnect()
155-
s.close()
156-
return translated.map { it.asString }
157-
} catch (e: Exception) {
158-
httpConn.disconnect()
159-
s.close()
160-
161-
throw e
94+
val translated = HttpHelper.post("$url/translate", JsonObject().apply {
95+
addProperty("source", from)
96+
addProperty("target", to)
97+
add("q", JsonArray().apply {
98+
for (s in request) {
99+
this.add(s)
162100
}
163-
}
164-
} catch (e: Exception) {
165-
writer.close()
166-
httpConn.disconnect()
101+
})
167102

168-
throw e
169-
}
103+
if (authKey?.isNotBlank() == true)
104+
addProperty("api_key", authKey)
105+
}).asJsonObject.get("translatedText").asJsonArray
106+
107+
return translated.map { it.asString }
170108
}
171109

172110
fun translate(text: String, from: Language, to: Language): String? {
@@ -180,44 +118,24 @@ open class LibreTranslateInstance(val url: String, private var weight: Int, val
180118
}
181119
}
182120

183-
// Copied from LibreTranslate-Java, there were race conditions everywhere.
184121
open fun translate(from: String, to: String, request: String): String {
185-
val url = URL("$url/translate")
186-
val httpConn = url.openConnection() as HttpURLConnection
187-
httpConn.requestMethod = "POST"
188-
httpConn.setRequestProperty("accept", "application/json")
189-
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
190-
httpConn.doOutput = true
191-
192-
val writer = OutputStreamWriter(httpConn.outputStream)
193-
writer.write(
194-
"q=" + URLEncoder.encode(
195-
request,
196-
"UTF-8"
197-
) + "&source=" + from + "&target=" + to + "&format=text" +
198-
if (authKey?.isNotBlank() == true) "&api_key=$authKey" else ""
199-
)
200-
201-
writer.flush()
202-
writer.close()
203-
httpConn.outputStream.close()
204-
if (httpConn.responseCode / 100 != 2) {
205-
throw Exception("Failed to load ${this.url}/translate (code ${httpConn.responseCode})")
206-
} else {
207-
val responseStream = httpConn.inputStream
208-
val s = Scanner(responseStream, "UTF-8").useDelimiter("\\A")
209-
val response = if (s.hasNext()) s.next() else ""
210-
211-
s.close()
212-
return JsonParser.parseString(response).asJsonObject.get("translatedText").asString
213-
}
122+
return HttpHelper.post("$url/translate", JsonObject().apply {
123+
addProperty("source", from)
124+
addProperty("target", to)
125+
addProperty("q", request)
126+
addProperty("format", "text")
127+
128+
if (authKey?.isNotBlank() == true)
129+
addProperty("api_key", authKey)
130+
})
131+
.asJsonObject.get("translatedText").asString
214132
}
215133

216134
override fun getWeight(): Weight {
217135
return Weight.of(weight)
218136
}
219137

220138
companion object {
221-
const val MAX_CONCURRENT_TRANSLATIONS = 5
139+
const val MAX_CONCURRENT_TRANSLATIONS = 15
222140
}
223141
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package xyz.bluspring.unitytranslate.util
2+
3+
import com.google.gson.JsonElement
4+
import com.google.gson.JsonObject
5+
import com.google.gson.JsonParser
6+
import xyz.bluspring.unitytranslate.UnityTranslate
7+
import java.io.BufferedInputStream
8+
import java.io.BufferedOutputStream
9+
import java.net.HttpURLConnection
10+
import java.net.URL
11+
12+
object HttpHelper {
13+
fun post(uri: String, body: JsonObject, headers: Map<String, String> = mapOf()): JsonElement {
14+
val url = URL(uri)
15+
var connection: HttpURLConnection? = null
16+
17+
val data = body.toString().toByteArray(Charsets.UTF_8)
18+
19+
try {
20+
connection = url.openConnection() as HttpURLConnection
21+
connection.requestMethod = "POST"
22+
23+
connection.setRequestProperty("Accept", "application/json")
24+
connection.setRequestProperty("Content-Type", "application/json")
25+
headers.forEach { (key, value) ->
26+
connection.setRequestProperty(key, value)
27+
}
28+
29+
connection.doOutput = true
30+
connection.setFixedLengthStreamingMode(data.size)
31+
32+
val outputStream = BufferedOutputStream(connection.outputStream)
33+
34+
outputStream.write(data)
35+
outputStream.flush()
36+
outputStream.close()
37+
38+
if (connection.responseCode / 100 != 2) {
39+
throw Exception("Failed to load $uri (code: ${connection.responseCode})")
40+
} else {
41+
val inputStream = BufferedInputStream(connection.inputStream)
42+
val reader = inputStream.bufferedReader(Charsets.UTF_8)
43+
val result = JsonParser.parseReader(reader)
44+
45+
reader.close()
46+
inputStream.close()
47+
48+
return result
49+
}
50+
} finally {
51+
connection?.disconnect()
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)