improve pylint score on some CLI files

cli/arghandler.py went from 8.30 to 9.52
cli/argparser.py went from 8.43 to 9.74
cli/grampscli.py went from 7.99 to 9.29
cli/plug/__init__.py went from 7.63 to 9.69
This commit is contained in:
Paul Franklin 2016-07-25 12:56:56 -07:00
parent 6efe71d303
commit a512c9d5eb
4 changed files with 338 additions and 279 deletions

View File

@ -117,7 +117,7 @@ def _split_options(options_str):
#print char, "This character ends the list" #print char, "This character ends the list"
in_list = False in_list = False
value += char value += char
elif not in_quotes and ( char == '"' or char == "'"): elif not in_quotes and (char == '"' or char == "'"):
#print char, "This character starts a quoted string" #print char, "This character starts a quoted string"
in_quotes = True in_quotes = True
quote_type = char quote_type = char
@ -155,9 +155,9 @@ class ArgHandler:
""" """
def __init__(self, dbstate, parser, sessionmanager, def __init__(self, dbstate, parser, sessionmanager,
errorfunc=None, gui=False): errorfunc=None, gui=False):
self.dbstate = dbstate self.dbstate = dbstate
self.sm = sessionmanager self.smgr = sessionmanager
self.errorfunc = errorfunc self.errorfunc = errorfunc
self.gui = gui self.gui = gui
self.user = sessionmanager.user self.user = sessionmanager.user
@ -176,7 +176,7 @@ class ArgHandler:
self.imp_db_path = None self.imp_db_path = None
self.dbman = CLIDbManager(self.dbstate) self.dbman = CLIDbManager(self.dbstate)
self.force_unlock = parser.force_unlock self.force_unlock = parser.force_unlock
self.cl = 0 self.cl_bool = False
self.imports = [] self.imports = []
self.exports = [] self.exports = []
self.removes = parser.removes self.removes = parser.removes
@ -221,22 +221,25 @@ class ArgHandler:
# We have a potential database path. # We have a potential database path.
# Check if it is good. # Check if it is good.
if not self.check_db(db_path, self.force_unlock): if not self.check_db(db_path, self.force_unlock):
sys.exit(0) sys.exit(1)
if create: if create:
self.__error( _("Error: Family Tree '%s' already exists.\n" self.__error(_("Error: Family Tree '%s' already exists.\n"
"The '-C' option cannot be used.") % value) "The '-C' option cannot be used."
sys.exit(0) ) % value)
sys.exit(1)
return db_path return db_path
elif create: elif create:
# create the tree here, and continue # create the tree here, and continue
dbid = config.get('database.backend') dbid = config.get('database.backend')
db_path, title = self.dbman.create_new_db_cli(title=value, dbid=dbid) db_path, title = self.dbman.create_new_db_cli(title=value,
dbid=dbid)
return db_path return db_path
else: else:
self.__error( _('Error: Input Family Tree "%s" does not exist.\n' self.__error(_('Error: Input Family Tree "%s" does not exist.\n'
"If GEDCOM, Gramps-xml or grdb, use the -i option " "If GEDCOM, Gramps-xml or grdb, use the -i option "
"to import into a Family Tree instead.") % value) "to import into a Family Tree instead."
sys.exit(0) ) % value)
sys.exit(1)
def __handle_import_option(self, value, family_tree_format): def __handle_import_option(self, value, family_tree_format):
""" """
@ -247,7 +250,7 @@ class ArgHandler:
fullpath = os.path.abspath(os.path.expanduser(fname)) fullpath = os.path.abspath(os.path.expanduser(fname))
if fname != '-' and not os.path.exists(fullpath): if fname != '-' and not os.path.exists(fullpath):
self.__error(_('Error: Import file %s not found.') % fname) self.__error(_('Error: Import file %s not found.') % fname)
sys.exit(0) sys.exit(1)
if family_tree_format is None: if family_tree_format is None:
# Guess the file format based on the file extension. # Guess the file format based on the file extension.
@ -265,10 +268,10 @@ class ArgHandler:
self.imports.append((fname, family_tree_format)) self.imports.append((fname, family_tree_format))
else: else:
self.__error(_('Error: Unrecognized type: "%(format)s" for ' self.__error(_('Error: Unrecognized type: "%(format)s" for '
'import file: %(filename)s') % 'import file: %(filename)s'
{'format' : family_tree_format, ) % {'format' : family_tree_format,
'filename' : fname}) 'filename' : fname})
sys.exit(0) sys.exit(1)
def __handle_export_option(self, value, family_tree_format): def __handle_export_option(self, value, family_tree_format):
""" """
@ -286,14 +289,15 @@ class ArgHandler:
if os.path.exists(fullpath): if os.path.exists(fullpath):
message = _("WARNING: Output file already exists!\n" message = _("WARNING: Output file already exists!\n"
"WARNING: It will be overwritten:\n %s" "WARNING: It will be overwritten:\n %s"
) % fullpath ) % fullpath
accepted = self.user.prompt(_('OK to overwrite?'), message, accepted = self.user.prompt(_('OK to overwrite?'), message,
_('yes'), _('no'), default_label=_('yes')) _('yes'), _('no'),
default_label=_('yes'))
if accepted: if accepted:
self.__error(_("Will overwrite the existing file: %s") self.__error(_("Will overwrite the existing file: %s"
% fullpath) ) % fullpath)
else: else:
sys.exit(0) sys.exit(1)
if family_tree_format is None: if family_tree_format is None:
# Guess the file format based on the file extension. # Guess the file format based on the file extension.
@ -310,9 +314,9 @@ class ArgHandler:
if plugin_found: if plugin_found:
self.exports.append((fullpath, family_tree_format)) self.exports.append((fullpath, family_tree_format))
else: else:
self.__error(_("ERROR: Unrecognized format for export file %s") self.__error(_("ERROR: Unrecognized format for export file %s"
% fname) ) % fname)
sys.exit(0) sys.exit(1)
def __deduce_db_path(self, db_name_or_path): def __deduce_db_path(self, db_name_or_path):
""" """
@ -361,12 +365,13 @@ class ArgHandler:
if not db_path: if not db_path:
# Apparently it is not a database. See if it is a file that # Apparently it is not a database. See if it is a file that
# can be imported. # can be imported.
db_path, title = self.dbman.import_new_db(self.open_gui, self.user) db_path, title = self.dbman.import_new_db(self.open_gui,
self.user)
if db_path: if db_path:
# Test if not locked or problematic # Test if not locked or problematic
if not self.check_db(db_path, self.force_unlock): if not self.check_db(db_path, self.force_unlock):
sys.exit(0) sys.exit(1)
# Add the file to the recent items # Add the file to the recent items
title = self.dbstate.db.get_dbname() title = self.dbstate.db.get_dbname()
if not title: if not title:
@ -375,7 +380,7 @@ class ArgHandler:
self.open = db_path self.open = db_path
self.__open_action() self.__open_action()
else: else:
sys.exit(0) sys.exit(1)
return db_path return db_path
# if not open_gui, parse any command line args. We can only have one # if not open_gui, parse any command line args. We can only have one
@ -398,12 +403,13 @@ class ArgHandler:
for name, dirname in sorted(self.dbman.family_tree_list(), for name, dirname in sorted(self.dbman.family_tree_list(),
key=lambda pair: pair[0].lower()): key=lambda pair: pair[0].lower()):
if (self.database_names is None or if (self.database_names is None
any([(re.match("^" + dbname + "$", name) or or any([(re.match("^" + dbname + "$", name)
dbname == name) or dbname == name)
for dbname in self.database_names])): for dbname in self.database_names])):
print(_("%(full_DB_path)s with name \"%(f_t_name)s\"") print(_('%(full_DB_path)s with name "%(f_t_name)s"'
% {'full_DB_path' : dirname, 'f_t_name' : name}) ) % {'full_DB_path' : dirname,
'f_t_name' : name})
return return
# Handle the "--remove" Family Tree # Handle the "--remove" Family Tree
@ -427,11 +433,12 @@ class ArgHandler:
# insertion of blank spaces when print on the same line is used # insertion of blank spaces when print on the same line is used
line_list = [_("Family Tree")] line_list = [_("Family Tree")]
for key in sorted(summary_list[0]): for key in sorted(summary_list[0]):
if key != _("Family Tree"): if key != _("Family Tree"):
line_list += [key] line_list += [key]
print("\t".join(line_list)) print("\t".join(line_list))
for summary in sorted(summary_list, for summary in sorted(summary_list,
key=lambda sum: sum[_("Family Tree")].lower()): key=lambda
sum: sum[_("Family Tree")].lower()):
line_list = [(_('"%s"') % summary[_("Family Tree")])] line_list = [(_('"%s"') % summary[_("Family Tree")])]
for item in sorted(summary): for item in sorted(summary):
if item != _("Family Tree"): if item != _("Family Tree"):
@ -444,22 +451,27 @@ class ArgHandler:
self.__import_action() self.__import_action()
for (action, op_string) in self.actions: for (action, op_string) in self.actions:
print(_("Performing action: %s.") % action, file=sys.stderr) print(_("Performing action: %s."
) % action,
file=sys.stderr)
if op_string: if op_string:
print(_("Using options string: %s") print(_("Using options string: %s"
% op_string, file=sys.stderr) ) % op_string,
file=sys.stderr)
self.cl_action(action, op_string) self.cl_action(action, op_string)
for expt in self.exports: for expt in self.exports:
print(_("Exporting: file %(filename)s, format %(format)s.") print(_("Exporting: file %(filename)s, format %(format)s."
% {'filename' : expt[0], ) % {'filename' : expt[0],
'format' : expt[1]}, file=sys.stderr) 'format' : expt[1]},
file=sys.stderr)
self.cl_export(expt[0], expt[1]) self.cl_export(expt[0], expt[1])
if cleanup: if cleanup:
self.cleanup() self.cleanup()
def cleanup(self): def cleanup(self):
""" clean up any remaining files """
print(_("Cleaning up."), file=sys.stderr) print(_("Cleaning up."), file=sys.stderr)
# remove files in import db subdir after use # remove files in import db subdir after use
self.dbstate.db.close() self.dbstate.db.close()
@ -478,13 +490,14 @@ class ArgHandler:
have happened that is now finished), if this is GUI, it is opened. have happened that is now finished), if this is GUI, it is opened.
""" """
if self.imports: if self.imports:
self.cl = bool(self.exports or self.actions or self.cl) self.cl_bool = bool(self.exports or self.actions or self.cl_bool)
if not self.open: if not self.open:
# Create empty dir for imported database(s) # Create empty dir for imported database(s)
if self.gui: if self.gui:
dbid = config.get('database.backend') dbid = config.get('database.backend')
self.imp_db_path, title = self.dbman.create_new_db_cli(dbid=dbid) self.imp_db_path, title = self.dbman.create_new_db_cli(
dbid=dbid)
else: else:
self.imp_db_path = get_empty_tempdir("import_dbdir") self.imp_db_path = get_empty_tempdir("import_dbdir")
dbid = config.get('database.backend') dbid = config.get('database.backend')
@ -492,17 +505,18 @@ class ArgHandler:
newdb.write_version(self.imp_db_path) newdb.write_version(self.imp_db_path)
try: try:
self.sm.open_activate(self.imp_db_path) self.smgr.open_activate(self.imp_db_path)
msg = _("Created empty Family Tree successfully") msg = _("Created empty Family Tree successfully")
print(msg, file=sys.stderr) print(msg, file=sys.stderr)
except: except:
print(_("Error opening the file."), file=sys.stderr) print(_("Error opening the file."), file=sys.stderr)
print(_("Exiting..."), file=sys.stderr) print(_("Exiting..."), file=sys.stderr)
sys.exit(0) sys.exit(1)
for imp in self.imports: for imp in self.imports:
msg = _("Importing: file %(filename)s, format %(format)s.") % \ msg = _("Importing: file %(filename)s, format %(format)s."
{'filename' : imp[0], 'format' : imp[1]} ) % {'filename' : imp[0],
'format' : imp[1]}
print(msg, file=sys.stderr) print(msg, file=sys.stderr)
self.cl_import(imp[0], imp[1]) self.cl_import(imp[0], imp[1])
@ -514,18 +528,18 @@ class ArgHandler:
if self.open: if self.open:
# Family Tree to open was given. Open it # Family Tree to open was given. Open it
# Then go on and process the rest of the command line arguments. # Then go on and process the rest of the command line arguments.
self.cl = bool(self.exports or self.actions) self.cl_bool = bool(self.exports or self.actions)
# we load this file for use # we load this file for use
try: try:
self.sm.open_activate(self.open) self.smgr.open_activate(self.open)
print(_("Opened successfully!"), file=sys.stderr) print(_("Opened successfully!"), file=sys.stderr)
except: except:
print(_("Error opening the file."), file=sys.stderr) print(_("Error opening the file."), file=sys.stderr)
print(_("Exiting..."), file=sys.stderr) print(_("Exiting..."), file=sys.stderr)
sys.exit(0) sys.exit(1)
def check_db(self, dbpath, force_unlock = False): def check_db(self, dbpath, force_unlock=False):
""" """
Test a given family tree path if it can be opened. Test a given family tree path if it can be opened.
""" """
@ -537,7 +551,7 @@ class ArgHandler:
_(" Info: %s")) % find_locker_name(dbpath)) _(" Info: %s")) % find_locker_name(dbpath))
return False return False
if self.dbman.needs_recovery(dbpath): if self.dbman.needs_recovery(dbpath):
self.__error( _("Database needs recovery, cannot open it!")) self.__error(_("Database needs recovery, cannot open it!"))
return False return False
return True return True
@ -589,7 +603,7 @@ class ArgHandler:
except: except:
options_str_dict = {} options_str_dict = {}
print(_("Ignoring invalid options string."), print(_("Ignoring invalid options string."),
file=sys.stderr) file=sys.stderr)
name = options_str_dict.pop('name', None) name = options_str_dict.pop('name', None)
_cl_list = pmgr.get_reg_reports(gui=False) _cl_list = pmgr.get_reg_reports(gui=False)
@ -615,29 +629,30 @@ class ArgHandler:
msg = _("Unknown report name.") msg = _("Unknown report name.")
else: else:
msg = _("Report name not given. " msg = _("Report name not given. "
"Please use one of %(donottranslate)s=reportname") % \ "Please use one of %(donottranslate)s=reportname"
{'donottranslate' : '[-p|--options] name'} ) % {'donottranslate' : '[-p|--options] name'}
print(_("%s\n Available names are:") % msg, file=sys.stderr) print(_("%s\n Available names are:") % msg, file=sys.stderr)
for pdata in sorted(_cl_list, key= lambda pdata: pdata.id.lower()): for pdata in sorted(_cl_list, key=lambda pdata: pdata.id.lower()):
# Print cli report name ([item[0]), GUI report name (item[4]) # Print cli report name ([item[0]), GUI report name (item[4])
if len(pdata.id) <= 25: if len(pdata.id) <= 25:
print(" %s%s- %s" print(" %s%s- %s" % (pdata.id,
% ( pdata.id, " " * (26 - len(pdata.id)), " " * (26 - len(pdata.id)),
pdata.name), file=sys.stderr) pdata.name),
file=sys.stderr)
else: else:
print(" %s\t- %s" print(" %s\t- %s" % (pdata.id, pdata.name),
% (pdata.id, pdata.name), file=sys.stderr) file=sys.stderr)
elif action == "tool": elif action == "tool":
from gramps.gui.plug import tool from gramps.gui.plug import tool
try: try:
options_str_dict = dict( [ tuple(chunk.split('=')) for options_str_dict = dict([tuple(chunk.split('='))
chunk in options_str.split(',') ] ) for chunk in options_str.split(',')])
except: except:
options_str_dict = {} options_str_dict = {}
print(_("Ignoring invalid options string."), print(_("Ignoring invalid options string."),
file=sys.stderr) file=sys.stderr)
name = options_str_dict.pop('name', None) name = options_str_dict.pop('name', None)
_cli_tool_list = pmgr.get_reg_tools(gui=False) _cli_tool_list = pmgr.get_reg_tools(gui=False)
@ -651,32 +666,32 @@ class ArgHandler:
category = pdata.category category = pdata.category
tool_class = eval('mod.' + pdata.toolclass) tool_class = eval('mod.' + pdata.toolclass)
options_class = eval('mod.' + pdata.optionclass) options_class = eval('mod.' + pdata.optionclass)
tool.cli_tool( tool.cli_tool(dbstate=self.dbstate,
dbstate=self.dbstate, name=name,
name=name, category=category,
category=category, tool_class=tool_class,
tool_class=tool_class, options_class=options_class,
options_class=options_class, options_str_dict=options_str_dict,
options_str_dict=options_str_dict, user=self.user)
user=self.user)
return return
msg = _("Unknown tool name.") msg = _("Unknown tool name.")
else: else:
msg = _("Tool name not given. " msg = _("Tool name not given. "
"Please use one of %(donottranslate)s=toolname.") % \ "Please use one of %(donottranslate)s=toolname."
{'donottranslate' : '[-p|--options] name'} ) % {'donottranslate' : '[-p|--options] name'}
print(_("%s\n Available names are:") % msg, file=sys.stderr) print(_("%s\n Available names are:") % msg, file=sys.stderr)
for pdata in sorted(_cli_tool_list, for pdata in sorted(_cli_tool_list,
key=lambda pdata: pdata.id.lower()): key=lambda pdata: pdata.id.lower()):
# Print cli report name ([item[0]), GUI report name (item[4]) # Print cli report name ([item[0]), GUI report name (item[4])
if len(pdata.id) <= 25: if len(pdata.id) <= 25:
print(" %s%s- %s" print(" %s%s- %s" % (pdata.id,
% ( pdata.id, " " * (26 - len(pdata.id)), " " * (26 - len(pdata.id)),
pdata.name), file=sys.stderr) pdata.name),
file=sys.stderr)
else: else:
print(" %s\t- %s" print(" %s\t- %s" % (pdata.id, pdata.name),
% (pdata.id, pdata.name), file=sys.stderr) file=sys.stderr)
elif action == "book": elif action == "book":
try: try:
@ -684,7 +699,7 @@ class ArgHandler:
except: except:
options_str_dict = {} options_str_dict = {}
print(_("Ignoring invalid options string."), print(_("Ignoring invalid options string."),
file=sys.stderr) file=sys.stderr)
name = options_str_dict.pop('name', None) name = options_str_dict.pop('name', None)
book_list = BookList('books.xml', self.dbstate.db) book_list = BookList('books.xml', self.dbstate.db)
@ -696,8 +711,8 @@ class ArgHandler:
msg = _("Unknown book name.") msg = _("Unknown book name.")
else: else:
msg = _("Book name not given. " msg = _("Book name not given. "
"Please use one of %(donottranslate)s=bookname.") % \ "Please use one of %(donottranslate)s=bookname."
{'donottranslate' : '[-p|--options] name'} ) % {'donottranslate' : '[-p|--options] name'}
print(_("%s\n Available names are:") % msg, file=sys.stderr) print(_("%s\n Available names are:") % msg, file=sys.stderr)
for name in sorted(book_list.get_book_names()): for name in sorted(book_list.get_book_names()):
@ -705,4 +720,4 @@ class ArgHandler:
else: else:
print(_("Unknown action: %s.") % action, file=sys.stderr) print(_("Unknown action: %s.") % action, file=sys.stderr)
sys.exit(0) sys.exit(1)

