~ubuntu-branches/ubuntu/intrepid/prewikka/intrepid

1 by Pierre Chifflier
Import upstream version 0.9.10
1
#!/usr/bin/env python
2
# Copyright (C) 2004,2005 by SICEm S.L.
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU Lesser General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU Lesser General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18
19
"""
20
This script makes easy all the boring steps to use gettext with a python
21
application.
22
23
For localization you need to:
24
25
  1 Mark the strings in the source code as translatable
26
  2 Use xgettext to get a pot file from it
27
  3 Use a copy of this pot file for every language you want to have
28
  translations
29
  4 Translate these po files
30
  5 Use msgmerge every time you change the source code and the strings you
31
  need to translate change
32
  6 Generate the mo binary files for every po file you have
33
34
To use this script you need to:
35
36
  - have a directory where you put the po files: the PO_DIR
37
  - have a directory where you put the mo files: the LANG_DIR
38
  - choose a name for the pot file: the POT_FILE
39
  - choose a name for the mo files: the MO_FILE
40
41
Note that you have only one POT_FILE but you have one po file in the PO_DIR for
42
every language you have translations. Then you have a MO_FILE for every po file
43
and they are stored in LANG_DIR/lang/LC_MESSAGES/ where lang is the language
44
this MO_FILE belongs to.
45
"""
46
47
from distutils.dep_util import newer
48
from glob import glob
49
import os
50
from os.path import join, splitext, basename, exists, isdir
51
from optparse import OptionParser
52
import sys
53
from shutil import copyfile
54
55
class LangAdmin:
56
57
    def __init__(self, po_dir, pot_file, mo_file, lang_dir):
58
        # where to put the po files (one for each language)
59
        self.po_dir = po_dir
60
61
        # name of the pot (po template) file (it is stored in the cwd)        
62
        self.pot_file = pot_file
63
        
64
        # name of the mo file (one for each directory)
65
        self.mo_file = mo_file
66
        
67
        # name of the directory where the mo files are stored
68
        self.lang_dir = lang_dir
69
        
70
    def get_languages(self):
71
        """Gives a list of all the languages that have translation"""
72
        languages = []
73
        for lang in glob(join(self.po_dir, '*.po')):
74
            languages.append(splitext(basename(lang))[0])
75
76
        return languages
77
78
    def _list_files(self, directory, recurse=True, ext="py"):
79
        files = glob(join(directory, "*." + ext))
80
        if recurse:
81
            dirs = [join(directory, filename) for filename \
82
                    in os.listdir(directory)
83
                    if isdir(join(directory, filename))]
84
            for d in dirs:
85
                files += self._list_files(d, recurse, ext)
86
        return files
87
88
    def generate_pot_file(self, recurse=True, directories=[]):
89
        """Get all the python files in the directories parameter and create
90
        a pot file using xgettext. If the recurse parameter is True it search
91
        for more .py files in the subdirectories of the directories list
92
        """
93
        files = []
94
        for dirname in directories:
95
            files += self._list_files(dirname, recurse)
96
97
        cmd = 'xgettext -k_ -kN_ -o %s %s' % (self.pot_file, ' '.join(files))
98
        print cmd
99
        os.system(cmd)
100
101
    def add_language(self, lang):
102
        """Create another language by copying the self.pot_file into the
103
        self.po_dir using the lang parameter for its name. You need to fill at
104
        least the charset property of the prolog of this new file if you don't
105
        want the other commands to fail
106
        """
107
        if not exists(self.pot_file):
108
            print 'ERROR: You need to generate the pot file before adding '\
109
                  'any language.\n' \
110
                  'Use the command pot for that'
111
            sys.exit(1)
112
        copyfile(self.pot_file, join(self.po_dir, lang+'.po'))
113
        print 'Please fill the prolog information of the file', \
114
              join(self.po_dir, lang+'.po')
115
116
    def merge_translations(self):
