schon/core/management/commands/fix_fuzzy.py

80 lines
2.6 KiB
Python

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)")