54fafdce1fc1e2f9d275272cb3827312c4c40c39
2 from os
import system
, makedirs
, remove
, listdir
3 from os
.path
import exists
, isfile
, join
4 from shutil
import move
, copy
6 from polib
import pofile
, POEntry
7 from ya2
.build
.build
import find_file_names
, FindFileNamesInfo
10 class LanguageBuilder
:
11 '''Tools for building files for l10n.'''
13 def __init__(self
, app_name
, po_path
, json_path
, mo_path
):
14 self
.__app
_name
= app_name
15 self
.__po
_path
= po_path
16 self
.__json
_path
= json_path
17 self
.__mo
_path
= mo_path
21 po_files
= [name
for name
in listdir(self
.__po
_path
)
22 if isfile(join(self
.__po
_path
, name
)) and
24 language_codes
= [f
.split('.')[0] for f
in po_files
]
25 for l
in language_codes
: self
.__process
_language
(l
)
27 def __build_pot(self
):
28 '''Builds the pot file in the lng_dir_code directory.'''
29 find_info
= FindFileNamesInfo(['py'], ['tests'])
30 src_files
= ' '.join(find_file_names(find_info
))
31 cmd_tmpl
= 'xgettext -ci18n -d {appname} -L python ' + \
32 '-o {pot_path}{appname}.pot '
33 system(cmd_tmpl
.format(appname
=self
.__app
_name
, pot_path
=self
.__po
_path
) + src_files
)
34 self
.__add
_from
_json
_to
_pot
()
36 def __add_from_json_to_pot(self
):
37 json_files
= [name
for name
in listdir(self
.__json
_path
)
38 if isfile(join(self
.__json
_path
, name
)) and
39 name
.endswith('.json') and
42 for json_file
in json_files
:
43 with
open(f
'{self.__json_path}{json_file}') as f
:
44 json
= loads(f
.read())
45 json_strings
+= [json
['name']]
46 for instruction_line
in json
['instructions'].split('\n'):
48 json_strings
+= [instruction_line
]
49 def process_json_escape(string
):
50 return bytes(string
, 'utf-8').decode('unicode-escape')
51 json_strings
= [process_json_escape(s
) for s
in json_strings
]
52 json_strings
= list(set(json_strings
))
53 pot
= pofile(f
'{self.__po_path}{self.__app_name}.pot')
54 pot_ids
= [entry
.msgid
for entry
in pot
]
55 for json_string
in json_strings
:
56 if json_string
not in pot_ids
:
57 entry
= POEntry(msgid
=json_string
)
59 pot
.save(f
'{self.__po_path}{self.__app_name}.pot')
61 def __process_language(self
, language_code
):
62 self
.__merge
(language_code
)
63 self
.__build
_mo
(language_code
)
65 def __build_mo(self
, language_code
):
66 '''Builds the mo file in the lng_dir_code directory.'''
67 mo_template
= '%s%s/LC_MESSAGES/%s.mo'
68 mo_name
= mo_template
% (self
.__mo
_path
, language_code
, self
.__app
_name
)
69 lng_code
= mo_name
[len(self
.__mo
_path
):].split('/')[0]
70 lng_dir
= self
.__mo
_path
+ lng_code
+ '/LC_MESSAGES/'
71 cmd
= 'msgfmt -o {lng_dir}{appname}.mo assets/locale/po/{lng_code}.po'
72 system(cmd
.format(lng_dir
=lng_dir
, appname
=self
.__app
_name
, lng_code
=lng_code
))
74 def __merge(self
, lng_code
):
75 '''Merges the new strings with the previous ones.'''
76 lng_base_dir
= self
.__prepare
(lng_code
)
77 self
.__do
_merge
(lng_base_dir
, lng_code
)
78 self
.__postprocess
(lng_code
)
80 def __prepare(self
, lng_code
):
81 '''Prepares a directory for working with languages.'''
82 makedirs(self
.__mo
_path
+ lng_code
+ '/LC_MESSAGES', exist_ok
=True)
83 lng_dir
= self
.__mo
_path
+ lng_code
+ '/LC_MESSAGES/'
84 if not exists('assets/locale/po/' + lng_code
+ '.po'):
85 lines_to_fix
= ['CHARSET/UTF-8', 'ENCODING/8bit']
86 [self
.__fix
_line
(line
, lng_dir
)
87 for line
in lines_to_fix
]
88 copy(lng_dir
+ self
.__app
_name
+ '.pot', lng_dir
+ self
.__app
_name
+ '.po')
91 def __fix_line(self
, line
, lng_dir
):
92 '''Fixes po files (misaligned entries).'''
93 cmd_tmpl
= "sed 's/{line}/' {lng_dir}{appname}.pot > " + \
94 "{lng_dir}{appname}tmp.po"
95 system(cmd_tmpl
.format(line
=line
, lng_dir
=lng_dir
, appname
=self
.__app
_name
))
96 move(lng_dir
+ self
.__app
_name
+ 'tmp.po', lng_dir
+ self
.__app
_name
+ '.pot')
98 def __do_merge(self
, lng_dir
, lng_code
):
99 '''Manages the msgmerge's invokation.'''
100 print('merge', lng_dir
)
101 cmd
= 'msgmerge -o {lng_dir}{appname}merge.po ' + \
102 '{tgt_path}{lng_code}.po {tgt_path}{appname}.pot'
103 cmd
= cmd
.format(lng_dir
=lng_dir
, lng_code
=lng_code
, appname
=self
.__app
_name
,
104 tgt_path
=self
.__po
_path
)
106 copy(lng_dir
+ self
.__app
_name
+ 'merge.po',
107 'assets/locale/po/%s.po' % lng_code
)
108 poname_tmpl
= '{lng_dir}{appname}merge.po'
109 remove(poname_tmpl
.format(lng_dir
=lng_dir
, appname
=self
.__app
_name
))
111 def __postprocess(self
, lng_code
):
112 '''Fixes po files at the end of the building process.'''
113 lines
= open('assets/locale/po/%s.po' % lng_code
, 'r').readlines()
114 with
open('assets/locale/po/%s.po' % lng_code
, 'w') as outf
:
116 po_str
= '"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n"\n'
117 outf
.write(po_str
if line
.startswith(po_str
[:20]) else line
)