Package translate :: Package filters :: Module pofilter
[hide private]
[frames] | no frames]

Source Code for Module translate.filters.pofilter

  1  #!/usr/bin/env python 
  2  #  
  3  # Copyright 2004-2007 Zuza Software Foundation 
  4  #  
  5  # This file is part of translate. 
  6  # 
  7  # translate is free software; you can redistribute it and/or modify 
  8  # it under the terms of the GNU General Public License as published by 
  9  # the Free Software Foundation; either version 2 of the License, or 
 10  # (at your option) any later version. 
 11  #  
 12  # translate is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 15  # GNU General Public License for more details. 
 16  # 
 17  # You should have received a copy of the GNU General Public License 
 18  # along with translate; if not, write to the Free Software 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 20   
 21  """Perform quality checks on Gettext PO, XLIFF and TMX localization files 
 22   
 23  Snippet files whenever a test fails.  These can be examined, corrected and  
 24  merged back into the originals using pomerge 
 25   
 26  See: http://translate.sourceforge.net/wiki/toolkit/pofilter for examples and 
 27  usage instructions and http://translate.sourceforge.net/wiki/toolkit/pofilter_tests 
 28  for full descriptions of all tests 
 29  """ 
 30   
 31  from translate.storage import factory 
 32  from translate.storage.poheader import poheader 
 33  from translate.filters import checks 
 34  from translate.filters import autocorrect 
 35  from translate.misc import optrecurse 
 36   
 37  import os 
 38   
