diff --git a/gramps/cli/arghandler.py b/gramps/cli/arghandler.py index 80bdf59f5..23b4a8d19 100644 --- a/gramps/cli/arghandler.py +++ b/gramps/cli/arghandler.py @@ -166,6 +166,7 @@ class ArgHandler(object): self.actions = parser.actions self.list = parser.list self.list_more = parser.list_more + self.list_table = parser.list_table self.open_gui = parser.open_gui self.imp_db_path = None self.dbman = CLIDbManager(self.dbstate) @@ -425,6 +426,25 @@ class ArgHandler(object): print(" %s: %s" % (item, summary[item])) sys.exit(0) + if self.list_table: + print(_('Gramps Family Trees:')) + summary_list = self.dbman.family_tree_summary() + print(_("Family Tree"), end="") + for key in sorted(summary_list[0]): + if key != "Family tree": + print("\t ", end="") + print(key, end="") + print() + for summary in sorted(summary_list, + key=lambda sum: sum[_("Family tree")].lower()): + print('"%s"' % summary["Family tree"], end="") + for item in sorted(summary): + if item != _("Family tree"): + print("\t ", end="") + print('"%s"' % summary[item], end="") + print() + sys.exit(0) + self.__open_action() self.__import_action() diff --git a/gramps/cli/argparser.py b/gramps/cli/argparser.py index 98f2d73ff..5c590e48d 100644 --- a/gramps/cli/argparser.py +++ b/gramps/cli/argparser.py @@ -73,6 +73,7 @@ Application options -d, --debug=LOGGER_NAME Enable debug logs -l List Family Trees -L List Family Trees in Detail + -t List Family Trees in tabular (tab delimited) form -u, --force-unlock Force unlock of family tree -s, --show Show config settings -c, --config=[config.setting[:value]] Set config setting(s) and start Gramps @@ -176,6 +177,7 @@ class ArgParser(object): self.imp_db_path = None self.list = False self.list_more = False + self.list_table = False self.help = False self.usage = False self.force_unlock = False @@ -293,6 +295,8 @@ class ArgParser(object): self.list = True elif option in ('-L'): self.list_more = True + elif option in ('-t'): + self.list_table = True elif option in ('-s','--show'): print(_("Gramps config settings from %s:") % config.filename) @@ -347,7 +351,8 @@ class ArgParser(object): del options[ind] if len(options) > 0 and self.open is None and self.imports == [] \ - and not (self.list or self.list_more or self.help or self.runqml): + and not (self.list or self.list_more or self.list_table or + self.help or self.runqml): # Extract and convert to unicode the arguments in the list. # The % operator replaces the list elements with repr() of # the list elements, which is OK for latin characters @@ -374,7 +379,7 @@ class ArgParser(object): #errors in argument parsing ==> give cli error, no gui needed return False - if self.list or self.list_more or self.help: + if self.list or self.list_more or self.list_table or self.help: return False if self.open_gui: diff --git a/gramps/cli/clidbman.py b/gramps/cli/clidbman.py index bb570bcec..f1f723d96 100644 --- a/gramps/cli/clidbman.py +++ b/gramps/cli/clidbman.py @@ -136,62 +136,85 @@ class CLIDbManager(object): """ pass - def get_dbdir_summary(self, file_name): + def get_dbdir_summary(self, dirpath, name): """ - Returns (people_count, version_number) of current DB. - Returns ("Unknown", "Unknown") if invalid DB or other error. + Returns (people_count, bsddb_version, schema_version) of + current DB. + Returns ("Unknown", "Unknown", "Unknown") if invalid DB or other error. """ if config.get('preferences.use-bsddb3') or sys.version_info[0] >= 3: from bsddb3 import dbshelve, db else: from bsddb import dbshelve, db + from gramps.gen.db import META, PERSON_TBL + from gramps.gen.db.dbconst import BDBVERSFN + + bdbversion_file = os.path.join(dirpath, BDBVERSFN) + if os.path.isfile(bdbversion_file): + vers_file = open(bdbversion_file) + bsddb_version = vers_file.readline().strip() + else: + return "Unknown", "Unknown", "Unknown" + + current_bsddb_version = str(db.version()) + if bsddb_version != current_bsddb_version: + return "Unknown", bsddb_version, "Unknown" + env = db.DBEnv() flags = db.DB_CREATE | db.DB_PRIVATE |\ db.DB_INIT_MPOOL |\ db.DB_INIT_LOG | db.DB_INIT_TXN try: - env.open(file_name, flags) - except: - return "Unknown", "Unknown" + env.open(dirpath, flags) + except Exception as msg: + LOG.warning("Error opening db environment for '%s': %s" % + (name, str(msg))) + try: + env.close() + except Exception as msg: + LOG.warning("Error closing db environment for '%s': %s" % + (name, str(msg))) + return "Unknown", bsddb_version, "Unknown" dbmap1 = dbshelve.DBShelf(env) - fname = os.path.join(file_name, META + ".db") + fname = os.path.join(dirpath, META + ".db") try: dbmap1.open(fname, META, db.DB_HASH, db.DB_RDONLY) except: env.close() - return "Unknown", "Unknown" - version = dbmap1.get(b'version', default=None) + return "Unknown", bsddb_version, "Unknown" + schema_version = dbmap1.get(b'version', default=None) dbmap1.close() dbmap2 = dbshelve.DBShelf(env) - fname = os.path.join(file_name, PERSON_TBL + ".db") + fname = os.path.join(dirpath, PERSON_TBL + ".db") try: dbmap2.open(fname, PERSON_TBL, db.DB_HASH, db.DB_RDONLY) except: env.close() - return "Unknown", "Unknown" + return "Unknown", bsddb_version, schema_version count = len(dbmap2) dbmap2.close() env.close() - return (count, version) + return (count, bsddb_version, schema_version) def family_tree_summary(self): """ Return a list of dictionaries of the known family trees. """ # make the default directory if it does not exist - list = [] + summary_list = [] for item in self.current_names: (name, dirpath, path_name, last, tval, enable, stock_id) = item - count, version = self.get_dbdir_summary(dirpath) + count, bsddb_version, schema_version = self.get_dbdir_summary(dirpath, name) retval = {} retval["Number of people"] = count if enable: retval["Locked?"] = "yes" else: retval["Locked?"] = "no" - retval["DB version"] = version + retval["Bsddb version"] = bsddb_version + retval["Schema version"] = schema_version if sys.version_info[0] < 3: retval["Family tree"] = name.encode(glocale.getfilesystemencoding()) else: @@ -199,8 +222,8 @@ class CLIDbManager(object): retval["Path"] = dirpath retval["Last accessed"] = time.strftime('%x %X', time.localtime(tval)) - list.append( retval ) - return list + summary_list.append( retval ) + return summary_list def _populate_cli(self): """ Get the list of current names in the database dir diff --git a/gramps/gen/const.py b/gramps/gen/const.py index 6f0861ab3..cb7676982 100644 --- a/gramps/gen/const.py +++ b/gramps/gen/const.py @@ -306,6 +306,6 @@ LONGOPTS = [ "qml", ] -SHORTOPTS = "O:C:i:e:f:a:p:d:c:lLhuv?s" +SHORTOPTS = "O:C:i:e:f:a:p:d:c:lLthuv?s" GRAMPS_UUID = uuid.UUID('516cd010-5a41-470f-99f8-eb22f1098ad6')