Skip to content

Commit 855ca22

Browse files
committed
Refactor Python script to create TMX for products
1 parent c636a6c commit 855ca22

3 files changed

Lines changed: 197 additions & 126 deletions

File tree

app/scripts/glossaire.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ function updateStandardRepo() {
153153
echogreen "Create ${repo_name^^} cache for $repo_name/$1"
154154
if [ "$1" = "en-US" ]
155155
then
156-
nice -20 python $install/app/scripts/tmxmaker.py ${!repo_source}/COMMUN/ ${!repo_source}/COMMUN/ en-US en-US $repo_name
156+
nice -20 $install/app/scripts/tmx_products.py ${!repo_source}/COMMUN/ ${!repo_source}/COMMUN/ en-US en-US $repo_name
157157
else
158-
nice -20 python $install/app/scripts/tmxmaker.py ${!repo_l10n}/$1/ ${!repo_source}/COMMUN/ $1 en-US $repo_name
158+
nice -20 $install/app/scripts/tmx_products.py ${!repo_l10n}/$1/ ${!repo_source}/COMMUN/ $1 en-US $repo_name
159159
fi
160160
}
161161

@@ -262,7 +262,7 @@ function updateGaiaRepo() {
262262
# Build the cache
263263
# $1: Locale code
264264
echogreen "Create ${repo_name^^} cache for $repo_name/$1"
265-
nice -20 python $install/app/scripts/tmxmaker.py ${!repo_name}/$1/ ${!repo_name}/en-US/ $1 en-US $repo_name
265+
nice -20 $install/app/scripts/tmx_products.py ${!repo_name}/$1/ ${!repo_name}/en-US/ $1 en-US $repo_name
266266
}
267267

268268
if [ "$1" == "gaia" ]

