def run_action(self, action, handler): options, options_help = self.get_plugin_options(action.handle) args = {} for key, default_value in options.items(): args[key] = handler.get_argument(key) if action.ptype == "Report": clr = run_report(self.gramps_database, action.handle, of="/tmp/test.html", off="html", **args) # can check for results with clr elif action.ptype == "Import": filename = download( args["i"], "/tmp/%s-%s-%s.%s" % (str(profile.user.username), str(handle), timestamp(), args["iff"])) if filename is not None: import_file(self.gramps_database, filename, User()) # callback elif action.ptype == "Export": pmgr = BasePluginManager.get_instance() pdata = pmgr.get_plugin(action.handle) export_file(self.gramps_database, "export." + pdata.extension, User()) # callback handler.redirect("/action")
def import_from_filename(self, db, filename, user=None): """ Import the filename into the db. """ from .plug import BasePluginManager from .const import PLUGINS_DIR from gprime.cli.user import User pmgr = BasePluginManager.get_instance() if user is None: user = User() (name, ext) = os.path.splitext(os.path.basename(filename)) extension = ext[1:].lower() import_list = pmgr.get_reg_importers() if import_list == []: # This might happen if using gramps from outside, and # we haven't loaded plugins yet pmgr.reg_plugins(PLUGINS_DIR, self, None) import_list = pmgr.get_reg_importers() for pdata in import_list: if extension == pdata.extension: mod = pmgr.load_plugin(pdata) if not mod: for item in pmgr.get_fail_list(): name, error_tuple, pdata = item etype, exception, traceback = error_tuple print("ERROR:", name, exception) return False import_function = getattr(mod, pdata.import_function) results = import_function(db, filename, user) return True return False
def import_as_dict(filename, user=None, skp_imp_adds=True): """ Import the filename into a InMemoryDB and return it. """ if user is None: user = User() db = make_database("inmemorydb") db.load(None) db.set_feature("skip-import-additions", skp_imp_adds) dbstate = DbState() climanager = CLIManager(dbstate, setloader=False, user=user) climanager.do_reg_plugins(dbstate, None) pmgr = BasePluginManager.get_instance() (name, ext) = os.path.splitext(os.path.basename(filename)) format = ext[1:].lower() import_list = pmgr.get_reg_importers() for pdata in import_list: if format == pdata.extension: mod = pmgr.load_plugin(pdata) if not mod: for item in pmgr.get_fail_list(): name, error_tuple, pdata = item # (filename, (exception-type, exception, traceback), pdata) etype, exception, traceback = error_tuple #print("ERROR:", name, exception) return False import_function = getattr(mod, pdata.import_function) results = import_function(db, filename, user) if results is None: return None return db return None
def load(self, directory, callback=None, mode=None, force_schema_upgrade=False, force_bsddb_upgrade=False, force_bsddb_downgrade=False, force_python_upgrade=False, update=True): super().load(directory, callback, mode, force_schema_upgrade, force_bsddb_upgrade, force_bsddb_downgrade, force_python_upgrade) # Dictionary-specific load: from gprime.plugins.importer.importxml import importData from gprime.cli.user import User if self._directory: backups = list( reversed( glob.glob(os.path.join(self._directory, "backup-*.gramps")))) if backups: filename = backups[0] if os.path.isfile(filename): importData(self, filename, User()) self.reindex_reference_map(lambda progress: None) self.rebuild_secondary(lambda progress: None)
def diff_db_to_file(old_db, filename, user=None): if user is None: user = User() # First, get data as a InMemoryDB new_db = import_as_dict(filename, user, user) if new_db is not None: # Next get differences: diffs, m_old, m_new = diff_dbs(old_db, new_db, user) return diffs, m_old, m_new
def __init__(self, user=None, dbstate=None): ## Setup: from gprime.cli.clidbman import CLIDbManager self.dbstate = dbstate or DbState() #we need a manager for the CLI session self.user = user or User(auto_accept=True, quiet=False) self.climanager = CLIManager(self.dbstate, setloader=True, user=self.user) self.clidbmanager = CLIDbManager(self.dbstate)
def run_action(self, action, handler): options, options_help = self.get_plugin_options(action.handle) args = {} for key, default_value in options.items(): args[key] = handler.get_argument(key) if action.ptype == "Report": output_file = "/tmp/%s.pdf" % action.name clr = run_report(self.gramps_database, action.handle, username=self.handler.current_user, of=output_file, off="pdf", **args) # can check for results with clr if clr: download_to_user(output_file, self.handler) else: handler.send_message("Error in report") handler.redirect(self.handler.app.make_url("/action")) elif action.ptype == "Import": filename = upload(args["i"], "/tmp/%s-%s-%s.%s" % (str(profile.user.username), str(handle), timestamp(), args["iff"])) if filename is not None: result = import_file(self.gramps_database, filename, User()) # callback if result: handler.redirect(self.handler.app.make_url("/action")) else: handler.send_message("Error in import") handler.redirect(self.handler.app.make_url("/action")) elif action.ptype == "Export": pmgr = BasePluginManager.get_instance() pdata = pmgr.get_plugin(action.handle) output_file = "/tmp/export." + pdata.extension result = export_file(self.gramps_database, output_file, User()) # callback if result: download_to_user(output_file, self.handler) else: handler.send_message("Error in export") handler.redirect(self.handler.app.make_url("/action"))
def setUpClass(cls): """ Import example database. """ cls.db = import_as_dict(EXAMPLE, User())
def main(): ## Tornado imports import tornado.ioloop import tornado.log from tornado.options import define, options ## Command-line configuration options: define("hostname", default="localhost", help="Name of gPrime server host", type=str) define("port", default=8000, help="Number of gPrime server port", type=int) define("site-dir", default=None, help="The gPrime site directory to use", type=str) define("sitename", default="gPrime", help="Name to appear on all web pages", type=str) define("debug", default=False, help="Set debugging True/False", type=bool) define("xsrf", default=True, help="Use xsrf cookie, True/False", type=bool) define("config-file", default=None, help="Config file of gPrime options", type=str) define("create", default=None, help="Create a site directory (given by --site-dir) with this Family Tree name", type=str) define("add-user", default=False, help="Add a user/password", type=bool) define("remove-user", default=False, help="Remove a user", type=bool) define("change-password", default=False, help="Change a user's password", type=bool) define("server", default=True, help="Start the server, True/False", type=bool) define("import-file", default=None, help="Import a file", type=str) define("open-browser", default=True, help="Open default web browser", type=bool) define("language", default=None, help="Language code (eg, 'fr') to use", type=str) # Let's go! # Really, just need the config-file: tornado.options.parse_command_line() # Read config-file options: if options.config_file: tornado.options.parse_config_file(options.config_file) # Parse args again, so that command-line options override config-file: tornado.options.parse_command_line() ################# Process command-line arguments if options.site_dir is None: raise Exception("--site-dir=NAME was not provided") else: options.site_dir = os.path.expanduser(options.site_dir) # Handle gPrime intialization: import gprime.const # initializes locale from gprime.dbstate import DbState from gprime.cli.user import User ### Handle site options: gprime.const.set_site_dir(options.site_dir) ## when we don't have options database_dir = os.path.join(options.site_dir, "database") users_dir = os.path.join(options.site_dir, "users") media_dir = os.path.join(options.site_dir, "media") media_cache_dir = os.path.join(options.site_dir, "media", "cache") if options.create: options.server = False # Make the site_dir: os.makedirs(options.site_dir) # Make the database: DbState().create_database(database_dir, options.create) # Make the user folders: os.makedirs(users_dir) # Make the media folder: os.makedirs(media_dir) os.makedirs(media_cache_dir) password_manager.save() with open(os.path.join(options.site_dir, "passwd"), "w") as fp: fp.write("### This is the password file for gPrime\n") fp.write("\n") password_manager.load() if options.add_user: username = input("Username: "******"users", username)) if options.remove_user: username = input("Username: "******"Username: "******"database", default="Untitled Family Tree", type=str) options.database = database.get_dbname() tornado.log.logging.info("gPrime starting...") if options.debug: import tornado.autoreload import logging log = logging.getLogger() log.setLevel(logging.DEBUG) tornado.log.logging.info("Debug mode...") directory = gprime.const.DATA_DIR template_directory = os.path.join(directory, 'templates') tornado.log.logging.info(template_directory) for dirpath, dirnames, filenames in os.walk(template_directory): for filename in filenames: template_filename = os.path.join(dirpath, filename) tornado.log.logging.info(" watching: " + os.path.relpath(template_filename)) tornado.autoreload.watch(template_filename) app = GPrimeApp(options, database) app.listen(options.port) tornado.log.logging.info("Starting with the folowing settings:") for key in ["port", "site_dir", "hostname", "sitename", "debug", "xsrf", "config_file"]: tornado.log.logging.info(" " + key + " = " + repr(getattr(options, key))) tornado.log.logging.info("Control+C twice to stop server. Running...") # Open up a browser window: if options.open_browser: try: browser = webbrowser.get(None) except webbrowser.Error as e: tornado.log.logging.warning('No web browser found: %s.' % e) browser = None if browser: b = lambda : browser.open("http://%s:%s" % (options.hostname, options.port), new=2) threading.Thread(target=b).start() app.init_signal() if sys.platform.startswith('win'): # add no-op to wake every 5s # to handle signals that may be ignored by the inner loop pc = tornado.ioloop.PeriodicCallback(lambda : None, 5000) pc.start() # Start Tornado server: try: tornado.ioloop.IOLoop.current().start() except KeyboardInterrupt: tornado.log.logging.info("gPrime received interrupt...") tornado.log.logging.info("gPrime shutting down...") if app.database: tornado.log.logging.info("gPrime closing database...") app.database.close()
def run_app(): ## Tornado imports import tornado.ioloop import tornado.log from tornado.options import define, options ## Command-line configuration options: define("hostname", default="localhost", help="Name of gPrime server host", type=str) define("port", default=8000, help="Number of gPrime server port", type=int) define("site-dir", default="gprime-site", help="The gPrime site directory to use", type=str) define("sitename", default="gPrime", help="Name to appear on all web pages", type=str) define("debug", default=False, help="Set debugging True/False", type=bool) define("xsrf", default=True, help="Use xsrf cookie, True/False", type=bool) define("config-file", default=None, help="Config file of gPrime options", type=str) define( "create", default=None, help= "Create a site directory (given by --site-dir) with this Family Tree name", type=str) define( "add-user", default=False, help= "Add a user; requires --user; optional --password and --permissions", type=bool) define("remove-user", default=False, help="Remove a user; requires --user=USERNAME", type=bool) define("change-password", default=False, help="Change a user's password; requires --user=USERNAME", type=bool) define("password", default=None, help="Give password on command-line (not recommended)", type=str) define("permissions", default=None, help="User permissions (edit, delete, add, admin)", type=str) define( "user", default=None, help="User for change-password, add-user, remove-user, or permissions", type=str) define("server", default=True, help="Start the server, True/False", type=bool) define("import-file", default=None, help="Import a file", type=str) define("import-media", default=True, help="Attempt to import associated media with --import-file", type=bool) define("open-browser", default=True, help="Open default web browser", type=bool) define("prefix", default="", help="Site URL prefix", type=str) define("version", default=False, help="Show the version of gprime (%s)" % VERSION, type=bool) define("info", default=False, help="Show information about the database", type=bool) # Let's go! # Really, just need the config-file: tornado.options.parse_command_line() # Read config-file options: if options.config_file: tornado.options.parse_config_file(options.config_file) # Parse args again, so that command-line options override config-file: tornado.options.parse_command_line() ################# Process command-line arguments if options.version: print("gPrime version is: %s" % VERSION) sys.exit(0) options.site_dir = os.path.expanduser(options.site_dir) # Use site-dir/config.cfg if one, and not overridden on command line: default_config_file = os.path.join(options.site_dir, "config.cfg") if options.config_file is None and os.path.exists(default_config_file): old_site_dir = options.site_dir tornado.options.parse_config_file(default_config_file) if options.site_dir != old_site_dir: tornado.log.logging.warning( "Ignoring site_dir = %s in config.cfg...", repr(options.site_dir)) # Parse args again, so that command-line options override config-file: tornado.options.parse_command_line() options.site_dir = old_site_dir # make sure this is not overridden if options.debug: import logging log = logging.getLogger() log.setLevel(logging.DEBUG) tornado.log.logging.info("Debug mode...") # Handle gPrime intialization: import gprime.const # initializes locale gprime.const.set_site_dir(options.site_dir) ## when we don't have options from gprime.dbstate import DbState from gprime.cli.user import User ### Handle site options: database_dir = os.path.join(options.site_dir, "database") users_dir = os.path.join(options.site_dir, "users") media_dir = os.path.join(options.site_dir, "media") media_cache_dir = os.path.join(options.site_dir, "media", "cache") if options.create: options.server = False # Make the site_dir: os.makedirs(options.site_dir) # Make the database: DbState().create_database(database_dir, options.create) # Make the user folders: os.makedirs(users_dir) # Make the media folder: os.makedirs(media_dir) os.makedirs(media_cache_dir) # Make an image-missing.png default: shutil.copy(os.path.join(gprime.const.IMAGE_DIR, "image-missing.png"), os.path.join(media_dir, "image-missing.png")) ## Open the database: database = DbState().open_database(database_dir) if options.add_user: options.server = False if options.user is None: raise Exception("Missing --user=USERNAME") if options.password: plaintext = options.password else: plaintext = getpass.getpass() options.server = False if options.permissions: permissions = { code.strip().lower() for code in options.permissions.split(",") } else: permissions = {"add", "edit", "delete"} ## Initialize user folder: try: os.makedirs(os.path.join(options.site_dir, "users", options.user)) except: pass database.add_user(username=options.user, password=crypt.hash(plaintext), permissions=permissions, data={}) # could set css here elif options.remove_user: options.server = False if options.user is None: raise Exception("Missing --user=USERNAME") options.server = False database.remove_user(username=options.user) elif options.change_password: options.server = False if options.user is None: raise Exception("Missing --user=USERNAME") if options.password: plaintext = options.password else: plaintext = getpass.getpass() options.server = False if options.permissions: permissions = { code.strip().lower() for code in options.permissions.split(",") } database.update_user_data(username=options.user, data={ "password": crypt.hash(plaintext), "permissions": permissions }) else: database.update_user_data(username=options.user, data={"password": crypt.hash(plaintext)}) elif options.permissions: options.server = False if options.user is None: raise Exception("Missing --user=USERNAME") permissions = { code.strip().lower() for code in options.permissions.split(",") } database.update_user_data(username=options.user, data={"permissions": permissions}) elif options.password: raise Exception("Missing --change-password --user=USERNAME") ## Options after opening: if options.info: options.server = False users = database.get_users() for user in users: print("%s:" % user) data = database.get_user_data(user) for key in data: print(" %s: %s" % (key, data[key])) elif options.import_file: options.server = False user = User() options.import_file = os.path.expanduser(options.import_file) import_file(database, options.import_file, user) # copy images to media subdirectory if options.import_media: media_dir = os.path.join(options.site_dir, "media") media_copies = set() with DbTxn("gPrime initial import", database) as transaction: for media in database.iter_media(): if media.path == "image-missing.png": continue # already there src = get_image_path_from_media(database, media) relative = make_path_relative(media.path) dst = os.path.join(media_dir, relative) if not os.path.exists(src): # try where import-file was src = os.path.join( os.path.dirname(options.import_file), relative) if os.path.exists(src): os.makedirs(os.path.dirname(dst), exist_ok=True) if dst not in media_copies: shutil.copy(src, dst) tornado.log.logging.info("Media copied to `%s`" % dst) media_copies.add(dst) media.path = relative database.commit_media(media, transaction) else: tornado.log.logging.warning( "Media file not found: `%s`" % media.path) database.set_mediapath( os.path.abspath(media_dir)) # relative or absolute # Start server up, or exit: if not options.server: database.close() return ############################ Starting server: media_dir = os.path.join(options.site_dir, "media") database.set_mediapath(os.path.abspath(media_dir)) # relative or absolute define("database", default="Untitled Family Tree", type=str) options.database = database.get_dbname() tornado.log.logging.info("gPrime starting...") if options.debug: import tornado.autoreload directory = gprime.const.DATA_DIR template_directory = os.path.join(directory, 'templates') tornado.log.logging.info(template_directory) for dirpath, dirnames, filenames in os.walk(template_directory): for filename in filenames: template_filename = os.path.join(dirpath, filename) tornado.log.logging.info(" watching: " + os.path.relpath(template_filename)) tornado.autoreload.watch(template_filename) app = GPrimeApp(options, database) app.listen(options.port) tornado.log.logging.info("Starting with the folowing settings:") tornado.log.logging.info(" DATA_DIR = " + gprime.const.DATA_DIR) tornado.log.logging.info(" serving = http://%s:%s%s" % (options.hostname, options.port, options.prefix)) for key in [ "port", "site_dir", "hostname", "sitename", "debug", "xsrf", "config_file" ]: tornado.log.logging.info(" " + key + " = " + repr(getattr(options, key))) tornado.log.logging.info("Control+C twice to stop server. Running...") # Open up a browser window: if options.open_browser: try: browser = webbrowser.get(None) except webbrowser.Error as e: tornado.log.logging.warning('No web browser found: %s.' % e) browser = None if browser: b = lambda: browser.open("http://%s:%s%s" % (options.hostname, options.port, app.make_url("/")), new=2) threading.Thread(target=b).start() app.init_signal() if sys.platform.startswith('win'): # add no-op to wake every 5s # to handle signals that may be ignored by the inner loop pc = tornado.ioloop.PeriodicCallback(lambda: None, 5000) pc.start() # Start Tornado server: try: tornado.ioloop.IOLoop.current().start() except KeyboardInterrupt: tornado.log.logging.info("gPrime received interrupt...") tornado.log.logging.info("gPrime shutting down...") if app.database: tornado.log.logging.info("gPrime closing database...") app.database.close()
def diff_dbs(db1, db2, user=None): """ 1. new objects => mark for insert 2. deleted objects, no change locally after delete date => mark for deletion 3. deleted objects, change locally => mark for user confirm for deletion 4. updated objects => do a diff on differences, mark origin values as new data """ if user is None: user = User() missing_from_old = [] missing_from_new = [] diffs = [] with user.progress(_('Family Tree Differences'), _('Searching...'), 10) as step: for item in [ 'Person', 'Family', 'Source', 'Citation', 'Event', 'Media', 'Place', 'Repository', 'Note', 'Tag' ]: step() handles1 = sorted([ handle for handle in db1.get_table_func(item, "handles_func")() ]) handles2 = sorted([ handle for handle in db2.get_table_func(item, "handles_func")() ]) p1 = 0 p2 = 0 while p1 < len(handles1) and p2 < len(handles2): if handles1[p1] == handles2[p2]: # in both item1 = db1.get_table_func(item, "handle_func")(handles1[p1]) item2 = db2.get_table_func(item, "handle_func")(handles2[p2]) diff = diff_items(item, item1.to_struct(), item2.to_struct()) if diff: diffs += [(item, item1, item2)] # else same! p1 += 1 p2 += 1 elif handles1[p1] < handles2[p2]: # p1 is mssing in p2 item1 = db1.get_table_func(item, "handle_func")(handles1[p1]) missing_from_new += [(item, item1)] p1 += 1 elif handles1[p1] > handles2[p2]: # p2 is mssing in p1 item2 = db2.get_table_func(item, "handle_func")(handles2[p2]) missing_from_old += [(item, item2)] p2 += 1 while p1 < len(handles1): item1 = db1.get_table_func(item, "handle_func")(handles1[p1]) missing_from_new += [(item, item1)] p1 += 1 while p2 < len(handles2): item2 = db2.get_table_func(item, "handle_func")(handles2[p2]) missing_from_old += [(item, item2)] p2 += 1 return diffs, missing_from_old, missing_from_new
""" Dynamically generate tests and attach to DatabaseCheck. """ struct = obj.to_struct() serialized = obj.__class__.from_struct(struct) def test(self): self.assertEqual(obj.to_struct(), struct) name = "test_serialize_%s_%s" % (obj.__class__.__name__, obj.handle) setattr(DatabaseCheck, name, test) #### #def test2(self): # self.assertEqual(obj.to_struct(), from_struct(struct).to_struct()) #name = "test_create_%s_%s" % (obj.__class__.__name__, obj.handle) #setattr(DatabaseCheck, name, test2) db = import_as_dict(EXAMPLE, User()) for table in db.get_table_func(): for handle in db.get_table_func(table,"handles_func")(): obj = db.get_table_func(table,"handle_func")(handle) generate_case(obj) class StructTest(unittest.TestCase): def test(self): family = db.get_family_from_gid("F0001") s = Struct(family.to_struct(), db) self.assertEqual(s["gid"], "F0001") s["gid"] = "TEST" self.assertEqual(s["gid"], "TEST") self.assertEqual(s.father_handle.primary_name.first_name, "Allen Carl") s["father_handle.primary_name.first_name"] = "Edward"