svn merge ^/trunk/blender -r40644:40720
[blender-staging.git] / po / clean_po.py
1 #!/usr/bin/env python
2
3 # $Id$
4 # ***** BEGIN GPL LICENSE BLOCK *****
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software Foundation,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #
20 # ***** END GPL LICENSE BLOCK *****
21
22 # <pep8 compliant>
23
24 # update the pot file according the POTFILES.in
25
26 import os
27 import sys
28 import collections
29
30 from codecs import open
31
32 CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
33
34 FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot")
35
36
37 def read_messages(fname):
38     def stripeol(s):
39         return s.rstrip("\n\r")
40
41     last_message = None
42
43     if hasattr(collections, 'OrderedDict'):
44         messages = collections.OrderedDict()
45         commented_messages = collections.OrderedDict()
46     else:
47         messages = {}
48         commented_messages = {}
49
50     reading_message = False
51     reading_translation = False
52     commented = False
53     message = ""
54     translation = ""
55     message_lines = []
56     translation_lines = []
57     comment_lines = []
58     with open(fname, 'r', "utf-8") as handle:
59         while True:
60             line = handle.readline()
61
62             if not line:
63                 break
64
65             line = stripeol(line)
66             if line.startswith("msgid") or line.startswith("#~ msgid"):
67                 if reading_translation:
68                     last_message['translation'] = translation
69                     translation_lines = []
70
71                 reading_message = True
72                 reading_translation = False
73
74                 if line.startswith('#~'):
75                     message = line[10:-1]
76                     commented = True
77                 else:
78                     message = line[7:-1]
79                     commented = False
80
81                 message_lines.append(message)
82             elif line.startswith("msgstr") or line.startswith("#~ msgstr"):
83                 reading_message = False
84                 reading_translation = True
85                 last_message = {'comment_lines': comment_lines,
86                                 'message_lines': message_lines,
87                                 'translation_lines': translation_lines}
88
89                 if commented:
90                     translation = line[11:-1]
91                     commented_messages[message] = last_message
92                 else:
93                     translation = line[8:-1]
94                     messages[message] = last_message
95
96                 message_lines = []
97                 comment_lines = []
98                 translation_lines.append(translation)
99             elif not line.startswith('"') and not line.startswith('#~ "'):
100                 if reading_translation:
101                     last_message['translation'] = translation
102                 else:
103                     comment_lines.append(line)
104
105                 reading_message = False
106                 reading_translation = False
107                 message_lines = []
108                 translation_lines = []
109             elif reading_message:
110                 if line.startswith('#~ "'):
111                     m = line[4:-1]
112                 else:
113                     m = line[1:-1]
114
115                 message += m
116                 message_lines.append(m)
117             elif reading_translation:
118                 if line.startswith('#~ "'):
119                     t = line[4:-1]
120                 else:
121                     t = line[1:-1]
122
123                 translation += t
124                 translation_lines.append(t)
125
126     return (messages, commented_messages)
127
128
129 def do_clean(po, pot_messages):
130     po_messages, commented_messages = read_messages(po)
131
132     for msgid in commented_messages:
133         if pot_messages.get(msgid):
134             t = po_messages.get(msgid)
135             if not t:
136                 print(('Reusing full item from commented ' + \
137                        'lines for msgid \'%s\'') % (msgid))
138                 po_messages[msgid] = commented_messages[msgid]
139             elif not t['translation']:
140                 print(('Reusing translation from commented ' + \
141                        'lines for msgid \'%s\'') % (msgid))
142                 m = commented_messages[msgid]
143                 t['translation'] = m['translation']
144                 t['translation_lines'] = m['translation_lines']
145
146     with open(po, 'w', 'utf-8') as handle:
147         for msgid in po_messages:
148             item = po_messages[msgid]
149
150             for x in item['comment_lines']:
151                 handle.write(x + "\n")
152
153             first = True
154             for x in item['message_lines']:
155                 if first:
156                     handle.write("msgid \"%s\"\n" % (x))
157                 else:
158                     handle.write("\"%s\"\n" % (x))
159                 first = False
160
161             first = True
162             for x in item['translation_lines']:
163                 if first:
164                     handle.write("msgstr \"%s\"\n" % (x))
165                 else:
166                     handle.write("\"%s\"\n" % (x))
167                 first = False
168
169             handle.write("\n")
170
171
172 def main():
173     pot_messages, commented_messages = read_messages(FILE_NAME_POT)
174
175     if len(sys.argv) > 1:
176         for lang in sys.argv[1:]:
177             po = os.path.join(CURRENT_DIR, lang + '.po')
178
179             if os.path.exists(po):
180                 do_clean(po, pot_messages)
181     else:
182         for po in os.listdir(CURRENT_DIR):
183             if po.endswith('.po'):
184                 print('Processing %s...' % (po))
185                 do_clean(po, pot_messages)
186
187
188 if __name__ == "__main__":
189     print("\n\n *** Running %r *** \n" % __file__)
190     main()