def initialise_database(args): settings = get_appsettings(args.configuration) setup_logging(args.configuration) engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) if args.drop_existing: Base.metadata.drop_all(engine) Base.metadata.create_all(engine) dbsession = DBSession() with transaction.manager: user = User(email='*****@*****.**', display_name='Admin', status='active') user.new_password('password') group = PermissionGroup(title='Site administrator') group.permissions.append( Permission(name='admin.users.view', title='View all users')) group.permissions.append( Permission(name='admin.users.edit', title='Edit all users')) group.permissions.append( Permission(name='admin.users.delete', title='Delete all users')) group.permissions.append( Permission(name='admin.users.permissions', title='Edit all user\'s permissions')) user.permission_groups.append(group) group = PermissionGroup(title='Developer') group.permissions.append( Permission(name='experiment.create', title='Create new experiments')) user.permission_groups.append(group) dbsession.add(user) group = PermissionGroup(title='Content administrator') group.permissions.append( Permission(name='experiment.view', title='View all experiments')) group.permissions.append( Permission(name='experiment.edit', title='Edit all experiments')) group.permissions.append( Permission(name='experiment.delete', title='Delete all experiments')) dbsession.add(group) question_types = load(QuestionTypeIOSchema(many=True), json.loads(resource_string('ess', 'scripts/templates/default_question_types.json').\ decode('utf-8'))) dbsession.add_all(question_types) alembic_config = config.Config(args.configuration, ini_section='app:main') alembic_config.set_section_option('app:main', 'script_location', 'ess:migrations') command.stamp(alembic_config, "head")
def initialise_database(args): """Initialises the database schema and adds the default :class:`~wte.models.Permission`, :class:`~wte.models.PermissionGroup`, and :class:`~wte.models.User` to the database. """ settings = get_appsettings(args.configuration) setup_logging(args.configuration) engine = engine_from_config(settings, 'sqlalchemy.') if args.drop_existing: Base.metadata.drop_all(engine) Base.metadata.create_all(engine) DBSession.configure(bind=engine) dbsession = DBSession() with transaction.manager: admin_user = User(email='*****@*****.**', display_name='Admin', password='******') dbsession.add(admin_user) admin_permission = Permission(name='admin', title='Administration Access') group = init_auth_permissions(dbsession) group.permissions.append(admin_permission) admin_user.permission_groups.append(group) group = PermissionGroup(title='Content Administration') dbsession.add(group) group.permissions.append(admin_permission) create_module_perm = Permission(name='modules.create', title='Create a new module') group.permissions.append(create_module_perm) group.permissions.append( Permission(name='admin.modules.view', title='View all modules')) group.permissions.append( Permission(name='admin.modules.edit', title='Edit all modules')) group.permissions.append( Permission(name='admin.modules.delete', title='Delete all modules')) admin_user.permission_groups.append(group) group = PermissionGroup(title='Teacher') dbsession.add(group) group.permissions.append(create_module_perm) group = PermissionGroup(title='Student') dbsession.add(group)
def run_timed_tasks(args): """Runs all timed tasks where the timestamp is in the past and the status is "ready". All :class:`~wte.models.TimedTask` that are to be run are given a unique "run-{random-number}" ``status`` to uniquely identify them for this run. Individual task runners are then responsible for setting that status to "completed" after the task completes successfully or to "failed" if it failed. All task runners are run in independent :class:`threading.Thread`\ s. After all :class:`~threading.Thread` complete, any :class:`~wte.models.TimedTask` that still have the unique "run-{random-number}" status are automatically set to the "failed" status. """ settings = get_appsettings(args.configuration) setup_logging(args.configuration) engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine dbsession = DBSession() tasks = dbsession.query(TimedTask).filter( and_(TimedTask.timestamp <= func.now(), TimedTask.status == 'ready')) rnd = randint(0, 1000000) with transaction.manager: tasks.update({TimedTask.status: 'running-%i' % (rnd)}, synchronize_session=False) tasks = dbsession.query(TimedTask).filter( TimedTask.status == 'running-%i' % (rnd)) task_count = tasks.count() if task_count > 0: logging.getLogger('wte').info('Running %i tasks' % (task_count)) threads = [] for task in tasks: if task.name == 'change_status': threads.append( Thread(None, target=run_change_status, args=(task.id, ))) for thread in threads: thread.start() for thread in threads: thread.join() dbsession.flush() failed_count = tasks.count() if failed_count > 0: logging.getLogger('wte').error('%i tasks failed' % (failed_count)) else: logging.getLogger('wte').info('All tasks completed') with transaction.manager: tasks.update({TimedTask.status: 'failed'})
def main(global_config, **settings): """Constructs, initialises, and returns the Web Teaching Environment's ``WSGIApplication``. """ # Init Database engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine check_database_version(DB_VERSION) # Init configuration config = Configurator(settings=settings) config.include('kajiki.integration.pyramid') # Init routes config.add_static_view('static', 'static', cache_max_age=3600) views.init(config, settings) # Init docutils text_formatter.init(settings) config.scan() return config.make_wsgi_app()
def database(): """The :func:`~ess_test.conftest.database` fixture initialises the database specified in the "testing.ini", removes any existing data, creates the standard permissions, and four test users: * admin - user with full administrative permissions * developer - user with full experiment development permissions * content - user with full editing permissions * general - user with no permissions """ global dbsession_initialised # Load settings settings = get_appsettings('testing.ini') setup_logging('testing.ini') # Init the DB engine = engine_from_config(settings, 'sqlalchemy.') if not dbsession_initialised: DBSession.configure(bind=engine) dbsession_initialised = True Base.metadata.drop_all(engine) Base.metadata.create_all(engine) dbsession = DBSession() # Create Test Users with transaction.manager: admin_user = User(email='*****@*****.**', display_name='Admin', password='******') developer_user = User(email='*****@*****.**', display_name='Developer', password='******') content_user = User(email='*****@*****.**', display_name='Content', password='******') general_user = User(email='*****@*****.**', display_name='General', password='******') dbsession.add(general_user) group = PermissionGroup(title='Site administrator') group.permissions.append(Permission(name='admin.users', title='Administer the users')) group.permissions.append(Permission(name='admin.groups', title='Administer the permission groups')) group.permissions.append(Permission(name='admin.question_types', title='Administer the question types')) admin_user.permission_groups.append(group) group = PermissionGroup(title='Developer') group.permissions.append(Permission(name='survey.new', title='Create new experiments')) admin_user.permission_groups.append(group) developer_user.permission_groups.append(group) group = PermissionGroup(title='Content administrator') group.permissions.append(Permission(name='survey.view-all', title='View all experiments')) group.permissions.append(Permission(name='survey.edit-all', title='Edit all experiments')) group.permissions.append(Permission(name='survey.delete-all', title='Delete all experiments')) content_user.permission_groups.append(group) dbsession.add(admin_user) dbsession.add(developer_user) dbsession.add(content_user) question_types = QuestionTypeIOSchema(include_schemas=(QuestionTypeGroupIOSchema,), many=True).\ loads(resource_string('ess','scripts/templates/default_question_types.json')) dbsession.add_all(question_types.data) # Alembic Stamp alembic_config = config.Config('testing.ini', ini_section='app:main') alembic_config.set_section_option('app:main', 'script_location', 'ess:migrations') command.stamp(alembic_config, "head") dbsession.close() DBSession.close_all() yield DBSession