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

Revision 215, 4.7 kB (checked in by arjanmol, 5 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="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                     #('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(self.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         """
138         import glob
139         import tokenize
140         source_files = []
141         for p in self.packages:
142             pathlist = p.split('.')
143             path = apply(os.path.join, pathlist)
144             source_files.extend(glob.glob(os.path.join(path, '*.py')))
145
146         # slurp through all the files
147         eater = pygettext.TokenEater(self.options)
148         for filename in source_files:
149             if self.verbose:
150                 print 'Working on %s' % filename
151             fp = open(filename)
152             try:
153                 eater.set_filename(filename)
154                 try:
155                     tokenize.tokenize(fp.readline, eater)
156                 except tokenize.TokenError, e:
157                     print '%s: %s, line %d, column %d' % (
158                         e[0], filename, e[1][0], e[1][1])
159             finally:
160                 fp.close()
161
162         # write the output
163         if self.output == '-':
164             fp = sys.stdout
165         else:
166             fp = open(self.output, 'w')
167         try:
168             eater.write(fp)
169         finally:
170             if fp is not sys.stdout:
171                 fp.close()
172
173     def merge_files(self):
174         if not self.all_linguas:
175             return
176
177         for lingua in self.all_linguas:
178             d = { 'msgmerge': self.msgmerge,
179                   'po': os.path.join(self.output_dir, lingua + '.po'),
180                   'pot': self.output
181             }
182             if self.verbose:
183                 print 'Merging %(pot)s and %(po)s' % d
184             res = os.system('%(msgmerge)s %(po)s %(pot)s -o %(po)s' % d)
185             if res:
186                 SystemExit, 'error while running msgmerge.'
187
Note: See TracBrowser for help on using the browser.