#!/usr/bin/env python #**************************************************************************** # cmdline.py, provides a class to read and execute command line arguments # # TreeLine, an information storage program # Copyright (C) 2005, Douglas W. Bell # # This is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License, Version 2. This program is # distributed in the hope that it will be useful, but WITTHOUT ANY WARRANTY. #***************************************************************************** usage = _(""" Usage: treeline [qt-options --] [infile] -or- (non-interactive): treeline [import-option] [export-option] [misc-options] infile [infile2 ...] Qt-options: see Qt documentation for valid Qt options Import-options: --import-tabbed import a tab indented text file --import-table import a tab-delimitted text table, one node per line --import-lines import plain text, one node per line --import-para import plain text, one node per paragraph --import-treepad import a Treepad text-node file --import-xbel import an XML bookmark file in XBEL format --import-mozilla import an html bookmark file in Mozilla format --import-xml import a generic XML file (non-TreeLine format) Export-options: --export-html export a single HTML file --export-dir export HTML in directories --export-xslt export an XSLT file --export-tabbed export a tab indented text file --export-table export a text table of the first children only --export-xbel export an XML bookmark file in XBEL format --export-mozilla export an html bookmark file in Mozilla format --export-xml export a generic XML file (non-TreeLine format) Misc-options: -o, --outfile=FILE the output filename, not used with multiple infiles -n, --no-root exclude the root node form the output if applicable --add-header add a header and footer to HTML exports --indent=NUM change the indent amount for HTML exports (default = 20) -q, --quiet supress normal status information, only give errors -h, --help display this information and exit No more than one import-option and one export-option may be specified. If either are not present, the native TreeLine file format is assumed. The output filename option can only be specified if there is only one input file. If it is not specified, the input's base file name is used with the appropriate output file extension. If the extensions are the same, an underscore is added before the extension. Note that this avoids overwriting the input file, but other files may be overwritten without notification if they share the output file's name. """, 'do not translate command line option strings') from treedoc import TreeDoc, ReadFileError from option import Option from optiondefaults import OptionDefaults import globalref, optiondefaults from qt import qApp import sys, os.path class CmdLine: """Parses and executes command line arguments for file translations""" options = 'o:nqh' longOptions = ['import-tabbed', 'import-table', 'import-lines', \ 'import-para', 'import-treepad', 'import-xbel', \ 'import-mozilla', 'import-xml', 'export-html', \ 'export-dir', 'export-xslt', 'export-tabbed', \ 'export-table', 'export-xbel', 'export-mozilla', \ 'export-xml', 'outfile=', 'no-root', 'indent=', \ 'quiet', 'help'] def __init__(self, opts, args): self.doc = None self.outfile = '' self.includeRoot = True self.addHeader = False self.indent = 20 self.quiet = False importType = '' exportType = '' globalref.options = Option('treeline', 21) optionDefaults = OptionDefaults(lambda text: \ unicode(qApp.translate('QAccel', text))) globalref.options.loadAll(optionDefaults.defaultOutput()) for englishName, transName, unusedKey in optionDefaults.keyBindList: for optionDict in globalref.options.dictList: key = optionDict.get(transName) if key: optionDict[englishName] = key for opt, arg in opts: if opt in ('-h', '--help'): print usage return elif opt.startswith('--import-'): if importType: print usage sys.exit(2) importType = opt[9:] elif opt.startswith('--export-'): if exportType: print usage sys.exit(2) exportType = opt[9:] elif opt in ('-o', '--outfile'): self.outfile = arg if len(args) > 1: print usage sys.exit(2) elif opt in ('-n', '--no-root'): self.includeRoot = False elif opt == '--add-header': self.addHeader = True elif opt == '--indent': try: self.indent = int(arg) except ValueError: print usage sys.exit(2) elif opt in ('-q', '--quiet'): self.quiet = True if not args: print usage sys.exit(2) if not importType: importType = 'trl' if not exportType: exportType = 'trl' errorFlag = False for fileName in args: self.doc = TreeDoc() try: self.importFile(fileName, importType) except (IOError, UnicodeError): print _('Error - could not read file %s', '%s is filename') % \ fileName.encode(TreeDoc.localEncoding) errorFlag = True continue except ReadFileError, e: print _('Error in %(filename)s - %(details)s') % \ {'filename': fileName.encode(TreeDoc.localEncoding), \ 'details': e} errorFlag = True continue try: newFileName = self.exportFile(fileName, exportType) if not self.quiet: print _('File "%(infile)s" (%(intype)s type) was exported'\ ' to "%(outfile)s" (%(outtype)s type)') \ % {'infile': fileName.encode(TreeDoc.localEncoding), \ 'intype': importType, \ 'outfile': newFileName.encode(TreeDoc.localEncoding), \ 'outtype': exportType} except IOError: errorFlag = True if errorFlag: sys.exit(1) def importFile(self, fileName, importType): """Import file using importType""" if importType == 'trl': importType = 'File' getattr(self.doc, 'read%s' % importType.title())(fileName) def exportFile(self, oldFileName, exportType): """Export file using exportType, return new filename on success""" if exportType == 'trl': fileName = self.newFileName(oldFileName, '.trl') self.doc.writeFile(fileName) elif exportType == 'html': fileName = self.newFileName(oldFileName, '.html') self.doc.exportHtml(fileName, self.doc.root, self.includeRoot, \ False, self.indent, self.addHeader) elif exportType == 'dir': dirName = os.path.split(oldFileName)[0] if not dirName: dirName = '.' fileName = dirName self.doc.exportDir(dirName, self.doc.root, self.addHeader) elif exportType == 'xslt': fileName = self.newFileName(oldFileName, '.xsl') self.doc.exportXslt(fileName, self.doc.root, self.indent) elif exportType == 'tabbed': fileName = self.newFileName(oldFileName, '.txt') self.doc.exportTabbedTitles(fileName, self.doc.root, \ self.includeRoot) elif exportType == 'table': fileName = self.newFileName(oldFileName, '.tbl') self.doc.exportTable(fileName, self.doc.root) elif exportType == 'xbel': fileName = self.newFileName(oldFileName, '.xml') self.doc.exportXbel(fileName, self.doc.root) elif exportType == 'mozilla': fileName = self.newFileName(oldFileName, '.html') self.doc.exportHtmlBookmarks(fileName, self.doc.root) elif exportType == 'xml': fileName = self.newFileName(oldFileName, '.xml') self.doc.exportGenericXml(fileName, self.doc.root) return fileName def newFileName(self, oldFileName, newExt): """Return a new filename with a new extension, add an underscore to base name if the names are the same""" if self.outfile: return self.outfile baseName, oldExt = os.path.splitext(oldFileName) if oldExt == newExt: baseName += '_' return baseName + newExt