39 -class pocheckfilter:
40 - def __init__(self, options, checkerclasses=None, checkerconfig=None):
41 # excludefilters={}, limitfilters=None, includefuzzy=True, includereview=True, autocorrect=False): 42 """builds a checkfilter using the given checker (a list is allowed too)""" 43 if checkerclasses is None: 44 checkerclasses = [checks.StandardChecker, checks.StandardUnitChecker] 45 self.checker = checks.TeeChecker(checkerconfig=checkerconfig, \ 46 excludefilters=options.excludefilters, \ 47 limitfilters=options.limitfilters, \ 48 checkerclasses=checkerclasses, \ 49 languagecode=checkerconfig.targetlanguage 50 ) 51 self.options = options
52
53 - def getfilterdocs(self):
54 """lists the docs for filters available on checker...""" 55 filterdict = self.checker.getfilters() 56 filterdocs = ["%s\t%s" % (name, filterfunc.__doc__) for (name, filterfunc) in filterdict.iteritems()] 57 filterdocs.sort() 58 return "\n".join(filterdocs)
59
60 - def filterunit(self, unit):
61 """runs filters on an element""" 62 if unit.isheader(): 63 return [] 64 if not self.options.includefuzzy and unit.isfuzzy(): 65 return [] 66 if not self.options.includereview and unit.isreview(): 67 return [] 68 failures = self.checker.run_filters(unit) 69 if failures and self.options.autocorrect: 70 # we can't get away with bad unquoting / requoting if we're going to change the result... 71 correction = autocorrect.correct(unit.source, unit.target) 72 if correction: 73 unit.target = correction 74 return autocorrect 75 else: 76 # ignore failures we can't correct when in autocorrect mode 77 return [] 78 return failures
79
80 - def filterfile(self, transfile):
81 """Runs filters on a translation store object. 82 Parameters: 83 - transfile. A translation store object. 84 Return value: 85 - A new translation store object with the results of the filter included.""" 86 newtransfile = type(transfile)() 87 newtransfile.setsourcelanguage(transfile.sourcelanguage) 88 newtransfile.settargetlanguage(transfile.targetlanguage) 89 for unit in transfile.units: 90 filterresult = self.filterunit(unit) 91 if filterresult: 92 if filterresult != autocorrect: 93 for filtername, filtermessage in filterresult.iteritems(): 94 if self.options.addnotes: 95 unit.adderror(filtername, filtermessage) 96 if isinstance(filtermessage, checks.SeriousFilterFailure): 97 unit.markfuzzy() 98 newtransfile.addunit(unit) 99 if isinstance(newtransfile, poheader): 100 newtransfile.updateheader(add=True, **transfile.parseheader()) 101 return newtransfile
102
103 -class FilterOptionParser(optrecurse.RecursiveOptionParser):
104 """a specialized Option Parser for filter tools..."""
105 - def __init__(self, formats):
106 """construct the specialized Option Parser""" 107 optrecurse.RecursiveOptionParser.__init__(self, formats) 108 self.set_usage() 109 self.add_option("-l", "--listfilters", action="callback", dest='listfilters', 110 default=False, callback_kwargs={'dest_value': True}, 111 callback=self.parse_noinput, help="list filters available")
112
113 - def parse_noinput(self, option, opt, value, parser, *args, **kwargs):
114 """this sets an option to true, but also sets input to - to prevent an error""" 115 setattr(parser.values, option.dest, kwargs['dest_value']) 116 parser.values.input = "-"
117
118 - def run(self):
119 """parses the arguments, and runs recursiveprocess with the resulting options""" 120 (options, args) = self.parse_args() 121 if options.filterclass is None: 122 checkerclasses = [checks.StandardChecker, checks.StandardUnitChecker] 123 else: 124 checkerclasses = [options.filterclass, checks.StandardUnitChecker] 125 checkerconfig = checks.CheckerConfig(targetlanguage=options.targetlanguage) 126 if options.notranslatefile: 127 options.notranslatefile = os.path.expanduser(options.notranslatefile) 128 if not os.path.exists(options.notranslatefile): 129 self.error("notranslatefile %r does not exist" % options.notranslatefile) 130 notranslatewords = [line.strip() for line in open(options.notranslatefile).readlines()] 131 notranslatewords = dict.fromkeys([key for key in notranslatewords]) 132 checkerconfig.notranslatewords.update(notranslatewords) 133 if options.musttranslatefile: 134 options.musttranslatefile = os.path.expanduser(options.musttranslatefile) 135 if not os.path.exists(options.musttranslatefile): 136 self.error("musttranslatefile %r does not exist" % options.musttranslatefile) 137 musttranslatewords = [line.strip() for line in open(options.musttranslatefile).readlines()] 138 musttranslatewords = dict.fromkeys([key for key in musttranslatewords]) 139 checkerconfig.musttranslatewords.update(musttranslatewords) 140 if options.validcharsfile: 141 options.validcharsfile = os.path.expanduser(options.validcharsfile) 142 if not os.path.exists(options.validcharsfile): 143 self.error("validcharsfile %r does not exist" % options.validcharsfile) 144 validchars = open(options.validcharsfile).read() 145 checkerconfig.updatevalidchars(validchars) 146 options.checkfilter = pocheckfilter(options, checkerclasses, checkerconfig) 147 if not options.checkfilter.checker.combinedfilters: 148 self.error("No valid filters were specified") 149 options.inputformats = self.inputformats 150 options.outputoptions = self.outputoptions 151 self.usepsyco(options) 152 if options.listfilters: 153 print options.checkfilter.getfilterdocs() 154 else: 155 self.recursiveprocess(options)
156
157 -def runfilter(inputfile, outputfile, templatefile, checkfilter=None):
158 """reads in inputfile, filters using checkfilter, writes to outputfile""" 159 fromfile = factory.getobject(inputfile) 160 tofile = checkfilter.filterfile(fromfile) 161 if tofile.isempty(): 162 return 0 163 outputfile.write(str(tofile)) 164 return 1
165
166 -def cmdlineparser():
167 formats = {"po":("po", runfilter), "pot":("pot", runfilter), 168 "xliff":("xliff", runfilter), "xlf":("xlf", runfilter), 169 "tmx":("tmx", runfilter), 170 None:("po", runfilter)} 171 172 parser = FilterOptionParser(formats) 173 parser.add_option("", "--review", dest="includereview", 174 action="store_true", default=True, 175 help="include units marked for review (default)") 176 parser.add_option("", "--noreview", dest="includereview", 177 action="store_false", default=True, 178 help="exclude units marked for review") 179 parser.add_option("", "--fuzzy", dest="includefuzzy", 180 action="store_true", default=True, 181 help="include units marked fuzzy (default)") 182 parser.add_option("", "--nofuzzy", dest="includefuzzy", 183 action="store_false", default=True, 184 help="exclude units marked fuzzy") 185 parser.add_option("", "--nonotes", dest="addnotes", 186 action="store_false", default=True, 187 help="don't add notes about the errors") 188 parser.add_option("", "--autocorrect", dest="autocorrect", 189 action="store_true", default=False, 190 help="output automatic corrections where possible rather than describing issues") 191 parser.add_option("", "--language", dest="targetlanguage", default=None, 192 help="set target language code (e.g. af-ZA) [required for spell check and recommended in general]", metavar="LANG") 193 parser.add_option("", "--openoffice", dest="filterclass", 194 action="store_const", default=None, const=checks.OpenOfficeChecker, 195 help="use the standard checks for OpenOffice translations") 196 parser.add_option("", "--mozilla", dest="filterclass", 197 action="store_const", default=None, const=checks.MozillaChecker, 198 help="use the standard checks for Mozilla translations") 199 parser.add_option("", "--drupal", dest="filterclass", 200 action="store_const", default=None, const=checks.DrupalChecker, 201 help="use the standard checks for Drupal translations") 202 parser.add_option("", "--gnome", dest="filterclass", 203 action="store_const", default=None, const=checks.GnomeChecker, 204 help="use the standard checks for Gnome translations") 205 parser.add_option("", "--kde", dest="filterclass", 206 action="store_const", default=None, const=checks.KdeChecker, 207 help="use the standard checks for KDE translations") 208 parser.add_option("", "--wx", dest="filterclass", 209 action="store_const", default=None, const=checks.KdeChecker, 210 help="use the standard checks for wxWidgets translations") 211 parser.add_option("", "--excludefilter", dest="excludefilters", 212 action="append", default=[], type="string", metavar="FILTER", 213 help="don't use FILTER when filtering") 214 parser.add_option("-t", "--test", dest="limitfilters", 215 action="append", default=None, type="string", metavar="FILTER", 216 help="only use test FILTERs specified with this option when filtering") 217 parser.add_option("", "--notranslatefile", dest="notranslatefile", 218 default=None, type="string", metavar="FILE", 219 help="read list of untranslatable words from FILE (must not be translated)") 220 parser.add_option("", "--musttranslatefile", dest="musttranslatefile", 221 default=None, type="string", metavar="FILE", 222 help="read list of translatable words from FILE (must be translated)") 223 parser.add_option("", "--validcharsfile", dest="validcharsfile", 224 default=None, type="string", metavar="FILE", 225 help="read list of all valid characters from FILE (must be in UTF-8)") 226 parser.passthrough.append('checkfilter') 227 parser.description = __doc__ 228 return parser
229
230 -def main():
231 parser = cmdlineparser() 232 parser.run()
233 234 if __name__ == '__main__': 235 main() 236