root/gaphor/tags/gaphor-0.2.0/utils/build_pot.py

Revision 190, 4.7 kB (checked in by arjanmol, 6 years ago)

*** empty log message ***

  • 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="This a distutils command for generating a .pot file 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                     #('no-docstrings=', 'X', ''),
50     ]
51
52     boolean_options = [ 'extract-all', 'escape', 'docstrings',
53                         'no-default-keywords', 'add-location',
54                         'no-location', 'no-docstrings' ]
55
56     # constants
57     GNU = 1
58     SOLARIS = 2
59
60     def initialize_options(self):
61         self.podir = 'po'
62         self.msgmerge = 'msgmerge'
63
64         self.options = Options()
65
66         # defaults for variable parsing:
67         self.escape = 0
68         self.width = 78
69         self.extract_all = 0 # doesn't do anything yet
70         self.default_domain = None
71         self.keyword = None
72         self.no_default_keywords = 0
73         self.no_location = 0
74         self.style = None
75         self.output = None
76         self.output_dir = None
77         self.docstrings = 0
78         self.exclude_file = None
79         #self.no_docstrings = None
80
81     def finalize_options(self):
82         options = self.options
83
84         self.name = self.distribution.get_name()
85
86         # Build default options for the TokenEater
87         if self.default_domain:
88             self.output = self.default_domain + '.pot'
89         if self.keyword:
90             options.keywords.extend(self.keyword.split(','))
91         if self.no_default_keywords:
92             options.keywords = [ ]
93         if self.no_location:
94             options.writelocations = 0
95         if self.style:
96             if self.style == 'gnu':
97                 options.locationstyle = self.GNU
98             elif self.style == 'solaris':
99                 options.locationstyle = self.SOLARIS
100             else:
101                 raise SystemExit, 'Invalid value for --style: %s' % self.style
102         if not self.output:
103             self.output = self.distribution.get_name() + '.pot'
104         if not self.output_dir:
105             self.output_dir = self.podir
106         if self.docstrings:
107             options.docstrings = 1
108         options.width = int(self.width)
109         if self.exclude_file:
110             try:
111                 fp = open(options.exclude_file)
112                 options.toexclude = fp.readlines()
113                 fp.close()
114             except IOError:
115                 raise SystemExit, "Can't read --exclude-file: %s" % self.exclude_file
116         # skip: self.no_docstrings
117
118         # calculate escapes
119         pygettext.make_escapes(self.escape)
120
121         # calculate all keywords
122         options.keywords.append('_')
123
124         if self.output_dir:
125             self.output = os.path.join(self.output_dir, self.output)
126
127         self.packages = self.distribution.packages
128         self.all_linguas = self.distribution.get_all_linguas()
129
130     def run(self):
131         self.create_pot_file()
132         self.merge_files()
133
134     def create_pot_file(self):
135         """Create a new .pot file. This is basically a rework of the
136         main function of pygettext."""
137         import glob
138         import tokenize
139         source_files = []
140         for p in self.packages:
141             pathlist = p.split('.')
142             path = apply(os.path.join, pathlist)
143             source_files.extend(glob.glob(os.path.join(path, '*.py')))
144
145         # slurp through all the files
146         eater = pygettext.TokenEater(self.options)
147         for filename in source_files:
148             if self.verbose:
149                 print 'Working on %s' % filename
150             fp = open(filename)
151             try:
152                 eater.set_filename(filename)
153                 try:
154                     tokenize.tokenize(fp.readline, eater)
155                 except tokenize.TokenError, e:
156                     print '%s: %s, line %d, column %d' % (
157                         e[0], filename, e[1][0], e[1][1])
158             finally:
159                 fp.close()
160
161         # write the output
162         if self.output == '-':
163             fp = sys.stdout
164             closep = 0
165         else:
166             fp = open(self.output, 'w')
167             closep = 1
168         try:
169             eater.write(fp)
170         finally:
171             if closep:
172                 fp.close()
173
174     def merge_files(self):
175         if not self.all_linguas:
176             return
177
178         for lingua in self.all_linguas:
179             d = { 'msgmerge': self.msgmerge,
180                   'po': os.path.join(self.output_dir, lingua + '.po'),
181                   'pot': self.output
182             }
183             if self.verbose:
184                 print 'Merging %(pot)s and %(po)s' % d
185             res = os.system('%(msgmerge)s %(po)s %(pot)s -o %(po)s' % d)
186             if res:
187                 SystemExit, 'error while running msgmerge.'
188
Note: See TracBrowser for help on using the browser.