@@ -89,6 +89,7 @@ class FileStats:
89
89
total_in_file : int = 0
90
90
untranslated : int = 0
91
91
translated_in_file : int = 0
92
+ fuzzy : int = 0
92
93
93
94
94
95
class TranslationService :
@@ -427,7 +428,10 @@ def _show_results_summary(self, stats: TranslationStats):
427
428
"""Show final results summary after processing."""
428
429
logging .info ("" )
429
430
logging .info ("=" * 70 )
430
- logging .info ("TRANSLATION RESULTS" )
431
+ if self .config .flags .fix_fuzzy :
432
+ logging .info ("FUZZY FIX RESULTS" )
433
+ else :
434
+ logging .info ("TRANSLATION RESULTS" )
431
435
logging .info ("=" * 70 )
432
436
433
437
logging .info ("PROCESSING SUMMARY:" )
@@ -436,8 +440,12 @@ def _show_results_summary(self, stats: TranslationStats):
436
440
logging .info (" Total files handled: %d" , stats .files .processed + stats .files .skipped )
437
441
438
442
logging .info ("" )
439
- logging .info ("TRANSLATION RESULTS:" )
440
- logging .info (" Entries successfully translated: %d" , stats .entries .translated )
443
+ if self .config .flags .fix_fuzzy :
444
+ logging .info ("FUZZY FIX RESULTS:" )
445
+ logging .info (" Fuzzy entries fixed: %d" , stats .entries .translated )
446
+ else :
447
+ logging .info ("TRANSLATION RESULTS:" )
448
+ logging .info (" Entries successfully translated: %d" , stats .entries .translated )
441
449
if stats .entries .failed > 0 :
442
450
logging .info (" Entries failed/skipped: %d" , stats .entries .failed )
443
451
@@ -515,22 +523,34 @@ def _show_mode_info(self, total_entries: int):
515
523
def _show_translation_summary (self , scan_results , languages ):
516
524
"""Show summary of files to translate."""
517
525
logging .info ("=" * 70 )
518
- logging .info ("TRANSLATION OVERVIEW" )
526
+ if self .config .flags .fix_fuzzy :
527
+ logging .info ("FUZZY FIX OVERVIEW" )
528
+ else :
529
+ logging .info ("TRANSLATION OVERVIEW" )
519
530
logging .info ("=" * 70 )
520
531
logging .info ("SCAN RESULTS:" )
521
532
logging .info (" Total PO files found: %d" , scan_results ['files_scanned' ])
522
533
files_matched = len (scan_results ['files_to_process' ]) + len (scan_results ['skipped_files' ])
523
534
logging .info (" Files matching languages: %d" , files_matched )
524
535
logging .info (" Files with language mismatch: %d" , scan_results ['language_mismatch_files' ])
525
536
logging .info ("" )
526
- logging .info ("TRANSLATION STATUS:" )
527
- logging .info (" Files needing translation: %d" , len (scan_results ['files_to_process' ]))
528
- logging .info (" Files already fully translated: %d" , len (scan_results ['skipped_files' ]))
529
- logging .info ("" )
530
- logging .info ("ENTRY STATISTICS:" )
531
- logging .info (" Total entries in all files: %d" , scan_results ['total_entries_in_all_files' ])
532
- logging .info (" Already translated entries: %d" , scan_results ['total_translated_in_all_files' ])
533
- logging .info (" Entries to translate: %d" , scan_results ['total_entries' ])
537
+ if self .config .flags .fix_fuzzy :
538
+ logging .info ("FUZZY STATUS:" )
539
+ logging .info (" Files with fuzzy entries: %d" , len (scan_results ['files_to_process' ]))
540
+ logging .info (" Files without fuzzy entries: %d" , len (scan_results ['skipped_files' ]))
541
+ logging .info ("" )
542
+ logging .info ("ENTRY STATISTICS:" )
543
+ logging .info (" Total entries in all files: %d" , scan_results ['total_entries_in_all_files' ])
544
+ logging .info (" Fuzzy entries to fix: %d" , scan_results ['total_entries' ])
545
+ else :
546
+ logging .info ("TRANSLATION STATUS:" )
547
+ logging .info (" Files needing translation: %d" , len (scan_results ['files_to_process' ]))
548
+ logging .info (" Files already fully translated: %d" , len (scan_results ['skipped_files' ]))
549
+ logging .info ("" )
550
+ logging .info ("ENTRY STATISTICS:" )
551
+ logging .info (" Total entries in all files: %d" , scan_results ['total_entries_in_all_files' ])
552
+ logging .info (" Already translated entries: %d" , scan_results ['total_translated_in_all_files' ])
553
+ logging .info (" Entries to translate: %d" , scan_results ['total_entries' ])
534
554
535
555
if scan_results ['total_entries_in_all_files' ] > 0 :
536
556
completion_percent = (
@@ -548,6 +568,15 @@ def _analyze_po_file(self, po_file):
548
568
stats .total_in_file = len ([e for e in po_file if e .msgid ])
549
569
stats .untranslated = len ([e for e in po_file if is_entry_untranslated (e )])
550
570
stats .translated_in_file = stats .total_in_file - stats .untranslated
571
+ # Also count fuzzy entries when fix_fuzzy is enabled
572
+ if self .config .flags .fix_fuzzy :
573
+ # Count all fuzzy entries
574
+ stats .fuzzy = len ([e for e in po_file if 'fuzzy' in e .flags ])
575
+ # Also count header if it's fuzzy
576
+ if hasattr (po_file , 'metadata_is_fuzzy' ) and po_file .metadata_is_fuzzy :
577
+ stats .fuzzy += 1
578
+ else :
579
+ stats .fuzzy = 0
551
580
return stats
552
581
553
582
def _scan_po_files (self , input_folder : str , languages : List [str ], gitignore_parser ):
@@ -569,11 +598,24 @@ def _scan_po_files(self, input_folder: str, languages: List[str], gitignore_pars
569
598
results .total_entries_in_all_files += stats .total_in_file
570
599
results .total_translated_in_all_files += stats .translated_in_file
571
600
572
- if stats .untranslated > 0 :
573
- results .files_to_process .append ((po_file_path , po_file_result , stats .untranslated ))
574
- results .total_entries += stats .untranslated
575
- logging .debug ("File %s: %d/%d entries need translation" ,
576
- po_file_path , stats .untranslated , stats .total_in_file )
601
+ # Include files with fuzzy entries when fix_fuzzy is enabled
602
+ if self .config .flags .fix_fuzzy :
603
+ # In fix-fuzzy mode, only process files with fuzzy entries
604
+ needs_processing = stats .fuzzy > 0
605
+ entries_to_process = stats .fuzzy
606
+ else :
607
+ # In normal mode, process files with untranslated entries
608
+ needs_processing = stats .untranslated > 0
609
+ entries_to_process = stats .untranslated
610
+
611
+ if needs_processing :
612
+ results .files_to_process .append ((po_file_path , po_file_result , entries_to_process ))
613
+ results .total_entries += entries_to_process
614
+ if self .config .flags .fix_fuzzy :
615
+ logging .debug ("File %s: %d fuzzy entries to fix" , po_file_path , stats .fuzzy )
616
+ else :
617
+ logging .debug ("File %s: %d/%d entries need translation" ,
618
+ po_file_path , stats .untranslated , stats .total_in_file )
577
619
else :
578
620
results .skipped_files .append (po_file_path )
579
621
logging .debug ("Skipping fully translated file: %s" , po_file_path )
@@ -586,7 +628,15 @@ def _track_file_progress(self, po_file_path, initial_count):
586
628
"""Track translation progress for a single file."""
587
629
try :
588
630
po_file = polib .pofile (po_file_path )
589
- remaining = len ([e for e in po_file if is_entry_untranslated (e )])
631
+ if self .config .flags .fix_fuzzy :
632
+ # In fix-fuzzy mode, count remaining fuzzy entries
633
+ remaining = len ([e for e in po_file if 'fuzzy' in e .flags ])
634
+ # Also check if header is still fuzzy
635
+ if hasattr (po_file , 'metadata_is_fuzzy' ) and po_file .metadata_is_fuzzy :
636
+ remaining += 1
637
+ else :
638
+ # In normal mode, count untranslated entries
639
+ remaining = len ([e for e in po_file if is_entry_untranslated (e )])
590
640
return initial_count - remaining , remaining
591
641
except Exception :
592
642
return initial_count , 0
@@ -919,25 +969,32 @@ def fix_fuzzy_entries(
919
969
detail_language : Optional [str ] = None ,
920
970
):
921
971
"""Find and fix fuzzy entries in a PO file using AI translation."""
972
+ # Check if the metadata/header is fuzzy
973
+ header_was_fuzzy = False
974
+ if hasattr (po_file , 'metadata_is_fuzzy' ) and po_file .metadata_is_fuzzy :
975
+ header_was_fuzzy = True
976
+ po_file .metadata_is_fuzzy = False
977
+ logging .info ("Removed fuzzy flag from file header in %s" , po_file_path )
978
+
979
+ # Find all fuzzy entries
922
980
fuzzy_entries = [entry for entry in po_file if 'fuzzy' in entry .flags ]
923
-
924
- if not fuzzy_entries :
981
+ if not fuzzy_entries and not header_was_fuzzy :
925
982
logging .info ("No fuzzy entries found in %s" , po_file_path )
926
983
return
984
+ if fuzzy_entries :
985
+ logging .info ("Found %d fuzzy entries to fix in %s" , len (fuzzy_entries ), po_file_path )
927
986
928
- logging .info ("Found %d fuzzy entries to fix in %s" , len (fuzzy_entries ), po_file_path )
929
-
930
- texts_to_translate = [entry .msgid for entry in fuzzy_entries ]
931
- translations = self .get_translations (texts_to_translate , target_language , po_file_path , detail_language )
987
+ texts_to_translate = [entry .msgid for entry in fuzzy_entries ]
988
+ translations = self .get_translations (texts_to_translate , target_language , po_file_path , detail_language )
932
989
933
- self ._update_fuzzy_po_entries (po_file , translations , entries_to_update = fuzzy_entries )
990
+ self ._update_fuzzy_po_entries (po_file , translations , entries_to_update = fuzzy_entries )
934
991
935
- po_file . save ( po_file_path )
936
-
937
- self . po_file_handler . log_translation_status (
938
- po_file_path ,
939
- texts_to_translate ,
940
- [ entry . msgstr for entry in fuzzy_entries ]
941
- )
942
-
943
- logging .info ("Fuzzy fix completed for %s" , po_file_path )
992
+ self . po_file_handler . log_translation_status (
993
+ po_file_path ,
994
+ texts_to_translate ,
995
+ [ entry . msgstr for entry in fuzzy_entries ]
996
+ )
997
+ # Save the file if any changes were made (header fuzzy removal or entry translations)
998
+ if header_was_fuzzy or fuzzy_entries :
999
+ po_file . save ( po_file_path )
1000
+ logging .info ("Fuzzy fix completed for %s" , po_file_path )
0 commit comments