View File

@ -172,7 +172,7 @@ class ArgParser:
If both input (-O or -i) and processing (-e or -a) options are given, If both input (-O or -i) and processing (-e or -a) options are given,
interactive session will not be launched. interactive session will not be launched.
When using import ot export options (-i or -e), the -f option may be When using import or export options (-i or -e), the -f option may be
specified to indicate the family tree format. specified to indicate the family tree format.
Possible values for ``ACTION`` are: 'report', 'book' and 'tool'. Possible values for ``ACTION`` are: 'report', 'book' and 'tool'.
@ -226,11 +226,13 @@ class ArgParser:
""" """
try: try:
options, leftargs = getopt.getopt(self.args[1:], options, leftargs = getopt.getopt(self.args[1:],
SHORTOPTS, LONGOPTS) SHORTOPTS, LONGOPTS)
except getopt.GetoptError as msg: except getopt.GetoptError as msg:
# Extract the arguments in the list. # Extract the arguments in the list.
# The % operator replaces the list elements with repr() of the list elemements # The % operator replaces the list elements
# which is OK for latin characters, but not for non latin characters in list elements # with repr() of the list elements
# which is OK for latin characters,
# but not for non latin characters in list elements
cliargs = "[ " cliargs = "[ "
for arg in range(len(self.args) - 1): for arg in range(len(self.args) - 1):
cliargs += self.args[arg + 1] + " " cliargs += self.args[arg + 1] + " "
@ -238,10 +240,11 @@ class ArgParser:
# Must first do str() of the msg object. # Must first do str() of the msg object.
msg = str(msg) msg = str(msg)
self.errors += [(_('Error parsing the arguments'), self.errors += [(_('Error parsing the arguments'),
msg + '\n' + msg + '\n' +
_("Error parsing the arguments: %s \n" _("Error parsing the arguments: %s \n"
"Type gramps --help for an overview of commands, or " "Type gramps --help for an overview of "
"read the manual pages.") % cliargs)] "commands, or read the manual pages."
) % cliargs)]
return return
# Some args can work on a list of databases: # Some args can work on a list of databases:
@ -256,8 +259,9 @@ class ArgParser:
# if there were an argument without option, # if there were an argument without option,
# use it as a file to open and return # use it as a file to open and return
self.open_gui = leftargs[0] self.open_gui = leftargs[0]
print(_("Trying to open: %s ...") % leftargs[0], print(_("Trying to open: %s ..."
file=sys.stderr) ) % leftargs[0],
file=sys.stderr)
#see if force open is on #see if force open is on
for opt_ix in range(len(options)): for opt_ix in range(len(options)):
option, value = options[opt_ix] option, value = options[opt_ix]
@ -277,27 +281,28 @@ class ArgParser:
self.create = value self.create = value
elif option in ['-i', '--import']: elif option in ['-i', '--import']:
family_tree_format = None family_tree_format = None
if opt_ix < len(options) - 1 \ if (opt_ix < len(options) - 1
and options[opt_ix + 1][0] in ( '-f', '--format'): and options[opt_ix + 1][0] in ('-f', '--format')):
family_tree_format = options[opt_ix + 1][1] family_tree_format = options[opt_ix + 1][1]
self.imports.append((value, family_tree_format)) self.imports.append((value, family_tree_format))
elif option in ['-r', '--remove']: elif option in ['-r', '--remove']:
self.removes.append(value) self.removes.append(value)
elif option in ['-e', '--export']: elif option in ['-e', '--export']:
family_tree_format = None family_tree_format = None
if opt_ix < len(options) - 1 \ if (opt_ix < len(options) - 1
and options[opt_ix + 1][0] in ( '-f', '--format'): and options[opt_ix + 1][0] in ('-f', '--format')):
family_tree_format = options[opt_ix + 1][1] family_tree_format = options[opt_ix + 1][1]
self.exports.append((value, family_tree_format)) self.exports.append((value, family_tree_format))
elif option in ['-a', '--action']: elif option in ['-a', '--action']:
action = value action = value
if action not in ('report', 'tool', 'book'): if action not in ('report', 'tool', 'book'):
print(_("Unknown action: %s. Ignoring.") % action, print(_("Unknown action: %s. Ignoring."
file=sys.stderr) ) % action,
file=sys.stderr)
continue continue
options_str = "" options_str = ""
if opt_ix < len(options)-1 \ if (opt_ix < len(options)-1
and options[opt_ix+1][0] in ( '-p', '--options' ): and options[opt_ix+1][0] in ('-p', '--options')):
options_str = options[opt_ix+1][1] options_str = options[opt_ix+1][1]
self.actions.append((action, options_str)) self.actions.append((action, options_str))
elif option in ['-d', '--debug']: elif option in ['-d', '--debug']:
@ -311,17 +316,16 @@ class ArgParser:
self.list_more = True self.list_more = True
elif option in ['-t']: elif option in ['-t']:
self.list_table = True self.list_table = True
elif option in ['-s','--show']: elif option in ['-s', '--show']:
print(_("Gramps config settings from %s:") print(_("Gramps config settings from %s:"
% config.filename) ) % config.filename)
for section in config.data: for sect in config.data:
for setting in config.data[section]: for setting in config.data[sect]:
print("%s.%s=%s" print("%s.%s=%s" % (sect, setting,
% (section, setting, repr(config.data[sect][setting])))
repr(config.data[section][setting])))
print() print()
sys.exit(0) sys.exit(0)
elif option in ['-b','--databases']: elif option in ['-b', '--databases']:
default = config.data["behavior"]["database-backend"] default = config.data["behavior"]["database-backend"]
pmgr = BasePluginManager.get_instance() pmgr = BasePluginManager.get_instance()
pmgr.reg_plugins(PLUGINS_DIR, self, None) pmgr.reg_plugins(PLUGINS_DIR, self, None)
@ -332,44 +336,46 @@ class ArgParser:
if mod: if mod:
database = getattr(mod, pdata.databaseclass) database = getattr(mod, pdata.databaseclass)
summary = database.get_class_summary() summary = database.get_class_summary()
print("Database backend ID:", pdata.id, "(default)" if pdata.id == default else "") print("Database backend ID:",
pdata.id,
"(default)" if pdata.id == default else "")
for key in sorted(summary.keys()): for key in sorted(summary.keys()):
print(" ", "%s:" % key, summary[key]) print(" ", _("%s:") % key, summary[key])
sys.exit(0) sys.exit(0)
elif option in ['-c', '--config']: elif option in ['-c', '--config']:
setting_name = value cfg_name = value
set_value = False set_value = False
if setting_name: if cfg_name:
if ":" in setting_name: if ":" in cfg_name:
setting_name, new_value = setting_name.split(":", 1) cfg_name, new_value = cfg_name.split(":", 1)
set_value = True set_value = True
if config.has_default(setting_name): if config.has_default(cfg_name):
setting_value = config.get(setting_name) setting_value = config.get(cfg_name)
print(_("Current Gramps config setting: " print(_("Current Gramps config setting: "
"%(name)s:%(value)s") "%(name)s:%(value)s"
% {'name' : setting_name, ) % {'name' : cfg_name,
'value' : repr(setting_value)}, 'value' : repr(setting_value)},
file=sys.stderr) file=sys.stderr)
if set_value: if set_value:
# does a user want the default config value? # does a user want the default config value?
if new_value in ("DEFAULT", _("DEFAULT")): if new_value in ("DEFAULT", _("DEFAULT")):
new_value = config.get_default(setting_name) new_value = config.get_default(cfg_name)
else: else:
converter = get_type_converter(setting_value) converter = get_type_converter(setting_value)
new_value = converter(new_value) new_value = converter(new_value)
config.set(setting_name, new_value) config.set(cfg_name, new_value)
# translators: indent "New" to match "Current" # translators: indent "New" to match "Current"
print(_(" New Gramps config setting: " print(_(" New Gramps config setting: "
"%(name)s:%(value)s") % "%(name)s:%(value)s"
{'name' : setting_name, ) % {'name' : cfg_name,
'value' : repr( 'value' : repr(config.get(cfg_name))},
config.get(setting_name))},
file=sys.stderr) file=sys.stderr)
else: else:
need_to_quit = True need_to_quit = True
else: else:
print(_("Gramps: no such config setting: '%s'") print(_("Gramps: no such config setting: '%s'"
% setting_name, file=sys.stderr) ) % cfg_name,
file=sys.stderr)
need_to_quit = True need_to_quit = True
cleandbg += [opt_ix] cleandbg += [opt_ix]
elif option in ['-h', '-?', '--help']: elif option in ['-h', '-?', '--help']:
@ -388,10 +394,14 @@ class ArgParser:
for ind in cleandbg: for ind in cleandbg:
del options[ind] del options[ind]
if (len(options) > 0 and self.open is None and self.imports == [] if (len(options) > 0
and self.removes == [] and self.open is None
and not (self.list or self.list_more or self.list_table or and self.imports == []
self.help)): and self.removes == []
and not (self.list
or self.list_more
or self.list_table
or self.help)):
# Extract and convert to unicode the arguments in the list. # Extract and convert to unicode the arguments in the list.
# The % operator replaces the list elements with repr() of # The % operator replaces the list elements with repr() of
# the list elements, which is OK for latin characters # the list elements, which is OK for latin characters
@ -403,7 +413,8 @@ class ArgParser:
self.errors += [(_('Error parsing the arguments'), self.errors += [(_('Error parsing the arguments'),
_("Error parsing the arguments: %s \n" _("Error parsing the arguments: %s \n"
"To use in the command-line mode, supply at " "To use in the command-line mode, supply at "
"least one input file to process.") % cliargs)] "least one input file to process."
) % cliargs)]
if need_to_quit: if need_to_quit:
sys.exit(0) sys.exit(0)
@ -429,8 +440,8 @@ class ArgParser:
return True return True
# If we have data to work with: # If we have data to work with:
if (self.open or self.imports): if self.open or self.imports:
if (self.exports or self.actions): if self.exports or self.actions:
# have both data and what to do with it => no GUI # have both data and what to do with it => no GUI
return False return False
elif self.create: elif self.create:

