mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-22 09:19:29 +00:00
131 lines
4.9 KiB
Python
Executable File
131 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# pofix - perform string fixups on incoming .po files.
|
|
#
|
|
# The purpose of this script is to save translators from having to
|
|
# apply various string fixes needed before stable release by hand. It is
|
|
# intended to be run on each incoming .po file as the Lord of
|
|
# Translations receives it. However, translators may run it on their
|
|
# own .po files to be sure, as a second application will harmlessly do
|
|
# nothing.
|
|
#
|
|
# To use this script, give it one or more paths to .po files as
|
|
# command-line arguments. Each file will be tweaked as needed.
|
|
# It should work on Windows and MacOS X as well as Linux, provided
|
|
# you have Python installed.
|
|
#
|
|
# This script will emit a report line for each file it modifies,
|
|
# and save a backup copy of the original with extension "-bak".
|
|
#
|
|
# This script will tell you when it is obsolete. Run it against all .po
|
|
# files in the main Wesnoth tree; when it says none are older than this script,
|
|
# it can be discarded (assunming that it has in fact been used to transform
|
|
# all incoming .po files in the meantime).
|
|
#
|
|
# Example usage:
|
|
# utils/pofix.py po/wesnoth*/*.po*
|
|
# find data/campaigns/ -name '*.cfg' -print0 | xargs -0 utils/pofix.py
|
|
#
|
|
# To make use of >1 CPU core, you have to rely on xargs. In this sample 10 files
|
|
# are handed over to 4 instances of pofix.py:
|
|
# ls po/wesnoth*/*.po* | xargs -P 4 -n 10 ./utils/pofix.py
|
|
#
|
|
#
|
|
# Please do make sure to add a comment before any new blocks of conversions
|
|
# that states when it was added (current version number is enough) so that
|
|
# the file can be cleaned up more easily every now and then.
|
|
# Example:
|
|
# # conversion added in 1.9.5+svn
|
|
# ("foo addwd bar", "foo added bar"),
|
|
# # conversion added in 1.9.8+svn
|
|
# ("fooba foo", "foobar foo"),
|
|
|
|
stringfixes = {
|
|
|
|
"1.8-announcement" : (
|
|
# conversion added shortly before 1.8.0, might be relevant for the 1.10.0 announcement
|
|
("WML events an AI components", "WML events and AI components"),
|
|
("1.7.3", "1.7.13"),
|
|
("/tags/1.8/", "/tags/1.8.0/"),
|
|
),
|
|
|
|
"1.10-announcement" : (
|
|
("roleplaying", "role-playing"),
|
|
),
|
|
|
|
}
|
|
|
|
# Speak, if all argument files are newer than this timestamp
|
|
# Try to use UTC here
|
|
# date --utc "+%s # %c"
|
|
timecheck = 1283156523 # Mo 30 Aug 2010 08:22:03 UTC
|
|
|
|
import os, sys, time, stat, re
|
|
try:
|
|
from multiprocessing import Pool, cpu_count
|
|
def parallel_map(*args, **kw):
|
|
pool = Pool(cpu_count())
|
|
return pool.map(*args, **kw)
|
|
except ImportError:
|
|
print "Failed to import 'multiprocessing' module. Multiple cpu cores won't be utilized"
|
|
parallel_map = map
|
|
|
|
def process_file(path):
|
|
before = open(path, "r").read()
|
|
decommented = re.sub("#.*", "", before)
|
|
lines = before.split('\n')
|
|
for (domain, fixes) in stringfixes.items():
|
|
# In case of screwed-up pairs that are hard to find, uncomment the following:
|
|
#for fix in fixes:
|
|
# if len(fix) != 2:
|
|
# print fix
|
|
for (old, new) in fixes:
|
|
if old is new:
|
|
#complain loudly
|
|
print "pofix: old string\n\t\"%s\"\n equals new string\n\t\"%s\"\nexiting." % (old, new)
|
|
sys.exit(1)
|
|
#this check is problematic and the last clause is added to prevent false
|
|
#positives in case that new is a substring of old, though this can also
|
|
#lead to "real" probs not found, the real check would be "does replacing
|
|
#old with new lead to duplicate msgids? (including old ones marked with #~)"
|
|
#which is not easily done in the current design...
|
|
elif new in decommented and old in decommented and not new in old:
|
|
print "pofix: %s already includes the new string\n\t\"%s\"\nbut also the old\n\t\"%s\"\nthis needs handfixing for now since it likely creates duplicate msgids." % (path, new, old)
|
|
else:
|
|
for (i, line) in enumerate(lines):
|
|
if line and line[0] != '#':
|
|
lines[i] = lines[i].replace(old, new)
|
|
after = '\n'.join(lines)
|
|
if after != before:
|
|
print "pofix: %s modified" % path
|
|
# Save a backup
|
|
os.rename(path, path + "-bak")
|
|
# Write out transformed version
|
|
ofp = open(path, "w")
|
|
ofp.write(after)
|
|
ofp.close()
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
if __name__ == '__main__':
|
|
newer = 0
|
|
modified = 0
|
|
pocount = 0
|
|
files = []
|
|
for path in sys.argv[1:]:
|
|
if not path.endswith(".po") and not path.endswith(".pot") and not path.endswith(".cfg"):
|
|
continue
|
|
pocount += 1
|
|
# Notice how many files are newer than the time check
|
|
statinfo = os.stat(path)
|
|
if statinfo.st_mtime > timecheck:
|
|
newer += 1
|
|
files.append(path)
|
|
modified = sum(parallel_map(process_file, files))
|
|
print "pofix: %d files processed, %d files modified, %d files newer" \
|
|
% (pocount, modified, newer)
|
|
if pocount > 1 and newer == pocount:
|
|
print "pofix: script may be obsolete"
|