Beispiel #1
0
 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")
Beispiel #2
0
 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
Beispiel #3
0
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
Beispiel #4
0
 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)
Beispiel #5
0
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
Beispiel #6
0
 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)
Beispiel #7
0
 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"))
Beispiel #8
0
 def setUpClass(cls):
     """
     Import example database.
     """
     cls.db = import_as_dict(EXAMPLE, User())
Beispiel #9
0
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()
Beispiel #10
0
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()
Beispiel #11
0
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
Beispiel #12
0
    """
    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"