app/scripts/tmx_products.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#!/usr/bin/python
2+
3+
import argparse
4+
import datetime
5+
import os
6+
import subprocess
7+
import sys
8+
from ConfigParser import SafeConfigParser
9+
10+
# Get absolute path of ../config from the current script location (not the
11+
# current folder)
12+
config_folder = os.path.abspath(
13+
os.path.join(os.path.dirname(__file__), os.pardir, 'config'))
14+
15+
# Read Transvision's configuration file from ../config/config.ini
16+
# If not available use default a /storage folder to store data
17+
config_file = os.path.join(config_folder, 'config.ini')
18+
if not os.path.isfile(config_file):
19+
print 'Configuration file /app/config/config.ini is missing. Default folders will be used.'
20+
storage_path = os.path.abspath(
21+
os.path.join(os.path.dirname(__file__), os.pardir))
22+
library_path = os.path.join(storage_path, 'libraries')
23+
storage_path = os.path.join(storage_path, 'tests', 'testfiles', 'output')
24+
else:
25+
config_parser = SafeConfigParser()
26+
config_parser.read(config_file)
27+
library_path = config_parser.get('config', 'libraries')
28+
storage_path = os.path.join(config_parser.get('config', 'root'), 'TMX')
29+
30+
# Import Silme library (http://hg.mozilla.org/l10n/silme/)
31+
silme_path = os.path.join(library_path, 'silme')
32+
33+
if not os.path.isdir(silme_path):
34+
try:
35+
print 'Cloning silme...'
36+
cmd_status = subprocess.check_output(
37+
['hg', 'clone', 'https://hg.mozilla.org/l10n/silme',
38+
silme_path, '-u', 'silme-0.8.0'],
39+
stderr=subprocess.STDOUT,
40+
shell=False)
41+
print cmd_status
42+
except Exception as e:
43+
print e
44+
45+
sys.path.append(os.path.join(silme_path, 'lib'))
46+
try:
47+
import silme.core
48+
import silme.io
49+
import silme.format
50+
silme.format.Manager.register('dtd', 'properties', 'ini', 'inc')
51+
except ImportError:
52+
print 'Error importing Silme library'
53+
sys.exit(1)
54+
55+
56+
def escape(translation):
57+
'''
58+
Escape quotes and backslahes in translation. There are two issues:
59+
* Internal Python escaping: the string "this is a \", has an internal
60+
representation as "this is a \\".
61+
Also, "\\ test" is equivalent to r"\ test" (raw string).
62+
* We need to print these strings into a file, with the format of a
63+
PHP array delimited by single quotes ('id' => 'translation'). Hence
64+
we need to escape single quotes, but also escape backslashes.
65+
"this is a 'test'" => "this is a \'test\'"
66+
"this is a \'test\'" => "this is a \\\'test\\\'"
67+
'''
68+
69+
# Escape slashes
70+
escaped_translation = translation.replace('\\', '\\\\')
71+
# Escape single quotes
72+
escaped_translation = escaped_translation.replace('\'', '\\\'')
73+
74+
return escaped_translation
75+
76+
77+
def get_strings(package, local_directory, strings_array):
78+
'''Store recursively translations from files in local_directory in a list of string'''
79+
for item in package:
80+
if (type(item[1]) is not silme.core.structure.Blob) and not(isinstance(item[1], silme.core.Package)):
81+
for entity in item[1]:
82+
# String ID is the format folder/filename:entity. Make
83+
# sure to remove a starting '/' from the folder's name
84+
string_id = u'{0}/{1}:{2}'.format(
85+
local_directory.lstrip('/'), item[0], entity)
86+
strings_array[string_id] = item[1][entity].get_value()
87+
elif (isinstance(item[1], silme.core.Package)):
88+
if (item[0] != 'en-US') and (item[0] != 'locales'):
89+
get_strings(item[1], local_directory + '/' + item[0],
90+
strings_array)
91+
else:
92+
get_strings(item[1], local_directory, strings_array)
93+
94+
95+
def create_directories_list(locale_repo, reference_repo, repository):
96+
''' Create a list of folders to analyze '''
97+
if repository.startswith('gaia') or repository == 'l20n_test':
98+
# Examine the entire folder
99+
dirs = ['']
100+
else:
101+
dirs_locale = os.listdir(locale_repo)
102+
dirs_reference = [
103+
'browser', 'calendar', 'chat', 'devtools', 'dom', 'editor',
104+
'extensions', 'mail', 'mobile', 'netwerk', 'other-licenses',
105+
'security', 'services', 'suite', 'toolkit', 'webapprt'
106+
]
107+
dirs = filter(lambda x: x in dirs_locale, dirs_reference)
108+
109+
return dirs
110+
111+
112+
def create_tmx_content(reference_repo, locale_repo, dirs):
113+
''' Extract strings from repository, return them as a list of PHP array
114+
elements. '''
115+
tmx_content = []
116+
for directory in dirs:
117+
path_reference = os.path.join(reference_repo, directory)
118+
path_locale = os.path.join(locale_repo, directory)
119+
120+
rcsClient = silme.io.Manager.get('file')
121+
try:
122+
l10nPackage_reference = rcsClient.get_package(
123+
path_reference, object_type='entitylist')
124+
except Exception as e:
125+
print 'Silme couldn\'t extract data for', path_reference
126+
print e
127+
continue
128+
129+
if not os.path.isdir(path_locale):
130+
# Folder doesn't exist for this locale, don't log a warning,
131+
# just continue to the next folder.
132+
continue
133+
134+
try:
135+
l10nPackage_locale = rcsClient.get_package(
136+
path_locale, object_type='entitylist')
137+
except Exception as e:
138+
print 'Silme couldn\'t extract data for', path_locale
139+
print e
140+
continue
141+
142+
strings_reference = {}
143+
strings_locale = {}
144+
get_strings(l10nPackage_reference, directory, strings_reference)
145+
get_strings(l10nPackage_locale, directory, strings_locale)
146+
for entity in strings_reference:
147+
# Append string to tmx_content, using the format of a PHP array
148+
# element
149+
translation = escape(
150+
strings_locale.get(entity, '')).encode('utf-8')
151+
tmx_content.append("'{0}' => '{1}'".format(
152+
entity.encode('utf-8'), translation))
153+
tmx_content.sort()
154+
155+
return tmx_content
156+
157+
158+
def write_php_file(filename, tmx_content):
159+
''' Write TMX content as a PHP array on file '''
160+
target_locale_file = open(filename, 'w')
161+
target_locale_file.write('<?php\n$tmx = [\n')
162+
for line in tmx_content:
163+
target_locale_file.write(line + ',\n')
164+
target_locale_file.write('];\n')
165+
target_locale_file.close()
166+
167+
168+
def main():
169+
# Read command line input parameters
170+
parser = argparse.ArgumentParser()
171+
parser.add_argument('locale_repo', help='Path to locale files')
172+
parser.add_argument('reference_repo', help='Path to reference files')
173+
parser.add_argument('locale_code', help='Locale language code')
174+
parser.add_argument('reference_code', help='Reference language code')
175+
parser.add_argument('repository', help='Repository name')
176+
args = parser.parse_args()
177+
178+
dirs = create_directories_list(
179+
args.reference_repo, args.locale_repo, args.repository
180+
)
181+
tmx_content = create_tmx_content(
182+
args.reference_repo, args.locale_repo, dirs
183+
)
184+
185+
# Store the actual file on disk
186+
filename_locale = os.path.join(
187+
os.path.join(storage_path, args.locale_code),
188+
'cache_{0}_{1}.php'.format(args.locale_code, args.repository)
189+
)
190+
write_php_file(filename_locale, tmx_content)
191+
192+
193+
if __name__ == '__main__':
194+
main()

app/scripts/tmxmaker.py

Lines changed: 0 additions & 123 deletions
This file was deleted.

0 commit comments

Comments
 (0)