Source

zine-main / scripts / compile-translations

Full commit
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    Compile translations
    ~~~~~~~~~~~~~~~~~~~~

    Compile translations into (almost) standard MO files and append pickled
    translations for client-side usage by javascript code.

    :copyright: (c) 2010 by the Zine Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""
import pickle
import struct
from os import listdir, path
from optparse import OptionParser
from babel.messages.pofile import read_po
from babel.messages.mofile import write_mo

domains = ['messages']


def is_untranslated(obj):
    if not obj:
        return True
    elif isinstance(obj, basestring):
        return not obj.strip()
    for translation in obj:
        if translation.strip():
            return False
    return True


def main():
    parser = OptionParser(usage='%prog [path]')
    parser.add_option('--statistics', '-s', default=False,
                      action='store_true', help="show statistics")
    options, args = parser.parse_args()
    if not args:
        print 'Compiling builtin languages'
        root = path.abspath(path.join(path.dirname(__file__),
                                      path.pardir, 'zine', 'i18n'))
    elif len(args) == 1:
        root = path.join(path.abspath(args[0]), 'i18n')
        if not path.isdir(root):
            parser.error('i18n folder missing')
        print 'Compiling', root
    else:
        parser.error('incorrect number of arguments')

    for domain in domains:
        for lang in listdir(root):
            folder = path.join(root, lang)
            translations = path.join(folder, domain + '.po')

            if path.isfile(translations):
                mo_file = open(translations.replace('.po', '.mo'), 'wb')
                print 'Compiling %r' % lang,
                f = file(translations)
                try:
                    catalog = read_po(f, locale=lang)
                finally:
                    f.close()
                # Write standard catalog
                write_mo(mo_file, catalog)

                # Find current file pointer position
                pickled_data_pointer_pos = mo_file.tell()

                # Gather client messages
                client_messages = set()
                if options.statistics:
                    translated = fuzzy = percentage = 0
                for message in catalog:
                    if options.statistics:
                        if message.string:
                            translated +=1
                        if 'fuzzy' in message.flags:
                            fuzzy += 1
                    for fname, _ in message.locations:
                        if fname.endswith('.js'):
                            client_messages.add(message)
                            break
                if options.statistics and len(catalog):
                    percentage = translated * 100 // len(catalog)
                    print "-> %d of %d messages (%d%%) translated" % (
                        translated, len(catalog), percentage),
                    if fuzzy:
                        if fuzzy == 1:
                            print "%d of which is fuzzy" % fuzzy,
                        else:
                            print "%d of which are fuzzy" % fuzzy,
                    print
                else:
                    print

                # Dump pickled data at the end of the standard catalog
                pickle.dump(client_messages, mo_file, 2)
                # Write offset of the start of the pickled data
                mo_file.write(struct.pack('i', pickled_data_pointer_pos))
                mo_file.close()
    print 'All done.'


if __name__ == '__main__':
    main()