summaryrefslogtreecommitdiffstats
path: root/gen_web_gettext.py
blob: 80186e9381316acc82a2807c2aa69239d8a02d61 (plain)
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
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env python
#
# Copyright (C) 2009-2012 Damien Churchill <damoxc@gmail.com>
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#

"""Script to parse javascript files for translation strings and generate gettext.js"""

import os
import re

WEBUI_JS_DIR = 'deluge/ui/web/js/deluge-all'
# Enabling Debug adds file and line number as comments to the gettext file.
DEBUG = False


def check_missing_markup(js_dir):
    """Search js to check for missed translation markup."""

    # A list of common extjs attributes that are usually marked for translation.
    attr_list = [
        "text: '",
        "msg: '",
        "title: '",
        "fieldLabel: '",
        "boxLabel: '",
        "tooltip: '",
        "header: '",
        "defaultText: '",
        "unit: '",
        r"setText\('",
        r"addButton\('",
    ]

    # Don't match against any of these chars at start of string value.
    except_chars = "' &#"

    # A list of strings that should be skipped shuold the match contain them.
    skip = ['HTTP:']

    # Create a list of the matching strings to search for with the except_chars appended to each one.
    string_re = re.compile(
        '('
        + ')|('.join(['%s[^' + except_chars + "].*'"] * len(attr_list))
        % tuple(attr_list)
        + ')'
    )

    strings = {}
    for root, dnames, files in os.walk(js_dir):
        for filename in files:
            if os.path.splitext(filename)[1] != '.js':
                continue
            for lineno, line in enumerate(open(os.path.join(root, filename))):
                for match in string_re.finditer(line):
                    for string in match.groups():
                        # Ignore string that contains only digits or specificied strings in skip.
                        if (
                            not string
                            or string.split('\'')[1].isdigit()
                            or any(x in string for x in skip)
                        ):
                            continue
                        locations = strings.get(string, [])
                        locations.append(
                            (os.path.join(root, filename), str(lineno + 1))
                        )
                        strings[string] = locations
    return strings


GETTEXT_TPL = (
    'GetText={maps:{},'
    'add:function(string,translation){this.maps[string]=translation},'
    'get:function(string){if (this.maps[string]){string=this.maps[string]} return string}};'
    'function _(string){return GetText.get(string)}'
)
GETTEXT_SUBST_TPL = "GetText.add('{key}','${{escape(_(\"{key}\"))}}')\n"


def create_gettext_js(js_dir):
    string_re = re.compile('_\\(\'(.*?)\'\\)')
    strings = {}
    for root, dnames, files in os.walk(js_dir):
        for filename in files:
            if filename.endswith('.js'):
                filepath = os.path.join(root, filename)
                with open(os.path.join(root, filename)) as _file:
                    for lineno, line in enumerate(_file, 1):
                        for match in string_re.finditer(line):
                            string = match.group(1)
                            locations = strings.get(string, [])
                            locations.append((filepath, lineno))
                            strings[string] = locations

    gettext_file = os.path.join(os.path.dirname(js_dir), 'gettext.js')
    with open(gettext_file, 'w') as fp:
        fp.write(GETTEXT_TPL)
        for key in sorted(strings):
            if DEBUG:
                fp.write(
                    '\n//: %s' % '//: '.join(['%s:%s\n' % x for x in strings[key]])
                )
            fp.write(GETTEXT_SUBST_TPL.format(key=key))
    return gettext_file


if __name__ == '__main__':
    gettext_fname = create_gettext_js(WEBUI_JS_DIR)
    print('Created: %s' % gettext_fname)
    missed_markup = check_missing_markup(WEBUI_JS_DIR)
    if missed_markup:
        print('Possible missed text for translation markup:')
        for text, filenames in missed_markup.iteritems():
            for filename_lineno in filenames:
                print('{:<58}    {}'.format(':'.join(filename_lineno), text))