View File

@ -99,12 +99,15 @@ class CLIDbLoader:
.. note:: Inherit for GUI action .. note:: Inherit for GUI action
""" """
self._errordialog( '', _("Low level database corruption detected") self._errordialog(
'',
_("Low level database corruption detected")
+ '\n' + + '\n' +
_("Gramps has detected a problem in the underlying " _("Gramps has detected a problem in the underlying "
"Berkeley database. This can be repaired from " "Berkeley database. This can be repaired from "
"the Family Tree Manager. Select the database and " "the Family Tree Manager. Select the database and "
'click on the Repair button') + '\n\n' + str(msg)) 'click on the Repair button'
) + '\n\n' + str(msg))
def _begin_progress(self): def _begin_progress(self):
""" """
@ -146,8 +149,8 @@ class CLIDbLoader:
if not os.access(filename, os.W_OK): if not os.access(filename, os.W_OK):
mode = "r" mode = "r"
self._warn(_('Read only database'), self._warn(_('Read only database'),
_('You do not have write access ' _('You do not have write access '
'to the selected file.')) 'to the selected file.'))
else: else:
mode = "w" mode = "w"
else: else:
@ -155,8 +158,8 @@ class CLIDbLoader:
dbid_path = os.path.join(filename, DBBACKEND) dbid_path = os.path.join(filename, DBBACKEND)
if os.path.isfile(dbid_path): if os.path.isfile(dbid_path):
with open(dbid_path) as fp: with open(dbid_path) as file:
dbid = fp.read().strip() dbid = file.read().strip()
else: else:
dbid = "bsddb" dbid = "bsddb"
@ -172,31 +175,31 @@ class CLIDbLoader:
self.dbstate.db.set_save_path(filename) self.dbstate.db.set_save_path(filename)
except DbEnvironmentError as msg: except DbEnvironmentError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except BsddbUpgradeRequiredError as msg: except BsddbUpgradeRequiredError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except BsddbDowngradeRequiredError as msg: except BsddbDowngradeRequiredError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except BsddbDowngradeError as msg: except BsddbDowngradeError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except DbUpgradeRequiredError as msg: except DbUpgradeRequiredError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except PythonDowngradeError as msg: except PythonDowngradeError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except PythonUpgradeRequiredError as msg: except PythonUpgradeRequiredError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except DbVersionError as msg: except DbVersionError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except DbPythonError as msg: except DbPythonError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( _("Cannot open database"), str(msg)) self._errordialog(_("Cannot open database"), str(msg))
except OSError as msg: except OSError as msg:
self.dbstate.no_database() self.dbstate.no_database()
self._errordialog( self._errordialog(
@ -217,8 +220,9 @@ class CLIDbLoader:
class CLIManager: class CLIManager:
""" """
Sessionmanager for Gramps. This is in effect a reduced :class:`.ViewManager` Sessionmanager for Gramps.
instance (see gui/viewmanager), suitable for CLI actions. This is in effect a reduced :class:`.ViewManager` instance
(see gui/viewmanager), suitable for CLI actions.
Aim is to manage a dbstate on which to work (load, unload), and interact Aim is to manage a dbstate on which to work (load, unload), and interact
with the plugin session with the plugin session
""" """
@ -249,20 +253,21 @@ class CLIManager:
""" """
Called when a file needs to be loaded Called when a file needs to be loaded
""" """
# A recent database should already have a directory If not, do nothing, # A recent database should already have a directory.
# just return. This can be handled better if family tree delete/rename # If not, do nothing, just return.
# also updated the recent file menu info in displaystate.py # This can be handled better if family tree delete/rename
# also updated the recent file menu info in displaystate.py
if not os.path.isdir(filename): if not os.path.isdir(filename):
self._errordialog( self._errordialog(
_("Could not load a recent Family Tree."), _("Could not load a recent Family Tree."),
_("Family Tree does not exist, as it has been deleted.")) _("Family Tree does not exist, as it has been deleted."))
return return
if os.path.isfile(os.path.join(filename, "lock")): if os.path.isfile(os.path.join(filename, "lock")):
self._errordialog( self._errordialog(
_("The database is locked."), _("The database is locked."),
_("Use the --force-unlock option if you are sure " _("Use the --force-unlock option if you are sure "
"that the database is not in use.")) "that the database is not in use."))
return return
if self.db_loader.read_file(filename): if self.db_loader.read_file(filename):
@ -308,7 +313,9 @@ class CLIManager:
# If the DB Owner Info is empty and # If the DB Owner Info is empty and
# [default] Researcher is not empty and # [default] Researcher is not empty and
# database is empty, then copy default researcher to DB owner # database is empty, then copy default researcher to DB owner
if res.is_empty() and not owner.is_empty() and self.dbstate.db.is_empty(): if (res.is_empty()
and not owner.is_empty()
and self.dbstate.db.is_empty()):
self.dbstate.db.set_researcher(owner) self.dbstate.db.set_researcher(owner)
name_displayer.set_name_format(self.dbstate.db.name_formats) name_displayer.set_name_format(self.dbstate.db.name_formats)
@ -346,8 +353,8 @@ def startcli(errors, argparser):
sys.exit(1) sys.exit(1)
if argparser.errors: if argparser.errors:
errmsg = _('Error encountered in argument parsing: %s') \ errmsg = _('Error encountered in argument parsing: %s'
% argparser.errors[0][0] ) % argparser.errors[0][0]
print(errmsg, file=sys.stderr) print(errmsg, file=sys.stderr)
errmsg = _(' Details: %s') % argparser.errors[0][1] errmsg = _(' Details: %s') % argparser.errors[0][1]
print(errmsg, file=sys.stderr) print(errmsg, file=sys.stderr)
@ -358,9 +365,8 @@ def startcli(errors, argparser):
#we need a manager for the CLI session #we need a manager for the CLI session
from .user import User from .user import User
user=User(auto_accept=argparser.auto_accept, user = User(auto_accept=argparser.auto_accept, quiet=argparser.quiet)
quiet=argparser.quiet) climanager = CLIManager(dbstate, True, user)
climanager = CLIManager(dbstate, setloader=True, user=user)
#load the plugins #load the plugins
climanager.do_reg_plugins(dbstate, uistate=None) climanager.do_reg_plugins(dbstate, uistate=None)

View File

@ -26,6 +26,7 @@
# cli.plug.__init__ # cli.plug.__init__
# #
""" Enable report generation from the command line interface (CLI) """
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -37,7 +38,7 @@ import os
import sys import sys
import logging import logging
log = logging.getLogger(".") LOG = logging.getLogger(".")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -46,11 +47,12 @@ log = logging.getLogger(".")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.plug import BasePluginManager from gramps.gen.plug import BasePluginManager
from gramps.gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle, from gramps.gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle,
PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc) PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc)
from gramps.gen.plug.menu import (FamilyOption, PersonOption, NoteOption, from gramps.gen.plug.menu import (FamilyOption, PersonOption, NoteOption,
MediaOption, PersonListOption, NumberOption, MediaOption, PersonListOption, NumberOption,
BooleanOption, DestinationOption, StringOption, BooleanOption, DestinationOption, Option,
TextOption, EnumeratedListOption, Option) TextOption, EnumeratedListOption,
StringOption)
from gramps.gen.display.name import displayer as name_displayer from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.errors import ReportError, FilterError from gramps.gen.errors import ReportError, FilterError
from gramps.gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK, from gramps.gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
@ -77,8 +79,8 @@ def _convert_str_to_match_type(str_val, type_val):
ret_type = type(type_val) ret_type = type(type_val)
if isinstance(type_val, str): if isinstance(type_val, str):
if ( str_val.startswith("'") and str_val.endswith("'") ) or \ if ((str_val.startswith("'") and str_val.endswith("'"))
( str_val.startswith('"') and str_val.endswith('"') ): or (str_val.startswith('"') and str_val.endswith('"'))):
# Remove enclosing quotes # Remove enclosing quotes
return str(str_val[1:-1]) return str(str_val[1:-1])
else: else:
@ -109,7 +111,7 @@ def _convert_str_to_match_type(str_val, type_val):
elif ret_type == list: elif ret_type == list:
ret_val = [] ret_val = []
if not ( str_val.startswith("[") and str_val.endswith("]") ): if not (str_val.startswith("[") and str_val.endswith("]")):
print("'%s' is not a list-- try: [%s]" % (str_val, str_val)) print("'%s' is not a list-- try: [%s]" % (str_val, str_val))
return ret_val return ret_val
@ -166,7 +168,7 @@ def _validate_options(options, dbase):
person = dbase.get_person_from_handle(phandle) person = dbase.get_person_from_handle(phandle)
if not person: if not person:
print(_("ERROR: Please specify a person"), print(_("ERROR: Please specify a person"),
file=sys.stderr) file=sys.stderr)
if person: if person:
option.set_value(person.get_gramps_id()) option.set_value(person.get_gramps_id())
@ -214,15 +216,30 @@ class CommandLineReport:
self.__textdoc_plugins.append(plugin) self.__textdoc_plugins.append(plugin)
if plugin.get_draw_support() and plugin.get_extension(): if plugin.get_draw_support() and plugin.get_extension():
self.__drawdoc_plugins.append(plugin) self.__drawdoc_plugins.append(plugin)
if plugin.get_text_support() and \ if (plugin.get_extension()
plugin.get_draw_support() and \ and plugin.get_text_support()
plugin.get_extension(): and plugin.get_draw_support()):
self.__bookdoc_plugins.append(plugin) self.__bookdoc_plugins.append(plugin)
self.database = database self.database = database
self.category = category self.category = category
self.options_dict = None # keep pylint happy
self.options_help = None
self.paper = None
self.orien = None
self.marginl = None
self.marginr = None
self.margint = None
self.marginb = None
self.doc_options = None
self.doc_option_class = None
self.selected_style = None
self.style_list = None
self.css_filename = None
self.format = None self.format = None
self.raw_name = name self.raw_name = name
self.option_class = option_class(name, database) self.option_class = option_class(name, database)
if category == CATEGORY_GRAPHVIZ: if category == CATEGORY_GRAPHVIZ:
# Need to include Graphviz options # Need to include Graphviz options
@ -231,11 +248,12 @@ class CommandLineReport:
self.__gvoptions.add_menu_options(menu) self.__gvoptions.add_menu_options(menu)
for name in menu.get_all_option_names(): for name in menu.get_all_option_names():
if name not in self.option_class.options_dict: if name not in self.option_class.options_dict:
self.option_class.options_dict[name] = \ self.option_class.options_dict[
menu.get_option_by_name(name).get_value() name] = menu.get_option_by_name(name).get_value()
self.option_class.load_previous_values() self.option_class.load_previous_values()
_validate_options(self.option_class, database) _validate_options(self.option_class, database)
self.show = options_str_dict.pop('show', None) self.show = options_str_dict.pop('show', None)
self.options_str_dict = options_str_dict self.options_str_dict = options_str_dict
self.init_standard_options(noopt) self.init_standard_options(noopt)
self.init_report_options() self.init_report_options()
@ -250,8 +268,8 @@ class CommandLineReport:
self.options_dict = { self.options_dict = {
'of' : self.option_class.handler.module_name, 'of' : self.option_class.handler.module_name,
'off' : self.option_class.handler.get_format_name(), 'off' : self.option_class.handler.get_format_name(),
'style' : \ 'style' :
self.option_class.handler.get_default_stylesheet_name(), self.option_class.handler.get_default_stylesheet_name(),
'papers' : self.option_class.handler.get_paper_name(), 'papers' : self.option_class.handler.get_paper_name(),
'papero' : self.option_class.handler.get_orientation(), 'papero' : self.option_class.handler.get_orientation(),
'paperml' : self.option_class.handler.get_margins()[0], 'paperml' : self.option_class.handler.get_margins()[0],
@ -262,21 +280,22 @@ class CommandLineReport:
} }
self.options_help = { self.options_help = {
'of' : [_("=filename"), _("Output file name. MANDATORY"),""], 'of' : [_("=filename"),
_("Output file name. MANDATORY"), ""],
'off' : [_("=format"), _("Output file format."), []], 'off' : [_("=format"), _("Output file format."), []],
'style' : [_("=name"), _("Style name."), ""], 'style' : [_("=name"), _("Style name."), ""],
'papers' : [_("=name"), _("Paper size name."), ""], 'papers' : [_("=name"), _("Paper size name."), ""],
'papero' : [_("=number"), _("Paper orientation number."), ""], 'papero' : [_("=number"), _("Paper orientation number."), ""],
'paperml' : [_("=number"), _("Left paper margin"), 'paperml' : [_("=number"),
_("Size in cm")], _("Left paper margin"), _("Size in cm")],
'papermr' : [_("=number"), _("Right paper margin"), 'papermr' : [_("=number"),
_("Size in cm")], _("Right paper margin"), _("Size in cm")],
'papermt' : [_("=number"), _("Top paper margin"), 'papermt' : [_("=number"),
_("Size in cm")], _("Top paper margin"), _("Size in cm")],
'papermb' : [_("=number"), _("Bottom paper margin"), 'papermb' : [_("=number"),
_("Size in cm")], _("Bottom paper margin"), _("Size in cm")],
'css' : [_("=css filename"), _("CSS filename to use, " 'css' : [_("=css filename"),
"html format only"), ""], _("CSS filename to use, html format only"), ""],
} }
if noopt: if noopt:
@ -288,29 +307,28 @@ class CommandLineReport:
if self.category == CATEGORY_TEXT: if self.category == CATEGORY_TEXT:
for plugin in self.__textdoc_plugins: for plugin in self.__textdoc_plugins:
self.options_help['off'][2].append( self.options_help['off'][2].append(
plugin.get_extension() + "\t" + plugin.get_description() ) plugin.get_extension() + "\t" + plugin.get_description())
elif self.category == CATEGORY_DRAW: elif self.category == CATEGORY_DRAW:
for plugin in self.__drawdoc_plugins: for plugin in self.__drawdoc_plugins:
self.options_help['off'][2].append( self.options_help['off'][2].append(
plugin.get_extension() + "\t" + plugin.get_description() ) plugin.get_extension() + "\t" + plugin.get_description())
elif self.category == CATEGORY_BOOK: elif self.category == CATEGORY_BOOK:
for plugin in self.__bookdoc_plugins: for plugin in self.__bookdoc_plugins:
self.options_help['off'][2].append( self.options_help['off'][2].append(
plugin.get_extension() + "\t" + plugin.get_description() ) plugin.get_extension() + "\t" + plugin.get_description())
elif self.category == CATEGORY_GRAPHVIZ: elif self.category == CATEGORY_GRAPHVIZ:
for graph_format in graphdoc.FORMATS: for graph_format in graphdoc.FORMATS:
self.options_help['off'][2].append( self.options_help['off'][2].append(
graph_format["type"] + "\t" + graph_format["descr"] ) graph_format["type"] + "\t" + graph_format["descr"])
else: else:
self.options_help['off'][2] = "NA" self.options_help['off'][2] = "NA"
self.options_help['papers'][2] = \ self.options_help['papers'][2] = [
[ paper.get_name() for paper in paper_sizes paper.get_name() for paper in paper_sizes
if paper.get_name() != 'Custom Size' ] if paper.get_name() != 'Custom Size']
self.options_help['papero'][2] = [ self.options_help['papero'][2] = ["%d\tPortrait" % PAPER_PORTRAIT,
"%d\tPortrait" % PAPER_PORTRAIT, "%d\tLandscape" % PAPER_LANDSCAPE]
"%d\tLandscape" % PAPER_LANDSCAPE ]
self.options_help['css'][2] = os.path.join(USER_HOME, self.options_help['css'][2] = os.path.join(USER_HOME,
"whatever_name.css") "whatever_name.css")
@ -333,8 +351,8 @@ class CommandLineReport:
if self.category == CATEGORY_BOOK: # a Book Report has no "menu" if self.category == CATEGORY_BOOK: # a Book Report has no "menu"
for key in self.option_class.options_dict: for key in self.option_class.options_dict:
self.options_dict[key] = self.option_class.options_dict[key] self.options_dict[key] = self.option_class.options_dict[key]
self.options_help[key] = \ self.options_help[
self.option_class.options_help[key][:3] key] = self.option_class.options_help[key][:3]
# a Book Report can't have HTML output so "css" is meaningless # a Book Report can't have HTML output so "css" is meaningless
self.options_dict.pop('css') self.options_dict.pop('css')
@ -355,15 +373,15 @@ class CommandLineReport:
menu = self.option_class.menu menu = self.option_class.menu
for name in menu.get_all_option_names(): for name in menu.get_all_option_names():
option = menu.get_option_by_name(name) option = menu.get_option_by_name(name)
self.options_help[name] = [ "", option.get_help() ] self.options_help[name] = ["", option.get_help()]
if isinstance(option, PersonOption): if isinstance(option, PersonOption):
id_list = [] id_list = []
for person_handle in self.database.get_person_handles(True): for person_handle in self.database.get_person_handles(True):
person = self.database.get_person_from_handle(person_handle) person = self.database.get_person_from_handle(person_handle)
id_list.append("%s\t%s" % ( id_list.append("%s\t%s"
person.get_gramps_id(), % (person.get_gramps_id(),
name_displayer.display(person))) name_displayer.display(person)))
self.options_help[name].append(id_list) self.options_help[name].append(id_list)
elif isinstance(option, FamilyOption): elif isinstance(option, FamilyOption):
id_list = [] id_list = []
@ -380,8 +398,8 @@ class CommandLineReport:
father = self.database.get_person_from_handle(fhandle) father = self.database.get_person_from_handle(fhandle)
if father: if father:
fname = name_displayer.display(father) fname = name_displayer.display(father)
text = "%s:\t%s, %s" % \ text = "%s:\t%s, %s" % (family.get_gramps_id(),
(family.get_gramps_id(), fname, mname) fname, mname)
id_list.append(text) id_list.append(text)
self.options_help[name].append(id_list) self.options_help[name].append(id_list)
elif isinstance(option, NoteOption): elif isinstance(option, NoteOption):
@ -409,7 +427,7 @@ class CommandLineReport:
elif isinstance(option, TextOption): elif isinstance(option, TextOption):
self.options_help[name].append( self.options_help[name].append(
"A list of text values. Each entry in the list " "A list of text values. Each entry in the list "
"represents one line of text." ) "represents one line of text.")
elif isinstance(option, EnumeratedListOption): elif isinstance(option, EnumeratedListOption):
ilist = [] ilist = []
for (value, description) in option.get_items(): for (value, description) in option.get_items():
@ -427,11 +445,11 @@ class CommandLineReport:
print(_("Unknown option: %s") % option, file=sys.stderr) print(_("Unknown option: %s") % option, file=sys.stderr)
print(_(" Valid options are:") + print(_(" Valid options are:") +
", ".join(list(self.options_dict.keys())), ", ".join(list(self.options_dict.keys())),
file=sys.stderr) file=sys.stderr)
print(_(" Use '%(donottranslate)s' to see description " print(_(" Use '%(donottranslate)s' to see description "
"and acceptable values") "and acceptable values"
% {'donottranslate' : "show=option"}, ) % {'donottranslate' : "show=option"},
file=sys.stderr) file=sys.stderr)
def parse_options(self): def parse_options(self):
""" """
@ -460,9 +478,9 @@ class CommandLineReport:
elif self.category == CATEGORY_BOOK: elif self.category == CATEGORY_BOOK:
plugins = self.__bookdoc_plugins plugins = self.__bookdoc_plugins
for plugin in plugins: for plugin in plugins:
if plugin.get_extension() == self.options_dict['off']: if plugin.get_extension() == self.options_dict['off']:
self.format = plugin.get_basedoc() self.format = plugin.get_basedoc()
self.doc_option_class = plugin.get_doc_option_class() self.doc_option_class = plugin.get_doc_option_class()
if self.format is None: if self.format is None:
# Pick the first one as the default. # Pick the first one as the default.
plugin = plugins[0] plugin = plugins[0]
@ -482,24 +500,23 @@ class CommandLineReport:
self.format = None self.format = None
if _chosen_format and _format_str: if _chosen_format and _format_str:
print(_("Ignoring '%(notranslate1)s=%(notranslate2)s' " print(_("Ignoring '%(notranslate1)s=%(notranslate2)s' "
"and using '%(notranslate1)s=%(notranslate3)s'.") "and using '%(notranslate1)s=%(notranslate3)s'."
% {'notranslate1' : "off", ) % {'notranslate1' : "off",
'notranslate2' : self.options_dict['off'], 'notranslate2' : self.options_dict['off'],
'notranslate3' : _chosen_format}, 'notranslate3' : _chosen_format},
file=sys.stderr) file=sys.stderr)
print(_("Use '%(notranslate)s' to see valid values.") print(_("Use '%(notranslate)s' to see valid values."
% {'notranslate' : "show=off"}, file=sys.stderr) ) % {'notranslate' : "show=off"}, file=sys.stderr)
self.do_doc_options() self.do_doc_options()
for opt in self.options_str_dict: for opt in self.options_str_dict:
if opt in self.options_dict: if opt in self.options_dict:
self.options_dict[opt] = \ self.options_dict[opt] = _convert_str_to_match_type(
_convert_str_to_match_type(self.options_str_dict[opt], self.options_str_dict[opt], self.options_dict[opt])
self.options_dict[opt])
self.option_class.handler.options_dict[opt] = \ self.option_class.handler.options_dict[
self.options_dict[opt] opt] = self.options_dict[opt]
if menu and opt in menu_opt_names: if menu and opt in menu_opt_names:
option = menu.get_option_by_name(opt) option = menu.get_option_by_name(opt)
@ -509,10 +526,11 @@ class CommandLineReport:
print(_("Ignoring unknown option: %s") % opt, file=sys.stderr) print(_("Ignoring unknown option: %s") % opt, file=sys.stderr)
print(_(" Valid options are:"), print(_(" Valid options are:"),
", ".join(list(self.options_dict.keys())), ", ".join(list(self.options_dict.keys())),
file=sys.stderr) file=sys.stderr)
print(_(" Use '%(donottranslate)s' to see description " print(_(" Use '%(donottranslate)s' to see description "
"and acceptable values") % "and acceptable values"
{'donottranslate' : "show=option"}, file=sys.stderr) ) % {'donottranslate' : "show=option"},
file=sys.stderr)
self.option_class.handler.output = self.options_dict['of'] self.option_class.handler.output = self.options_dict['of']
@ -542,6 +560,9 @@ class CommandLineReport:
self.selected_style = self.style_list.get_style_sheet(style_name) self.selected_style = self.style_list.get_style_sheet(style_name)
def do_doc_options(self): def do_doc_options(self):
"""
Process docgen options, if any (options for the backend, e.g. AsciiDoc)
"""
self.doc_options = None self.doc_options = None
if not self.doc_option_class: if not self.doc_option_class:
return # this docgen type has no options return # this docgen type has no options
@ -558,9 +579,8 @@ class CommandLineReport:
for oname in docgen_menu.get_option_names('Document Options'): for oname in docgen_menu.get_option_names('Document Options'):
docgen_opt = docgen_menu.get_option('Document Options', oname) docgen_opt = docgen_menu.get_option('Document Options', oname)
if oname in self.options_str_dict and oname in doc_options_dict: if oname in self.options_str_dict and oname in doc_options_dict:
doc_options_dict[oname] = \ doc_options_dict[oname] = _convert_str_to_match_type(
_convert_str_to_match_type(self.options_str_dict[oname], self.options_str_dict[oname], doc_options_dict[oname])
doc_options_dict[oname])
self.options_str_dict.pop(oname) self.options_str_dict.pop(oname)
if oname in doc_options_dict: if oname in doc_options_dict:
docgen_opt.set_value(doc_options_dict[oname]) docgen_opt.set_value(doc_options_dict[oname])
@ -588,8 +608,8 @@ class CommandLineReport:
_('(no help available)')) _('(no help available)'))
print(optmsg) print(optmsg)
print(_(" Use '%(donottranslate)s' to see description " print(_(" Use '%(donottranslate)s' to see description "
"and acceptable values") "and acceptable values"
% {'donottranslate' : "show=option"}) ) % {'donottranslate' : "show=option"})
elif self.show in self.options_help: elif self.show in self.options_help:
opt = self.options_help[self.show] opt = self.options_help[self.show]
tabs = '\t\t' if len(self.show) < 10 else '\t' tabs = '\t\t' if len(self.show) < 10 else '\t'
@ -605,10 +625,10 @@ class CommandLineReport:
else: else:
#there was a show option given, but the option is invalid #there was a show option given, but the option is invalid
print(_("option '%(optionname)s' not valid. " print(_("option '%(optionname)s' not valid. "
"Use '%(donottranslate)s' to see all valid options.") "Use '%(donottranslate)s' to see all valid options."
% {'optionname' : self.show, ) % {'optionname' : self.show,
'donottranslate' : "show=all"}, 'donottranslate' : "show=all"},
file=sys.stderr) file=sys.stderr)
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -617,6 +637,9 @@ class CommandLineReport:
#------------------------------------------------------------------------ #------------------------------------------------------------------------
def cl_report(database, name, category, report_class, options_class, def cl_report(database, name, category, report_class, options_class,
options_str_dict): options_str_dict):
"""
function to actually run the selected report
"""
err_msg = _("Failed to write report. ") err_msg = _("Failed to write report. ")
clr = CommandLineReport(database, name, category, options_class, clr = CommandLineReport(database, name, category, options_class,
@ -631,38 +654,38 @@ def cl_report(database, name, category, report_class, options_class,
if category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK]: if category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK]:
if clr.doc_options: if clr.doc_options:
clr.option_class.handler.doc = clr.format( clr.option_class.handler.doc = clr.format(
clr.selected_style, clr.selected_style,
PaperStyle(clr.paper,clr.orien,clr.marginl, PaperStyle(clr.paper, clr.orien, clr.marginl,
clr.marginr,clr.margint,clr.marginb), clr.marginr, clr.margint, clr.marginb),
clr.doc_options) clr.doc_options)
else: else:
clr.option_class.handler.doc = clr.format( clr.option_class.handler.doc = clr.format(
clr.selected_style, clr.selected_style,
PaperStyle(clr.paper,clr.orien,clr.marginl, PaperStyle(clr.paper, clr.orien, clr.marginl,
clr.marginr,clr.margint,clr.marginb)) clr.marginr, clr.margint, clr.marginb))
elif category == CATEGORY_GRAPHVIZ: elif category == CATEGORY_GRAPHVIZ:
clr.option_class.handler.doc = clr.format( clr.option_class.handler.doc = clr.format(
clr.option_class, clr.option_class,
PaperStyle(clr.paper,clr.orien,clr.marginl, PaperStyle(clr.paper, clr.orien, clr.marginl,
clr.marginr,clr.margint,clr.marginb)) clr.marginr, clr.margint, clr.marginb))
if clr.css_filename is not None and \ if (clr.css_filename is not None
hasattr(clr.option_class.handler.doc, 'set_css_filename'): and hasattr(clr.option_class.handler.doc, 'set_css_filename')):
clr.option_class.handler.doc.set_css_filename(clr.css_filename) clr.option_class.handler.doc.set_css_filename(clr.css_filename)
MyReport = report_class(database, clr.option_class, User()) my_report = report_class(database, clr.option_class, User())
MyReport.doc.init() my_report.doc.init()
MyReport.begin_report() my_report.begin_report()
MyReport.write_report() my_report.write_report()
MyReport.end_report() my_report.end_report()
return clr return clr
except ReportError as msg: except ReportError as msg:
(m1, m2) = msg.messages() (msg1, msg2) = msg.messages()
print(err_msg, file=sys.stderr) print(err_msg, file=sys.stderr)
print(m1, file=sys.stderr) print(msg1, file=sys.stderr)
if m2: if msg2:
print(m2, file=sys.stderr) print(msg2, file=sys.stderr)
except: except:
if len(log.handlers) > 0: if len(LOG.handlers) > 0:
log.error(err_msg, exc_info=True) LOG.error(err_msg, exc_info=True)
else: else:
print(err_msg, file=sys.stderr) print(err_msg, file=sys.stderr)
## Something seems to eat the exception above. ## Something seems to eat the exception above.
@ -694,7 +717,7 @@ def run_report(db, name, **options_str_dict):
filename in clr.option_class.get_output() filename in clr.option_class.get_output()
""" """
dbstate = DbState() dbstate = DbState()
climanager = CLIManager(dbstate, setloader=False, user=User()) # don't load db climanager = CLIManager(dbstate, False, User()) # don't load db
climanager.do_reg_plugins(dbstate, None) climanager.do_reg_plugins(dbstate, None)
pmgr = BasePluginManager.get_instance() pmgr = BasePluginManager.get_instance()
cl_list = pmgr.get_reg_reports() cl_list = pmgr.get_reg_reports()
@ -724,6 +747,10 @@ def run_report(db, name, **options_str_dict):
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
def cl_book(database, name, book, options_str_dict): def cl_book(database, name, book, options_str_dict):
"""
function to actually run the selected book,
which in turn runs whatever reports the book has in it
"""
clr = CommandLineReport(database, name, CATEGORY_BOOK, clr = CommandLineReport(database, name, CATEGORY_BOOK,
ReportOptions, options_str_dict) ReportOptions, options_str_dict)
@ -773,11 +800,11 @@ def cl_book(database, name, book, options_str_dict):
rpt.write_report() rpt.write_report()
doc.close() doc.close()
except ReportError as msg: except ReportError as msg:
(m1, m2) = msg.messages() (msg1, msg2) = msg.messages()
print(err_msg % name, file=sys.stderr) # which report has the error? print(err_msg % name, file=sys.stderr) # which report has the error?
print(m1, file=sys.stderr) print(msg1, file=sys.stderr)
if m2: if msg2:
print(m2, file=sys.stderr) print(msg2, file=sys.stderr)
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -790,11 +817,11 @@ def write_book_item(database, report_class, options, user):
try: try:
return report_class(database, options, user) return report_class(database, options, user)
except ReportError as msg: except ReportError as msg:
(m1, m2) = msg.messages() (msg1, msg2) = msg.messages()
print("ReportError", m1, m2, file=sys.stderr) print("ReportError", msg1, msg2, file=sys.stderr)
except FilterError as msg: except FilterError as msg:
(m1, m2) = msg.messages() (msg1, msg2) = msg.messages()
print("FilterError", m1, m2, file=sys.stderr) print("FilterError", msg1, msg2, file=sys.stderr)
except: except:
log.error("Failed to write book item.", exc_info=True) LOG.error("Failed to write book item.", exc_info=True)
return None return None