Package translate :: Package misc :: Module optrecurse
[hide private]
[frames] | no frames]

Source Code for Module translate.misc.optrecurse

  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  import sys 
 23  import os.path 
 24  import fnmatch 
 25  import traceback 
 26  import optparse 
 27  from translate.misc import progressbar 
 28  from translate import __version__ 
 29  try: 
 30      from cStringIO import StringIO 
 31  except ImportError: 
 32      from StringIO import StringIO 
 33   
34 -class ManPageOption(optparse.Option, object):
35 ACTIONS = optparse.Option.ACTIONS + ("manpage",) 36
37 - def take_action(self, action, dest, opt, value, values, parser):
38 """take_action that can handle manpage as well as standard actions""" 39 if action == "manpage": 40 parser.print_manpage() 41 sys.exit(0) 42 return super(ManPageOption, self).take_action(action, dest, opt, value, values, parser)
43
44 -class ManHelpFormatter (optparse.HelpFormatter):
45 - def __init__ (self, 46 indent_increment=0, 47 max_help_position=0, 48 width=80, 49 short_first=1):
50 optparse.HelpFormatter.__init__( 51 self, indent_increment, max_help_position, width, short_first)
52
53 - def format_option_strings (self, option):
54 """Return a comma-separated list of option strings & metavariables.""" 55 if option.takes_value(): 56 metavar = option.metavar or option.dest.upper() 57 metavar = '\\fI%s\\fP'%metavar 58 short_opts = [sopt + metavar for sopt in option._short_opts] 59 long_opts = [lopt + "\\fR=\\fP" + metavar for lopt in option._long_opts] 60 else: 61 short_opts = option._short_opts 62 long_opts = option._long_opts 63 64 if self.short_first: 65 opts = short_opts + long_opts 66 else: 67 opts = long_opts + short_opts 68 69 return '\\fB%s\\fP'%("\\fR, \\fP".join(opts))
70
71 -class RecursiveOptionParser(optparse.OptionParser, object):
72 """A specialized Option Parser for recursing through directories.""" 73
74 - def __init__(self, formats, usetemplates=False, allowmissingtemplate=False, description=None):
75 """Construct the specialized Option Parser. 76 77 @type formats: Dictionary 78 @param formats: See L{setformats()} for an explanation of the formats parameter. 79 80 """ 81 82 optparse.OptionParser.__init__(self, version="%prog "+__version__.ver, description=description) 83 self.setmanpageoption() 84 self.setprogressoptions() 85 self.seterrorleveloptions() 86 self.setformats(formats, usetemplates) 87 self.setpsycooption() 88 self.passthrough = [] 89 self.allowmissingtemplate = allowmissingtemplate
90
91 - def get_prog_name(self):
92 return os.path.basename(sys.argv[0])
93
94 - def setmanpageoption(self):
95 """creates a manpage option that allows the optionparser to generate a manpage""" 96 manpageoption = ManPageOption(None, "--manpage", dest="manpage", default=False, action="manpage", 97 help="output a manpage based on the help") 98 self.define_option(manpageoption)
99
100 - def format_manpage(self):
101 """returns a formatted manpage""" 102 result = [] 103 prog = self.get_prog_name() 104 formatprog = lambda x: x.replace("%prog", prog) 105 formatToolkit = lambda x: x.replace("%prog", "Translate Toolkit") 106 result.append('.\\" Autogenerated manpage\n') 107 result.append('.TH %s 1 "%s" "" "%s"\n' % (prog, 108 formatToolkit(self.version), 109 formatToolkit(self.version))) 110 result.append('.SH NAME\n') 111 result.append('%s \\- %s\n' % (self.get_prog_name(), self.description.split('\n\n')[0])) 112 result.append('.SH SYNOPSIS\n') 113 result.append('.PP\n') 114 usage = "\\fB%prog " 115 usage += " ".join([self.getusageman(option) for option in self.option_list]) 116 usage += "\\fP" 117 result.append('%s\n' % formatprog(usage)) 118 description_lines = self.description.split('\n\n')[1:] 119 if description_lines: 120 result.append('.SH DESCRIPTION\n') 121 result.append('\n'.join(description_lines)) 122 result.append('.SH OPTIONS\n') 123 ManHelpFormatter().store_option_strings(self) 124 result.append('.PP\n') 125 for option in self.option_list: 126 result.append('.TP\n') 127 result.append('%s\n'%option) 128 result.append('%s\n'%option.help) 129 return "".join(result)
130
131 - def print_manpage(self, file=None):
132 """outputs a manpage for the program using the help information""" 133 if file is None: 134 file = sys.stdout 135 file.write(self.format_manpage())
136
137 - def setpsycooption(self):
138 psycomodes = ["none", "full", "profile"] 139 psycooption = optparse.Option(None, "--psyco", dest="psyco", default=None, 140 choices=psycomodes, metavar="MODE", 141 help="use psyco to speed up the operation, modes: %s" % (", ".join(psycomodes))) 142 self.define_option(psycooption)
143
144 - def usepsyco(self, options):
145 # options.psyco == None means the default, which is "full", but don't give a warning... 146 # options.psyco == "none" means don't use psyco at all... 147 if options.psyco == "none": 148 return 149 try: 150 import psyco 151 except Exception: 152 if options.psyco is not None: 153 self.warning("psyco unavailable", options, sys.exc_info()) 154 return 155 if options.psyco is None: 156 options.psyco = "full" 157 if options.psyco == "full": 158 psyco.full() 159 elif options.psyco == "profile": 160 psyco.profile() 161 # tell psyco the functions it cannot compile, to prevent warnings 162 import encodings 163 psyco.cannotcompile(encodings.search_function)
164
165 - def set_usage(self, usage=None):
166 """sets the usage string - if usage not given, uses getusagestring for each option""" 167 if usage is None: 168 self.usage = "%prog " + " ".join([self.getusagestring(option) for option in self.option_list]) 169 else: 170 super(RecursiveOptionParser, self).set_usage(usage)
171
172 - def warning(self, msg, options=None, exc_info=None):
173 """Print a warning message incorporating 'msg' to stderr and exit.""" 174 if options: 175 if options.errorlevel == "traceback": 176 errorinfo = "\n".join(traceback.format_exception(exc_info[0], exc_info[1], exc_info[2])) 177 elif options.errorlevel == "exception": 178 errorinfo = "\n".join(traceback.format_exception_only(exc_info[0], exc_info[1])) 179 elif options.errorlevel == "message": 180 errorinfo = str(exc_info[1]) 181 else: 182 errorinfo = "" 183 if errorinfo: 184 msg += ": " + errorinfo 185 print >> sys.stderr, "\n%s: warning: %s" % (self.get_prog_name(), msg)
186
187 - def getusagestring(self, option):
188 """returns the usage string for the given option""" 189 optionstring = "|".join(option._short_opts + option._long_opts) 190 if getattr(option, "optionalswitch", False): 191 optionstring = "[%s]" % optionstring 192 if option.metavar: 193 optionstring += " " + option.metavar 194 if getattr(option, "required", False): 195 return optionstring 196 else: 197 return "[%s]" % optionstring
198
199 - def getusageman(self, option):
200 """returns the usage string for the given option""" 201 optionstring = "\\fR|\\fP".join(option._short_opts + option._long_opts) 202 if getattr(option, "optionalswitch", False): 203 optionstring = "\\fR[\\fP%s\\fR]\\fP" % optionstring 204 if option.metavar: 205 optionstring += " \\fI%s\\fP" % option.metavar 206 if getattr(option, "required", False): 207 return optionstring 208 else: 209 return "\\fR[\\fP%s\\fR]\\fP" % optionstring
210
211 - def define_option(self, option):
212 """defines the given option, replacing an existing one of the same short name if neccessary...""" 213 for short_opt in option._short_opts: 214 if self.has_option(short_opt): 215 self.remove_option(short_opt) 216 for long_opt in option._long_opts: 217 if self.has_option(long_opt): 218 self.remove_option(long_opt) 219 self.add_option(option)
220
221 - def setformats(self, formats, usetemplates):
222 """Sets the format options using the given format dictionary. 223 224 @type formats: Dictionary 225 @param formats: The dictionary I{keys} should be: 226 - single strings (or 1-tuples) containing an input format (if not usetemplates) 227 - tuples containing an input format and template format (if usetemplates) 228 - formats can be None to indicate what to do with standard input 229 The dictionary I{values} should be tuples of outputformat (string) and processor method. 230 231 """ 232 233 inputformats = [] 234 outputformats = [] 235 templateformats = [] 236 self.outputoptions = {} 237 self.usetemplates = usetemplates 238 for formatgroup, outputoptions in formats.iteritems(): 239 if isinstance(formatgroup, (str, unicode)) or formatgroup is None: 240 formatgroup = (formatgroup, ) 241 if not isinstance(formatgroup, tuple): 242 raise ValueError("formatgroups must be tuples or None/str/unicode") 243 if len(formatgroup) < 1 or len(formatgroup) > 2: 244 raise ValueError("formatgroups must be tuples of length 1 or 2") 245 if len(formatgroup) == 1: 246 formatgroup += (None, ) 247 inputformat, templateformat = formatgroup 248 if not isinstance(outputoptions, tuple) or len(outputoptions) != 2: 249 raise ValueError("output options must be tuples of length 2") 250 outputformat, processor = outputoptions 251 if not inputformat in inputformats: inputformats.append(inputformat) 252 if not outputformat in outputformats: outputformats.append(outputformat) 253 if not templateformat in templateformats: templateformats.append(templateformat) 254 self.outputoptions[(inputformat, templateformat)] = (outputformat, processor) 255 self.inputformats = inputformats 256 inputformathelp = self.getformathelp(inputformats) 257 inputoption = optparse.Option("-i", "--input", dest="input", default=None, metavar="INPUT", 258 help="read from INPUT in %s" % (inputformathelp)) 259 inputoption.optionalswitch = True 260 inputoption.required = True 261 self.define_option(inputoption) 262 excludeoption = optparse.Option("-x", "--exclude", dest="exclude", action="append", 263 type="string", default=["CVS", ".svn", "_darcs"], metavar="EXCLUDE", 264 help="exclude names matching EXCLUDE from input paths") 265 self.define_option(excludeoption) 266 outputformathelp = self.getformathelp(outputformats) 267 outputoption = optparse.Option("-o", "--output", dest="output", default=None, metavar="OUTPUT", 268 help="write to OUTPUT in %s" % (outputformathelp)) 269 outputoption.optionalswitch = True 270 outputoption.required = True 271 self.define_option(outputoption) 272 if self.usetemplates: 273 self.templateformats = templateformats 274 templateformathelp = self.getformathelp(self.templateformats) 275 templateoption = optparse.Option("-t", "--template", dest="template", default=None, metavar="TEMPLATE", 276 help="read from TEMPLATE in %s" % (templateformathelp)) 277 self.define_option(templateoption)
278
279 - def setprogressoptions(self):
280 """sets the progress options""" 281 self.progresstypes = { 282 "none": progressbar.NoProgressBar, 283 "bar": progressbar.HashProgressBar, 284 "dots": progressbar.DotsProgressBar, 285 "names": progressbar.MessageProgressBar, 286 "verbose": progressbar.VerboseProgressBar 287 } 288 progressoption = optparse.Option(None, "--progress", dest="progress", default="bar", 289 choices = self.progresstypes.keys(), metavar="PROGRESS", 290 help="show progress as: %s" % (", ".join(self.progresstypes))) 291 self.define_option(progressoption)
292
293 - def seterrorleveloptions(self):
294 """sets the errorlevel options""" 295 self.errorleveltypes = ["none", "message", "exception", "traceback"] 296 errorleveloption = optparse.Option(None, "--errorlevel", dest="errorlevel", default="message", 297 choices = self.errorleveltypes, metavar="ERRORLEVEL", 298 help="show errorlevel as: %s" % (", ".join(self.errorleveltypes))) 299 self.define_option(errorleveloption)
300
301 - def getformathelp(self, formats):
302 """make a nice help string for describing formats...""" 303 if None in formats: 304 formats = filter(lambda format: format is not None, formats) 305 if len(formats) == 0: 306 return "" 307 elif len(formats) == 1: 308 return "%s format" % (", ".join(formats)) 309 else: 310 return "%s formats" % (", ".join(formats))
311
312 - def isrecursive(self, fileoption, filepurpose='input'):
313 """checks if fileoption is a recursive file""" 314 if fileoption is None: 315 return False 316 elif isinstance(fileoption, list): 317 return True 318 else: 319 return os.path.isdir(fileoption)
320
321 - def parse_args(self, args=None, values=None):
322 """parses the command line options, handling implicit input/output args""" 323 (options, args) = super(RecursiveOptionParser, self).parse_args(args, values) 324 # some intelligent as to what reasonable people might give on the command line 325 if args and not options.input: 326 if len(args) > 1: 327 options.input = args[:-1] 328 args = args[-1:] 329 else: 330 options.input = args[0] 331 args = [] 332 if args and not options.output: 333 options.output = args[-1] 334 args = args[:-1] 335 if args: 336 self.error("You have used an invalid combination of --input, --output and freestanding args") 337 if isinstance(options.input, list) and len(options.input) == 1: 338 options.input = options.input[0] 339 if options.input is None: 340 self.error("You need to give an inputfile or use - for stdin ; use --help for full usage instructions") 341 elif options.input == '-': 342 options.input = None 343 return (options, args)
344
345 - def getpassthroughoptions(self, options):
346 """get the options required to pass to the filtermethod...""" 347 passthroughoptions = {} 348 for optionname in dir(options): 349 if optionname in self.passthrough: 350 passthroughoptions[optionname] = getattr(options, optionname) 351 return passthroughoptions
352
353 - def getoutputoptions(self, options, inputpath, templatepath):
354 """works out which output format and processor method to use...""" 355 if inputpath: 356 inputbase, inputext = self.splitinputext(inputpath) 357 else: 358 inputext = None 359 if templatepath: 360 templatebase, templateext = self.splittemplateext(templatepath) 361 else: 362 templateext = None 363 if (inputext, templateext) in options.outputoptions: 364 return options.outputoptions[inputext, templateext] 365 elif (inputext, "*") in options.outputoptions: 366 outputformat, fileprocessor = options.outputoptions[inputext, "*"] 367 elif ("*", templateext) in options.outputoptions: 368 outputformat, fileprocessor = options.outputoptions["*", templateext] 369 elif ("*", "*") in options.outputoptions: 370 outputformat, fileprocessor = options.outputoptions["*", "*"] 371 elif (inputext, None) in options.outputoptions: 372 return options.outputoptions[inputext, None] 373 elif (None, templateext) in options.outputoptions: 374 return options.outputoptions[None, templateext] 375 elif ("*", None) in options.outputoptions: 376 outputformat, fileprocessor = options.outputoptions["*", None] 377 elif (None, "*") in options.outputoptions: 378 outputformat, fileprocessor = options.outputoptions[None, "*"] 379 else: 380 if self.usetemplates: 381 if inputext is None: 382 raise ValueError("don't know what to do with input format (no file extension), no template file") 383 elif templateext is None: 384 raise ValueError("don't know what to do with input format %s, no template file" % (os.extsep + inputext)) 385 else: 386 raise ValueError("don't know what to do with input format %s, template format %s" % (os.extsep + inputext, os.extsep + templateext)) 387 else: 388 raise ValueError("don't know what to do with input format %s" % os.extsep + inputext) 389 if outputformat == "*": 390 if inputext: 391 outputformat = inputext 392 elif templateext: 393 outputformat = templateext 394 elif ("*", "*") in options.outputoptions: 395 outputformat = None 396 else: 397 if self.usetemplates: 398 if templateext is None: 399 raise ValueError("don't know what to do with input format %s, no template file" % (os.extsep + inputext)) 400 else: 401 raise ValueError("don't know what to do with input format %s, template format %s" % (os.extsep + inputext, os.extsep + templateext)) 402 else: 403 raise ValueError("don't know what to do with input format %s" % os.extsep + inputext) 404 return outputformat, fileprocessor
405
406 - def initprogressbar(self, allfiles, options):
407 """sets up a progress bar appropriate to the options and files""" 408 if options.progress in ('bar', 'verbose'): 409 self.progressbar = self.progresstypes[options.progress](0, len(allfiles)) 410 print >> sys.stderr, "processing %d files..." % len(allfiles) 411 else: 412 self.progressbar = self.progresstypes[options.progress]()
413
414 - def getfullinputpath(self, options, inputpath):
415 """gets the absolute path to an input file""" 416 if options.input: 417 return os.path.join(options.input, inputpath) 418 else: 419 return inputpath
420
421 - def getfulloutputpath(self, options, outputpath):
422 """gets the absolute path to an output file""" 423 if options.recursiveoutput and options.output: 424 return os.path.join(options.output, outputpath) 425 else: 426 return outputpath
427
428 - def getfulltemplatepath(self, options, templatepath):
429 """gets the absolute path to a template file""" 430 if not options.recursivetemplate: 431 return templatepath 432 elif templatepath is not None and self.usetemplates and options.template: 433 return os.path.join(options.template, templatepath) 434 else: 435 return None
436
437 - def run(self):
438 """parses the arguments, and runs recursiveprocess with the resulting options...""" 439 (options, args) = self.parse_args() 440 # this is so derived classes can modify the inputformats etc based on the options 441 options.inputformats = self.inputformats 442 options.outputoptions = self.outputoptions 443 self.usepsyco(options) 444 self.recursiveprocess(options)
445
446 - def recursiveprocess(self, options):
447 """recurse through directories and process files""" 448 if self.isrecursive(options.input, 'input') and getattr(options, "allowrecursiveinput", True): 449 if not self.isrecursive(options.output, 'output'): 450 try: 451 self.warning("Output directory does not exist. Attempting to create") 452 os.mkdir(options.output) 453 except IOError, e: 454 self.error(optparse.OptionValueError("Output directory does not exist, attempt to create failed")) 455 if isinstance(options.input, list): 456 inputfiles = self.recurseinputfilelist(options) 457 else: 458 inputfiles = self.recurseinputfiles(options) 459 else: 460 if options.input: 461 inputfiles = [os.path.basename(options.input)] 462 options.input = os.path.dirname(options.input) 463 else: 464 inputfiles = [options.input] 465 options.recursiveoutput = self.isrecursive(options.output, 'output') and getattr(options, "allowrecursiveoutput", True) 466 options.recursivetemplate = self.usetemplates and self.isrecursive(options.template, 'template') and getattr(options, "allowrecursivetemplate", True) 467 self.initprogressbar(inputfiles, options) 468 for inputpath in inputfiles: 469 try: 470 templatepath = self.gettemplatename(options, inputpath) 471 # If we have a recursive template, but the template doesn't have this 472 # input file, let's drop it. 473 if options.recursivetemplate and templatepath is None and not self.allowmissingtemplate: 474 self.warning("No template at %s. Skipping %s." % (templatepath, inputpath)) 475 continue 476 outputformat, fileprocessor = self.getoutputoptions(options, inputpath, templatepath) 477 fullinputpath = self.getfullinputpath(options, inputpath) 478 fulltemplatepath = self.getfulltemplatepath(options, templatepath) 479 outputpath = self.getoutputname(options, inputpath, outputformat) 480 fulloutputpath = self.getfulloutputpath(options, outputpath) 481 if options.recursiveoutput and outputpath: 482 self.checkoutputsubdir(options, os.path.dirname(outputpath)) 483 except Exception, error: 484 if isinstance(error, KeyboardInterrupt): 485 raise 486 self.warning("Couldn't handle input file %s" % inputpath, options, sys.exc_info()) 487 continue 488 try: 489 success = self.processfile(fileprocessor, options, fullinputpath, fulloutputpath, fulltemplatepath) 490 except Exception, error: 491 if isinstance(error, KeyboardInterrupt): 492 raise 493 self.warning("Error processing: input %s, output %s, template %s" % (fullinputpath, fulloutputpath, fulltemplatepath), options, sys.exc_info()) 494 success = False 495 self.reportprogress(inputpath, success) 496 del self.progressbar
497
498 - def openinputfile(self, options, fullinputpath):
499 """opens the input file""" 500 if fullinputpath is None: 501 return sys.stdin 502 return open(fullinputpath, 'r')
503
504 - def openoutputfile(self, options, fulloutputpath):
505 """opens the output file""" 506 if fulloutputpath is None: 507 return sys.stdout 508 return open(fulloutputpath, 'w')
509
510 - def opentempoutputfile(self, options, fulloutputpath):
511 """opens a temporary output file""" 512 return StringIO()
513
514 - def finalizetempoutputfile(self, options, outputfile, fulloutputpath):
515 """write the temp outputfile to its final destination""" 516 outputfile.reset() 517 outputstring = outputfile.read() 518 outputfile = self.openoutputfile(options, fulloutputpath) 519 outputfile.write(outputstring) 520 outputfile.close()
521
522 - def opentemplatefile(self, options, fulltemplatepath):
523 """opens the template file (if required)""" 524 if fulltemplatepath is not None: 525 if os.path.isfile(fulltemplatepath): 526 return open(fulltemplatepath, 'r') 527 else: 528 self.warning("missing template file %s" % fulltemplatepath) 529 return None
530
531 - def processfile(self, fileprocessor, options, fullinputpath, fulloutputpath, fulltemplatepath):
532 """process an individual file""" 533 inputfile = self.openinputfile(options, fullinputpath) 534 if fulloutputpath and fulloutputpath in (fullinputpath, fulltemplatepath): 535 outputfile = self.opentempoutputfile(options, fulloutputpath) 536 tempoutput = True 537 else: 538 outputfile = self.openoutputfile(options, fulloutputpath) 539 tempoutput = False 540 templatefile = self.opentemplatefile(options, fulltemplatepath) 541 passthroughoptions = self.getpassthroughoptions(options) 542 if fileprocessor(inputfile, outputfile, templatefile, **passthroughoptions): 543 if tempoutput: 544 self.warning("writing to temporary output...") 545 self.finalizetempoutputfile(options, outputfile, fulloutputpath) 546 return True 547 else: 548 # remove the file if it is a file (could be stdout etc) 549 if fulloutputpath and os.path.isfile(fulloutputpath): 550 outputfile.close() 551 os.unlink(fulloutputpath) 552 return False
553
554 - def reportprogress(self, filename, success):
555 """shows that we are progressing...""" 556 self.progressbar.amount += 1 557 self.progressbar.show(filename)
558
559 - def mkdir(self, parent, subdir):
560 """makes a subdirectory (recursively if neccessary)""" 561 if not os.path.isdir(parent): 562 raise ValueError("cannot make child directory %r if parent %r does not exist" % (subdir, parent)) 563 currentpath = parent 564 subparts = subdir.split(os.sep) 565 for part in subparts: 566 currentpath = os.path.join(currentpath, part) 567 if not os.path.isdir(currentpath): 568 os.mkdir(currentpath)
569
570 - def checkoutputsubdir(self, options, subdir):
571 """checks to see if subdir under options.output needs to be created, creates if neccessary""" 572 fullpath = os.path.join(options.output, subdir) 573 if not os.path.isdir(fullpath): 574 self.mkdir(options.output, subdir)
575
576 - def isexcluded(self, options, inputpath):
577 """checks if this path has been excluded""" 578 basename = os.path.basename(inputpath) 579 for excludename in options.exclude: 580 if fnmatch.fnmatch(basename, excludename): 581 return True 582 return False
583
584 - def recurseinputfilelist(self, options):
585 """use a list of files, and find a common base directory for them""" 586 # find a common base directory for the files to do everything relative to 587 commondir = os.path.dirname(os.path.commonprefix(options.input)) 588 inputfiles = [] 589 for inputfile in options.input: 590 if self.isexcluded(options, inputfile): 591 continue 592 if inputfile.startswith(commondir+os.sep): 593 inputfiles.append(inputfile.replace(commondir+os.sep, "", 1)) 594 else: 595 inputfiles.append(inputfile.replace(commondir, "", 1)) 596 options.input = commondir 597 return inputfiles
598
599 - def recurseinputfiles(self, options):
600 """recurse through directories and return files to be processed...""" 601 dirstack = [''] 602 join = os.path.join 603 inputfiles = [] 604 while dirstack: 605 top = dirstack.pop(-1) 606 names = os.listdir(join(options.input, top)) 607 dirs = [] 608 for name in names: 609 inputpath = join(top, name) 610 if self.isexcluded(options, inputpath): 611 continue 612 fullinputpath = self.getfullinputpath(options, inputpath) 613 # handle directories... 614 if os.path.isdir(fullinputpath): 615 dirs.append(inputpath) 616 elif os.path.isfile(fullinputpath): 617 if not self.isvalidinputname(options, name): 618 # only handle names that match recognized input file extensions 619 continue 620 inputfiles.append(inputpath) 621 # make sure the directories are processed next time round... 622 dirs.reverse() 623 dirstack.extend(dirs) 624 return inputfiles
625
626 - def splitext(self, pathname):
627 """splits into name and ext, and removes the extsep""" 628 root, ext = os.path.splitext(pathname) 629 ext = ext.replace(os.extsep, "", 1) 630 return (root, ext)
631
632 - def splitinputext(self, inputpath):
633 """splits an inputpath into name and extension""" 634 return self.splitext(inputpath)
635
636 - def splittemplateext(self, templatepath):
637 """splits a templatepath into name and extension""" 638 return self.splitext(templatepath)
639
640 - def templateexists(self, options, templatepath):
641 """returns whether the given template exists...""" 642 fulltemplatepath = self.getfulltemplatepath(options, templatepath) 643 return os.path.isfile(fulltemplatepath)
644
645 - def gettemplatename(self, options, inputname):
646 """gets an output filename based on the input filename""" 647 if not self.usetemplates: return None 648 if not inputname or not options.recursivetemplate: return options.template 649 inputbase, inputext = self.splitinputext(inputname) 650 if options.template: 651 for inputext1, templateext1 in options.outputoptions: 652 if inputext == inputext1: 653 if templateext1: 654 templatepath = inputbase + os.extsep + templateext1 655 if self.templateexists(options, templatepath): 656 return templatepath 657 if "*" in options.inputformats: 658 for inputext1, templateext1 in options.outputoptions: 659 if (inputext == inputext1) or (inputext1 == "*"): 660 if templateext1 == "*": 661 templatepath = inputname 662 if self.templateexists(options, templatepath): 663 return templatepath 664 elif templateext1: 665 templatepath = inputbase + os.extsep + templateext1 666 if self.templateexists(options, templatepath): 667 return templatepath 668 return None
669
670 - def getoutputname(self, options, inputname, outputformat):
671 """gets an output filename based on the input filename""" 672 if not inputname or not options.recursiveoutput: return options.output 673 inputbase, inputext = self.splitinputext(inputname) 674 outputname = inputbase 675 if outputformat: 676 outputname += os.extsep + outputformat 677 return outputname
678
679 - def isvalidinputname(self, options, inputname):
680 """checks if this is a valid input filename""" 681 inputbase, inputext = self.splitinputext(inputname) 682 return (inputext in options.inputformats) or ("*" in options.inputformats)
683