feat: apps can provide custom message extractors

- custom extractors take precedence
- default extractors are used as a fallback
This commit is contained in:
barredterra 2023-12-27 01:44:48 +01:00
parent e1140a22b8
commit 7d4bdbebb9
2 changed files with 25 additions and 13 deletions

9
babel_extractors.csv Normal file
View file

@ -0,0 +1,9 @@
hooks.py,frappe.gettext.extractors.navbar.extract
**/doctype/*/*.json,frappe.gettext.extractors.doctype.extract
**/workspace/*/*.json,frappe.gettext.extractors.workspace.extract
**/onboarding_step/*/*.json,frappe.gettext.extractors.onboarding_step.extract
**/module_onboarding/*/*.json,frappe.gettext.extractors.module_onboarding.extract
**/report/*/*.json,frappe.gettext.extractors.report.extract
**.py,frappe.gettext.extractors.python.extract
**.js,frappe.gettext.extractors.javascript.extract
**.html,frappe.gettext.extractors.jinja2.extract
1 hooks.py frappe.gettext.extractors.navbar.extract
2 **/doctype/*/*.json frappe.gettext.extractors.doctype.extract
3 **/workspace/*/*.json frappe.gettext.extractors.workspace.extract
4 **/onboarding_step/*/*.json frappe.gettext.extractors.onboarding_step.extract
5 **/module_onboarding/*/*.json frappe.gettext.extractors.module_onboarding.extract
6 **/report/*/*.json frappe.gettext.extractors.report.extract
7 **.py frappe.gettext.extractors.python.extract
8 **.js frappe.gettext.extractors.javascript.extract
9 **.html frappe.gettext.extractors.jinja2.extract

View file

@ -96,6 +96,16 @@ def write_binary(app: str, catalog: Catalog, locale: str) -> Path:
return mo_path
def get_method_map(app: str):
file_path = Path(frappe.get_app_path(app)).parent / "babel_extractors.csv"
if file_path.exists():
with open(file_path) as f:
reader = csv.reader(f)
return [(row[0], row[1]) for row in reader]
return []
def generate_pot(target_app: str | None = None):
"""
Generate a POT (PO template) file. This file will contain only messages IDs.
@ -111,24 +121,17 @@ def generate_pot(target_app: str | None = None):
return not (subdir.startswith(".") or subdir.startswith("_"))
apps = [target_app] if target_app else frappe.get_all_apps(True)
method_map = [
# Each file will only be processed by the first method that matches,
# so more specific methods should be listed first.
("hooks.py", "frappe.gettext.extractors.navbar.extract"),
("**/doctype/*/*.json", "frappe.gettext.extractors.doctype.extract"),
("**/workspace/*/*.json", "frappe.gettext.extractors.workspace.extract"),
("**/onboarding_step/*/*.json", "frappe.gettext.extractors.onboarding_step.extract"),
("**/module_onboarding/*/*.json", "frappe.gettext.extractors.module_onboarding.extract"),
("**/report/*/*.json", "frappe.gettext.extractors.report.extract"),
("**.py", "frappe.gettext.extractors.python.extract"),
("**.js", "frappe.gettext.extractors.javascript.extract"),
("**.html", "frappe.gettext.extractors.jinja2.extract"),
]
default_method_map = get_method_map("frappe")
for app in apps:
app_path = frappe.get_pymodule_path(app)
catalog = get_catalog(app)
# Each file will only be processed by the first method that matches,
# so more specific methods should come first.
method_map = [] if app == "frappe" else get_method_map(app)
method_map.extend(default_method_map)
for filename, lineno, message, comments, context in extract_from_dir(
app_path, method_map, directory_filter=directory_filter
):