Last active
December 21, 2015 04:39
-
-
Save yoloseem/6251469 to your computer and use it in GitHub Desktop.
PO-to-JSON Distutils/Setuptools Command Integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" :mod:`po2json` | |
~~~~~~~~~~~~~~ | |
Convert PO files to JSON-serialized files. | |
By Hyunjun Kim <[email protected]> for StyleShare. | |
Skeleton source code from `babel.messages.frontend.compile_catalog` that does compiling PO to MO files. | |
""" | |
try: | |
import omnijson as json | |
except ImportError: | |
import json | |
import os | |
from babel.messages.pofile import read_po | |
from distutils import log | |
from distutils.cmd import Command | |
from distutils.errors import DistutilsOptionError | |
class po2json(Command): | |
"""Catalog to-json conversion command for use in ``setup.py`` scripts. """ | |
description = 'convert message catalogs to JSON-serialized format files' | |
user_options = [ | |
('domain=', 'D', | |
"domain of PO file (default 'messages')"), | |
('input-dir=', None, | |
'path to base directory containing the catalogs'), | |
('input-file=', 'i', | |
'name of the input file'), | |
('output-dir=', None, | |
'path to base directory for creating output files'), | |
('output-file=', 'o', | |
"name of the output file (default " | |
"'<output_dir>/<locale>/LC_MESSAGES/<domain>.json')"), | |
('locale=', 'l', | |
'locale of the catalog to compile'), | |
('statistics', None, | |
'print statistics about translations') | |
] | |
boolean_options = ['statistics'] | |
def initialize_options(self): | |
self.domain = 'messages' | |
self.input_dir = None | |
self.input_file = None | |
self.output_dir = None | |
self.output_file = None | |
self.locale = None | |
self.statistics = False | |
def finalize_options(self): | |
if not self.input_file and not self.input_dir: | |
raise DistutilsOptionError('you must specify either the input file ' | |
'or the base directory') | |
if not self.output_file and not self.output_dir: | |
raise DistutilsOptionError('you must specify either the output file ' | |
'or the base directory') | |
def run(self): | |
po_files = [] | |
json_files = [] | |
if not self.input_file: | |
if self.locale: | |
po_files.append((self.locale, | |
os.path.join(self.input_dir, 'LC_MESSAGES', | |
self.domain + '.po'))) | |
json_files.append((self.locale, | |
os.path.join(self.output_dir, | |
self.locale, | |
'LC_MESSAGES', | |
self.domain + '.json'))) | |
else: | |
for locale in os.listdir(self.input_dir): | |
po_file = os.path.join(self.input_dir, locale, | |
'LC_MESSAGES', | |
self.domain + '.po') | |
if os.path.exists(po_file): | |
po_files.append((locale, po_file)) | |
json_files.append(os.path.join(self.output_dir, | |
locale, | |
'LC_MESSAGES', | |
self.domain + '.json')) | |
else: | |
po_files.append((self.locale, self.input_file)) | |
if self.output_file: | |
json_files.append(self.output_file) | |
else: | |
json_files.append(os.path.join(self.output_dir, | |
self.locale, | |
'LC_MESSAGES', | |
self.domain + '.json')) | |
if not po_files: | |
raise DistutilsOptionError('no message catalogs found') | |
for idx, (locale, po_file) in enumerate(po_files): | |
json_file = json_files[idx] | |
with open(po_file, 'r') as infile: | |
catalog = read_po(infile, locale) | |
if self.statistics: | |
translated = 0 | |
for message in list(catalog)[1:]: | |
if message.string: | |
translated += 1 | |
percentage = 0 | |
if len(catalog): | |
percentage = translated * 100 // len(catalog) | |
log.info("%d of %d messages (%d%%) translated in %r", | |
translated, len(catalog), percentage, po_file) | |
for message, errors in catalog.check(): | |
for error in errors: | |
log.error('error: %s:%d: %s', po_file, message.lineno, | |
error) | |
log.info('compiling catalog %r to %r', po_file, json_file) | |
messages = {} | |
for message in catalog: | |
msgid = message.id | |
if isinstance(msgid, (list, tuple)): | |
msgid = msgid[0] | |
messages[msgid] = message.string | |
json_compiled = json.dumps({ | |
'messages': messages, | |
'plural_expr': catalog.plural_expr, | |
'locale': str(locale), | |
'domain': self.domain, | |
}) | |
if not os.path.exists(os.path.dirname(json_file)): | |
os.makedirs(os.path.dirname(json_file)) | |
with open(json_file, 'wb') as outfile: | |
outfile.write(json_compiled) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment