Esempio n. 1
0
def setup_app(command, conf, vars):
    """Called by ``paster setup-app``.

    This script is responsible for:

        * Creating the initial database schema and loading default data.
        * Executing any migrations necessary to bring an existing database
          up-to-date. Your data should be safe but, as always, be sure to
          make backups before using this.
        * Re-creating the default database for every run of the test suite.

    XXX: All your data will be lost IF you run the test suite with a
         config file named 'test.ini'. Make sure you have this configured
         to a different database than in your usual deployment.ini or
         development.ini file because all database tables are dropped a
         and recreated every time this script runs.

    XXX: If you are upgrading from MediaCore v0.7.2 or v0.8.0, run whichever
         one of these that applies:
           ``python batch-scripts/upgrade/upgrade_from_v072.py deployment.ini``
           ``python batch-scripts/upgrade/upgrade_from_v080.py deployment.ini``

    XXX: For search to work, we depend on a number of MySQL triggers which
         copy the data from our InnoDB tables to a MyISAM table for its
         fulltext indexing capability. Triggers can only be installed with
         a mysql superuser like root, so you must run the setup_triggers.sql
         script yourself.

    """
    # paster just scans the source code for a "websetup.py". Due to our
    # compatibility module for the old "mediacore" namespace it actually finds
    # two modules (mediadrop.websetup and mediacore.websetup) even though both
    # actually point to the same source code.
    # Because of that "paster setup-app" actually runs "setup_app()" twice
    # which causes some bad stuff to happen (e.g. duplicate metadata
    # initialization. Until we get rid of the compat package we should make
    # sure the following code is only run once.
    global did_run_setup
    if did_run_setup:
        return
    config = load_environment(conf.global_conf, conf.local_conf)
    plugin_manager = config['pylons.app_globals'].plugin_mgr
    mediadrop_migrator = MediaDropMigrator.from_config(conf, log=log)
    
    engine = metadata.bind
    db_connection = engine.connect()
    # simplistic check to see if MediaDrop tables are present, just check for
    # the media_files table and assume that all other tables are there as well
    from mediadrop.model.media import media_files
    mediadrop_tables_exist = engine.dialect.has_table(db_connection, media_files.name)
    
    run_migrations = True
    if not mediadrop_tables_exist:
        head_revision = mediadrop_migrator.head_revision()
        log.info('Initializing new database with version %r' % head_revision)
        metadata.create_all(bind=DBSession.bind, checkfirst=True)
        mediadrop_migrator.init_db(revision=head_revision)
        run_migrations = False
        add_default_data()
        for migrator in plugin_manager.migrators():
            migrator.init_db()
        events.Environment.database_initialized()
    elif not mediadrop_migrator.alembic_table_exists():
        if not mediadrop_migrator.migrate_table_exists():
            log.error('No migration table found, probably your MediaDrop install '
                'is too old (< 0.9?). Please upgrade to MediaCore CE 0.9 first.')
            raise AssertionError('no migration table found')
        alembic_revision = mediadrop_migrator.map_migrate_version()
        mediadrop_migrator.stamp(alembic_revision)
    if run_migrations:
        mediadrop_migrator.migrate_db()
        for migrator in plugin_manager.migrators():
            migrator.migrate_db()
        events.Environment.database_migrated()
    
    cleanup_players_table(enabled=True)
    
    # Save everything, along with the dummy data if applicable
    DBSession.commit()
    events.Environment.database_ready()

    log.info('Generating appearance.css from your current settings')
    settings = DBSession.query(Setting.key, Setting.value)
    if settings.count() == 0:
        error_msg = (
            u"Unable to find any settings in the database. This may happen if a previous\n"
            u"setup did not complete successfully.\n"
            u"Please inspect your database contents. If you don't have any valuable data in\n"
            u"that db you can try to remove all tables and run the setup process again.\n"
            u"BE CAREFUL: REMOVING ALL TABLES MIGHT CAUSE DATA LOSS!\n"
        )
        sys.stderr.write(error_msg)
        log.error(error_msg.replace('\n', u' '))
        sys.exit(99)
    generate_appearance_css(settings, cache_dir=conf['cache_dir'])

    did_run_setup = True
    log.info('Successfully setup')
Esempio n. 2
0
def setup_app(command, conf, vars):
    """Called by ``paster setup-app``.

    This script is responsible for:

        * Creating the initial database schema and loading default data.
        * Executing any migrations necessary to bring an existing database
          up-to-date. Your data should be safe but, as always, be sure to
          make backups before using this.
        * Re-creating the default database for every run of the test suite.

    XXX: All your data will be lost IF you run the test suite with a
         config file named 'test.ini'. Make sure you have this configured
         to a different database than in your usual deployment.ini or
         development.ini file because all database tables are dropped a
         and recreated every time this script runs.

    XXX: If you are upgrading from MediaCore v0.7.2 or v0.8.0, run whichever
         one of these that applies:
           ``python batch-scripts/upgrade/upgrade_from_v072.py deployment.ini``
           ``python batch-scripts/upgrade/upgrade_from_v080.py deployment.ini``

    XXX: For search to work, we depend on a number of MySQL triggers which
         copy the data from our InnoDB tables to a MyISAM table for its
         fulltext indexing capability. Triggers can only be installed with
         a mysql superuser like root, so you must run the setup_triggers.sql
         script yourself.

    """
    # paster just scans the source code for a "websetup.py". Due to our
    # compatibility module for the old "mediacore" namespace it actually finds
    # two modules (mediadrop.websetup and mediacore.websetup) even though both
    # actually point to the same source code.
    # Because of that "paster setup-app" actually runs "setup_app()" twice
    # which causes some bad stuff to happen (e.g. duplicate metadata
    # initialization. Until we get rid of the compat package we should make
    # sure the following code is only run once.
    global did_run_setup
    if did_run_setup:
        return
    config = load_environment(conf.global_conf, conf.local_conf)
    plugin_manager = config['pylons.app_globals'].plugin_mgr
    mediadrop_migrator = MediaDropMigrator.from_config(conf, log=log)

    engine = metadata.bind
    db_connection = engine.connect()
    # simplistic check to see if MediaDrop tables are present, just check for
    # the media_files table and assume that all other tables are there as well
    from mediadrop.model.media import media_files
    mediadrop_tables_exist = engine.dialect.has_table(db_connection,
                                                      media_files.name)

    run_migrations = True
    if not mediadrop_tables_exist:
        head_revision = mediadrop_migrator.head_revision()
        log.info('Initializing new database with version %r' % head_revision)
        metadata.create_all(bind=DBSession.bind, checkfirst=True)
        mediadrop_migrator.init_db(revision=head_revision)
        run_migrations = False
        add_default_data()
        for migrator in plugin_manager.migrators():
            migrator.init_db()
        events.Environment.database_initialized()
    elif not mediadrop_migrator.alembic_table_exists():
        if not mediadrop_migrator.migrate_table_exists():
            log.error(
                'No migration table found, probably your MediaDrop install '
                'is too old (< 0.9?). Please upgrade to MediaCore CE 0.9 first.'
            )
            raise AssertionError('no migration table found')
        alembic_revision = mediadrop_migrator.map_migrate_version()
        mediadrop_migrator.stamp(alembic_revision)
    if run_migrations:
        mediadrop_migrator.migrate_db()
        for migrator in plugin_manager.migrators():
            migrator.migrate_db()
        events.Environment.database_migrated()

    cleanup_players_table(enabled=True)

    # Save everything, along with the dummy data if applicable
    DBSession.commit()
    events.Environment.database_ready()

    log.info('Generating appearance.css from your current settings')
    settings = DBSession.query(Setting.key, Setting.value)
    if settings.count() == 0:
        error_msg = (
            u"Unable to find any settings in the database. This may happen if a previous\n"
            u"setup did not complete successfully.\n"
            u"Please inspect your database contents. If you don't have any valuable data in\n"
            u"that db you can try to remove all tables and run the setup process again.\n"
            u"BE CAREFUL: REMOVING ALL TABLES MIGHT CAUSE DATA LOSS!\n")
        sys.stderr.write(error_msg)
        log.error(error_msg.replace('\n', u' '))
        sys.exit(99)
    generate_appearance_css(settings, cache_dir=conf['cache_dir'])

    did_run_setup = True
    log.info('Successfully setup')
Esempio n. 3
0
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
    """Create a Pylons WSGI application and return it

    ``global_conf``
        The inherited configuration for this application. Normally from
        the [DEFAULT] section of the Paste ini file.

    ``full_stack``
        Whether this application provides a full WSGI stack (by default,
        meaning it handles its own exceptions and errors). Disable
        full_stack when this application is "managed" by another WSGI
        middleware.

    ``static_files``
        Whether this application serves its own static files; disable
        when another web server is responsible for serving them.

    ``app_conf``
        The application's local configuration. Normally specified in
        the [app:<name>] section of the Paste ini file (where <name>
        defaults to main).

    """
    # Configure the Pylons environment
    config = load_environment(global_conf, app_conf)
    alembic_migrations = MediaDropMigrator.from_config(config, log=log)
    db_is_current = True
    if not alembic_migrations.is_db_scheme_current():
        log.warn(
            'Running with an outdated database scheme. Please upgrade your database.'
        )
        db_is_current = False
    plugin_mgr = config['pylons.app_globals'].plugin_mgr
    db_current_for_plugins = plugin_mgr.is_db_scheme_current_for_all_plugins()
    if db_is_current and not db_current_for_plugins:
        log.warn(db_current_for_plugins.message)
        db_is_current = False
    if db_is_current:
        events.Environment.database_ready()

    # The Pylons WSGI app
    app = PylonsApp(config=config)

    # Allow the plugin manager to tweak our WSGI app
    app = plugin_mgr.wrap_pylons_app(app)

    # Routing/Session/Cache Middleware
    app = RoutesMiddleware(app, config['routes.map'], singleton=False)
    app = SessionMiddleware(app, config)

    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)

    # add repoze.who middleware with our own authorization library
    app = add_auth(app, config)

    # ToscaWidgets Middleware
    app = setup_tw_middleware(app, config)

    # Strip the name of the .fcgi script, if using one, from the SCRIPT_NAME
    app = FastCGIScriptStripperMiddleware(app)

    # If enabled, set up the proxy prefix for routing behind
    # fastcgi and mod_proxy based deployments.
    if config.get('proxy_prefix', None):
        app = setup_prefix_middleware(app, global_conf, config['proxy_prefix'])

    # END CUSTOM MIDDLEWARE

    if asbool(full_stack):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

        # by default Apache uses  a global alias for "/error" in the httpd.conf
        # which means that users can not send error reports through MediaDrop's
        # error page (because that POSTs to /error/report).
        # To make things worse Apache (at least up to 2.4) has no "unalias"
        # functionality. So we work around the issue by using the "/errors"
        # prefix (extra "s" at the end)
        error_path = '/errors/document'
        # Display error documents for 401, 403, 404 status codes (and
        # 500 when debug is disabled)
        if asbool(config['debug']):
            app = StatusCodeRedirect(app, path=error_path)
        else:
            app = StatusCodeRedirect(app,
                                     errors=(400, 401, 403, 404, 500),
                                     path=error_path)

    # Cleanup the DBSession only after errors are handled
    app = DBSessionRemoverMiddleware(app)

    # Establish the Registry for this application
    app = RegistryManager(app)

    app = setup_db_sanity_checks(app, config)

    if asbool(static_files):
        # Serve static files from our public directory
        public_app = StaticURLParser(config['pylons.paths']['static_files'])

        static_urlmap = URLMap()
        # Serve static files from all plugins
        for dir, path in plugin_mgr.public_paths().iteritems():
            static_urlmap[dir] = StaticURLParser(path)

        # Serve static media and podcast images from outside our public directory
        for image_type in ('media', 'podcasts'):
            dir = '/images/' + image_type
            path = os.path.join(config['image_dir'], image_type)
            static_urlmap[dir] = StaticURLParser(path)

        # Serve appearance directory outside of public as well
        dir = '/appearance'
        path = os.path.join(config['app_conf']['cache_dir'], 'appearance')
        static_urlmap[dir] = StaticURLParser(path)

        # We want to serve goog closure code for debugging uncompiled js.
        if config['debug']:
            goog_path = os.path.join(config['pylons.paths']['root'], '..',
                                     'closure-library', 'closure', 'goog')
            if os.path.exists(goog_path):
                static_urlmap['/scripts/goog'] = StaticURLParser(goog_path)

        app = Cascade([public_app, static_urlmap, app])

    if asbool(config.get('enable_gzip', 'true')):
        app = setup_gzip_middleware(app, global_conf)

    app.config = config
    return app
Esempio n. 4
0
def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
    """Create a Pylons WSGI application and return it

    ``global_conf``
        The inherited configuration for this application. Normally from
        the [DEFAULT] section of the Paste ini file.

    ``full_stack``
        Whether this application provides a full WSGI stack (by default,
        meaning it handles its own exceptions and errors). Disable
        full_stack when this application is "managed" by another WSGI
        middleware.

    ``static_files``
        Whether this application serves its own static files; disable
        when another web server is responsible for serving them.

    ``app_conf``
        The application's local configuration. Normally specified in
        the [app:<name>] section of the Paste ini file (where <name>
        defaults to main).

    """
    # Configure the Pylons environment
    config = load_environment(global_conf, app_conf)
    alembic_migrations = MediaDropMigrator.from_config(config, log=log)
    db_is_current = True
    if not alembic_migrations.is_db_scheme_current():
        log.warn('Running with an outdated database scheme. Please upgrade your database.')
        db_is_current = False
    plugin_mgr = config['pylons.app_globals'].plugin_mgr
    db_current_for_plugins = plugin_mgr.is_db_scheme_current_for_all_plugins()
    if db_is_current and not db_current_for_plugins:
        log.warn(db_current_for_plugins.message)
        db_is_current = False
    if db_is_current:
        events.Environment.database_ready()

    # The Pylons WSGI app
    app = PylonsApp(config=config)

    # Allow the plugin manager to tweak our WSGI app
    app = plugin_mgr.wrap_pylons_app(app)

    # Routing/Session/Cache Middleware
    app = RoutesMiddleware(app, config['routes.map'], singleton=False)
    app = SessionMiddleware(app, config)

    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)

    # add repoze.who middleware with our own authorization library
    app = add_auth(app, config)

    # ToscaWidgets Middleware
    app = setup_tw_middleware(app, config)

    # Strip the name of the .fcgi script, if using one, from the SCRIPT_NAME
    app = FastCGIScriptStripperMiddleware(app)

    # If enabled, set up the proxy prefix for routing behind
    # fastcgi and mod_proxy based deployments.
    if config.get('proxy_prefix', None):
        app = setup_prefix_middleware(app, global_conf, config['proxy_prefix'])

    # END CUSTOM MIDDLEWARE

    if asbool(full_stack):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

        # by default Apache uses  a global alias for "/error" in the httpd.conf
        # which means that users can not send error reports through MediaDrop's
        # error page (because that POSTs to /error/report).
        # To make things worse Apache (at least up to 2.4) has no "unalias"
        # functionality. So we work around the issue by using the "/errors"
        # prefix (extra "s" at the end)
        error_path = '/errors/document'
        # Display error documents for 401, 403, 404 status codes (and
        # 500 when debug is disabled)
        if asbool(config['debug']):
            app = StatusCodeRedirect(app, path=error_path)
        else:
            app = StatusCodeRedirect(app, errors=(400, 401, 403, 404, 500),
                                     path=error_path)

    # Cleanup the DBSession only after errors are handled
    app = DBSessionRemoverMiddleware(app)

    # Establish the Registry for this application
    app = RegistryManager(app)

    app = setup_db_sanity_checks(app, config)

    if asbool(static_files):
        # Serve static files from our public directory
        public_app = StaticURLParser(config['pylons.paths']['static_files'])

        static_urlmap = URLMap()
        # Serve static files from all plugins
        for dir, path in plugin_mgr.public_paths().iteritems():
            static_urlmap[dir] = StaticURLParser(path)

        # Serve static media and podcast images from outside our public directory
        for image_type in ('media', 'podcasts'):
            dir = '/images/' + image_type
            path = os.path.join(config['image_dir'], image_type)
            static_urlmap[dir] = StaticURLParser(path)

        # Serve appearance directory outside of public as well
        dir = '/appearance'
        path = os.path.join(config['app_conf']['cache_dir'], 'appearance')
        static_urlmap[dir] = StaticURLParser(path)

        # We want to serve goog closure code for debugging uncompiled js.
        if config['debug']:
            goog_path = os.path.join(config['pylons.paths']['root'], '..',
                'closure-library', 'closure', 'goog')
            if os.path.exists(goog_path):
                static_urlmap['/scripts/goog'] = StaticURLParser(goog_path)

        app = Cascade([public_app, static_urlmap, app])

    if asbool(config.get('enable_gzip', 'true')):
        app = setup_gzip_middleware(app, global_conf)

    app.config = config
    return app
