def __init__(self, context, backend_addr, friendly_name, concurrency, tasks_filesystem, problem_types): """ :param context: ZeroMQ context for this process :param backend_addr: address of the backend (for example, "tcp://127.0.0.1:2222") :param friendly_name: a string containing a friendly name to identify agent :param tasks_filesystem: FileSystemProvider to the course/tasks :param problem_types: Problem types dictionary """ super().__init__(context, backend_addr, friendly_name, concurrency, tasks_filesystem) self._logger = logging.getLogger("inginious.agent.mcq") self._problem_types = problem_types # Init gettext self._translations = {"en": gettext.NullTranslations()} available_translations = [ x for x in os.listdir(get_root_path() + '/agent/mcq_agent/i18n') if os.path.isdir( os.path.join(get_root_path() + '/agent/mcq_agent/i18n', x)) ] self._translations.update({ lang: gettext.translation('messages', get_root_path() + '/agent/mcq_agent/i18n', [lang]) for lang in available_translations })
def get_custom_renderer(self, dir_path, layout=True): """ Create a template renderer on templates in the directory specified, and returns it. See the web.py documentation. This function is deprecated, use render() (that uses Jinja) instead. :param dir_path: the path to the template dir. If it is not absolute, it will be taken from the root of the inginious package. :param layout: can either be True (use the base layout of the running app), False (use no layout at all), or the path to the layout to use. If this path is relative, it is taken from the INGInious package root. """ # if dir_path/base is a absolute path, os.path.join(something, an_absolute_path) returns an_absolute_path. root_path = inginious.get_root_path() if isinstance(layout, str): layout_path = os.path.join(root_path, layout) elif layout is True: layout_path = os.path.join(root_path, self._layout) else: layout_path = None return web.template.render(os.path.join(root_path, dir_path), globals=self._template_globals, base=layout_path)
def __init__(self, context, backend_addr, friendly_name, concurrency, tasks_filesystem): """ :param context: ZeroMQ context for this process :param backend_addr: address of the backend (for example, "tcp://127.0.0.1:2222") :param friendly_name: a string containing a friendly name to identify agent :param tasks_filesystem: FileSystemProvider to the course/tasks """ super().__init__(context, backend_addr, friendly_name, concurrency, tasks_filesystem) self._logger = logging.getLogger("inginious.agent.mcq") # Create a course factory course_factory, _ = create_factories(tasks_filesystem) self.course_factory = course_factory # Init gettext languages = ["en", "fr"] self._translations = { lang: gettext.translation('messages', get_root_path() + '/agent/mcq_agent/i18n', [lang]) for lang in languages }
def _get_jinja_renderer(self, template_folder=""): # Always include the main template folder template_folders = [ os.path.join(inginious.get_root_path(), self._template_dir) ] # Include the additional template folder if specified if template_folder: template_folders += [ os.path.join(inginious.get_root_path(), template_folder) ] env = Environment(loader=FileSystemLoader(template_folders), autoescape=select_autoescape(['html', 'htm', 'xml'])) env.globals.update(self._template_globals) return env
def _get_jinja_renderer(self, base_template_folder=None): if base_template_folder is None: base_template_folder = self._template_dir # if base_template_folder is not an absolute path, take it wrt INGInious root folder base_template_folder = os.path.join(inginious.get_root_path(), base_template_folder) env = Environment(loader=FileSystemLoader(base_template_folder), autoescape=select_autoescape(['html', 'htm', 'xml'])) env.globals.update(self._template_globals) return env
def __init__(self, context, backend_addr, friendly_name, concurrency, tasks_filesystem, course_factory): """ :param context: ZeroMQ context for this process :param backend_addr: address of the backend (for example, "tcp://127.0.0.1:2222") :param friendly_name: a string containing a friendly name to identify agent :param tasks_filesystem: FileSystemProvider to the course/tasks :param course_factory: Course factory used to get course/tasks """ super().__init__(context, backend_addr, friendly_name, concurrency, tasks_filesystem) self._logger = logging.getLogger("inginious.agent.mcq") self.course_factory = course_factory # Init gettext languages = ["en", "fr"] self._translations = { lang: gettext.translation('messages', get_root_path() + '/agent/mcq_agent/i18n', [lang]) for lang in languages }
def get_custom_renderer(self, dir_path, layout=True): """ Create a template renderer on templates in the directory specified, and returns it. :param dir_path: the path to the template dir. If it is not absolute, it will be taken from the root of the inginious package. :param layout: can either be True (use the base layout of the running app), False (use no layout at all), or the path to the layout to use. If this path is relative, it is taken from the INGInious package root. """ # if dir_path/base is a absolute path, os.path.join(something, an_absolute_path) returns an_absolute_path. root_path = inginious.get_root_path() if isinstance(layout, str): layout_path = os.path.join(root_path, layout) elif layout is True: layout_path = os.path.join(root_path, self._layout) else: layout_path = None return web.template.render(os.path.join(root_path, dir_path), globals=self._template_globals, base=layout_path)
def get_app(config): """ :param config: the configuration dict :return: A new app """ config = _put_configuration_defaults(config) mongo_client = MongoClient( host=config.get('mongo_opt', {}).get('host', 'localhost')) database = mongo_client[config.get('mongo_opt', {}).get('database', 'INGInious')] gridfs = GridFS(database) # Init database if needed db_version = database.db_version.find_one({}) if db_version is None: database.submissions.ensure_index([("username", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.submissions.ensure_index([("submitted_on", pymongo.DESCENDING) ]) # sort speed database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)], unique=True) database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("username", pymongo.ASCENDING)]) appli = CookieLessCompatibleApplication(MongoStore(database, 'sessions')) # Init gettext available_languages = {"en": "English", "fr": "Français"} for lang in available_languages.keys(): appli.add_translation( lang, gettext.translation('messages', get_root_path() + '/frontend/i18n', [lang])) builtins.__dict__['_'] = appli.gettext if config.get("maintenance", False): template_helper = TemplateHelper(PluginManager(), None, 'frontend/templates', 'frontend/templates/layout', 'frontend/templates/layout_lti', config.get('use_minified_js', True)) template_helper.add_to_template_globals("get_homepath", appli.get_homepath) template_helper.add_to_template_globals("_", _) appli.template_helper = template_helper appli.init_mapping(urls_maintenance) return appli.wsgifunc(), appli.stop default_allowed_file_extensions = config['allowed_file_extensions'] default_max_file_size = config['max_file_size'] zmq_context, __ = start_asyncio_and_zmq(config.get('debug_asyncio', False)) # Init the different parts of the app plugin_manager = PluginManager() # Create the FS provider if "fs" in config: fs_provider = filesystem_from_config_dict(config["fs"]) else: task_directory = config["tasks_directory"] fs_provider = LocalFSProvider(task_directory) default_problem_types = { problem_type.get_type(): problem_type for problem_type in [ DisplayableCodeProblem, DisplayableCodeSingleLineProblem, DisplayableFileProblem, DisplayableMultipleChoiceProblem, DisplayableMatchProblem ] } course_factory, task_factory = create_factories(fs_provider, default_problem_types, plugin_manager, WebAppCourse, WebAppTask) user_manager = UserManager(appli.get_session(), database, config.get('superadmins', [])) update_pending_jobs(database) client = create_arch(config, fs_provider, zmq_context, course_factory) lti_outcome_manager = LTIOutcomeManager(database, user_manager, course_factory) submission_manager = WebAppSubmissionManager(client, user_manager, database, gridfs, plugin_manager, lti_outcome_manager) template_helper = TemplateHelper(plugin_manager, user_manager, 'frontend/templates', 'frontend/templates/layout', 'frontend/templates/layout_lti', config.get('use_minified_js', True)) # Init web mail smtp_conf = config.get('smtp', None) if smtp_conf is not None: web.config.smtp_server = smtp_conf["host"] web.config.smtp_port = int(smtp_conf["port"]) web.config.smtp_starttls = bool(smtp_conf.get("starttls", False)) web.config.smtp_username = smtp_conf.get("username", "") web.config.smtp_password = smtp_conf.get("password", "") web.config.smtp_sendername = smtp_conf.get("sendername", "*****@*****.**") # Add some helpers for the templates template_helper.add_to_template_globals("_", _) template_helper.add_to_template_globals("str", str) template_helper.add_to_template_globals("available_languages", available_languages) template_helper.add_to_template_globals("get_homepath", appli.get_homepath) template_helper.add_to_template_globals( "allow_registration", config.get("allow_registration", True)) template_helper.add_to_template_globals("user_manager", user_manager) template_helper.add_to_template_globals("default_allowed_file_extensions", default_allowed_file_extensions) template_helper.add_to_template_globals("default_max_file_size", default_max_file_size) template_helper.add_other( "course_admin_menu", lambda course, current: course_admin_utils.get_menu( course, current, template_helper.get_renderer(False), plugin_manager, user_manager)) template_helper.add_other( "preferences_menu", lambda current: preferences_utils.get_menu( appli, current, template_helper.get_renderer(False), plugin_manager, user_manager)) # Not found page appli.notfound = lambda: web.notfound(template_helper.get_renderer(). notfound('Page not found')) # Enable stacktrace display if logging is at level DEBUG if config.get('log_level', 'INFO') == 'DEBUG': appli.internalerror = debugerror # Insert the needed singletons into the application, to allow pages to call them appli.plugin_manager = plugin_manager appli.course_factory = course_factory appli.task_factory = task_factory appli.submission_manager = submission_manager appli.user_manager = user_manager appli.template_helper = template_helper appli.database = database appli.gridfs = gridfs appli.default_allowed_file_extensions = default_allowed_file_extensions appli.default_max_file_size = default_max_file_size appli.backup_dir = config.get("backup_directory", './backup') appli.webterm_link = config.get("webterm", None) appli.lti_outcome_manager = lti_outcome_manager appli.allow_registration = config.get("allow_registration", True) appli.allow_deletion = config.get("allow_deletion", True) appli.available_languages = available_languages appli.welcome_page = config.get("welcome_page", None) appli.static_directory = config.get("static_directory", "./static") appli.webdav_host = config.get("webdav_host", None) # Init the mapping of the app appli.init_mapping(urls) # Loads plugins plugin_manager.load(client, appli, course_factory, task_factory, database, user_manager, submission_manager, config.get("plugins", [])) # Start the inginious.backend client.start() return appli.wsgifunc(), lambda: _close_app(appli, mongo_client, client)
def get_app(config): """ :param config: the configuration dict :return: A new app """ # First, disable debug. It will be enabled in the configuration, later. web.config.debug = False config = _put_configuration_defaults(config) web.config.session_parameters.update(config['session_parameters']) mongo_client = MongoClient( host=config.get('mongo_opt', {}).get('host', 'localhost')) database = mongo_client[config.get('mongo_opt', {}).get('database', 'INGInious')] gridfs = GridFS(database) # Init database if needed db_version = database.db_version.find_one({}) if db_version is None: database.submissions.ensure_index([("username", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.submissions.ensure_index([("submitted_on", pymongo.DESCENDING) ]) # sort speed database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)], unique=True) database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("username", pymongo.ASCENDING)]) appli = CookieLessCompatibleApplication(MongoStore(database, 'sessions')) # Init gettext available_translations = { "fr": "Français", "es": "Español", "pt": "Português", "el": "ελληνικά", "vi": "Tiếng Việt", "nl": "Nederlands", "de": "Deutsch" } available_languages = {"en": "English"} available_languages.update(available_translations) appli.add_translation( "en", gettext.NullTranslations()) # English does not need translation ;-) for lang in available_translations.keys(): appli.add_translation( lang, gettext.translation('messages', get_root_path() + '/frontend/i18n', [lang])) builtins.__dict__['_'] = appli.gettext if config.get("maintenance", False): template_helper = TemplateHelper(PluginManager(), None, 'frontend/templates', 'frontend/templates/layout', 'frontend/templates/layout_lti', config.get('use_minified_js', True)) template_helper.add_to_template_globals("get_homepath", appli.get_homepath) template_helper.add_to_template_globals("_", _) appli.template_helper = template_helper appli.init_mapping(urls_maintenance) return appli.wsgifunc(), appli.stop default_allowed_file_extensions = config['allowed_file_extensions'] default_max_file_size = config['max_file_size'] zmq_context, __ = start_asyncio_and_zmq(config.get('debug_asyncio', False)) # Init the different parts of the app plugin_manager = PluginManager() # Add the "agent types" inside the frontend, to allow loading tasks and managing envs register_base_env_types() # Create the FS provider if "fs" in config: fs_provider = filesystem_from_config_dict(config["fs"]) else: task_directory = config["tasks_directory"] fs_provider = LocalFSProvider(task_directory) default_task_dispensers = { task_dispenser.get_id(): task_dispenser for task_dispenser in [TableOfContents, CombinatoryTest] } default_problem_types = { problem_type.get_type(): problem_type for problem_type in [ DisplayableCodeProblem, DisplayableCodeSingleLineProblem, DisplayableFileProblem, DisplayableMultipleChoiceProblem, DisplayableMatchProblem ] } course_factory, task_factory = create_factories(fs_provider, default_task_dispensers, default_problem_types, plugin_manager) user_manager = UserManager(appli.get_session(), database, config.get('superadmins', [])) update_pending_jobs(database) client = create_arch(config, fs_provider, zmq_context, course_factory) lti_outcome_manager = LTIOutcomeManager(database, user_manager, course_factory) submission_manager = WebAppSubmissionManager(client, user_manager, database, gridfs, plugin_manager, lti_outcome_manager) template_helper = TemplateHelper(plugin_manager, user_manager, 'frontend/templates', 'frontend/templates/layout', 'frontend/templates/layout_lti', config.get('use_minified_js', True)) register_utils(database, user_manager, template_helper) is_tos_defined = config.get("privacy_page", "") and config.get( "terms_page", "") # Init web mail smtp_conf = config.get('smtp', None) if smtp_conf is not None: web.config.smtp_server = smtp_conf["host"] web.config.smtp_port = int(smtp_conf["port"]) web.config.smtp_starttls = bool(smtp_conf.get("starttls", False)) web.config.smtp_username = smtp_conf.get("username", "") web.config.smtp_password = smtp_conf.get("password", "") web.config.smtp_sendername = smtp_conf.get("sendername", "*****@*****.**") # Add some helpers for the templates template_helper.add_to_template_globals("_", _) template_helper.add_to_template_globals("str", str) template_helper.add_to_template_globals("available_languages", available_languages) template_helper.add_to_template_globals("get_homepath", appli.get_homepath) template_helper.add_to_template_globals( "allow_registration", config.get("allow_registration", True)) template_helper.add_to_template_globals("sentry_io_url", config.get("sentry_io_url")) template_helper.add_to_template_globals("user_manager", user_manager) template_helper.add_to_template_globals("default_allowed_file_extensions", default_allowed_file_extensions) template_helper.add_to_template_globals("default_max_file_size", default_max_file_size) template_helper.add_to_template_globals("is_tos_defined", is_tos_defined) template_helper.add_other( "course_admin_menu", lambda course, current: course_admin_utils.get_menu( course, current, template_helper.get_renderer(False), plugin_manager, user_manager)) template_helper.add_other( "preferences_menu", lambda current: preferences_utils.get_menu( appli, current, template_helper.get_renderer(False), plugin_manager, user_manager)) # Not found page appli.notfound = lambda message='Page not found': web.notfound( template_helper.get_renderer().notfound(message)) # Forbidden page appli.forbidden = lambda message='Forbidden': web.forbidden( template_helper.get_renderer().forbidden(message)) # Enable stacktrace display if needed web_debug = config.get('web_debug', False) appli.internalerror = internalerror_generator( template_helper.get_renderer(False)) if web_debug is True: web.config.debug = True appli.internalerror = debugerror elif isinstance(web_debug, str): web.config.debug = False appli.internalerror = emailerrors(web_debug, appli.internalerror) # Insert the needed singletons into the application, to allow pages to call them appli.plugin_manager = plugin_manager appli.course_factory = course_factory appli.task_factory = task_factory appli.submission_manager = submission_manager appli.user_manager = user_manager appli.template_helper = template_helper appli.database = database appli.gridfs = gridfs appli.client = client appli.default_allowed_file_extensions = default_allowed_file_extensions appli.default_max_file_size = default_max_file_size appli.backup_dir = config.get("backup_directory", './backup') appli.webterm_link = config.get("webterm", None) appli.lti_outcome_manager = lti_outcome_manager appli.allow_registration = config.get("allow_registration", True) appli.allow_deletion = config.get("allow_deletion", True) appli.available_languages = available_languages appli.welcome_page = config.get("welcome_page", None) appli.terms_page = config.get("terms_page", None) appli.privacy_page = config.get("privacy_page", None) appli.static_directory = config.get("static_directory", "./static") appli.webdav_host = config.get("webdav_host", None) # Init the mapping of the app appli.init_mapping(urls) # Loads plugins plugin_manager.load(client, appli, course_factory, task_factory, database, user_manager, submission_manager, config.get("plugins", [])) # Start the inginious.backend client.start() return appli.wsgifunc(), lambda: _close_app(appli, mongo_client, client)
def get_app(config): """ :param config: the configuration dict :return: A new app """ # First, disable debug. It will be enabled in the configuration, later. config = _put_configuration_defaults(config) mongo_client = MongoClient( host=config.get('mongo_opt', {}).get('host', 'localhost')) database = mongo_client[config.get('mongo_opt', {}).get('database', 'INGInious')] gridfs = GridFS(database) # Init database if needed db_version = database.db_version.find_one({}) if db_version is None: database.submissions.ensure_index([("username", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.submissions.ensure_index([("submitted_on", pymongo.DESCENDING) ]) # sort speed database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)], unique=True) database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("username", pymongo.ASCENDING)]) flask_app = flask.Flask(__name__) flask_app.config.from_mapping(**config) flask_app.session_interface = MongoDBSessionInterface( mongo_client, config.get('mongo_opt', {}).get('database', 'INGInious'), "sessions", config.get('SESSION_USE_SIGNER', False), True # config.get('SESSION_PERMANENT', True) ) # Init gettext available_translations = { "fr": "Français", "es": "Español", "pt": "Português", "el": "ελληνικά", "vi": "Tiếng Việt", "nl": "Nederlands", "de": "Deutsch" } available_languages = {"en": "English"} available_languages.update(available_translations) l10n_manager = L10nManager() l10n_manager.translations["en"] = gettext.NullTranslations( ) # English does not need translation ;-) for lang in available_translations.keys(): l10n_manager.translations[lang] = gettext.translation( 'messages', get_root_path() + '/frontend/i18n', [lang]) builtins.__dict__['_'] = l10n_manager.gettext if config.get("maintenance", False): template_helper = TemplateHelper(PluginManager(), None, config.get('use_minified_js', True)) template_helper.add_to_template_globals("get_homepath", get_homepath) template_helper.add_to_template_globals("pkg_version", __version__) template_helper.add_to_template_globals("available_languages", available_languages) template_helper.add_to_template_globals("_", _) flask_app.template_helper = template_helper init_flask_maintenance_mapping(flask_app) return flask_app.wsgi_app, lambda: None default_allowed_file_extensions = config['allowed_file_extensions'] default_max_file_size = config['max_file_size'] zmq_context, __ = start_asyncio_and_zmq(config.get('debug_asyncio', False)) # Init the different parts of the app plugin_manager = PluginManager() # Add the "agent types" inside the frontend, to allow loading tasks and managing envs register_base_env_types() # Create the FS provider if "fs" in config: fs_provider = filesystem_from_config_dict(config["fs"]) else: task_directory = config["tasks_directory"] fs_provider = LocalFSProvider(task_directory) default_task_dispensers = { task_dispenser.get_id(): task_dispenser for task_dispenser in [TableOfContents, CombinatoryTest] } default_problem_types = { problem_type.get_type(): problem_type for problem_type in [ DisplayableCodeProblem, DisplayableCodeSingleLineProblem, DisplayableFileProblem, DisplayableMultipleChoiceProblem, DisplayableMatchProblem ] } course_factory, task_factory = create_factories(fs_provider, default_task_dispensers, default_problem_types, plugin_manager) user_manager = UserManager(database, config.get('superadmins', [])) update_pending_jobs(database) client = create_arch(config, fs_provider, zmq_context, course_factory) lti_outcome_manager = LTIOutcomeManager(database, user_manager, course_factory) submission_manager = WebAppSubmissionManager(client, user_manager, database, gridfs, plugin_manager, lti_outcome_manager) template_helper = TemplateHelper(plugin_manager, user_manager, config.get('use_minified_js', True)) register_utils(database, user_manager, template_helper) is_tos_defined = config.get("privacy_page", "") and config.get( "terms_page", "") # Init web mail mail.init_app(flask_app) # Add some helpers for the templates template_helper.add_to_template_globals("_", _) template_helper.add_to_template_globals("str", str) template_helper.add_to_template_globals("available_languages", available_languages) template_helper.add_to_template_globals("get_homepath", get_homepath) template_helper.add_to_template_globals("pkg_version", __version__) template_helper.add_to_template_globals( "allow_registration", config.get("allow_registration", True)) template_helper.add_to_template_globals("sentry_io_url", config.get("sentry_io_url")) template_helper.add_to_template_globals("user_manager", user_manager) template_helper.add_to_template_globals("default_allowed_file_extensions", default_allowed_file_extensions) template_helper.add_to_template_globals("default_max_file_size", default_max_file_size) template_helper.add_to_template_globals("is_tos_defined", is_tos_defined) template_helper.add_other( "course_admin_menu", lambda course, current: course_admin_utils.get_menu( course, current, template_helper.render, plugin_manager, user_manager)) template_helper.add_other( "preferences_menu", lambda current: preferences_utils.get_menu( config.get("allow_deletion", True), current, template_helper. render, plugin_manager, user_manager)) # Not found page def flask_not_found(e): return template_helper.render("notfound.html", message=e.description), 404 flask_app.register_error_handler(404, flask_not_found) # Forbidden page def flask_forbidden(e): return template_helper.render("forbidden.html", message=e.description), 403 flask_app.register_error_handler(403, flask_forbidden) # Enable stacktrace display if needed web_debug = config.get('web_debug', False) def flask_internalerror(e): return template_helper.render("internalerror.html", message=e.description), 500 flask_app.register_error_handler(InternalServerError, flask_internalerror) if web_debug is True: flask_app.debug = True elif isinstance(web_debug, str): flask_app.debug = False # Insert the needed singletons into the application, to allow pages to call them flask_app.get_homepath = get_homepath flask_app.plugin_manager = plugin_manager flask_app.course_factory = course_factory flask_app.task_factory = task_factory flask_app.submission_manager = submission_manager flask_app.user_manager = user_manager flask_app.l10n_manager = l10n_manager flask_app.template_helper = template_helper flask_app.database = database flask_app.gridfs = gridfs flask_app.client = client flask_app.default_allowed_file_extensions = default_allowed_file_extensions flask_app.default_max_file_size = default_max_file_size flask_app.backup_dir = config.get("backup_directory", './backup') flask_app.webterm_link = config.get("webterm", None) flask_app.lti_outcome_manager = lti_outcome_manager flask_app.allow_registration = config.get("allow_registration", True) flask_app.allow_deletion = config.get("allow_deletion", True) flask_app.available_languages = available_languages flask_app.welcome_page = config.get("welcome_page", None) flask_app.terms_page = config.get("terms_page", None) flask_app.privacy_page = config.get("privacy_page", None) flask_app.static_directory = config.get("static_directory", "./static") flask_app.webdav_host = config.get("webdav_host", None) # Init the mapping of the app init_flask_mapping(flask_app) # Loads plugins plugin_manager.load(client, flask_app, course_factory, task_factory, database, user_manager, submission_manager, config.get("plugins", [])) # Start the inginious.backend client.start() return flask_app.wsgi_app, lambda: _close_app(mongo_client, client)
def get_app(config): """ :param config: the configuration dict :return: A new app """ # First, disable debug. It will be enabled in the configuration, later. web.config.debug = False config = _put_configuration_defaults(config) mongo_client = MongoClient(host=config.get('mongo_opt', {}).get('host', 'localhost')) database = mongo_client[config.get('mongo_opt', {}).get('database', 'INGInious')] gridfs = GridFS(database) # Init database if needed db_version = database.db_version.find_one({}) if db_version is None: database.submissions.ensure_index([("username", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING)]) database.submissions.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.submissions.ensure_index([("submitted_on", pymongo.DESCENDING)]) # sort speed database.user_tasks.ensure_index( [("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)], unique=True) database.user_tasks.ensure_index([("username", pymongo.ASCENDING), ("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING), ("taskid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("courseid", pymongo.ASCENDING)]) database.user_tasks.ensure_index([("username", pymongo.ASCENDING)]) appli = CookieLessCompatibleApplication(MongoStore(database, 'sessions')) # Init gettext available_languages = { "en": "English", "fr": "Français" } for lang in available_languages.keys(): appli.add_translation(lang, gettext.translation('messages', get_root_path() + '/frontend/i18n', [lang])) builtins.__dict__['_'] = appli.gettext if config.get("maintenance", False): template_helper = TemplateHelper(PluginManager(), None, 'frontend/templates', 'frontend/templates/layout', 'frontend/templates/layout_lti', config.get('use_minified_js', True)) template_helper.add_to_template_globals("get_homepath", appli.get_homepath) template_helper.add_to_template_globals("_", _) appli.template_helper = template_helper appli.init_mapping(urls_maintenance) return appli.wsgifunc(), appli.stop default_allowed_file_extensions = config['allowed_file_extensions'] default_max_file_size = config['max_file_size'] zmq_context, __ = start_asyncio_and_zmq(config.get('debug_asyncio', False)) # Init the different parts of the app plugin_manager = PluginManager() # Create the FS provider if "fs" in config: fs_provider = filesystem_from_config_dict(config["fs"]) else: task_directory = config["tasks_directory"] fs_provider = LocalFSProvider(task_directory) default_problem_types = { problem_type.get_type(): problem_type for problem_type in [DisplayableCodeProblem, DisplayableCodeSingleLineProblem, DisplayableFileProblem, DisplayableMultipleChoiceProblem, DisplayableMatchProblem] } course_factory, task_factory = create_factories(fs_provider, default_problem_types, plugin_manager, WebAppCourse, WebAppTask) user_manager = UserManager(appli.get_session(), database, config.get('superadmins', [])) update_pending_jobs(database) client = create_arch(config, fs_provider, zmq_context, course_factory) lti_outcome_manager = LTIOutcomeManager(database, user_manager, course_factory) submission_manager = WebAppSubmissionManager(client, user_manager, database, gridfs, plugin_manager, lti_outcome_manager) template_helper = TemplateHelper(plugin_manager, user_manager, 'frontend/templates', 'frontend/templates/layout', 'frontend/templates/layout_lti', config.get('use_minified_js', True)) # Init web mail smtp_conf = config.get('smtp', None) if smtp_conf is not None: web.config.smtp_server = smtp_conf["host"] web.config.smtp_port = int(smtp_conf["port"]) web.config.smtp_starttls = bool(smtp_conf.get("starttls", False)) web.config.smtp_username = smtp_conf.get("username", "") web.config.smtp_password = smtp_conf.get("password", "") web.config.smtp_sendername = smtp_conf.get("sendername", "*****@*****.**") # Add some helpers for the templates template_helper.add_to_template_globals("_", _) template_helper.add_to_template_globals("str", str) template_helper.add_to_template_globals("available_languages", available_languages) template_helper.add_to_template_globals("get_homepath", appli.get_homepath) template_helper.add_to_template_globals("allow_registration", config.get("allow_registration", True)) template_helper.add_to_template_globals("user_manager", user_manager) template_helper.add_to_template_globals("default_allowed_file_extensions", default_allowed_file_extensions) template_helper.add_to_template_globals("default_max_file_size", default_max_file_size) template_helper.add_other("course_admin_menu", lambda course, current: course_admin_utils.get_menu(course, current, template_helper.get_renderer(False), plugin_manager, user_manager)) template_helper.add_other("preferences_menu", lambda current: preferences_utils.get_menu(appli, current, template_helper.get_renderer(False), plugin_manager, user_manager)) # Not found page appli.notfound = lambda: web.notfound(template_helper.get_renderer().notfound('Page not found')) # Enable stacktrace display if needed web_debug = config.get('web_debug', False) appli.internalerror = internalerror_generator(template_helper.get_renderer(False)) if web_debug is True: web.config.debug = True appli.internalerror = debugerror elif isinstance(web_debug, str): web.config.debug = False appli.internalerror = emailerrors(web_debug, appli.internalerror) # Insert the needed singletons into the application, to allow pages to call them appli.plugin_manager = plugin_manager appli.course_factory = course_factory appli.task_factory = task_factory appli.submission_manager = submission_manager appli.user_manager = user_manager appli.template_helper = template_helper appli.database = database appli.gridfs = gridfs appli.default_allowed_file_extensions = default_allowed_file_extensions appli.default_max_file_size = default_max_file_size appli.backup_dir = config.get("backup_directory", './backup') appli.webterm_link = config.get("webterm", None) appli.lti_outcome_manager = lti_outcome_manager appli.allow_registration = config.get("allow_registration", True) appli.allow_deletion = config.get("allow_deletion", True) appli.available_languages = available_languages appli.welcome_page = config.get("welcome_page", None) appli.static_directory = config.get("static_directory", "./static") appli.webdav_host = config.get("webdav_host", None) # Init the mapping of the app appli.init_mapping(urls) # Loads plugins plugin_manager.load(client, appli, course_factory, task_factory, database, user_manager, submission_manager, config.get("plugins", [])) # Start the inginious.backend client.start() return appli.wsgifunc(), lambda: _close_app(appli, mongo_client, client)