@@ -24,11 +24,21 @@ class GoogleTranslator : AbsGoogleTranslator() {
2424
2525 private val log = Logger .getInstance(GoogleTranslator ::class .java)
2626
27+ private val useCustomApiKey: Boolean
28+ get() = GoogleTranslatorSettings .getInstance().useCustomApiKey
29+
2730 override val key: String = KEY
2831
2932 override val icon: Icon = PluginIcons .GOOGLE_ICON
3033
3134 override fun getRequestUrl (fromLang : Lang , toLang : Lang , text : String ): String {
35+ if (useCustomApiKey) {
36+ val apiKey = credentialValue(API_KEY_DESCRIPTOR .id)
37+ return UrlBuilder (CLOUD_TRANSLATE_V2_URL )
38+ .addQueryParameter(" key" , apiKey)
39+ .build()
40+ }
41+
3242 val source = if (fromLang.code.equals(Languages .AUTO .code, ignoreCase = true )) " auto" else fromLang.translationCode
3343 val builder = UrlBuilder (googleApiUrl(TRANSLATE_PATH ))
3444 .addQueryParameter(" client" , " gtx" )
@@ -44,17 +54,51 @@ class GoogleTranslator : AbsGoogleTranslator() {
4454 }
4555
4656 override fun getRequestParams (fromLang : Lang , toLang : Lang , text : String ): List <Pair <String , String >> {
57+ if (useCustomApiKey) return emptyList()
58+
4759 return listOf (Pair .create(" q" , text))
4860 }
4961
5062 override fun configureRequestBuilder (requestBuilder : RequestBuilder ) {
51- requestBuilder.withGoogleHeaders()
63+ if (! useCustomApiKey) {
64+ requestBuilder.withGoogleHeaders()
65+ }
66+ }
67+
68+ override val requestContentType: String
69+ get() = if (useCustomApiKey) JSON_CONTENT_TYPE else super .requestContentType
70+
71+ override fun getRequestBody (fromLang : Lang , toLang : Lang , text : String ): String {
72+ if (! useCustomApiKey) return " "
73+
74+ val request = GoogleCloudTranslationRequest (
75+ q = listOf (text),
76+ target = toLang.translationCode,
77+ format = " text" ,
78+ source = fromLang.takeUnless { it.code.equals(Languages .AUTO .code, ignoreCase = true ) }?.translationCode
79+ )
80+ return GsonUtil .getInstance().gson.toJson(request)
5281 }
5382
5483 /* *
5584 * Parses the JSON payload and surfaces API errors as `TranslationException`.
5685 */
5786 override fun parsingResult (fromLang : Lang , toLang : Lang , text : String , resultText : String ): String {
87+ return if (useCustomApiKey) {
88+ parseCloudResponse(fromLang, toLang, text, resultText)
89+ } else {
90+ parseWebResponse(fromLang, toLang, text, resultText)
91+ }
92+ }
93+
94+ companion object {
95+ private const val KEY = " Google"
96+ private const val TRANSLATE_PATH = " /translate_a/single"
97+ private const val CLOUD_TRANSLATE_V2_URL = " https://translation.googleapis.com/language/translate/v2"
98+ private const val JSON_CONTENT_TYPE = " application/json; charset=UTF-8"
99+ }
100+
101+ private fun parseWebResponse (fromLang : Lang , toLang : Lang , text : String , resultText : String ): String {
58102 val response = GsonUtil .getInstance().gson.fromJson(resultText, GoogleTranslationResponse ::class .java)
59103 response.error?.message?.let { message ->
60104 throw TranslationException (fromLang, toLang, text, message)
@@ -73,8 +117,36 @@ class GoogleTranslator : AbsGoogleTranslator() {
73117 return translation
74118 }
75119
76- companion object {
77- private const val KEY = " Google"
78- private const val TRANSLATE_PATH = " /translate_a/single"
120+ private fun parseCloudResponse (fromLang : Lang , toLang : Lang , text : String , resultText : String ): String {
121+ val response = GsonUtil .getInstance().gson.fromJson(resultText, GoogleCloudTranslationResponse ::class .java)
122+ response.error?.message?.let { message ->
123+ throw TranslationException (fromLang, toLang, text, message)
124+ }
125+ val translation = response.data?.translations
126+ ?.mapNotNull { it.translatedText }
127+ ?.joinToString(separator = " " )
128+ ?.trim()
129+ .orEmpty()
130+ if (translation.isEmpty()) {
131+ log.warn(" Empty translation from Google Cloud Translation API: $resultText " )
132+ return " "
133+ }
134+ return translation
79135 }
80136}
137+
138+ private data class GoogleCloudTranslationRequest (
139+ val q : List <String >,
140+ val target : String ,
141+ val format : String ,
142+ val source : String?
143+ )
144+
145+ private data class GoogleCloudTranslationResponse (
146+ val data : TranslationData ? ,
147+ val error : CloudError ?
148+ ) {
149+ data class TranslationData (val translations : List <TranslationEntry >? )
150+ data class TranslationEntry (val translatedText : String? )
151+ data class CloudError (val message : String? )
152+ }
0 commit comments