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("\n".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