From de57317848934baec7178c1be7da5d0d80503e9a Mon Sep 17 00:00:00 2001 From: denyshon Date: Mon, 10 Aug 2026 05:53:05 +0200 Subject: [PATCH 1/3] Fix DB l10n comments --- kitsune/sumo/management/commands/extract_db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kitsune/sumo/management/commands/extract_db.py b/kitsune/sumo/management/commands/extract_db.py index 0a4cb776dcb..f609cbc057e 100644 --- a/kitsune/sumo/management/commands/extract_db.py +++ b/kitsune/sumo/management/commands/extract_db.py @@ -96,6 +96,6 @@ def handle(self, *args, **options): comments = s["comments"] if comments: for c in comments: - f.write("# {comment}\n".format(comment=c)) + f.write("# L10n: {comment}\n".format(comment=c)) f.write(L10N_STRING.format(id=s["id"], context=s["context"])) From 0a0bf0be690621f13c1ade4dcd41415a33c96c31 Mon Sep 17 00:00:00 2001 From: denyshon Date: Mon, 10 Aug 2026 05:54:05 +0200 Subject: [PATCH 2/3] Improve karma title l10n comment --- kitsune/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kitsune/settings.py b/kitsune/settings.py index 0bb19678de6..c11c79f99e7 100644 --- a/kitsune/settings.py +++ b/kitsune/settings.py @@ -402,7 +402,7 @@ def path(*parts): "karma": { "Title": { "attrs": ["name"], - "comments": ["This is a karma title."], + "comments": ["This is a karma title, displayed for eligible users next to their username on the forums."], } }, "products": { From a0526380e289dca977b7f50d90a41e3d2a2440d0 Mon Sep 17 00:00:00 2001 From: denyshon Date: Mon, 10 Aug 2026 05:55:27 +0200 Subject: [PATCH 3/3] Add l10n comments for Topic, Product and Badge --- .../sumo/management/commands/extract_db.py | 120 +++++++++++++++++- 1 file changed, 113 insertions(+), 7 deletions(-) diff --git a/kitsune/sumo/management/commands/extract_db.py b/kitsune/sumo/management/commands/extract_db.py index f609cbc057e..e6211f14989 100644 --- a/kitsune/sumo/management/commands/extract_db.py +++ b/kitsune/sumo/management/commands/extract_db.py @@ -25,6 +25,95 @@ L10N_STRING = 'pgettext("{context}", """{id}""")\n' +def product_title_comment(product): + comments = ["This is a product title."] + + if product.is_archived: + comments[0] += "Archived. " + comments[0] + + if product.description: + comments.append('The product description is "{}"'.format(product.description)) + + return comments + + +def product_description_comment(product): + comments = ["This is a description for the {} product.".format(product.title)] + + if product.is_archived: + comments[0] += "Archived. " + comments[0] + + return comments + + +def topic_hierarchy_comment(topic): + hierarchy = [topic] + parent_topic = topic + while parent_topic.parent: + parent_topic = parent_topic.parent + hierarchy.append(parent_topic) + if len(hierarchy) > 1: + return "The topic hierarcy is as follows: {}.".format(" > ".join([t.title for t in hierarchy])) + else: + return "The {} topic has no parent topics.".format(topic.title) + + +def topic_products_comment(topic): + products = topic.products.all() + if products.count() > 1: + return "This topic is associated with the following products: {}.".format( + ", ".join([p.title for p in products]) + ) + elif products.count() == 1: + return "This topic is associated with the {} product.".format(products[0].title) + else: + return "This topic is not associated with any products." + + +def topic_title_comment(topic): + comments = ["This is a topic title."] + + if topic.is_archived: + comments[0] += "Archived. " + comments[0] + + comments.append(topic_hierarchy_comment(topic)) + + comments.append(topic_products_comment(topic)) + + if topic.description: + comments.append('The topic description is "{}"'.format(topic.description)) + + return comments + + +def topic_description_comment(topic): + comments = ["This is a description for the {} topic.".format(topic.title)] + + if topic.is_archived: + comments[0] += "Archived. " + comments[0] + + comments.append(topic_hierarchy_comment(topic)) + + comments.append(topic_products_comment(topic)) + + return comments + + +def badge_title_comment(badge): + comments = ["This is a badge title."] + + if badge.description: + comments.append('The badge description is "{}"'.format(badge.description)) + + return comments + + +def badge_description_comment(badge): + comments = ["This is a description for the {} badge.".format(badge.title)] + + return comments + + class Command(BaseCommand): """ Pulls strings from the database and puts them in a python file, @@ -71,17 +160,34 @@ def handle(self, *args, **options): for model, params in list(models.items()): model_class = apps.get_model(app, model) attrs = params["attrs"] - qs = model_class.objects.all().values_list(*attrs).distinct() - for item in qs: - for i in range(len(attrs)): - if not item[i]: + qs = model_class.objects.all() + for object in qs: + for attr in attrs: + value = getattr(object, attr) + if not value: # Skip empty strings because empty string msgids # are super bad. continue + enforced_comments = [] + # Enforce complex comments for certain models/attributes. + if app == "products": + if model == "Topic" and attr == "title": + enforced_comments = topic_title_comment(object) + elif model == "Topic" and attr == "description": + enforced_comments = topic_description_comment(object) + elif model == "Product" and attr == "title": + enforced_comments = product_title_comment(object) + elif model == "Product" and attr == "description": + enforced_comments = product_description_comment(object) + elif app == "kbadge": + if model == "Badge" and attr == "title": + enforced_comments = badge_title_comment(object) + elif model == "Badge" and attr == "description": + enforced_comments = badge_description_comment(object) msg = { - "id": item[i], - "context": "DB: {}.{}.{}".format(app, model, attrs[i]), - "comments": params.get("comments"), + "id": value, + "context": "DB: {}.{}.{}".format(app, model, attr), + "comments": enforced_comments + params.get("comments", []), } strings.append(msg)