Skip to content

Commit 0fae7e1

Browse files
Merge pull request #385 from woocommerce/issue/translations-script
Translations Script
2 parents 70828cc + 0736c34 commit 0fae7e1

File tree

2 files changed

+1049
-10
lines changed

2 files changed

+1049
-10
lines changed

Scripts/localize.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# This program is free software. It comes without any warranty, to
5+
# the extent permitted by applicable law. You can redistribute it
6+
# and/or modify it under the terms of the Do What The Fuck You Want
7+
# To Public License, Version 2, as published by Sam Hocevar. See
8+
# http://sam.zoy.org/wtfpl/COPYING for more details.
9+
#
10+
# Localize.py - Incremental localization on XCode projects
11+
# João Moreno 2009
12+
# http://joaomoreno.com/
13+
14+
from sys import argv
15+
from codecs import open
16+
from re import compile
17+
from copy import copy
18+
import os
19+
20+
STRINGS_FILE = 'Localizable.strings'
21+
22+
re_translation = compile(r'^"(.+)" = "(.+)";$')
23+
re_comment_single = compile(r'^/(/.*|\*.*\*/)$')
24+
re_comment_start = compile(r'^/\*.*$')
25+
re_comment_end = compile(r'^.*\*/$')
26+
27+
def print_help():
28+
print u"""Usage: merge.py merged_file old_file new_file
29+
Xcode localizable strings merger script. João Moreno 2009."""
30+
31+
class LocalizedString():
32+
def __init__(self, comments, translation):
33+
self.comments, self.translation = comments, translation
34+
self.key, self.value = re_translation.match(self.translation).groups()
35+
36+
def __unicode__(self):
37+
return u'%s%s\n' % (u''.join(self.comments), self.translation)
38+
39+
class LocalizedFile():
40+
def __init__(self, fname=None, auto_read=False):
41+
self.fname = fname
42+
self.strings = []
43+
self.strings_d = {}
44+
45+
if auto_read:
46+
self.read_from_file(fname)
47+
48+
def read_from_file(self, fname=None):
49+
fname = self.fname if fname == None else fname
50+
try:
51+
f = open(fname, encoding='utf_8', mode='r')
52+
except:
53+
print 'File %s does not exist.' % fname
54+
exit(-1)
55+
56+
line = f.readline()
57+
while line and line == u'\n':
58+
line = f.readline()
59+
60+
while line:
61+
comments = [line]
62+
63+
if not re_comment_single.match(line):
64+
while line and not re_comment_end.match(line):
65+
line = f.readline()
66+
comments.append(line)
67+
68+
line = f.readline()
69+
if line and re_translation.match(line):
70+
translation = line
71+
else:
72+
raise Exception('invalid file: %s' % line)
73+
74+
line = f.readline()
75+
while line and line == u'\n':
76+
line = f.readline()
77+
78+
string = LocalizedString(comments, translation)
79+
self.strings.append(string)
80+
self.strings_d[string.key] = string
81+
82+
f.close()
83+
84+
def save_to_file(self, fname=None):
85+
fname = self.fname if fname == None else fname
86+
try:
87+
f = open(fname, encoding='utf_8', mode='w')
88+
except:
89+
print 'Couldn\'t open file %s.' % fname
90+
exit(-1)
91+
92+
for string in self.strings:
93+
f.write(string.__unicode__())
94+
95+
f.close()
96+
97+
def merge_with(self, new):
98+
merged = LocalizedFile()
99+
100+
for string in new.strings:
101+
if self.strings_d.has_key(string.key):
102+
new_string = copy(self.strings_d[string.key])
103+
new_string.comments = string.comments
104+
string = new_string
105+
106+
merged.strings.append(string)
107+
merged.strings_d[string.key] = string
108+
109+
return merged
110+
111+
def merge(merged_fname, old_fname, new_fname):
112+
try:
113+
old = LocalizedFile(old_fname, auto_read=True)
114+
new = LocalizedFile(new_fname, auto_read=True)
115+
except Exception as e:
116+
print 'Error: input files have invalid format. old: %s, new: %s' % (old_fname, new_fname)
117+
print e
118+
119+
merged = old.merge_with(new)
120+
121+
merged.save_to_file(merged_fname)
122+
123+
def convert_file_encoding(input_file, input_encoding, output_encoding):
124+
tmp_file = input_file + '.' + output_encoding
125+
os.system('iconv -f %s -t %s "%s" > "%s"' % (input_encoding, output_encoding, input_file, tmp_file))
126+
os.rename(tmp_file, input_file)
127+
128+
def gen_strings(output_dir, input_files):
129+
os.system('genstrings -q -o "%s" %s' % (output_dir, input_files))
130+
# genstrings always produces output in UTF-16LE so we must explictly convert to UTF-8
131+
convert_file_encoding(output_dir + os.path.sep + STRINGS_FILE, 'UTF-16LE', 'UTF-8')
132+
133+
def localize(paths, language):
134+
# Failsafe
135+
current_path = os.getcwd()
136+
os.chdir(current_path)
137+
138+
if not os.path.exists('Scripts'):
139+
print "Must run script from the root folder"
140+
quit()
141+
142+
# Output
143+
original = merged = language + os.path.sep + STRINGS_FILE
144+
old = original + '.old'
145+
new = original + '.new'
146+
147+
# Localization Loop
148+
target_folders = ' '.join(paths)
149+
find_cmd = 'find ' + target_folders + ' -name "*.m" -o -name "*.swift" | grep -v Vendor'
150+
filelist = os.popen(find_cmd).read().replace("\n", " ")
151+
152+
if os.path.isfile(original):
153+
os.rename(original, old)
154+
gen_strings(language, filelist)
155+
os.rename(original, new)
156+
merge(merged, old, new)
157+
os.remove(new)
158+
os.remove(old)
159+
else:
160+
gen_strings(language, filelist)
161+
162+
## Main
163+
##
164+
if __name__ == '__main__':
165+
paths = ['WooCommerce', 'Pods/WordPress*', 'Storage/Storage', 'Networking/Networking']
166+
language = 'WooCommerce/Resources/en.lproj'
167+
168+
localize(paths, language)
169+

0 commit comments

Comments
 (0)