Package translate :: Package convert :: Module oo2po

[hide private]
[frames] | no frames]

# Source Code for Module translate.convert.oo2po

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2003-2008 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
     23  """convert an OpenOffice.org (SDF) localization file to Gettext PO localization files
     24
     25  See: http://translate.sourceforge.net/wiki/toolkit/oo2po for examples and
     26  usage instructions
     27  """
     28
     29  import os
     30  import sys
     31  from translate.storage import po
     32  from translate.storage import oo
     33
     34  # TODO: support using one GSI file as template, another as input (for when English is in one and translation in another)
     35
     36 -class oo2po:
     37 -    def __init__(self, sourcelanguage, targetlanguage, blankmsgstr=False, long_keys=False):
     38          """construct an oo2po converter for the specified languages"""
     39          self.sourcelanguage = sourcelanguage
     40          self.targetlanguage = targetlanguage
     41          self.blankmsgstr = blankmsgstr
     42          self.long_keys = long_keys
     43
     44 -    def maketargetunit(self, part1, part2, translators_comment, key, subkey):
     45          """makes a base unit (.po or XLIFF) out of a subkey of two parts"""
     46          #TODO: Do better
     47          text1 = getattr(part1, subkey)
     48          if text1 == "":
     49              return None
     50          text2 = getattr(part2, subkey)
     51
     52          unit = po.pounit(text1.decode('utf-8'), encoding="UTF-8")
     53          unit.target = text2.decode('utf-8')
     54          unit.addlocation(key + "." + subkey)
     55          if getattr(translators_comment, subkey).strip() != "":
     56              unit.addnote(getattr(translators_comment, subkey), origin="developer")
     57          return unit
     58
     59 -    def makekey(self, ookey):
     60          """converts an oo key tuple into a key identifier for the base class file (.po or XLIFF)"""
     61          project, sourcefile, resourcetype, groupid, localid, platform = ookey
     62          sourcefile = sourcefile.replace('\\','/')
     63          if self.long_keys:
     64              sourcebase = os.path.join(project, sourcefile)
     65          else:
     66              sourceparts = sourcefile.split('/')
     67              sourcebase = "".join(sourceparts[-1:])
     68          if (groupid) == 0 or len(localid) == 0:
     69              ooid = groupid + localid
     70          else:
     71              ooid = groupid + "." + localid
     72          if resourcetype:
     73              ooid = ooid + "." + resourcetype
     74          key = "%s#%s" % (sourcebase, ooid)
     75          return oo.normalizefilename(key)
     76
     77 -    def convertelement(self, theoo):
     78          """convert an oo element into a list of base units (.po or XLIFF)"""
     79          if self.sourcelanguage in theoo.languages:
     80              part1 = theoo.languages[self.sourcelanguage]
     81          else:
     82              print >> sys.stderr, "/".join(theoo.lines[0].getkey()), "language not found: %s" % (self.sourcelanguage)
     83              return []
     84          if self.blankmsgstr:
     85              # use a blank part2
     86              part2 = oo.ooline()
     87          else:
     88              if self.targetlanguage in theoo.languages:
     89                  part2 = theoo.languages[self.targetlanguage]
     90              else:
     91                  # if the language doesn't exist, the translation is missing ... so make it blank
     92                  part2 = oo.ooline()
     93          if "x-comment" in theoo.languages:
     94              translators_comment = theoo.languages["x-comment"]
     95          else:
     96              translators_comment = oo.ooline()
     97          key = self.makekey(part1.getkey())
     98          unitlist = []
     99          for subkey in ("text", "quickhelptext", "title"):
    100              unit = self.maketargetunit(part1, part2, translators_comment, key, subkey)
    101              if unit is not None:
    102                  unitlist.append(unit)
    103          return unitlist
    104
    105 -    def convertstore(self, theoofile, duplicatestyle="msgctxt"):
    106          """converts an entire oo file to a base class format (.po or XLIFF)"""
    107          thetargetfile = po.pofile()
    108          thetargetfile.setsourcelanguage(self.sourcelanguage)
    109          thetargetfile.settargetlanguage(self.targetlanguage)
    110          # create a header for the file
    111          bug_url = 'http://qa.openoffice.org/issues/enter_bug.cgi' + ('''?subcomponent=ui&comment=&short_desc=Localization issue in file: %(filename)s&component=l10n&form_name=enter_issue''' % {"filename": theoofile.filename}).replace(" ", "%20").replace(":", "%3A")
    112          targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="~", report_msgid_bugs_to=bug_url)
    113          targetheader.addnote("extracted from %s" % theoofile.filename, "developer")
    114          thetargetfile.addunit(targetheader)
    115          # go through the oo and convert each element
    116          for theoo in theoofile.units:
    117              unitlist = self.convertelement(theoo)
    118              for unit in unitlist:
    119                  thetargetfile.addunit(unit)
    120          thetargetfile.removeduplicates(duplicatestyle)
    121          return thetargetfile
    122
    123 -def verifyoptions(options):
    124      """verifies the commandline options"""
    125      if not options.pot and not options.targetlanguage:
    126          raise ValueError("You must specify the target language unless generating POT files (-P)")
    127
    128 -def convertoo(inputfile, outputfile, templates, pot=False, sourcelanguage=None, targetlanguage=None, duplicatestyle="msgid_comment", multifilestyle="single"):
    129      """reads in stdin using inputstore class, converts using convertorclass, writes to stdout"""
    130      inputstore = oo.oofile()
    131      if hasattr(inputfile, "filename"):
    132          inputfilename = inputfile.filename
    133      else:
    134          inputfilename = "(input file name not known)"
    135      inputstore.filename = inputfilename
    136      inputstore.parse(inputfile.read())
    137      if not sourcelanguage:
    138          testlangtype = targetlanguage or (inputstore and inputstore.languages[0]) or ""
    139          if testlangtype.isdigit():
    140              sourcelanguage = "01"
    141          else:
    142              sourcelanguage = "en-US"
    143      if not sourcelanguage in inputstore.languages:
    144          print >> sys.stderr, "Warning: sourcelanguage '%s' not found in inputfile '%s' (contains %s)" % (sourcelanguage, inputfilename, ", ".join(inputstore.languages))
    145      if targetlanguage and targetlanguage not in inputstore.languages:
    146          print >> sys.stderr, "Warning: targetlanguage '%s' not found in inputfile '%s' (contains %s)" % (targetlanguage, inputfilename, ", ".join(inputstore.languages))
    147      convertor = oo2po(sourcelanguage, targetlanguage, blankmsgstr=pot, long_keys=multifilestyle!="single")
    148      outputstore = convertor.convertstore(inputstore, duplicatestyle)
    149      if outputstore.isempty():
    150          return 0
    151      outputfile.write(str(outputstore))
    152      return 1
    153
    154 -def main(argv=None):
    155      from translate.convert import convert
    156      formats = {"oo":("po", convertoo), "sdf":("po", convertoo)}
    157      # always treat the input as an archive unless it is a directory
    158      archiveformats = {(None, "input"): oo.oomultifile}
    159      parser = convert.ArchiveConvertOptionParser(formats, usepots=True, description=__doc__, archiveformats=archiveformats)
    160      parser.add_option("-l", "--language", dest="targetlanguage", default=None,
    161              help="set target language to extract from oo file (e.g. af-ZA)", metavar="LANG")
    162      parser.add_option("", "--source-language", dest="sourcelanguage", default=None,
    163              help="set source language code (default en-US)", metavar="LANG")
    164      parser.add_option("", "--nonrecursiveinput", dest="allowrecursiveinput", default=True, action="store_false", help="don't treat the input oo as a recursive store")
    165      parser.add_duplicates_option()
    166      parser.add_multifile_option()
    167      parser.passthrough.append("pot")
    168      parser.passthrough.append("sourcelanguage")
    169      parser.passthrough.append("targetlanguage")
    170      parser.verifyoptions = verifyoptions
    171      parser.run(argv)
    172
    173  if __name__ == '__main__':
    174      main()
    175