Package translate :: Package convert :: Module prop2po
[hide private]
[frames] | no frames]

Source Code for Module translate.convert.prop2po

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2002-2006 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  8  # translate 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. 
 12  #  
 13  # translate 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. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21   
 22  """convert Java/Mozilla .properties files to Gettext PO localization files 
 23   
 24  See: http://translate.sourceforge.net/wiki/toolkit/prop2po for examples and  
 25  usage instructions 
 26  """ 
 27   
 28  import sys 
 29  from translate.storage import po 
 30  from translate.storage import properties 
 31   
32 -class prop2po:
33 """convert a .properties file to a .po file for handling the translation..."""
34 - def convertstore(self, thepropfile, duplicatestyle="msgctxt"):
35 """converts a .properties file to a .po file...""" 36 thetargetfile = po.pofile() 37 targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="&") 38 targetheader.addnote("extracted from %s" % thepropfile.filename, "developer") 39 # we try and merge the header po with any comments at the start of the properties file 40 appendedheader = 0 41 waitingcomments = [] 42 for propunit in thepropfile.units: 43 pounit = self.convertunit(propunit, "developer") 44 if pounit is None: 45 waitingcomments.extend(propunit.comments) 46 # FIXME the storage class should not be creating blank units 47 if pounit is "discard": 48 continue 49 if not appendedheader: 50 if propunit.isblank(): 51 pounit = targetheader 52 else: 53 thetargetfile.addunit(targetheader) 54 appendedheader = 1 55 if pounit is not None: 56 pounit.addnote("".join(waitingcomments).rstrip(), "developer", position="prepend") 57 waitingcomments = [] 58 thetargetfile.addunit(pounit) 59 thetargetfile.removeduplicates(duplicatestyle) 60 return thetargetfile
61
62 - def mergestore(self, origpropfile, translatedpropfile, blankmsgstr=False, duplicatestyle="msgctxt"):
63 """converts two .properties files to a .po file...""" 64 thetargetfile = po.pofile() 65 targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit") 66 targetheader.addnote("extracted from %s, %s" % (origpropfile.filename, translatedpropfile.filename), "developer") 67 translatedpropfile.makeindex() 68 # we try and merge the header po with any comments at the start of the properties file 69 appendedheader = 0 70 waitingcomments = [] 71 # loop through the original file, looking at units one by one 72 for origprop in origpropfile.units: 73 origpo = self.convertunit(origprop, "developer") 74 if origpo is None: 75 waitingcomments.extend(origprop.comments) 76 # FIXME the storage class should not be creating blank units 77 if origpo is "discard": 78 continue 79 # handle the header case specially... 80 if not appendedheader: 81 if origprop.isblank(): 82 origpo = targetheader 83 else: 84 thetargetfile.addunit(targetheader) 85 appendedheader = 1 86 # try and find a translation of the same name... 87 if origprop.name in translatedpropfile.locationindex: 88 translatedprop = translatedpropfile.locationindex[origprop.name] 89 # Need to check that this comment is not a copy of the developer comments 90 translatedpo = self.convertunit(translatedprop, "translator") 91 else: 92 translatedpo = None 93 # if we have a valid po unit, get the translation and add it... 94 if origpo is not None: 95 if translatedpo is not None and not blankmsgstr: 96 origpo.target = translatedpo.source 97 origpo.addnote("".join(waitingcomments).rstrip(), "developer", position="prepend") 98 waitingcomments = [] 99 thetargetfile.addunit(origpo) 100 elif translatedpo is not None: 101 print >> sys.stderr, "error converting original properties definition %s" % origprop.name 102 thetargetfile.removeduplicates(duplicatestyle) 103 return thetargetfile
104
105 - def convertunit(self, propunit, commenttype):
106 """Converts a .properties unit to a .po unit. Returns None if empty 107 or not for translation.""" 108 if propunit is None: 109 return None 110 # escape unicode 111 pounit = po.pounit(encoding="UTF-8") 112 if hasattr(propunit, "comments"): 113 for comment in propunit.comments: 114 if "DONT_TRANSLATE" in comment: 115 return "discard" 116 pounit.addnote("".join(propunit.comments).rstrip(), commenttype) 117 # TODO: handle multiline msgid 118 if propunit.isblank(): 119 return None 120 pounit.addlocation(propunit.name) 121 pounit.source = propunit.source 122 pounit.target = "" 123 return pounit
124
125 -def convertprop(inputfile, outputfile, templatefile, pot=False, duplicatestyle="msgctxt"):
126 """reads in inputfile using properties, converts using prop2po, writes to outputfile""" 127 inputstore = properties.propfile(inputfile) 128 convertor = prop2po() 129 if templatefile is None: 130 outputstore = convertor.convertstore(inputstore, duplicatestyle=duplicatestyle) 131 else: 132 templatestore = properties.propfile(templatefile) 133 outputstore = convertor.mergestore(templatestore, inputstore, blankmsgstr=pot, duplicatestyle=duplicatestyle) 134 if outputstore.isempty(): 135 return 0 136 outputfile.write(str(outputstore)) 137 return 1
138
139 -def main(argv=None):
140 from translate.convert import convert 141 formats = {"properties": ("po", convertprop), ("properties", "properties"): ("po", convertprop)} 142 parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__) 143 parser.add_duplicates_option() 144 parser.passthrough.append("pot") 145 parser.run(argv)
146 147 if __name__ == '__main__': 148 main() 149