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, personality="java", duplicatestyle="msgctxt"):
35 """converts a .properties file to a .po file...""" 36 self.personality = personality 37 thetargetfile = po.pofile() 38 if self.personality == "mozilla": 39 targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="&") 40 else: 41 targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit") 42 targetheader.addnote("extracted from %s" % thepropfile.filename, "developer") 43 # we try and merge the header po with any comments at the start of the properties file 44 appendedheader = False 45 waitingcomments = [] 46 for propunit in thepropfile.units: 47 pounit = self.convertunit(propunit, "developer") 48 if pounit is None: 49 waitingcomments.extend(propunit.comments) 50 # FIXME the storage class should not be creating blank units 51 if pounit is "discard": 52 continue 53 if not appendedheader: 54 if propunit.isblank(): 55 pounit = targetheader 56 else: 57 thetargetfile.addunit(targetheader) 58 appendedheader = True 59 if pounit is not None: 60 pounit.addnote("".join(waitingcomments).rstrip(), "developer", position="prepend") 61 waitingcomments = [] 62 thetargetfile.addunit(pounit) 63 thetargetfile.removeduplicates(duplicatestyle) 64 return thetargetfile
65
66 - def mergestore(self, origpropfile, translatedpropfile, personality="java", blankmsgstr=False, duplicatestyle="msgctxt"):
67 """converts two .properties files to a .po file...""" 68 self.personality = personality 69 thetargetfile = po.pofile() 70 if self.personality == "mozilla": 71 targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="&") 72 else: 73 targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit") 74 targetheader.addnote("extracted from %s, %s" % (origpropfile.filename, translatedpropfile.filename), "developer") 75 translatedpropfile.makeindex() 76 # we try and merge the header po with any comments at the start of the properties file 77 appendedheader = False 78 waitingcomments = [] 79 # loop through the original file, looking at units one by one 80 for origprop in origpropfile.units: 81 origpo = self.convertunit(origprop, "developer") 82 if origpo is None: 83 waitingcomments.extend(origprop.comments) 84 # FIXME the storage class should not be creating blank units 85 if origpo is "discard": 86 continue 87 # handle the header case specially... 88 if not appendedheader: 89 if origprop.isblank(): 90 origpo = targetheader 91 else: 92 thetargetfile.addunit(targetheader) 93 appendedheader = True 94 # try and find a translation of the same name... 95 if origprop.name in translatedpropfile.locationindex: 96 translatedprop = translatedpropfile.locationindex[origprop.name] 97 # Need to check that this comment is not a copy of the developer comments 98 translatedpo = self.convertunit(translatedprop, "translator") 99 if translatedpo is "discard": 100 continue 101 else: 102 translatedpo = None 103 # if we have a valid po unit, get the translation and add it... 104 if origpo is not None: 105 if translatedpo is not None and not blankmsgstr: 106 origpo.target = translatedpo.source 107 origpo.addnote(u"".join(waitingcomments).rstrip(), "developer", position="prepend") 108 waitingcomments = [] 109 thetargetfile.addunit(origpo) 110 elif translatedpo is not None: 111 print >> sys.stderr, "error converting original properties definition %s" % origprop.name 112 thetargetfile.removeduplicates(duplicatestyle) 113 return thetargetfile
114
115 - def convertunit(self, propunit, commenttype):
116 """Converts a .properties unit to a .po unit. Returns None if empty 117 or not for translation.""" 118 if propunit is None: 119 return None 120 # escape unicode 121 pounit = po.pounit(encoding="UTF-8") 122 if hasattr(propunit, "comments"): 123 for comment in propunit.comments: 124 if "DONT_TRANSLATE" in comment: 125 return "discard" 126 pounit.addnote(u"".join(propunit.getnotes()).rstrip(), commenttype) 127 # TODO: handle multiline msgid 128 if propunit.isblank(): 129 return None 130 pounit.addlocation(propunit.name) 131 pounit.source = propunit.source 132 pounit.target = u"" 133 return pounit
134
135 -def convertmozillaprop(inputfile, outputfile, templatefile, pot=False, duplicatestyle="msgctxt"):
136 """Mozilla specific convertor function""" 137 return convertprop(inputfile, outputfile, templatefile, personality="mozilla", pot=pot, duplicatestyle=duplicatestyle)
138
139 -def convertprop(inputfile, outputfile, templatefile, personality="java", pot=False, duplicatestyle="msgctxt"):
140 """reads in inputfile using properties, converts using prop2po, writes to outputfile""" 141 inputstore = properties.propfile(inputfile, personality) 142 convertor = prop2po() 143 if templatefile is None: 144 outputstore = convertor.convertstore(inputstore, personality, duplicatestyle=duplicatestyle) 145 else: 146 templatestore = properties.propfile(templatefile, personality) 147 outputstore = convertor.mergestore(templatestore, inputstore, personality, blankmsgstr=pot, duplicatestyle=duplicatestyle) 148 if outputstore.isempty(): 149 return 0 150 outputfile.write(str(outputstore)) 151 return 1
152
153 -def main(argv=None):
154 from translate.convert import convert 155 formats = {"properties": ("po", convertprop), ("properties", "properties"): ("po", convertprop)} 156 parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__) 157 parser.add_option("", "--personality", dest="personality", default="java", type="choice", 158 choices=["java", "mozilla"], 159 help="set the input behaviour: java (default), mozilla", metavar="TYPE") 160 parser.add_duplicates_option() 161 parser.passthrough.append("pot") 162 parser.passthrough.append("personality") 163 parser.run(argv)
164 165 if __name__ == '__main__': 166 main() 167