From 353a6c8d6e2823c4befc59de447dbf1d7baf6f8f Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Sun, 15 Oct 2023 20:25:44 +0200 Subject: [PATCH] feat: doctype extractor --- frappe/gettext/extractors/doctype.py | 60 ++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 frappe/gettext/extractors/doctype.py diff --git a/frappe/gettext/extractors/doctype.py b/frappe/gettext/extractors/doctype.py new file mode 100644 index 0000000000..2a03e9b1ec --- /dev/null +++ b/frappe/gettext/extractors/doctype.py @@ -0,0 +1,60 @@ +import json + + +def extract(fileobj, *args, **kwargs): + """ + Extract messages from DocType JSON files. To be used to babel extractor + :param fileobj: the file-like object the messages should be extracted from + :rtype: `iterator` + """ + data = json.load(fileobj) + + if isinstance(data, list): + return + + doctype = data.get("name") + + yield None, "_", doctype, ["Name of a DocType"] + + messages = [] + fields = data.get("fields", []) + links = data.get("links", []) + + for field in fields: + fieldtype = field.get("fieldtype") + + if label := field.get("label"): + messages.append((label, f"Label of a {fieldtype} field in DocType '{doctype}'")) + + if description := field.get("description"): + messages.append((description, f"Description of a {fieldtype} field in DocType '{doctype}'")) + + if message := field.get("options"): + if fieldtype == "Select": + select_options = [option for option in message.split("\n") if option and not option.isdigit()] + + if select_options and "icon" in select_options[0]: + continue + + messages.extend( + (option, f"Option for a Select field in DocType '{doctype}'") for option in select_options + ) + elif fieldtype == "HTML": + messages.append((message, f"Content of an HTML field in DocType '{doctype}'")) + + for link in links: + if group := link.get("group"): + messages.append((group, f"Group in {doctype}'s connections")) + + if link_doctype := link.get("link_doctype"): + messages.append((link_doctype, f"Linked DocType in {doctype}'s connections")) + + # By using "pgettext" as the function name we can supply the doctype as context + yield from ((None, "pgettext", (doctype, message), [comment]) for message, comment in messages) + + # Role names do not get context because they are used with multiple doctypes + yield from ( + (None, "_", perm["role"], ["Name of a role"]) + for perm in data.get("permissions", []) + if "role" in perm + )