2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
35 logger
= cmk
.log
.get_logger(__name__
)
37 # TODO: Inherit from MKGeneralException?
38 class LocalizeException(Exception):
39 def __init__(self
, reason
):
41 super(LocalizeException
, self
).__init
__(reason
)
52 locale_base
= cmk
.paths
.local_locale_dir
54 if os
.path
.exists(cmk
.paths
.local_locale_dir
+ '/multisite.pot'):
55 pot_file
= cmk
.paths
.local_locale_dir
+ '/multisite.pot'
57 pot_file
= locale_base
+ '/multisite.pot'
60 os
.makedirs(locale_base
)
64 def localize_usage(err
= ''):
65 sys
.stdout
.write("""Usage: check_mk [-v] --localize COMMAND [ARGS]
67 Available commands are:
68 update LANG [ALIAS] ... Creates or updates a .po file for the given
69 language. The alias is an optional attribute
70 which will be used as display string in the
72 compile LANG ... Compiles the .po file into a .mo file which can
74 edit LANG ... Call update, open .po in editor and compile in one step
76 The regular process for translating is:
78 1.) Create/update the .po file for the given language
80 3.) Compile the .po file to get a .mo file which can be used by gettext
82 Locale files are located in: %s
85 def do_localize(args
):
101 "update" : localize_update
,
102 "compile" : localize_compile
,
103 "edit" : localize_edit
,
105 f
= commands
.get(command
)
112 except LocalizeException
, e
:
113 logger
.error("%s" % e
)
116 allc
= commands
.keys()
118 allc
= [ tty
.bold
+ c
+ tty
.normal
for c
in allc
]
119 logger
.error("Invalid localize command. Allowed are: %s and %s.",
120 ", ".join(allc
[:-1]), allc
[-1])
123 def write_alias(alias
):
128 os
.remove(alias_file
)
130 file(alias_file
, 'w').write(alias
)
132 def check_binaries():
133 # Are the xgettext utils available?
134 for b
in [ 'xgettext', 'msgmerge', 'msgfmt' ]:
135 if subprocess
.call(['which', b
], stdout
=open(os
.devnull
, "wb")) != 0:
136 raise LocalizeException('%s binary not found in PATH\n' % b
)
140 return [ l
for l
in os
.listdir(locale_base
) if os
.path
.isdir(locale_base
+ '/' + l
) ]
143 def init_files(lang
):
144 global po_file
, mo_file
, alias_file
145 po_file
= locale_base
+ '/%s/LC_MESSAGES/%s.po' % (lang
, domain
)
146 mo_file
= locale_base
+ '/%s/LC_MESSAGES/%s.mo' % (lang
, domain
)
147 alias_file
= locale_base
+ '/%s/alias' % (lang
)
150 def localize_update_po():
151 # Merge the current .pot file with a given .po file
152 logger
.verbose("Merging translations...")
153 if subprocess
.call(['msgmerge', '-U', po_file
, pot_file
], stdout
=open(os
.devnull
, "wb")) != 0:
154 logger
.error('Failed!')
156 logger
.info('Success! Output: %s', po_file
)
159 def localize_init_po(lang
):
160 if subprocess
.call(['msginit', '-i', pot_file
, '--no-translator', '-l', lang
,
161 '-o', po_file
], stdout
=open(os
.devnull
, "wb")) != 0:
162 logger
.error('Failed!\n')
165 # Dig into the source code and generate a new .pot file
166 def localize_sniff():
167 logger
.info('Sniffing source code...')
169 paths
= [ cmk
.paths
.default_config_dir
, cmk
.paths
.web_dir
]
170 if os
.path
.exists(cmk
.paths
.local_web_dir
):
171 paths
.append(cmk
.paths
.local_web_dir
)
175 for root
, _dirs
, files
in os
.walk(path
):
177 if f
.endswith(".py") or f
.endswith(".mk"):
178 sniff_files
.append(os
.path
.join(root
, f
))
180 if subprocess
.call(['xgettext', '--no-wrap', '--sort-output', '--force-po',
181 '-L', 'Python', '--from-code=utf-8', '--omit-header',
182 '-o', pot_file
] + sniff_files
,
183 stdout
=open(os
.devnull
, "wb")) != 0:
184 logger
.error('Failed!\n')
186 header
= r
'''# +------------------------------------------------------------------+
187 # | ____ _ _ __ __ _ __ |
188 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
189 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
190 # | | |___| | | | __/ (__| < | | | | . \ |
191 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
193 # | Copyright Mathias Kettner 2010 mk@mathias-kettner.de |
194 # +------------------------------------------------------------------+
196 # This file is part of Check_MK.
197 # The official homepage is at http://mathias-kettner.de/check_mk.
199 # check_mk is free software; you can redistribute it and/or modify it
200 # under the terms of the GNU General Public License as published by
201 # the Free Software Foundation in version 2. check_mk is distributed
202 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
203 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
204 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
205 # tails. You should have received a copy of the GNU General Public
206 # License along with GNU Make; see the file COPYING. If not, write
207 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
208 # Boston, MA 02110-1301 USA.
211 "Project-Id-Version: Check_MK Multisite translation 0.1\n"
212 "Report-Msgid-Bugs-To: checkmk-en@lists.mathias-kettner.de\n"
213 "POT-Creation-Date: 2011-05-13 09:42+0200\n"
214 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
215 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
216 "Language-Team: LANGUAGE <LL@li.org>\n"
217 "Language: LANGUAGE \n"
218 "MIME-Version: 1.0\n"
219 "Content-Type: text/plain; charset=utf-8\n"
220 "Content-Transfer-Encoding: 8bit\n"
224 f
= open(pot_file
).read()
225 open(pot_file
, 'w').write(header
+ f
)
226 logger
.info('Success! Output: %s', pot_file
)
229 def localize_edit(lang
):
230 localize_update(lang
)
232 editor
= os
.getenv("VISUAL", os
.getenv("EDITOR", "/usr/bin/vi"))
233 if not os
.path
.exists(editor
):
236 if subprocess
.call([editor
, po_file
]) == 0:
237 localize_compile(lang
)
239 logger
.error("Aborted.")
242 # Start translating in a new language
243 def localize_update(lang
):
245 raise LocalizeException('No language given')
250 os
.makedirs(os
.path
.dirname(po_file
))
254 # Maybe initialize the file in the local hierarchy with the file in
255 # the default hierarchy
256 if not os
.path
.exists(po_file
) \
257 and os
.path
.exists(cmk
.paths
.locale_dir
+ '/%s/LC_MESSAGES/%s.po' % (lang
, domain
)):
258 file(po_file
, 'w').write(file(cmk
.paths
.locale_dir
+ '/%s/LC_MESSAGES/%s.po' % (lang
, domain
)).read())
259 logger
.info('Initialize %s with the file in the default hierarchy', po_file
)
263 if not os
.path
.exists(po_file
):
264 logger
.info('Initializing .po file for language %s...', lang
)
265 localize_init_po(lang
)
267 logger
.info('Updating .po file for language %s...', lang
)
270 # Create a .mo file from the given .po file
271 def localize_compile(lang
):
273 raise LocalizeException('No language given')
274 if lang
not in get_languages():
275 raise LocalizeException('Invalid language given. Available: %s' % ' '.join(get_languages()))
279 # Maybe initialize the file in the local hierarchy with the file in
280 # the default hierarchy
281 if not os
.path
.exists(po_file
) \
282 and os
.path
.exists(cmk
.paths
.locale_dir
+ '/%s/LC_MESSAGES/%s.po' % (lang
, domain
)):
283 file(po_file
, 'w').write(file(cmk
.paths
.locale_dir
+ '/%s/LC_MESSAGES/%s.po' % (lang
, domain
)).read())
284 logger
.info('Initialize %s with the file in the default hierarchy', po_file
)
286 if not os
.path
.exists(po_file
):
287 raise LocalizeException('The .po file %s does not exist.' % po_file
)
289 if subprocess
.call(['msgfmt', po_file
, '-o', mo_file
]) != 0:
290 logger
.error('Failed!')
292 logger
.info('Success! Output: %s', mo_file
)