summaryrefslogtreecommitdiff
path: root/odoo/tools/translate.py
AgeCommit message (Collapse)Author
2021-03-24[FIX] translate.py: CSV export correct module nameNicolas Lempereur
Correct small typo that the module when exporting translations as CSV file might have been the wrong module because we used variable from previous loop. This did not seem to cause any issue since in this given case in import we got the module from the part before . in XML ID ({module}.{name}) that was right. found when working on opw-2439029 closes odoo/odoo#68284 Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
2021-03-23[FIX] translate.py: import model from CSV correctlyNicolas Lempereur
When importing transtlation from CSV, we: - cut at `:` character to get the model - used a model for types other than model and model_terms This caused error that do not happen in PO import because: - the model is before the `,` character - the imd_model column is constrained to 64 characters, and a name that is not a model could be over that size. With this changeset, the CSV import match better current PO import. opw-2439029 closes odoo/odoo#68260 X-original-commit: cff91c6acbb7ef6a884d4dc4170574b83ff6e4cb Signed-off-by: Martin Trigaux (mat) <mat@odoo.com> Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
2021-03-09[FIX] tools: properly format error messageMartin Trigaux
To reproduce: 1. take a translatable record with an external id 2. delete the record but keep the ir.model.data (sql) 3. export the translations of the module linked to the orphan ir.model.data -> Error while formating the message This commit fixes three issues: - %d instead of %s to construct the string - wrong order to identify the missing records - display the external ids instead of the ids (which may not be very helpful to debug) Courtesy of Yannick Brant closes odoo/odoo#67509 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2020-12-08[FIX] core: parsing of external ids in PO filesRaphael Collet
The parsing of external ids was made with the regexp `(\w+)\.([\w-]+)`. This regexp is inadequate for external ids that contain non-alphanumeric characters like. We have such a use-case with the selections of field `rating_operator` in module `sale_subscription` that uses the values `">"` and `"<"`. The fix consists in replacing the regexp by `(\w+)\.([^ ]+)`. closes odoo/odoo#62976 Related: odoo/enterprise#15182 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-11-17[FIX] tools: extract translations in static/src/ directoryMartin Trigaux
Since 14.0, the javascript code of snippets is moved inside a /static/src/snippets directory. With owl, the components are defined in static/src/components Some other modules were using more exotic path and ended up with no translations. opw-2381030
2020-10-27[IMP] translate: add add/radd methods on _lt classPaul Morelle
In order to ease the usage of lazy translation, add the possibility to add the _lt objects together and with strings. Adding two _lt objects together or to a string will execute their translation, so these operations still must be done once the user's language has been defined. For example, this is now possible: MESSAGES = { 1: _lt("Hello, world!"), 2: _lt("Lorem ipsum"), } def get_text(code): return _("Text is: ") + MESSAGES[code] closes odoo/odoo#60842 X-original-commit: c4596664e5514018c565eaf14b93e000d972bd30 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com> Signed-off-by: Paul Morelle <madprog@users.noreply.github.com>
2020-08-06[FIX] tools: skip inexistant modelMartin Trigaux
When trying to generate translation for a model that is not present in the registry (leftover of migration?), the code used to return self.browse(), expecting an empty recordset. self was however a TranslationModuleReader that has no browse method return empty recordset with no model specified closes odoo/odoo#55574 X-original-commit: c004f00bdec83b7c56664425011db53db85da53a Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2020-06-30[IMP] tools: use same syntax for _lt than _Martin Trigaux
A new gettext syntax was added at odoo/odoo#52155 but only for _, not for _lt Allow to have the same syntax
2020-06-30[IMP] tools: fallback on empty translationMartin Trigaux
Avoid returning False if, for any reason, the return is falsy (False, None,...) Following the discussion in odoo/odoo#53254, the root cause was a call in the form _(foo) where foo was equal False While nothing else than a string should be the argument of _, it's still technically possible to pass something else and get a bad return value. Fallback on empty string to be consistent.
2020-06-18[IMP] *: replace to new _() syntaxMartin Trigaux
Using a few regex like \((_\(.*%s.*)(\) % )([\w\[\]][\w .\[\]\(\)'"]*)\) ($1, $3)) Old syntax is still compatible but starts the migration to the new syntax that catches error.
2020-06-18[IMP] tools: add placeholder support to _Martin Trigaux
Mimic the syntax of logging to use placeholders in translatable message. The main advantage is to be able to fallback on the source term if the translation can not be formatted properly. It is very common to have errors in translations with missing placeholders or badly translated (ie. the source "%(subject)s" -> "%(sujet)s"). Instead of blocking the execution of the code, fallback on source string. Task-id: 1853119
2020-05-19[FIX] tools: reimport translations in csvMartin Trigaux
Before this commit trying to reimport csv of a translation failed. The reason was that before 632fa044c3c20cd the parsing was common between po and csv while now it's split in two different parsers. The res_id column of the CSV is the external id of the record and is handled by IrTranslationImport. Use DictReader instead of csv_reader to easily add new keys and still be flexible on the given csv files. Match the POReader format with a imd_model and imd_name column. As for the PoFileReader, the code translations are unique and must be discarded in case of duplicate. Correct the error message if the imported file is not correct (was missing an argument) Fixes odoo/odoo#50975 closes odoo/odoo#51468 X-original-commit: 3cedadb5ba606e156f52e70ed08b25ac2df8d58b Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2020-04-17[FIX] translate: do not export OWL directive's attributeLucas Perais (lpe)
Have a static template of the form: ```xml <div t-name="ComponentA"> <ComponentB title="no export" /> </div> ``` To be used by OWL (github.com/odoo/owl) In this context, the title in the attributes of ComponentB should not be considered as *the* title attribute of HTML but as a sort of variable declaration Before this commit, the string contained in the value of this title attribute was exported. It was not translated at runtime, but we want to export as less stuff as possible in PO files So, after this commit, none of the attributes held by a OWL directive are exported This commit relies on OWL Syntax, which makes mandatory for a component directive's first letter to be capitalized https://github.com/odoo/owl/blob/master/doc/reference/component.md#composition Also, it relies on the good practice and widespread convention to have every HTML node lower cased https://www.w3schools.com/html/html5_syntax.asp closes odoo/odoo#46191 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2020-03-24[FIX] translate.py,web: aria-label qweb translation and exportNicolas Lempereur
In 12.0 9de1bc0e aria-label translation was added for python views, but: - aria-label attribute are not exported - aria-label are not translated for JS view rendering So by default, aria-label would only be translated for python views that had the same aria-label term in a translatable element (eg. "title" attribute). opw-2222504 closes #48255 closes odoo/odoo#48275 X-original-commit: 6b6b11ea2f8391f1f195bd1650531f77b6bed729 Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
2019-11-28[FIX] tools: no pollution during export translationMartin Trigaux
Before this commit, the export of translations was incorrect for code and model translations: For code translations, the field 'name' was used for the matching while the _() method explicitly use None in the _get_source call to only use the field 'src' for the search. For model translations, the field 'res_id' was not used when searching for a translation. For instance, if a ir.model.fields did not have translated label, exporting the translations was using the translations of the first field having the same source. While this could be convient during the import (to be discussed), doing so in an export of translation is clearly an unexpected side-effect. closes odoo/odoo#40909 X-original-commit: 4534181f106cf5aa50c65c942c260eeec122d3d2 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-11-22[REV] tools: partially revert 0ec6acc458e1Martin Trigaux
No justification, commit message not linked to the diff. If there is an issue in the line_number extraction it must be investigated. I suspect an outdated polib version. closes odoo/odoo#40684 X-original-commit: 0f92dae8eb76a47326bd2bb8924df8fa09645145 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-11-19[IMP] tools: create TranslationModuleReader classMartin Trigaux
Instead of previous long methods, use a class to clarify what the export actually does. The TranslationModuleReader is written to copy the API of the TranslationFileWriter. This way, exporting translations is reduced to: 1. create a reader that will fetch all module translations (either from db or from static files) 2. create a writer in a specific format (po or csv) 3. export the content from the reader to the writer Simplify the writer by deducing modules from exported translations instead of fetching it again in a oneliner (this way can benefit from yield operations) Remove the 'all_installed' possibility in modules as it was not working (creating query with 2 WHERE clause). The new methode _get_translatable_records works on a per model basis. This will allow a big performance gain as the previous code was making a .exists() for each record individually. In the future, this method could be removed as the main goal is to test the presence of the rare attribute _translate=False.
2019-11-19[IMP] tools: remove module_name parameterMartin Trigaux
It was misleading as only forced for translations of type 'code' but for the other translations, it was retrieved from the imported file (the comment in a .po file or column in a .csv) This will allow another optimisation in the next commit, moving to a TranslationModuleReader instance
2019-11-19[IMP] base: explicitly pass parameters for translation methodsMartin Trigaux
Instead of relying on the context content, pass explicit values for overwrite and create_empty_translations applu this to trans_load and trans_load_data Adapt the test that was trying to create empty translations.
2019-11-19[IMP] base: split and deprecate load_langMartin Trigaux
load_lang was a kind of hybrid method trying to active or creating a language if not found. This was error prone. Instead rely on two methods with clear purpose: ResLang._create_lang(lang, lang_name=None) - create a new res.lang entry using the locale of the server return the res.lang record to match the API of _activate_lang ResLang._active_lang(code) - activate the given code lang Most of the time, _active_lang is what is expected tools.trans_load_data and IrTranslation._load_module_terms no longer activate the language if not active. Loading the translations should be explicit on an activated language, it is too error prone to silently activate/create a language if not found. Remove lang_name from trans_load_data as no longer needed.
2019-10-30[IMP] core: mark a few osutil functions as deprecatedXavier Morel
* walksymlinks is useless, os.walk got followlinks in 2.6 * tempdir is redundant with tempfile.TemporaryDirectory added in 3.2 * listdir(recursive=False) is just os.listdir (I guess recursive=True is somewhat useful) * zip_dir is *not* redundant with shutil.make_archive: - zip_dir handles the archived root differently - zip_dir sorts files, make_archive sorts directories - make_archive explicitly adds entries for directories (including empty), sorts directories, doesn't sort files; zip_dir sorts files (including with a custom key function) but ignores directories - zip_dir filters out a bunch of trash files closes odoo/odoo#39573 Signed-off-by: Christophe Simonis <chs@odoo.com>
2019-10-21[FIX] tools: skip bad translationsMartin Trigaux
Do not return a boolean but skip bad translations Introduced at 19e50ea37435c2d9 Fixes odoo/odoo#39001 At least fix the error that is thrown, however, this does not solve the initial error of trying to export the terms of a record that is no longer present in the database. As this issue is no longer reproducable, just log a warning as it was expected. closes odoo/odoo#39122 X-original-commit: 5c0677bf2fbf6d18978989f1ee70e4a0946da035 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-09-20[IMP] module.py: deprecate openerpJulien Castiaux
[PEP-594] is deprecating the `imp` module, that module is used in `module.py` in order to dynamically import addons using any of the `odoo.addons` or `openerp.addons` import anchor. We are deprecating `openerp` module/addons imports in v13 in order to remove the support in v14 and greatly simplify how modules/addons are loaded. If you are still using the old `import openerp` or `import openerp.addons`, `import odoo` and `import odoo.addons` are drop-in replacements. The `odoo.modules.module.ad_paths` addon paths list has been deprecated too. The list is now accessible on `odoo.addons.__path__` where they are now directly loaded [2]. See also: [PEP-594]: https://python.org/dev/peps/pep-0594/ [2]: https://packaging.python.org/guides/packaging-namespace-packages/ closes odoo/odoo#36597 Task: 2003936 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2019-09-09[FIX] tools: do not translate selections with _translate=FalseMartin Trigaux
If a model is tagged with _translate=False, it should not be translated. A special case was made for ir.model.fields but not ir.model.fields.selection Before this commit, the selections of web_editor.converter.test were translated closes odoo/odoo#36576 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-09-02[FIX] core: fix translation of selection fields with dashesXavier-Do
When a selection field has a dash the parsing was failing only returning the begining of this selection, leading to a mismatch fot the ir_model_fields_selection. This was discovered because "iot.trigger" add multiple selection fields element with name only differing by the post dash part: print print-op print-slip This was leading to a failure of the ON CONFLICT DO UPDATE (ir_translation line 120) since multiple EXCLUDED where similar in mrp_workorder_iot/i18n/fr.po(same res_id). closes odoo/odoo#36347 Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2019-08-26[FIX] base: multi-company codeFabien Pinckaers
2019-08-20[FIX] tools : use babel to format timedeltaDavid Beguin
Babel is already taking the language into account while formating a time delta into a readable string like '2 minutes ago'. _format_time_ago was put in translate.py file to be able to use the _ translate class. But it can be placed in misc like other format function already using babel. This fix the PR #34624 and is linked to Task ID : 2028059 Task ID: 2055847 Closes PR #35806 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2019-08-19[REF] fields: use ir.model.fields.selectionMartin Trigaux
The selection values of a selection field are now stored in database in the model ir.model.fields.selection This will allow to have a modular approche on selections and each selection is now linked to the module that declared it. Previously to this change, the selections were linked to the field, meaning uninstalling a module had no impact on the selections stored on database. With this change, the selections will now be translated in the correct module (having an external id) and the records having a used selection will now be reset to null. closes odoo/odoo#30228 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com> Co-authored-by: Raphaël Collet <rco@odoo.com>
2019-08-19[IMP] website : add website visitors activity trackingDavid Beguin
This commit adds the website_visitor model that will be used to track website visitor activity (page viewed, number of visits and more general info about the visitor (country, lang, etc..) This model will, in later commit, be used to send chat requests and push notification from the operators (or backend users) directly to the visitor. - A website_visitor is created once the visitor is requesting a website.page that is tracked. - A website_visitor is considered as connected if his last tracked website_page request is within the last 5 minutes. - The number of visits for a website_visitor is incremented if his last tracked website_page request was at least 8 hours ago. - A website_visitor is only handled by the system. Users cannot create, edit or delete a website_visitor. - A unique website_visitor is created per website. That means that the same real person can triggers multiple visitor creation if visits multiple websites. This is because, for livechat purpose on later commit, for example, the chat request can be created on the correct livecaht channel (linked to the correct website) - The visitor is recognized via his cookie (visitor_id). So if the visitor flush his cookies, a new visitor will be created the next time he will request a tracked website_page. - Link user's res.partner to website.visitor. If a website_visitor log in (a visitor that has visitor_id in his cookie), the website_visitor is linked to the res.partner. The website visitor name is than adapted to match the name of the first res.partner linked to the visitor. A visitor can have multiple partners as the same session can be used by multiple person (one PC for a team for example). To keep a detailed history of the visitor page views, we add a website.visitor.page model that makes the link between visitor and website.page but that keeps the visit date. So that we can see if a visitor went mulitple times on the same page and when. It's usefull to see his last page views. Task ID : 2028059 PR #34624
2019-08-09[IMP] tools: ignore line number for code translationsMartin Trigaux
The line number was only indicative and was not used by the system. When the translations source were updated, a big part of the diff was only about the line numbers. Ignore the given res_id value and export the line at 0 When reading the po file, the res_id from the file is still read and stored in database but should be ignored closes odoo/odoo#35582 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-08-01[ADD] tools: lazy translation methodMartin Trigaux
Introduces the method _lt The translation method is now evaluated lazily. It allows to declare global variables with translatable content e.g. this code will now work: LABEL = _lt("User") def _compute_label(self): context = {'lang': self.partner_id.lang} self.user_label = LABEL
2019-07-18[IMP] models: remove support for _constraintsAdrian Torres
Using api.constrains should be used instead Simply leave a warning in case a model uses a non-empty attribute `_constraints`. closes odoo/odoo#34679 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-07-11[IMP] base: replace 'sql_constraint' translations by 'model' translationsMartin Trigaux
Store the SQL constraint message directly in the field `message` of the corresponding `ir.model.constraint` record, and manage translations from there. Those records are given an XML id in order to be tracked in PO files. The translation type 'sql_constraint` is removed.
2019-06-06[MERGE] forward port branch saas-12.3 up to 409679866b2Christophe Simonis
2019-06-05[FIX] tools: ensure 0 res_id are handledMartin Trigaux
if an POEntry has an occurrence with a 0 res_id >>> entry.occurrences.append(("selection:report.paper,format", 0)) >>> str(entry) #: selection:report.paperformat,format ... Use the string '0' to bypass this
2019-06-05[IMP] tools: remove custom pofile writerMartin Trigaux
And create a generic class to handles it, using polib for po files
2019-06-05[IMP] tools: remove custom pofile readerMartin Trigaux
Use polib library that handles this correctly The complexity of the parser is moved to the library
2019-05-31[MERGE] forward port branch 12.0 up to 8f21148e1a8Christophe Simonis
2019-05-29[MERGE] forward port branch saas-11.3 up to 8a0e819d0bbChristophe Simonis
2019-05-28[MERGE] forward port branch 11.0 up to a20a31486cdChristophe Simonis
2019-05-27[FIX] tools: export UTF-8 charactersNicolas Martinelli
- Install Babel 2.3.4 as specified in the `requirements.txt` - In a Python file, do not add the line `# -*- coding: utf-8 -*-` - Create a translatable string with a non-ASCII character, e.g. `Amount in €` - Export the translation The exported term is incorrect: `Amount in â¬`. Since the default encoding for Python 3 is UTF-8, it is logical for the Babel extraction to use it as a default encoding. The issue was solved in Babel 2.4.0 with commit: https://github.com/python-babel/babel/commit/33a8fc40d417b401162e2d20021fcbebcc4ab7db opw-1984480 closes odoo/odoo#33671 Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2019-03-29[MERGE] forward port branch 12.0 up to 09fb2469b49Christophe Simonis
2019-03-29[FIX] tools: extract module from po fileMartin Trigaux
When a single po file is processed (i.e. direct po import, not read from a i18n directory inside a module), there was no module information on code translations The module information is important for web translations where the list of modules is given in the call to the route '/website/translations' and '/web/webclient/translations' and only the web translations of these specific modules is retrieved and used. To manually import the translations of a custom module (e.g. openerp_enterprise), the base.language.import wizard is typically used and the give .po file is directly imported. For model and model_terms, the module information is easily deducted from the the record external id (<module>.<reference>) but for code translation, we relied on the global variable module_name. The .po file do contain the module information but this information was ignored. Real example: #. module: openerp_enterprise #. openerp-web #: code:addons/openerp_enterprise/static/src/js/odoo_enterprise_start_trial.js:249 #, python-format msgid "Please choose your domain name" msgstr "Veuillez choisir votre nom de domaine" Before this commit, the above translation was imported without the module and was not retrieved in the '/website/translations' call on the /trial page The global module_name is still used when set for backward compatibility. Co-authored-by: Raphael Collet <rco@odoo.com>
2019-03-25[MERGE] forward port branch 12.0 up to 11b1e12cde3Christophe Simonis
2019-03-21[FIX] base: ignore empty translatable attributeMartin Trigaux
Complete cd4080839f501ad01bd <span class="fa fa-globe" title="Title stuff"/> is not correctly extracted but <span class="fa fa-globe" title=""/> was also extracted while there is no content Check the size of the content too Similar content is present on odoo.com website and should not be translatable on Transifex closes odoo/odoo#32018 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-01-08[MERGE] forward port branch 11.0 up to c07b7200b26Christophe Simonis
2019-01-03[FIX] tools: properly verify the size of HTML nodesMartin Trigaux
Instead of checking the size of text only node, let the xml_translate verify it. The size verification using etree was introduced at 40efdccc3d1e1f070c9 but was probably too simple. Since 45352512a842, this becomes redundant with the nonspace method which can be extended. The re.sub is still relevant as some terms may contain only non-alphanumeric and use push_translation (e.g. '>=' as a selection or xml terms extracted by babel in static repository) closes odoo/odoo#29432
2019-01-03[FIX] translate: inline elements with translatable attributes onlyRaphael Collet
2019-01-14[MERGE] forward port branch 12.0 up to 6a0675d36ddChristophe Simonis
2019-01-09[MERGE] forward port branch 12.0 up to 3e4138deaa2Christophe Simonis
closes odoo/odoo#30045