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, 'r', 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, l in enumerate(ent) if l.startswith('#,') and 'fuzzy' in l), 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 = [l for l in ent if not l.startswith('#| msgid')] ent = ['msgstr ""\n' if l.startswith('msgstr') else l for l 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(f" (no fuzzy entries found)")