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