root/gaphor/tags/gaphor-0.12.5/utils/command/build_pot.py

Revision 1141, 4.9 kB (checked in by arjanmol, 2 years ago)

esetup.py works as good as.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 # vim:sw=4:et
2 """build_pot
3
4 Build a PO template (for i18n) and update the .po files to reflect
5 the last changes.
6 """
7
8 from distutils.core import Command
9 from commands import getstatus
10 import sys, os.path
11 import pygettext
12
13 # from pygettext.main():
14 class Options:
15     # constants
16     GNU = 1
17     SOLARIS = 2
18     # defaults
19     extractall = 0 # FIXME: currently this option has no effect at all.
20     keywords = []
21     writelocations = 1
22     locationstyle = GNU
23     verbose = 0
24     width = 78
25     excludefilename = ''
26     docstrings = 0
27     nodocstrings = {}
28     toexclude = []
29
30
31 class build_pot(Command):
32
33     description="Generate a .po template file (.pot) from python source files"
34
35     user_options = [('msgmerge=', None, 'location of the msgmerge program'),
36                     ('extract-all', 'a', ''),
37                     ('default-domain=', 'd', ''),
38                     ('escape', 'E', ''),
39                     ('docstrings', 'D', ''),
40                     ('keyword=', 'k', 'Comma separated list of keywords'),
41                     ('no-default-keywords', 'K', ''),
42                     ('add-location', 'n', ''),
43                     ('no-location', None, ''),
44                     ('style=', 'S', 'POT file style "gnu" or "solaris"'),
45                     ('output=', 'o', ''),
46                     ('output-dir=', 'p', ''),
47                     ('width=', 'w', ''),
48                     ('exclude-file=', 'x', ''),
49                     ('all-linguas=', None, ''),
50                     #('no-docstrings=', 'X', ''),
51     ]
52
53     boolean_options = [ 'extract-all', 'escape', 'docstrings',
54                         'no-default-keywords', 'add-location',
55                         'no-location', 'no-docstrings' ]
56
57     # constants
58     GNU = 1
59     SOLARIS = 2
60
61     def initialize_options(self):
62         self.podir = 'po'
63         self.msgmerge = 'msgmerge'
64
65         self.options = Options()
66
67         # defaults for variable parsing:
68         self.escape = 0
69         self.width = 78
70         self.extract_all = 0 # doesn't do anything yet
71         self.default_domain = None
72         self.keyword = None
73         self.no_default_keywords = 0
74         self.no_location = 0
75         self.style = None
76         self.output = None
77         self.output_dir = None
78         self.docstrings = 0
79         self.exclude_file = None
80         #self.no_docstrings = None
81         self.all_linguas = []
82
83     def finalize_options(self):
84         options = self.options
85
86         self.name = self.distribution.get_name()
87
88         # Build default options for the TokenEater
89         if self.default_domain:
90             self.output = self.default_domain + '.pot'
91         if self.keyword:
92             options.keywords.extend(self.keyword.split(','))
93         if self.no_default_keywords:
94             options.keywords = [ ]
95         if self.no_location:
96             options.writelocations = 0
97         if self.style:
98             if self.style == 'gnu':
99                 options.locationstyle = self.GNU
100             elif self.style == 'solaris':
101                 options.locationstyle = self.SOLARIS
102             else:
103                 raise SystemExit, 'Invalid value for --style: %s' % self.style
104         if not self.output:
105             self.output = self.distribution.get_name() + '.pot'
106         if not self.output_dir:
107             self.output_dir = self.podir
108         if self.docstrings:
109             options.docstrings = 1
110         options.width = int(self.width)
111         if self.exclude_file:
112             try:
113                 fp = open(self.exclude_file)
114                 options.toexclude = fp.readlines()
115                 fp.close()
116             except IOError:
117                 raise SystemExit, "Can't read --exclude-file: %s" % self.exclude_file
118         # skip: self.no_docstrings
119         if self.all_linguas:
120             self.all_linguas = self.all_linguas.split(',')
121
122         # calculate escapes
123         pygettext.make_escapes(self.escape)
124
125         # calculate all keywords
126         options.keywords.append('_')
127
128         if self.output_dir:
129             self.output = os.path.join(self.output_dir, self.output)
130
131         self.packages = self.distribution.packages
132         #self.all_linguas = self.distribution.get_all_linguas()
133         #self.all_linguas = self.distribution.options['po']['all_linguas']
134
135     def run(self):
136         self.create_pot_file()
137         self.merge_files()
138
139     def create_pot_file(self):
140         """
141         Create a new .pot file. This is basically a rework of the
142         main function of pygettext.
143         """
144         import glob
145         import tokenize
146         source_files = []
147         for p in self.packages:
148             pathlist = p.split('.')
149             path = apply(os.path.join, pathlist)
150             source_files.extend(glob.glob(os.path.join(path, '*.py')))
151
152         # slurp through all the files
153         eater = pygettext.TokenEater(self.options)
154         for filename in source_files:
155             if self.verbose:
156                 print 'Working on %s' % filename
157             fp = open(filename)
158             try:
159                 eater.set_filename(filename)
160                 try:
161                     tokenize.tokenize(fp.readline, eater)
162                 except tokenize.TokenError, e:
163                     print '%s: %s, line %d, column %d' % (
164                         e[0], filename, e[1][0], e[1][1])
165             finally:
166                 fp.close()
167
168         # write the output
169         if self.output == '-':
170             fp = sys.stdout
171         else:
172             fp = open(self.output, 'w')
173         try:
174             eater.write(fp)
175         finally:
176             if fp is not sys.stdout:
177                 fp.close()
178
179     def merge_files(self):
180         if not self.all_linguas:
181             return
182
183         for lingua in self.all_linguas:
184             d = { 'msgmerge': self.msgmerge,
185                   'po': os.path.join(self.output_dir, lingua + '.po'),
186                   'pot': self.output
187             }
188             if self.verbose:
189                 sys.stdout.write('Merging %(pot)s and %(po)s ' % d)
190                 sys.stdout.flush()
191             res = os.system('%(msgmerge)s %(po)s %(pot)s -o %(po)s' % d)
192             if res:
193                 SystemExit, 'error while running msgmerge.'
194
Note: See TracBrowser for help on using the browser.