import os from django.conf import settings from django.core.management.base import BaseCommand class Command(BaseCommand): help = ( "Traverse all .po files under BASE_DIR (or a given base-dir), " "remove 'fuzzy' flags, drop '#| msgid' comments, and reset msgstr to empty." ) def add_arguments(self, parser): parser.add_argument( "-b", "--base-dir", default=settings.BASE_DIR, help="Root directory to start searching for .po files (default: settings.BASE_DIR).", ) def handle(self, *args, **options): base_dir = options["base_dir"] for root, _dirs, files in os.walk(base_dir): for fname in files: if not fname.endswith(".po"): continue path = os.path.join(root, fname) self.stdout.write(f"→ Processing {path}") self._clean_po_file(path) def _clean_po_file(self, filepath): with open(filepath, encoding="utf-8") as f: lines = f.readlines() entries, curr = [], [] for line in lines: if line.strip() == "": if curr: entries.append(curr) curr = [] else: curr.append(line) if curr: entries.append(curr) new_lines = [] changed = False for ent in entries: if ent and ent[0].startswith('msgid ""'): new_lines.extend(ent) new_lines.append("\n") continue fuzzy_idx = next((i for i, line in enumerate(ent) if line.startswith("#,") and "fuzzy" in line), None) if fuzzy_idx is not None: flag_line = ent[fuzzy_idx] remaining = [f.strip() for f in flag_line[2:].split(",") if f.strip() != "fuzzy"] if remaining: ent[fuzzy_idx] = "#, " + ", ".join(remaining) + "\n" else: del ent[fuzzy_idx] ent = [line for line in ent if not line.startswith("#| msgid")] ent = ['msgstr ""\n' if line.startswith("msgstr") else line for line in ent] changed = True new_lines.extend(ent) new_lines.append("\n") if changed: with open(filepath, "w", encoding="utf-8") as f: f.writelines(new_lines) self.stdout.write(self.style.SUCCESS(f" → Updated {filepath}")) else: self.stdout.write(" (no fuzzy entries found)")