Esempio n. 5
0
def setup_app(command, conf, vars):
    """Called by ``paster setup-app``.

    This script is responsible for:

        * Creating the initial database schema and loading default data.
        * Executing any migrations necessary to bring an existing database
          up-to-date. Your data should be safe but, as always, be sure to
          make backups before using this.
        * Re-creating the default database for every run of the test suite.

    XXX: All your data will be lost IF you run the test suite with a
         config file named 'test.ini'. Make sure you have this configured
         to a different database than in your usual deployment.ini or
         development.ini file because all database tables are dropped a
         and recreated every time this script runs.

    XXX: If you are upgrading from MediaCore v0.7.2 or v0.8.0, run whichever
         one of these that applies:
           ``python batch-scripts/upgrade/upgrade_from_v072.py deployment.ini``
           ``python batch-scripts/upgrade/upgrade_from_v080.py deployment.ini``

    XXX: For search to work, we depend on a number of MySQL triggers which
         copy the data from our InnoDB tables to a MyISAM table for its
         fulltext indexing capability. Triggers can only be installed with
         a mysql superuser like root, so you must run the setup_triggers.sql
         script yourself.

    """
    config = load_environment(conf.global_conf, conf.local_conf)
    plugin_manager = config['pylons.app_globals'].plugin_mgr
    mediadrop_migrator = MediaDropMigrator.from_config(conf, log=log)
    
    engine = metadata.bind
    db_connection = engine.connect()
    # simplistic check to see if MediaDrop tables are present, just check for
    # the media_files table and assume that all other tables are there as well
    from mediadrop.model.media import media_files
    mediadrop_tables_exist = engine.dialect.has_table(db_connection, media_files.name)
    
    run_migrations = True
    if not mediadrop_tables_exist:
        head_revision = mediadrop_migrator.head_revision()
        log.info('Initializing new database with version %r' % head_revision)
        metadata.create_all(bind=DBSession.bind, checkfirst=True)
        mediadrop_migrator.init_db(revision=head_revision)
        run_migrations = False
        add_default_data()
        for migrator in plugin_manager.migrators():
            migrator.init_db()
        events.Environment.database_initialized()
    elif not mediadrop_migrator.migrate_table_exists():
        log.error('No migration table found, probably your MediaDrop install '
            'is too old (< 0.9?). Please upgrade to MediaCore CE 0.9 first.')
        raise AssertionError('no migration table found')
    elif not mediadrop_migrator.alembic_table_exists():
        alembic_revision = mediadrop_migrator.map_migrate_version()
        mediadrop_migrator.stamp(alembic_revision)
    if run_migrations:
        mediadrop_migrator.migrate_db()
        for migrator in plugin_manager.migrators():
            migrator.migrate_db()
        events.Environment.database_migrated()
    
    cleanup_players_table(enabled=True)
    
    # Save everything, along with the dummy data if applicable
    DBSession.commit()
    events.Environment.database_ready()

    log.info('Generating appearance.css from your current settings')
    settings = DBSession.query(Setting.key, Setting.value)
    generate_appearance_css(settings, cache_dir=conf['cache_dir'])

    log.info('Successfully setup')