diff options
Diffstat (limited to 'translate-toolkit-1.5.1/translate/misc/optrecurse.py')
-rw-r--r-- | translate-toolkit-1.5.1/translate/misc/optrecurse.py | 699 |
1 files changed, 699 insertions, 0 deletions
diff --git a/translate-toolkit-1.5.1/translate/misc/optrecurse.py b/translate-toolkit-1.5.1/translate/misc/optrecurse.py new file mode 100644 index 0000000..d89c31a --- /dev/null +++ b/translate-toolkit-1.5.1/translate/misc/optrecurse.py @@ -0,0 +1,699 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2002-2006 Zuza Software Foundation +# +# This file is part of translate. +# +# translate is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# translate is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with translate; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import sys +import os.path +import fnmatch +import traceback +import optparse +from translate.misc import progressbar +from translate import __version__ +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +class ManPageOption(optparse.Option, object): + ACTIONS = optparse.Option.ACTIONS + ("manpage",) + + def take_action(self, action, dest, opt, value, values, parser): + """take_action that can handle manpage as well as standard actions""" + if action == "manpage": + parser.print_manpage() + sys.exit(0) + return super(ManPageOption, self).take_action(action, dest, opt, value, values, parser) + +class ManHelpFormatter (optparse.HelpFormatter): + def __init__ (self, + indent_increment=0, + max_help_position=0, + width=80, + short_first=1): + optparse.HelpFormatter.__init__( + self, indent_increment, max_help_position, width, short_first) + + def format_option_strings (self, option): + """Return a comma-separated list of option strings & metavariables.""" + if option.takes_value(): + metavar = option.metavar or option.dest.upper() + metavar = '\\fI%s\\fP'%metavar + short_opts = [sopt + metavar for sopt in option._short_opts] + long_opts = [lopt + "\\fR=\\fP" + metavar for lopt in option._long_opts] + else: + short_opts = option._short_opts + long_opts = option._long_opts + + if self.short_first: + opts = short_opts + long_opts + else: + opts = long_opts + short_opts + + return '\\fB%s\\fP'%("\\fR, \\fP".join(opts)) + +class RecursiveOptionParser(optparse.OptionParser, object): + """A specialized Option Parser for recursing through directories.""" + + def __init__(self, formats, usetemplates=False, allowmissingtemplate=False, description=None): + """Construct the specialized Option Parser. + + @type formats: Dictionary + @param formats: See L{setformats()} for an explanation of the formats parameter. + + """ + + optparse.OptionParser.__init__(self, version="%prog "+__version__.sver, description=description) + self.setmanpageoption() + self.setprogressoptions() + self.seterrorleveloptions() + self.setformats(formats, usetemplates) + self.setpsycooption() + self.passthrough = [] + self.allowmissingtemplate = allowmissingtemplate + + def get_prog_name(self): + return os.path.basename(sys.argv[0]) + + def setmanpageoption(self): + """creates a manpage option that allows the optionparser to generate a manpage""" + manpageoption = ManPageOption(None, "--manpage", dest="manpage", default=False, action="manpage", + help="output a manpage based on the help") + self.define_option(manpageoption) + + def format_manpage(self): + """returns a formatted manpage""" + result = [] + prog = self.get_prog_name() + formatprog = lambda x: x.replace("%prog", prog) + formatToolkit = lambda x: x.replace("%prog", "Translate Toolkit") + result.append('.\\" Autogenerated manpage\n') + result.append('.TH %s 1 "%s" "" "%s"\n' % (prog, + formatToolkit(self.version), + formatToolkit(self.version))) + result.append('.SH NAME\n') + result.append('%s \\- %s\n' % (self.get_prog_name(), self.description.split('\n\n')[0])) + result.append('.SH SYNOPSIS\n') + result.append('.PP\n') + usage = "\\fB%prog " + usage += " ".join([self.getusageman(option) for option in self.option_list]) + usage += "\\fP" + result.append('%s\n' % formatprog(usage)) + description_lines = self.description.split('\n\n')[1:] + if description_lines: + result.append('.SH DESCRIPTION\n') + result.append('\n'.join(description_lines)) + result.append('.SH OPTIONS\n') + ManHelpFormatter().store_option_strings(self) + result.append('.PP\n') + for option in self.option_list: + result.append('.TP\n') + result.append('%s\n'%option) + result.append('%s\n'%option.help) + return "".join(result) + + def print_manpage(self, file=None): + """outputs a manpage for the program using the help information""" + if file is None: + file = sys.stdout + file.write(self.format_manpage()) + + def setpsycooption(self): + try: + import psyco + except Exception: + return + psycomodes = ["none", "full", "profile"] + psycooption = optparse.Option(None, "--psyco", dest="psyco", default=None, + choices=psycomodes, metavar="MODE", + help="use psyco to speed up the operation, modes: %s" % (", ".join(psycomodes))) + self.define_option(psycooption) + + def usepsyco(self, options): + # options.psyco == None means the default, which is "full", but don't give a warning... + # options.psyco == "none" means don't use psyco at all... + if getattr(options, "psyco", "none") == "none": + return + try: + import psyco + except Exception: + if options.psyco is not None: + self.warning("psyco unavailable", options, sys.exc_info()) + return + if options.psyco is None: + options.psyco = "full" + if options.psyco == "full": + psyco.full() + elif options.psyco == "profile": + psyco.profile() + # tell psyco the functions it cannot compile, to prevent warnings + import encodings + psyco.cannotcompile(encodings.search_function) + + def set_usage(self, usage=None): + """sets the usage string - if usage not given, uses getusagestring for each option""" + if usage is None: + self.usage = "%prog " + " ".join([self.getusagestring(option) for option in self.option_list]) + else: + super(RecursiveOptionParser, self).set_usage(usage) + + def warning(self, msg, options=None, exc_info=None): + """Print a warning message incorporating 'msg' to stderr and exit.""" + if options: + if options.errorlevel == "traceback": + errorinfo = "\n".join(traceback.format_exception(exc_info[0], exc_info[1], exc_info[2])) + elif options.errorlevel == "exception": + errorinfo = "\n".join(traceback.format_exception_only(exc_info[0], exc_info[1])) + elif options.errorlevel == "message": + errorinfo = str(exc_info[1]) + else: + errorinfo = "" + if errorinfo: + msg += ": " + errorinfo + print >> sys.stderr, "\n%s: warning: %s" % (self.get_prog_name(), msg) + + def getusagestring(self, option): + """returns the usage string for the given option""" + optionstring = "|".join(option._short_opts + option._long_opts) + if getattr(option, "optionalswitch", False): + optionstring = "[%s]" % optionstring + if option.metavar: + optionstring += " " + option.metavar + if getattr(option, "required", False): + return optionstring + else: + return "[%s]" % optionstring + + def getusageman(self, option): + """returns the usage string for the given option""" + optionstring = "\\fR|\\fP".join(option._short_opts + option._long_opts) + if getattr(option, "optionalswitch", False): + optionstring = "\\fR[\\fP%s\\fR]\\fP" % optionstring + if option.metavar: + optionstring += " \\fI%s\\fP" % option.metavar + if getattr(option, "required", False): + return optionstring + else: + return "\\fR[\\fP%s\\fR]\\fP" % optionstring + + def define_option(self, option): + """defines the given option, replacing an existing one of the same short name if neccessary...""" + for short_opt in option._short_opts: + if self.has_option(short_opt): + self.remove_option(short_opt) + for long_opt in option._long_opts: + if self.has_option(long_opt): + self.remove_option(long_opt) + self.add_option(option) + + def setformats(self, formats, usetemplates): + """Sets the format options using the given format dictionary. + + @type formats: Dictionary + @param formats: The dictionary I{keys} should be: + - single strings (or 1-tuples) containing an input format (if not usetemplates) + - tuples containing an input format and template format (if usetemplates) + - formats can be None to indicate what to do with standard input + The dictionary I{values} should be tuples of outputformat (string) and processor method. + + """ + + inputformats = [] + outputformats = [] + templateformats = [] + self.outputoptions = {} + self.usetemplates = usetemplates + for formatgroup, outputoptions in formats.iteritems(): + if isinstance(formatgroup, (str, unicode)) or formatgroup is None: + formatgroup = (formatgroup, ) + if not isinstance(formatgroup, tuple): + raise ValueError("formatgroups must be tuples or None/str/unicode") + if len(formatgroup) < 1 or len(formatgroup) > 2: + raise ValueError("formatgroups must be tuples of length 1 or 2") + if len(formatgroup) == 1: + formatgroup += (None, ) + inputformat, templateformat = formatgroup + if not isinstance(outputoptions, tuple) or len(outputoptions) != 2: + raise ValueError("output options must be tuples of length 2") + outputformat, processor = outputoptions + if not inputformat in inputformats: + inputformats.append(inputformat) + if not outputformat in outputformats: + outputformats.append(outputformat) + if not templateformat in templateformats: + templateformats.append(templateformat) + self.outputoptions[(inputformat, templateformat)] = (outputformat, processor) + self.inputformats = inputformats + inputformathelp = self.getformathelp(inputformats) + inputoption = optparse.Option("-i", "--input", dest="input", default=None, metavar="INPUT", + help="read from INPUT in %s" % (inputformathelp)) + inputoption.optionalswitch = True + inputoption.required = True + self.define_option(inputoption) + excludeoption = optparse.Option("-x", "--exclude", dest="exclude", action="append", + type="string", default=["CVS", ".svn", "_darcs", ".git", ".hg", ".bzr"], metavar="EXCLUDE", + help="exclude names matching EXCLUDE from input paths") + self.define_option(excludeoption) + outputformathelp = self.getformathelp(outputformats) + outputoption = optparse.Option("-o", "--output", dest="output", default=None, metavar="OUTPUT", + help="write to OUTPUT in %s" % (outputformathelp)) + outputoption.optionalswitch = True + outputoption.required = True + self.define_option(outputoption) + if self.usetemplates: + self.templateformats = templateformats + templateformathelp = self.getformathelp(self.templateformats) + templateoption = optparse.Option("-t", "--template", dest="template", default=None, metavar="TEMPLATE", + help="read from TEMPLATE in %s" % (templateformathelp)) + self.define_option(templateoption) + + def setprogressoptions(self): + """sets the progress options""" + self.progresstypes = { + "none": progressbar.NoProgressBar, + "bar": progressbar.HashProgressBar, + "dots": progressbar.DotsProgressBar, + "names": progressbar.MessageProgressBar, + "verbose": progressbar.VerboseProgressBar + } + progressoption = optparse.Option(None, "--progress", dest="progress", default="bar", + choices = self.progresstypes.keys(), metavar="PROGRESS", + help="show progress as: %s" % (", ".join(self.progresstypes))) + self.define_option(progressoption) + + def seterrorleveloptions(self): + """sets the errorlevel options""" + self.errorleveltypes = ["none", "message", "exception", "traceback"] + errorleveloption = optparse.Option(None, "--errorlevel", dest="errorlevel", default="message", + choices = self.errorleveltypes, metavar="ERRORLEVEL", + help="show errorlevel as: %s" % (", ".join(self.errorleveltypes))) + self.define_option(errorleveloption) + + def getformathelp(self, formats): + """make a nice help string for describing formats...""" + if None in formats: + formats = filter(lambda format: format is not None, formats) + if len(formats) == 0: + return "" + elif len(formats) == 1: + return "%s format" % (", ".join(formats)) + else: + return "%s formats" % (", ".join(formats)) + + def isrecursive(self, fileoption, filepurpose='input'): + """checks if fileoption is a recursive file""" + if fileoption is None: + return False + elif isinstance(fileoption, list): + return True + else: + return os.path.isdir(fileoption) + + def parse_args(self, args=None, values=None): + """parses the command line options, handling implicit input/output args""" + (options, args) = super(RecursiveOptionParser, self).parse_args(args, values) + # some intelligent as to what reasonable people might give on the command line + if args and not options.input: + if len(args) > 1: + options.input = args[:-1] + args = args[-1:] + else: + options.input = args[0] + args = [] + if args and not options.output: + options.output = args[-1] + args = args[:-1] + if args: + self.error("You have used an invalid combination of --input, --output and freestanding args") + if isinstance(options.input, list) and len(options.input) == 1: + options.input = options.input[0] + if options.input is None: + self.error("You need to give an inputfile or use - for stdin ; use --help for full usage instructions") + elif options.input == '-': + options.input = None + return (options, args) + + def getpassthroughoptions(self, options): + """get the options required to pass to the filtermethod...""" + passthroughoptions = {} + for optionname in dir(options): + if optionname in self.passthrough: + passthroughoptions[optionname] = getattr(options, optionname) + return passthroughoptions + + def getoutputoptions(self, options, inputpath, templatepath): + """works out which output format and processor method to use...""" + if inputpath: + inputbase, inputext = self.splitinputext(inputpath) + else: + inputext = None + if templatepath: + templatebase, templateext = self.splittemplateext(templatepath) + else: + templateext = None + if (inputext, templateext) in options.outputoptions: + return options.outputoptions[inputext, templateext] + elif (inputext, "*") in options.outputoptions: + outputformat, fileprocessor = options.outputoptions[inputext, "*"] + elif ("*", templateext) in options.outputoptions: + outputformat, fileprocessor = options.outputoptions["*", templateext] + elif ("*", "*") in options.outputoptions: + outputformat, fileprocessor = options.outputoptions["*", "*"] + elif (inputext, None) in options.outputoptions: + return options.outputoptions[inputext, None] + elif (None, templateext) in options.outputoptions: + return options.outputoptions[None, templateext] + elif ("*", None) in options.outputoptions: + outputformat, fileprocessor = options.outputoptions["*", None] + elif (None, "*") in options.outputoptions: + outputformat, fileprocessor = options.outputoptions[None, "*"] + else: + if self.usetemplates: + if inputext is None: + raise ValueError("don't know what to do with input format (no file extension), no template file") + elif templateext is None: + raise ValueError("don't know what to do with input format %s, no template file" % (os.extsep + inputext)) + else: + raise ValueError("don't know what to do with input format %s, template format %s" % (os.extsep + inputext, os.extsep + templateext)) + else: + raise ValueError("don't know what to do with input format %s" % os.extsep + inputext) + if outputformat == "*": + if inputext: + outputformat = inputext + elif templateext: + outputformat = templateext + elif ("*", "*") in options.outputoptions: + outputformat = None + else: + if self.usetemplates: + if templateext is None: + raise ValueError("don't know what to do with input format %s, no template file" % (os.extsep + inputext)) + else: + raise ValueError("don't know what to do with input format %s, template format %s" % (os.extsep + inputext, os.extsep + templateext)) + else: + raise ValueError("don't know what to do with input format %s" % os.extsep + inputext) + return outputformat, fileprocessor + + def initprogressbar(self, allfiles, options): + """sets up a progress bar appropriate to the options and files""" + if options.progress in ('bar', 'verbose'): + self.progressbar = self.progresstypes[options.progress](0, len(allfiles)) + print >> sys.stderr, "processing %d files..." % len(allfiles) + else: + self.progressbar = self.progresstypes[options.progress]() + + def getfullinputpath(self, options, inputpath): + """gets the absolute path to an input file""" + if options.input: + return os.path.join(options.input, inputpath) + else: + return inputpath + + def getfulloutputpath(self, options, outputpath): + """gets the absolute path to an output file""" + if options.recursiveoutput and options.output: + return os.path.join(options.output, outputpath) + else: + return outputpath + + def getfulltemplatepath(self, options, templatepath): + """gets the absolute path to a template file""" + if not options.recursivetemplate: + return templatepath + elif templatepath is not None and self.usetemplates and options.template: + return os.path.join(options.template, templatepath) + else: + return None + + def run(self): + """parses the arguments, and runs recursiveprocess with the resulting options...""" + (options, args) = self.parse_args() + # this is so derived classes can modify the inputformats etc based on the options + options.inputformats = self.inputformats + options.outputoptions = self.outputoptions + self.usepsyco(options) + self.recursiveprocess(options) + + def recursiveprocess(self, options): + """recurse through directories and process files""" + if self.isrecursive(options.input, 'input') and getattr(options, "allowrecursiveinput", True): + if not self.isrecursive(options.output, 'output'): + try: + self.warning("Output directory does not exist. Attempting to create") + os.mkdir(options.output) + except IOError, e: + self.error(optparse.OptionValueError("Output directory does not exist, attempt to create failed")) + if isinstance(options.input, list): + inputfiles = self.recurseinputfilelist(options) + else: + inputfiles = self.recurseinputfiles(options) + else: + if options.input: + inputfiles = [os.path.basename(options.input)] + options.input = os.path.dirname(options.input) + else: + inputfiles = [options.input] + options.recursiveoutput = self.isrecursive(options.output, 'output') and getattr(options, "allowrecursiveoutput", True) + options.recursivetemplate = self.usetemplates and self.isrecursive(options.template, 'template') and getattr(options, "allowrecursivetemplate", True) + self.initprogressbar(inputfiles, options) + for inputpath in inputfiles: + try: + templatepath = self.gettemplatename(options, inputpath) + # If we have a recursive template, but the template doesn't have this + # input file, let's drop it. + if options.recursivetemplate and templatepath is None and not self.allowmissingtemplate: + self.warning("No template at %s. Skipping %s." % (templatepath, inputpath)) + continue + outputformat, fileprocessor = self.getoutputoptions(options, inputpath, templatepath) + fullinputpath = self.getfullinputpath(options, inputpath) + fulltemplatepath = self.getfulltemplatepath(options, templatepath) + outputpath = self.getoutputname(options, inputpath, outputformat) + fulloutputpath = self.getfulloutputpath(options, outputpath) + if options.recursiveoutput and outputpath: + self.checkoutputsubdir(options, os.path.dirname(outputpath)) + except Exception, error: + if isinstance(error, KeyboardInterrupt): + raise + self.warning("Couldn't handle input file %s" % inputpath, options, sys.exc_info()) + continue + try: + success = self.processfile(fileprocessor, options, fullinputpath, fulloutputpath, fulltemplatepath) + except Exception, error: + if isinstance(error, KeyboardInterrupt): + raise + self.warning("Error processing: input %s, output %s, template %s" % (fullinputpath, fulloutputpath, fulltemplatepath), options, sys.exc_info()) + success = False + self.reportprogress(inputpath, success) + del self.progressbar + + def openinputfile(self, options, fullinputpath): + """opens the input file""" + if fullinputpath is None: + return sys.stdin + return open(fullinputpath, 'r') + + def openoutputfile(self, options, fulloutputpath): + """opens the output file""" + if fulloutputpath is None: + return sys.stdout + return open(fulloutputpath, 'w') + + def opentempoutputfile(self, options, fulloutputpath): + """opens a temporary output file""" + return StringIO() + + def finalizetempoutputfile(self, options, outputfile, fulloutputpath): + """write the temp outputfile to its final destination""" + outputfile.reset() + outputstring = outputfile.read() + outputfile = self.openoutputfile(options, fulloutputpath) + outputfile.write(outputstring) + outputfile.close() + + def opentemplatefile(self, options, fulltemplatepath): + """opens the template file (if required)""" + if fulltemplatepath is not None: + if os.path.isfile(fulltemplatepath): + return open(fulltemplatepath, 'r') + else: + self.warning("missing template file %s" % fulltemplatepath) + return None + + def processfile(self, fileprocessor, options, fullinputpath, fulloutputpath, fulltemplatepath): + """process an individual file""" + inputfile = self.openinputfile(options, fullinputpath) + if fulloutputpath and fulloutputpath in (fullinputpath, fulltemplatepath): + outputfile = self.opentempoutputfile(options, fulloutputpath) + tempoutput = True + else: + outputfile = self.openoutputfile(options, fulloutputpath) + tempoutput = False + templatefile = self.opentemplatefile(options, fulltemplatepath) + passthroughoptions = self.getpassthroughoptions(options) + if fileprocessor(inputfile, outputfile, templatefile, **passthroughoptions): + if tempoutput: + self.warning("writing to temporary output...") + self.finalizetempoutputfile(options, outputfile, fulloutputpath) + return True + else: + # remove the file if it is a file (could be stdout etc) + if fulloutputpath and os.path.isfile(fulloutputpath): + outputfile.close() + os.unlink(fulloutputpath) + return False + + def reportprogress(self, filename, success): + """shows that we are progressing...""" + self.progressbar.amount += 1 + self.progressbar.show(filename) + + def mkdir(self, parent, subdir): + """makes a subdirectory (recursively if neccessary)""" + if not os.path.isdir(parent): + raise ValueError("cannot make child directory %r if parent %r does not exist" % (subdir, parent)) + currentpath = parent + subparts = subdir.split(os.sep) + for part in subparts: + currentpath = os.path.join(currentpath, part) + if not os.path.isdir(currentpath): + os.mkdir(currentpath) + + def checkoutputsubdir(self, options, subdir): + """checks to see if subdir under options.output needs to be created, creates if neccessary""" + fullpath = os.path.join(options.output, subdir) + if not os.path.isdir(fullpath): + self.mkdir(options.output, subdir) + + def isexcluded(self, options, inputpath): + """checks if this path has been excluded""" + basename = os.path.basename(inputpath) + for excludename in options.exclude: + if fnmatch.fnmatch(basename, excludename): + return True + return False + + def recurseinputfilelist(self, options): + """use a list of files, and find a common base directory for them""" + # find a common base directory for the files to do everything relative to + commondir = os.path.dirname(os.path.commonprefix(options.input)) + inputfiles = [] + for inputfile in options.input: + if self.isexcluded(options, inputfile): + continue + if inputfile.startswith(commondir+os.sep): + inputfiles.append(inputfile.replace(commondir+os.sep, "", 1)) + else: + inputfiles.append(inputfile.replace(commondir, "", 1)) + options.input = commondir + return inputfiles + + def recurseinputfiles(self, options): + """recurse through directories and return files to be processed...""" + dirstack = [''] + join = os.path.join + inputfiles = [] + while dirstack: + top = dirstack.pop(-1) + names = os.listdir(join(options.input, top)) + dirs = [] + for name in names: + inputpath = join(top, name) + if self.isexcluded(options, inputpath): + continue + fullinputpath = self.getfullinputpath(options, inputpath) + # handle directories... + if os.path.isdir(fullinputpath): + dirs.append(inputpath) + elif os.path.isfile(fullinputpath): + if not self.isvalidinputname(options, name): + # only handle names that match recognized input file extensions + continue + inputfiles.append(inputpath) + # make sure the directories are processed next time round... + dirs.reverse() + dirstack.extend(dirs) + return inputfiles + + def splitext(self, pathname): + """Splits L{pathname} into name and ext, and removes the extsep + + @param pathname: A file path + @type pathname: string + @return: root, ext + @rtype: tuple + """ + root, ext = os.path.splitext(pathname) + ext = ext.replace(os.extsep, "", 1) + return (root, ext) + + def splitinputext(self, inputpath): + """splits an inputpath into name and extension""" + return self.splitext(inputpath) + + def splittemplateext(self, templatepath): + """splits a templatepath into name and extension""" + return self.splitext(templatepath) + + def templateexists(self, options, templatepath): + """returns whether the given template exists...""" + fulltemplatepath = self.getfulltemplatepath(options, templatepath) + return os.path.isfile(fulltemplatepath) + + def gettemplatename(self, options, inputname): + """gets an output filename based on the input filename""" + if not self.usetemplates: + return None + if not inputname or not options.recursivetemplate: + return options.template + inputbase, inputext = self.splitinputext(inputname) + if options.template: + for inputext1, templateext1 in options.outputoptions: + if inputext == inputext1: + if templateext1: + templatepath = inputbase + os.extsep + templateext1 + if self.templateexists(options, templatepath): + return templatepath + if "*" in options.inputformats: + for inputext1, templateext1 in options.outputoptions: + if (inputext == inputext1) or (inputext1 == "*"): + if templateext1 == "*": + templatepath = inputname + if self.templateexists(options, templatepath): + return templatepath + elif templateext1: + templatepath = inputbase + os.extsep + templateext1 + if self.templateexists(options, templatepath): + return templatepath + return None + + def getoutputname(self, options, inputname, outputformat): + """gets an output filename based on the input filename""" + if not inputname or not options.recursiveoutput: + return options.output + inputbase, inputext = self.splitinputext(inputname) + outputname = inputbase + if outputformat: + outputname += os.extsep + outputformat + return outputname + + def isvalidinputname(self, options, inputname): + """checks if this is a valid input filename""" + inputbase, inputext = self.splitinputext(inputname) + return (inputext in options.inputformats) or ("*" in options.inputformats) + |