2 ## -*- coding: utf-8 -*-
3 ## Copyright (C) 2001 Red Hat, Inc.
4 ## Copyright (C) 2001 Trond Eivind Glomsrød <teg@redhat.com>
8 ## This program is free software; you can redistribute it and/or modify
9 ## it under the terms of the GNU General Public License as published by
10 ## the Free Software Foundation; either version 2 of the License, or
11 ## (at your option) any later version.
13 ## This program is distributed in the hope that it will be useful,
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ## GNU General Public License for more details.
18 ## You should have received a copy of the GNU General Public License
19 ## along with this program; if not, write to the Free Software
20 ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 A class containing a message, its msgid and various references pointing at it
34 def __init__(self,id=None,message=None,refs=[]):
36 The constructor for the GTMessage class
37 @self The object instance
39 @id The messageid associated with the object
41 self._message=string.strip(message)
42 self._id=string.strip(id)
45 self._refs.append(ref)
49 Return a string representation of the object
50 @self The object instance
53 for ref in self._refs:
55 res=res+"msgid %s\nmsgstr %s\n" % (self._id,self._message)
58 def invertedStrings(self):
60 Returns a string representation, but with msgid and msgstr inverted.
61 Note: Don't invert the "" string
62 @self The object instance
65 for ref in self._refs:
67 if not self._id=="\"\"":
68 res=res+"msgid %s\nmsgstr %s\n" % (self._message,self._id)
70 res=res+"msgid %s\nmsgstr %s\n" % (self._id,self._message)
73 def emptyMsgStrings(self):
75 Return a string representation of the object, but leave the msgstr
76 empty - create a pot file from a po file
77 Note: Won't remove the "" string
78 @self The object instance
81 for ref in self._refs:
83 if not self._id=="\"\"":
84 res=res+"msgid %s\nmsgstr \"\"\n" % (self._id)
86 res=res+"msgid %s\nmsgstr %s\n" % (self._id,self._message)
89 def compareMessage(self,msg):
91 Return if the messages have identical msgids, 0 otherwise
92 @self The object instance
93 @msg The message to compare to
96 if self._id == msg._id:
101 class GTMasterMessage:
103 A class containing a message, its msgid and various references pointing at it
104 The difference between GTMessage and GTMasterMessage is that this class
105 can do less operations, but is able to store multiple msgstrs with identifiers
106 (usually language, like 'msgst(no)'
109 def __init__(self,id=None,refs=[]):
111 The constructor for the GTMessage class
112 @self The object instance
113 @id The messageid associated with the object
119 self._refs.append(ref)
121 def addMessage(self,message,identifier):
123 Add a new message and identifier to the GTMasterMessage object
124 @self The object instance
125 @message The message to append
126 @identifier The identifier of the message
128 self._messages.append((identifier,message))
132 Return a string representation of the object
133 @self The object instance
136 for ref in self._refs:
138 res=res+"msgid %s\n" % self._id
139 for message in self._messages:
140 res=res+"msgstr(%s) %s\n" %(message[0],message[1])
146 A class containing the GTMessages contained in a file
149 def __init__(self,filename):
151 The constructor of the GTMFile class
152 @self The object instance
153 @filename The file to initialize from
155 self._filename=filename
157 self.readFile(filename)
161 Return a string representation of the object
162 @self The object instance
165 for message in self._messages:
166 res=res+str(message)+"\n"
169 def invertedStrings(self):
171 Return a string representation of the object, with msgid and msgstr
172 swapped. Will remove duplicates...
173 @self The object instance
179 for message in self._messages:
180 if message._id=='""' and len(msgar)==0:
181 msgar.append(GTMessage(message._id,message._message,message._refs))
183 msg=GTMessage(message._message,message._id,message._refs)
184 if not msght.has_key(msg._id):
189 for ref in msg._refs:
190 msg2._refs.append(ref)
192 for message in msgar:
193 res=res+str(message)+"\n"
196 def msgidDupes(self):
198 Search for duplicates in the msgids.
199 @self The object instance
203 for message in self._messages:
205 if msgids.has_key(msgid):
206 res=res+"Duplicate: %s\n" % (msgid)
211 def getMsgstr(self,msgid):
213 Return the msgstr matching the given id. 'None' if missing
214 @self The object instance
218 for message in self._messages:
219 if msgid == message._id:
220 return message._message
223 def emptyMsgStrings(self):
225 Return a string representation of the object, but leave the msgstr
226 empty - create a pot file from a po file
227 @self The object instance
231 for message in self._messages:
232 res=res+message.emptyMsgStrings()+"\n"
238 Append entries from dictionary B which aren't
239 already present in this dictionary
240 @self The object instance
241 @B the dictionary to append messages from
244 for message in B._messages:
245 if not self.getMsgstr(message._id):
246 self._messages.append(message)
249 def readFile(self,filename):
251 Read the contents of a file into the GTFile object
252 @self The object instance
253 @filename The name of the file to read
256 file=open(filename,"r")
263 templines=file.readlines()
264 for line in templines:
265 lines.append(string.strip(line))
267 pos=string.find(line,'"')
268 pos2=string.rfind(line,'"')
269 if line and line[0]=="#":
270 refs.append(string.strip(line))
271 if inmsgstr==0 and line[:6]=="msgstr":
278 #Handle entries with and without "" consistently
279 if msgid[:2]=='""' and len(msgid)>4:
281 if msgstr[:2]=='""' and len(msgstr)>4:
283 message=GTMessage(msgid,msgstr,refs)
284 self._messages.append(message)
289 msgstr=msgstr+line[pos:pos2+1]+"\n"
290 if inmsgid==0 and line[:5]=="msgid":
297 msgid=msgid+line[pos:pos2+1]+"\n"
299 message=GTMessage(msgid,msgstr,refs)
300 self._messages.append(message)
305 A class containing a master catalogue of gettext dictionaries
308 def __init__(self,dicts):
310 The constructor for the GTMaster class
311 @self The object instance
312 @dicts An array of dictionaries to merge
315 self.createMaster(dicts)
317 def createMaster(self,dicts):
319 Create the master catalogue
320 @self The object instance
321 @dicts An array of dictionaries to merge
324 self._master=dicts[0]
325 self._dicts=dicts[1:]
327 for message in self._master._messages:
328 gtm=GTMasterMessage(message._id,message._refs)
329 gtm.addMessage(message._message,self._master._filename[:-3])
330 for dict in self._dicts:
331 res=dict.getMsgstr(message._id)
333 gtm.addMessage(res,dict._filename[:-3])
334 self._messages.append(gtm)
338 Return a string representation of the object
339 @self The object instance
342 for message in self._messages:
343 res=res+str(message)+"\n"
347 if __name__=="__main__":
350 if("-o") in sys.argv:
351 output=sys.argv[sys.argv.index("-o")+1]
352 sys.argv.remove("-o")
353 sys.argv.remove(output)
354 if("--invert") in sys.argv:
355 file=sys.argv[sys.argv.index("--invert")+1]
357 res1=gtf.msgidDupes()
359 sys.stderr.write(res1)
361 res=str(gtf.invertedStrings())
362 elif("--empty") in sys.argv:
363 file=sys.argv[sys.argv.index("--empty")+1]
365 res=str(gtf.emptyMsgStrings())
366 elif("--master") in sys.argv:
367 loc=sys.argv.index("--master")+1
369 for file in sys.argv[loc:]:
370 gtfs.append(GTFile(file))
371 master=GTMaster(gtfs)
373 elif("--append") in sys.argv:
374 file=sys.argv[sys.argv.index("--append")+1]
375 file2=sys.argv[sys.argv.index("--append")+2]
381 #print "Not implemented: "+str(sys.argv)
383 Usage: ", str(sys.argv[0])," [OPTION] file.po [ref.po]\n\
384 This program can be used to alter .po files in ways no sane mind would think about.\n\
385 -o result will be written to FILE\n\
386 --invert invert a po file by switching msgid and msgstr\n\
387 --master join any number of files in a master-formatted catalog\n\
388 --empty empty the contents of the .po file, creating a .pot\n\
389 --append append entries from ref.po that don't exist in file.po\n\
391 Note: It is just a replacement of msghack for backward support.\n\
397 file=open(output,"w")