Coverage for app/venv/lib/python3.14/site-packages/weblate/machinery/google.py: 48%
44 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
4from __future__ import annotations
6from typing import TYPE_CHECKING, ClassVar
8from requests.exceptions import RequestException
10from .base import MachineTranslation, MachineTranslationError
11from .forms import KeyMachineryForm
13if TYPE_CHECKING: 13 ↛ 14line 13 didn't jump to line 14 because the condition on line 13 was never true
14 from .base import DownloadTranslations
16GOOGLE_API_ROOT = "https://translation.googleapis.com/language/translate/v2/"
19class GoogleBaseTranslation(MachineTranslation):
20 # Map codes used by Google to the ones used by Weblate
21 language_map: ClassVar[dict[str, str]] = {
22 "nb": "no",
23 "nb_NO": "no",
24 "fil": "tl",
25 "zh_Hant": "zh-TW",
26 "zh_Hans": "zh-CN",
27 "ber-Latn": "kab", # Adding Kabyle language by mapping Tamazight latin
28 }
29 language_aliases = ({"zh-CN", "zh"},)
31 def map_language_code(self, code):
32 """Convert language to service specific code."""
33 return super().map_language_code(code).replace("_", "-").split("@")[0]
35 def is_supported(self, source, language):
36 # Avoid translation between aliases
37 return super().is_supported(source, language) and not any(
38 {source, language} == item for item in self.language_aliases
39 )
42class GoogleTranslation(GoogleBaseTranslation):
43 """Google Translate API v2 machine translation support."""
45 name = "Google Cloud Translation Basic"
46 max_score = 90
47 settings_form = KeyMachineryForm
49 @classmethod
50 def get_identifier(cls) -> str:
51 return "google-translate"
53 def check_failure(self, response) -> None:
54 super().check_failure(response)
55 payload = response.json()
57 if "error" in payload:
58 raise MachineTranslationError(payload["error"]["message"])
60 def download_languages(self):
61 """List of supported languages."""
62 response = self.request(
63 "get", GOOGLE_API_ROOT + "languages", params={"key": self.settings["key"]}
64 )
65 payload = response.json()
67 return [d["language"] for d in payload["data"]["languages"]]
69 def download_translations(
70 self,
71 source,
72 language,
73 text: str,
74 unit,
75 user,
76 threshold: int = 75,
77 ) -> DownloadTranslations:
78 """Download list of possible translations from a service."""
79 response = self.request(
80 "get",
81 GOOGLE_API_ROOT,
82 params={
83 "key": self.settings["key"],
84 "q": text,
85 "source": source,
86 "target": language,
87 "format": "text",
88 },
89 )
90 payload = response.json()
92 translation = payload["data"]["translations"][0]["translatedText"]
94 yield {
95 "text": translation,
96 "quality": self.max_score,
97 "service": self.name,
98 "source": text,
99 }
101 def get_error_message(self, exc):
102 if isinstance(exc, RequestException) and exc.response is not None:
103 data = exc.response.json()
104 try:
105 return data["error"]["message"]
106 except KeyError:
107 pass
109 return super().get_error_message(exc)