136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
from siphashc import siphash
|
|
|
|
from odoo import _, api, models
|
|
from odoo.exceptions import UserError
|
|
|
|
DEFAULT_WEBLATE_ADDRESS = "weblate.rudoo.ru"
|
|
DEFAULT_WEBLATE_PROTOCOL = "https"
|
|
DEFAULT_WEBLATE_PROJECT_ALIAS = "testovyj-proekt"
|
|
|
|
|
|
def raw_hash(*parts: str) -> int:
|
|
"""Calculate checksum identifying translation."""
|
|
if not parts:
|
|
data = ""
|
|
elif len(parts) == 1:
|
|
data = parts[0]
|
|
else:
|
|
data = "".join(part for part in parts)
|
|
return siphash("Weblate Sip Hash", data)
|
|
|
|
|
|
def calculate_checksum(*parts: str):
|
|
"""Calculate siphashc checksum for given strings."""
|
|
return format(raw_hash(*parts), "016x")
|
|
|
|
|
|
class TranslationHelper(models.AbstractModel):
|
|
_name = "translation.service"
|
|
_description = "Translation Helper"
|
|
|
|
@api.model
|
|
def get_action(self, data=None):
|
|
model_name = data.get("resModel")
|
|
field_name = data.get("field", {}).get("name")
|
|
# Use current user's language as the default language (Odoo 19 compatible)
|
|
default_lang = self.env.user.lang
|
|
query = """
|
|
SELECT field_description
|
|
FROM ir_model_fields
|
|
WHERE model = %s AND name = %s
|
|
"""
|
|
self.env.cr.execute(query, [model_name, field_name])
|
|
translation_field_data = self.env.cr.fetchone()
|
|
current_user_language = self.env.context.get("lang", default_lang)
|
|
translation_value = translation_field_data[0].get(current_user_language)
|
|
term_to_translate = translation_field_data[0].get(default_lang)
|
|
if not term_to_translate:
|
|
term_to_translate = data.get("label")
|
|
data["translation_field_data"] = translation_field_data[0]
|
|
|
|
field = (
|
|
self.env["ir.model.fields"]
|
|
.sudo()
|
|
.search([("model", "=", model_name), ("name", "=", field_name)])
|
|
)
|
|
if not field:
|
|
raise UserError(
|
|
_("Field '%s' not found on model '%s'.") % (field_name, model_name)
|
|
)
|
|
# field.modules may be empty or a comma-separated string in Odoo 19
|
|
if field.modules:
|
|
module_names_list = field.modules.split(", ")
|
|
else:
|
|
module_names_list = []
|
|
checksum = calculate_checksum(term_to_translate)
|
|
|
|
weblate_address = (
|
|
self.env["ir.config_parameter"]
|
|
.sudo()
|
|
.get_param(
|
|
"translation_helper.translation_weblate_server_address",
|
|
default=DEFAULT_WEBLATE_ADDRESS,
|
|
)
|
|
)
|
|
weblate_protocol = (
|
|
self.env["ir.config_parameter"]
|
|
.sudo()
|
|
.get_param(
|
|
"translation_helper.translation_weblate_server_protocol",
|
|
default=DEFAULT_WEBLATE_PROTOCOL,
|
|
)
|
|
)
|
|
weblate_project_alias = (
|
|
self.env["ir.config_parameter"]
|
|
.sudo()
|
|
.get_param(
|
|
"translation_helper.translation_weblate_project_alias",
|
|
default=DEFAULT_WEBLATE_PROJECT_ALIAS,
|
|
)
|
|
)
|
|
weblate_project_language = (
|
|
self.env["res.lang"]
|
|
.sudo()
|
|
.search(
|
|
[
|
|
("code", "=", current_user_language),
|
|
"|",
|
|
("active", "=", True),
|
|
("active", "=", False),
|
|
]
|
|
)
|
|
)
|
|
for module_name in module_names_list:
|
|
url_for_module = f"{weblate_protocol}://{weblate_address}/translate/{weblate_project_alias}/{module_name}/{weblate_project_language.iso_code}/?checksum={checksum}"
|
|
wizard_record = (
|
|
self.env["translation.helper.wizard"]
|
|
.sudo()
|
|
.create(
|
|
{
|
|
"weblate_link": url_for_module,
|
|
"term_value": term_to_translate,
|
|
"language_id": weblate_project_language.id,
|
|
"translation_value": translation_value,
|
|
"modules": field.modules,
|
|
"metadata": data,
|
|
}
|
|
)
|
|
)
|
|
window_action = {
|
|
"name": _("Write your translation"),
|
|
"target": "new",
|
|
"view_mode": "form",
|
|
"res_model": "translation.helper.wizard",
|
|
"type": "ir.actions.act_window",
|
|
"res_id": wizard_record.id,
|
|
"views": [
|
|
[
|
|
self.env.ref(
|
|
"translation_helper.translation_helper_wizard_form"
|
|
).id,
|
|
"form",
|
|
]
|
|
],
|
|
}
|
|
return window_action
|