示例#1
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()
示例#2
0
文件: app.py 项目: benlaurie/gprime
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()