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