117
        """Merge the new self.pot_file with the existing po files in the
118
        self.po_dir directory using the command msgmerge
119
        """
120
        for lang_file in glob(join(self.po_dir, '*.po')):
121
            cmd = 'msgmerge -U %s %s' % (lang_file, self.pot_file)
122
            print cmd
123
            os.system(cmd)
124
125
    def generate_mo_files(self, verbose=True):
126
        """For every po file in the self.po_dir directory generates a
127
        self.mo_file using msgfmt. It guess the language name from the po file
128
        and creates the directories needed under self.lang_dir to put the final
129
        self.mo_file in the right place
130
        """
131
        if not exists(self.lang_dir):
132
            os.mkdir(self.lang_dir)
133
        
134
        for lang in self.get_languages():
135
            src = join(self.po_dir, lang+'.po')
136
            dst = join(self.lang_dir, lang, 'LC_MESSAGES', self.mo_file)
137
            if not exists(join(self.lang_dir, lang, 'LC_MESSAGES')):
138
                if not exists(join(self.lang_dir, lang)):
139
                    os.mkdir(join(self.lang_dir, lang))
140
                os.mkdir(join(self.lang_dir, lang, 'LC_MESSAGES'))
141
       		
142
	    # Skip files which are not modified
143
            if not newer(src, dst):
144
                continue
145
            cmd = 'msgfmt -o %s %s' % (dst, src)
146
            if verbose:
147
                print 'running', cmd
148
            os.system(cmd)
149
150
if __name__ == '__main__':
151
    usage = """usage: %prog [options] command
152
    
153
    where command can be one of:
154
155
       list       List all the languages supported
156
       add LANG   Add the language LANG
157
       pot DIRS   Get the translatable strings for every file in DIRS that
158
                  is a .py file and creates the .pot file from them
159
       merge      Merge all the languages files with the POT file
160
       mo         Create a .mo file for every .po file and put it in the right
161
                  place"""
162
    
163
    parser = OptionParser(usage)
164
    parser.add_option('--po-dir',
165
                      action='store',
166
                      dest='po_dir',
167
                      default='po',
168
                      help='directory to store the po files')
169
    parser.add_option('--pot-file',
170
                      action='store',
171
                      dest='pot_file',
172
                      default='prewikka.pot',
173
                      help='name of the pot (po template) file. It is stored in the cwd')
174
    parser.add_option('--mo-file',
175
                      action='store',
176
                      dest='mo_file',
177
                      default='prewikka.mo',
178
                      help='name of the mo file')
179
    parser.add_option('--lang-dir',
180
                      action='store',
181
                      dest='lang_dir',
182
                      default='locale',
183
                      help='directory to store the mo files')
184
185
    options, args = parser.parse_args()
186
187
    if len(args) == 0:
188
        parser.print_help()
189
        print '\nERROR: You should provide one command'
190
        sys.exit(1)
191
192
    langadmin = LangAdmin(options.po_dir, options.pot_file, options.mo_file,
193
                          options.lang_dir)
194
    
195
    command = args.pop(0)
196
    if command == 'list':
197
        langs = langadmin.get_languages()
198
        print ' '.join(langs)
199
200
    elif command == 'pot':
201
        if len(args) == 0:
202
            parser.print_help()
203
            print '\nERROR: The pot command needs at least one directory to '\
204
            'look for .py files with translatable strings'
205
            sys.exit(1)
206
        langadmin.generate_pot_file(True, args)
207
208
    elif command == 'add':
209
        if len(args) != 1:
210
            parser.print_help()
211
            print '\nERROR: You need to specify one and only one language '\
212
                  'to add'
213
            sys.exit(1)
214
        langadmin.add_language(args[0])
215
216
    elif command == 'merge':
217
        langadmin.merge_translations()
218
219
    elif command == 'mo':
220
        langadmin.generate_mo_files()
221
222
    else:
223
        parser.print_help()
224
        print '\nERROR: Unknown command'
225
        sys.exit(1)