File: translate.py

package info (click to toggle)
python-babelgladeextractor 0.7.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 156 kB
  • sloc: python: 248; xml: 101; makefile: 7
file content (107 lines) | stat: -rw-r--r-- 4,303 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import codecs
import logging

import os
import xml.etree.ElementTree as etree

from babel.messages.pofile import read_po

log = logging.getLogger(__name__)


def translate_desktop_file(infile, outfile, localedir):
    infp = codecs.open(infile, 'rb', encoding='utf-8')
    outfp = codecs.open(outfile, 'wb', encoding='utf-8')

    catalogs = get_catalogs(localedir)

    for line in (x.strip() for x in infp):
        log.debug('Found in original (%s): %r', type(line), line)
        # We intend to ignore the first line
        if line.startswith('[Desktop'):
            additional_lines = []
        else:
            additional_lines = []
            # This is a rather primitive approach to generating the translated
            # desktop file.  For example we don't really care about all the
            # keys in the file.  But its simplicity is a feature and we
            # ignore the runtime overhead, because it should only run centrally
            # once.
            key, value = line.split('=', 1)
            log.debug("Found key: %r", key)
            for locale, catalog in catalogs.items():
                translated = catalog.get(value)
                log.debug("Translated %r[%r]=%r: %r (%r)",
                          key, locale, value, translated,
                          translated.string if translated else '')
                if translated and translated.string \
                              and translated.string != value:
                    additional_line = u'{keyword}[{locale}]={translated}'.format(
                                        keyword=key,
                                        locale=locale,
                                        translated=translated.string,
                                    )
                    additional_lines.append(additional_line)
                log.debug("Writing more lines: %s", additional_lines)

        # Write the new file.
        # First the original line found it in the file, then the translations.
        outfp.writelines((outline+'\n' for outline in ([line] + additional_lines)))

    infp.close()
    outfp.close()


def translate_appdata_file(infile, outfile, localedir):
    catalogs = get_catalogs(localedir)
    tree = etree.parse(infile)
    root = tree.getroot()
    add_translations(root, catalogs)
    tree.write(outfile, encoding='utf-8', xml_declaration=True)


def add_translations(parent, catalogs):
    tail = parent.text
    last_tail = None
    for pos, elem in enumerate(parent, start=1):
        if elem.get("translatable") == "yes":
            elem.attrib.pop("translatable", None)
            elem.attrib.pop("comments", None)  # Are comments allowed?
            last_tail = elem.tail
            elem.tail = tail
            message = elem.text
            for locale, catalog in catalogs.items():
                translated = catalog.get(message)
                if translated and translated.string \
                        and translated.string != message:
                    log.debug("Translated [%s]%r: %r (%r)",
                              locale, message, translated, translated.string)
                    tr = etree.Element(elem.tag)
                    attrib = tr.attrib
                    attrib["{http://www.w3.org/XML/1998/namespace}lang"] = str(locale)
                    tr.text = translated.string
                    tr.tail = tail
                    parent.insert(pos, tr)
        else:
            add_translations(elem, catalogs)
    if last_tail:
        parent[-1].tail = last_tail

def get_catalogs(localedir):
    # glob in Python 3.5 takes ** syntax
    # pofiles = glob.glob(os.path.join(localedir, '**.po', recursive=True))
    pofiles = sorted([os.path.join(dirpath, f)
               for dirpath, dirnames, files in os.walk(localedir)
               for f in files if f.endswith('.po')])
    logging.debug('Loading %r', pofiles)
    catalogs = {}

    for pofile in pofiles:
        with open(pofile, 'r') as f:
            catalog = read_po(f)
        catalogs[catalog.locale] = catalog
        logging.info("Found %d strings for %s", len(catalog), catalog.locale)
        # logging.debug("Strings for %r", catalog, catalog.values())
    if not catalogs:
        logging.warning("Could not find pofiles in %r", pofiles)
    return catalogs