def get_jinja_loader(source_dir): return ChoiceLoader([ FileSystemLoader(source_dir), PackageLoader('clay', basename(source_dir)), ])
def run(args): usage = "xia2.report [options] scaled_unmerged.mtz" parser = OptionParser( usage=usage, phil=phil_scope, check_format=False, epilog=help_message ) params, options, args = parser.parse_args( show_diff_phil=True, return_unhandled=True ) if len(args) == 0: parser.print_help() return unmerged_mtz = args[0] report = Report.from_unmerged_mtz(unmerged_mtz, params, report_dir=".") # xtriage xtriage_success, xtriage_warnings, xtriage_danger = None, None, None if params.xtriage_analysis: try: xtriage_success, xtriage_warnings, xtriage_danger = report.xtriage_report() except Exception as e: params.xtriage_analysis = False print("Exception runnning xtriage:") print(e) json_data = {} if params.xtriage_analysis: json_data["xtriage"] = xtriage_success + xtriage_warnings + xtriage_danger ( overall_stats_table, merging_stats_table, stats_plots, ) = report.resolution_plots_and_stats() json_data.update(stats_plots) json_data.update(report.batch_dependent_plots()) json_data.update(report.intensity_stats_plots(run_xtriage=False)) json_data.update(report.pychef_plots()) resolution_graphs = OrderedDict( (k, json_data[k]) for k in ( "cc_one_half", "i_over_sig_i", "second_moments", "wilson_intensity_plot", "completeness", "multiplicity_vs_resolution", ) if k in json_data ) if params.include_radiation_damage: batch_graphs = OrderedDict( (k, json_data[k]) for k in ( "scale_rmerge_vs_batch", "i_over_sig_i_vs_batch", "completeness_vs_dose", "rcp_vs_dose", "scp_vs_dose", "rd_vs_batch_difference", ) ) else: batch_graphs = OrderedDict( (k, json_data[k]) for k in ("scale_rmerge_vs_batch", "i_over_sig_i_vs_batch") ) misc_graphs = OrderedDict( (k, json_data[k]) for k in ("cumulative_intensity_distribution", "l_test", "multiplicities") if k in json_data ) for k, v in report.multiplicity_plots().items(): misc_graphs[k] = {"img": v} styles = {} for axis in ("h", "k", "l"): styles["multiplicity_%s" % axis] = "square-plot" loader = ChoiceLoader( [PackageLoader("xia2", "templates"), PackageLoader("dials", "templates")] ) env = Environment(loader=loader) if params.log_include: with open(params.log_include, "rb") as fh: log_text = fh.read().decode("utf-8") else: log_text = "" template = env.get_template("report.html") html = template.render( page_title=params.title, filename=os.path.abspath(unmerged_mtz), space_group=report.intensities.space_group_info().symbol_and_number(), unit_cell=str(report.intensities.unit_cell()), mtz_history=[h.strip() for h in report.mtz_object.history()], xtriage_success=xtriage_success, xtriage_warnings=xtriage_warnings, xtriage_danger=xtriage_danger, overall_stats_table=overall_stats_table, merging_stats_table=merging_stats_table, cc_half_significance_level=params.cc_half_significance_level, resolution_graphs=resolution_graphs, batch_graphs=batch_graphs, misc_graphs=misc_graphs, styles=styles, xia2_version=Version, log_text=log_text, ) with open("%s-report.json" % params.prefix, "w") as fh: json.dump(json_data, fh, indent=params.json.indent) with open("%s-report.html" % params.prefix, "wb") as fh: fh.write(html.encode("utf-8", "xmlcharrefreplace"))
def _init_script_templating(self): from jinja2 import Environment, BaseLoader, FileSystemLoader, ChoiceLoader, TemplateNotFound from jinja2.nodes import Include, Const from jinja2.ext import Extension class SnippetExtension(Extension): tags = {"snippet"} fields = Include.fields def parse(self, parser): node = parser.parse_include() if not node.template.value.startswith("/"): node.template.value = "snippets/" + node.template.value return node class SettingsScriptLoader(BaseLoader): def __init__(self, s): self._settings = s def get_source(self, environment, template): parts = template.split("/") if not len(parts): raise TemplateNotFound(template) script = self._settings.get(["scripts"], merged=True) for part in parts: if isinstance(script, dict) and part in script: script = script[part] else: raise TemplateNotFound(template) source = script if source is None: raise TemplateNotFound(template) mtime = self._settings._mtime return source, None, lambda: mtime == self._settings.last_modified def list_templates(self): scripts = self._settings.get(["scripts"], merged=True) return self._get_templates(scripts) def _get_templates(self, scripts): templates = [] for key in scripts: if isinstance(scripts[key], dict): templates += map(lambda x: key + "/" + x, self._get_templates(scripts[key])) elif isinstance(scripts[key], basestring): templates.append(key) return templates class SelectLoader(BaseLoader): def __init__(self, default, mapping, sep=":"): self._default = default self._mapping = mapping self._sep = sep def get_source(self, environment, template): if self._sep in template: prefix, name = template.split(self._sep, 1) if not prefix in self._mapping: raise TemplateNotFound(template) return self._mapping[prefix].get_source(environment, name) return self._default.get_source(environment, template) def list_templates(self): return self._default.list_templates() class RelEnvironment(Environment): def __init__(self, prefix_sep=":", *args, **kwargs): Environment.__init__(self, *args, **kwargs) self._prefix_sep = prefix_sep def join_path(self, template, parent): prefix, name = self._split_prefix(template) if name.startswith("/"): return self._join_prefix(prefix, name[1:]) else: _, parent_name = self._split_prefix(parent) parent_base = parent_name.split("/")[:-1] return self._join_prefix( prefix, "/".join(parent_base) + "/" + name) def _split_prefix(self, template): if self._prefix_sep in template: return template.split(self._prefix_sep, 1) else: return "", template def _join_prefix(self, prefix, template): if len(prefix): return prefix + self._prefix_sep + template else: return template file_system_loader = FileSystemLoader(self.getBaseFolder("scripts")) settings_loader = SettingsScriptLoader(self) choice_loader = ChoiceLoader([file_system_loader, settings_loader]) select_loader = SelectLoader( choice_loader, dict(bundled=settings_loader, file=file_system_loader)) return RelEnvironment(loader=select_loader, extensions=[SnippetExtension])
from mdbenchmark.mdengines import detect_md_engine, utils # Order where to look for host templates: HOME -> etc -> package # home _loaders = [FileSystemLoader(os.path.join(xdg.XDG_CONFIG_HOME, "MDBenchmark"))] # allow custom folder for templates. Useful for environment modules _mdbenchmark_env = os.getenv("MDBENCHMARK_TEMPLATES") if _mdbenchmark_env is not None: _loaders.append(FileSystemLoader(_mdbenchmark_env)) # global _loaders.extend( [FileSystemLoader(os.path.join(d, "MDBenchmark")) for d in xdg.XDG_CONFIG_DIRS] ) # from package _loaders.append(PackageLoader("mdbenchmark", "templates")) ENV = Environment(loader=ChoiceLoader(_loaders)) def get_possible_hosts(): return ENV.list_templates() def print_possible_hosts(): all_hosts = get_possible_hosts() console.info("Available host templates:") for host in all_hosts: console.info(host) def guess_host(): hostname = socket.gethostname()
def __init__(self, name='__main__', app=None, rows: int = 1, columns: int = 1, sidebar: bool = False, title: str = 'Bowtie App', theme: Optional[str] = None, background_color: str = 'White', socketio: str = '', debug: bool = False) -> None: """Create a Bowtie App. Parameters ---------- name : str, optional Use __name__ or leave as default if using a single module. Consult the Flask docs on "import_name" for details on more complex apps. app : Flask app, optional If you are defining your own Flask app, pass it in here. You only need this if you are doing other stuff with Flask outside of bowtie. row : int, optional Number of rows in the grid. columns : int, optional Number of columns in the grid. sidebar : bool, optional Enable a sidebar for control components. title : str, optional Title of the HTML. theme : str, optional Color for Ant Design components. background_color : str, optional Background color of the control pane. socketio : string, optional Socket.io path prefix, only change this for advanced deployments. debug : bool, optional Enable debugging in Flask. Disable in production! """ self.title = title self.theme = theme self._init: Optional[Callable] = None self._socketio_path = socketio self._schedules: List[Scheduler] = [] self._subscriptions: Dict[Event, List[Tuple[List[Event], Callable]]] = defaultdict(list) self._pages: Dict[Pager, Callable] = {} self._uploads: Dict[int, Callable] = {} self._root = View(rows=rows, columns=columns, sidebar=sidebar, background_color=background_color) self._routes: List[Route] = [] self._package_dir = Path(os.path.dirname(__file__)) self._jinjaenv = Environment( loader=FileSystemLoader(str(self._package_dir / 'templates')), trim_blocks=True, lstrip_blocks=True ) if app is None: self.app = Flask(name) else: self.app = app self.app.debug = debug self._socketio = SocketIO(self.app, binary=True, path=socketio + 'socket.io') self.app.secret_key = secrets.token_bytes() self.add_route(view=self._root, path='/', exact=True) # https://buxty.com/b/2012/05/custom-template-folders-with-flask/ templates = Path(__file__).parent / 'templates' self.app.jinja_loader = ChoiceLoader([ # type: ignore self.app.jinja_loader, FileSystemLoader(str(templates)), ]) self._build_dir = self.app.root_path / _DIRECTORY # type: ignore self.app.before_first_request(self._endpoints)
def custom_template(a): custom_loader = ChoiceLoader([FileSystemLoader(a)]) app.jinja_loader = custom_loader
def render_pdf(report, dash_url, max_runs=5): """ Create a PDF report using LaTeX. Parameters ---------- report: :py:class:`solarforecastarbiter.datamodel.Report` dash_url: str URL of the Solar Forecast Arbiter dashboard to use when building links. max_runs: int, default 5 Maximum number of times to run pdflatex Returns ------- bytes The rendered PDF report Notes ----- This code was inspired by the latex package available at https://github.com/mbr/latex/ under the following license: Copyright (c) 2015, Marc Brinkmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of latex nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ # NOQA env = Environment(loader=ChoiceLoader([ PackageLoader('solarforecastarbiter.reports', 'templates/pdf'), PackageLoader('solarforecastarbiter.reports', 'templates'), ]), autoescape=False, lstrip_blocks=True, trim_blocks=True, block_start_string='\\BLOCK{', block_end_string='}', variable_start_string='\\VAR{', variable_end_string='}', comment_start_string='\\#{', comment_end_string='}', line_statement_prefix='%-', line_comment_prefix='%#') env.filters['html_to_tex'] = _html_to_tex kwargs = _get_render_kwargs(report, dash_url, False) with tempfile.TemporaryDirectory() as _tmpdir: tmpdir = Path(_tmpdir) logfile, auxfile = _prepare_latex_support_files(tmpdir, env, kwargs) _save_figures_to_pdf(tmpdir, report) _compile_files_into_pdf(tmpdir, logfile, auxfile, max_runs) return (tmpdir / 'out.pdf').read_bytes()
def __init__(self, paths=None, packages=None, assets_path=None, globals=None, overlay=None, extensions=None, env_template_params_key='pywb.template_params', env_template_dir_key='pywb.templates_dir'): """Construct a new JinjaEnv. :param list[str] paths: List of paths to search for templates :param list[str] packages: List of assets package names :param str assets_path: Path to a yaml file containing assets :param dict[str, str] globals: Dictionary of additional globals available during template rendering :param overlay: :param list extensions: List of webassets extension classes :param str env_template_params_key: The full pywb package key for the template params :param str env_template_dir_key: The full pywb package key for the template directory """ if paths is None: paths = ['templates', '.', '/'] if packages is None: packages = ['pywb'] self._init_filters() loader = ChoiceLoader(self._make_loaders(paths, packages)) self.env_template_params_key = env_template_params_key self.env_template_dir_key = env_template_dir_key extensions = extensions or [] if assets_path: extensions.append(AssetsExtension) if overlay: jinja_env = overlay.jinja_env.overlay( loader=loader, autoescape=select_autoescape(), trim_blocks=True, extensions=extensions) else: jinja_env = RelEnvironment(loader=loader, autoescape=select_autoescape(), trim_blocks=True, extensions=extensions) jinja_env.filters.update(self.filters) if globals: jinja_env.globals.update(globals) self.jinja_env = jinja_env # init assets if assets_path: assets_loader = YAMLLoader(load(assets_path)) assets_env = assets_loader.load_environment() assets_env.resolver = PkgResResolver() jinja_env.assets_environment = assets_env self.default_locale = ''
def instrument_cms_toolbox(env): env.filters["extract_token_params"] = extract_token_params env.tests["contest_visible"] = contest_visible @contextfilter def wrapped_format_token_rules(ctx, tokens, t_type=None): translation = ctx["translation"] return format_token_rules(tokens, t_type, translation=translation) def instrument_formatting_toolbox(env): env.globals["get_score_class"] = get_score_class env.filters["format_token_rules"] = wrapped_format_token_rules CWS_ENVIRONMENT = GLOBAL_ENVIRONMENT.overlay( # Load templates from CWS's package (use package rather than file # system as that works even in case of a compressed distribution). loader=ChoiceLoader([ PackageLoader('cms.server.contest', 'templates'), FileSystemLoader('/var/local/lib/cms/templates') ])) instrument_cms_toolbox(CWS_ENVIRONMENT) instrument_formatting_toolbox(CWS_ENVIRONMENT)
class TemplateLoader: def __init__(self): self.templates = {} def __call__(self, name: str): return self.templates.get(name, None) def add_template(self, name: str, content: str): self.templates[name] = content _PATH_HERE = os.path.abspath(os.path.dirname(__file__)) TEMPLATE_LOADER = TemplateLoader() ENVIRONMENT = Environment(loader=ChoiceLoader([ FileSystemLoader(os.path.join(_PATH_HERE, "templates")), FunctionLoader(TEMPLATE_LOADER) ])) class AutoDataSources(Directive): has_content = True required_arguments = 2 optional_arguments = 0 def run(self): data_module_path, data_module_name = self.arguments string_list = self.content source = string_list.source(0) TEMPLATE_LOADER.add_template(data_module_name, "\n".join(string_list.data))
def _configured_environment(): logger.info('Loading templates from {dir}'.format(dir=_templates)) loaders = [] for templates in _templates: loaders.append(FileSystemLoader(templates)) return environment(loader=ChoiceLoader(loaders))
mail_handler.setFormatter( logging.Formatter( '[%(asctime)s] %(levelname)s: %(filename)s %(lineno)d\n%(message)s' )) app.logger.addHandler(mail_handler) # Set which files are autoescaped when rendering app.jinja_options = { "autoescape": select_autoescape([".html", ".htm", ".xml", ".xhtml", ".html.j2"]) } # Ability to load templates from instance/templates/ directory loader = ChoiceLoader([ FileSystemLoader(os.path.join(app.instance_path, "templates/")), app.jinja_loader ]) app.jinja_loader = loader # So we can load 'static' files from the instance/static/ directory for rule in app.url_map.iter_rules('static'): # Remove the default rule as our static files are handled in routes/static.py app.url_map._rules.remove(rule) # pylint: disable=protected-access # Set default config file app.config.from_pyfile( os.path.join(app.root_path, 'sandhill.default_settings.cfg')) # If a instance specific config exists, load it if os.path.exists(os.path.join(app.instance_path, "sandhill.cfg")): app.config.from_pyfile('sandhill.cfg')
def initialize(self, *args, **kwargs): """Load configuration settings.""" super().initialize(*args, **kwargs) self.load_config_file(self.config_file) # hook up tornado logging if self.debug: self.log_level = logging.DEBUG tornado.options.options.logging = logging.getLevelName(self.log_level) tornado.log.enable_pretty_logging() self.log = tornado.log.app_log self.init_pycurl() # initialize kubernetes config if self.builder_required: try: kubernetes.config.load_incluster_config() except kubernetes.config.ConfigException: kubernetes.config.load_kube_config() self.tornado_settings[ "kubernetes_client"] = self.kube_client = kubernetes.client.CoreV1Api( ) # times 2 for log + build threads self.build_pool = ThreadPoolExecutor(self.concurrent_build_limit * 2) # default executor for asyncifying blocking calls (e.g. to kubernetes, docker). # this should not be used for long-running requests self.executor = ThreadPoolExecutor(self.executor_threads) jinja_options = dict(autoescape=True, ) template_paths = [self.template_path] base_template_path = self._template_path_default() if base_template_path not in template_paths: # add base templates to the end, so they are looked up at last after custom templates template_paths.append(base_template_path) loader = ChoiceLoader([ # first load base templates with prefix PrefixLoader({'templates': FileSystemLoader([base_template_path])}, '/'), # load all templates FileSystemLoader(template_paths) ]) jinja_env = Environment(loader=loader, **jinja_options) if self.use_registry and self.builder_required: registry = self.docker_registry_class(parent=self) else: registry = None self.launcher = Launcher( parent=self, hub_url=self.hub_url, hub_url_local=self.hub_url_local, hub_api_token=self.hub_api_token, create_user=not self.auth_enabled, ) self.event_log = EventLog(parent=self) for schema_file in glob(os.path.join(HERE, 'event-schemas', '*.json')): with open(schema_file) as f: self.event_log.register_schema(json.load(f)) self.tornado_settings.update({ "log_function": log_request, "push_secret": self.push_secret, "image_prefix": self.image_prefix, "debug": self.debug, "launcher": self.launcher, "appendix": self.appendix, "ban_networks": self.ban_networks, "ban_networks_min_prefix_len": self.ban_networks_min_prefix_len, "build_namespace": self.build_namespace, "build_image": self.build_image, "build_node_selector": self.build_node_selector, "build_pool": self.build_pool, "sticky_builds": self.sticky_builds, "log_tail_lines": self.log_tail_lines, "pod_quota": self.pod_quota, "per_repo_quota": self.per_repo_quota, "per_repo_quota_higher": self.per_repo_quota_higher, "repo_providers": self.repo_providers, "use_registry": self.use_registry, "registry": registry, "traitlets_config": self.config, "google_analytics_code": self.google_analytics_code, "google_analytics_domain": self.google_analytics_domain, "about_message": self.about_message, "banner_message": self.banner_message, "extra_footer_scripts": self.extra_footer_scripts, "jinja2_env": jinja_env, "build_memory_limit": self.build_memory_limit, "build_memory_request": self.build_memory_request, "build_docker_host": self.build_docker_host, "build_docker_config": self.build_docker_config, "base_url": self.base_url, "badge_base_url": self.badge_base_url, "static_path": os.path.join(HERE, "static"), "static_url_prefix": url_path_join(self.base_url, "static/"), "template_variables": self.template_variables, "executor": self.executor, "auth_enabled": self.auth_enabled, "event_log": self.event_log, "normalized_origin": self.normalized_origin, }) if self.auth_enabled: self.tornado_settings['cookie_secret'] = os.urandom(32) handlers = [ (r'/metrics', MetricsHandler), (r'/versions', VersionHandler), (r"/build/([^/]+)/(.+)", BuildHandler), (r"/v2/([^/]+)/(.+)", ParameterizedMainHandler), (r"/repo/([^/]+)/([^/]+)(/.*)?", LegacyRedirectHandler), # for backward-compatible mybinder.org badge URLs # /assets/images/badge.svg (r'/assets/(images/badge\.svg)', tornado.web.StaticFileHandler, { 'path': self.tornado_settings['static_path'] }), # /badge.svg (r'/(badge\.svg)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), # /badge_logo.svg (r'/(badge\_logo\.svg)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), # /logo_social.png (r'/(logo\_social\.png)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), # /favicon_XXX.ico (r'/(favicon\_fail\.ico)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), (r'/(favicon\_success\.ico)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), (r'/(favicon\_building\.ico)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), (r'/about', AboutHandler), (r'/health', HealthHandler, { 'hub_url': self.hub_url_local }), (r'/_config', ConfigHandler), (r'/', MainHandler), (r'.*', Custom404), ] handlers = self.add_url_prefix(self.base_url, handlers) if self.extra_static_path: handlers.insert(-1, (re.escape( url_path_join(self.base_url, self.extra_static_url_prefix)) + r"(.*)", tornado.web.StaticFileHandler, { 'path': self.extra_static_path })) if self.auth_enabled: oauth_redirect_uri = os.getenv('JUPYTERHUB_OAUTH_CALLBACK_URL') or \ url_path_join(self.base_url, 'oauth_callback') oauth_redirect_uri = urlparse(oauth_redirect_uri).path handlers.insert( -1, (re.escape(oauth_redirect_uri), HubOAuthCallbackHandler)) self.tornado_app = tornado.web.Application(handlers, **self.tornado_settings)
def create_global_jinja_loader(self): default_loader = super(PluginFlaskMixin, self).create_global_jinja_loader() return ChoiceLoader([self.plugin_jinja_loader(self), default_loader])
def app(self): app = Sanic(__name__) default_templates = str(app_root / "datasette" / "templates") template_paths = [] if self.template_dir: template_paths.append(self.template_dir) template_paths.extend([ plugin["templates_path"] for plugin in get_plugins(pm) if plugin["templates_path"] ]) template_paths.append(default_templates) template_loader = ChoiceLoader([ FileSystemLoader(template_paths), # Support {% extends "default:table.html" %}: PrefixLoader({"default": FileSystemLoader(default_templates)}, delimiter=":"), ]) self.jinja_env = Environment(loader=template_loader, autoescape=True) self.jinja_env.filters["escape_css_string"] = escape_css_string self.jinja_env.filters[ "quote_plus"] = lambda u: urllib.parse.quote_plus(u) self.jinja_env.filters["escape_sqlite"] = escape_sqlite self.jinja_env.filters["to_css_class"] = to_css_class pm.hook.prepare_jinja2_environment(env=self.jinja_env) app.add_route(IndexView.as_view(self), "/<as_format:(\.jsono?)?$>") # TODO: /favicon.ico and /-/static/ deserve far-future cache expires app.add_route(favicon, "/favicon.ico") app.static("/-/static/", str(app_root / "datasette" / "static")) for path, dirname in self.static_mounts: app.static(path, dirname) # Mount any plugin static/ directories for plugin in get_plugins(pm): if plugin["static_path"]: modpath = "/-/static-plugins/{}/".format(plugin["name"]) app.static(modpath, plugin["static_path"]) app.add_route( JsonDataView.as_view(self, "inspect.json", self.inspect), "/-/inspect<as_format:(\.json)?$>", ) app.add_route( JsonDataView.as_view(self, "metadata.json", lambda: self.metadata), "/-/metadata<as_format:(\.json)?$>", ) app.add_route( JsonDataView.as_view(self, "versions.json", self.versions), "/-/versions<as_format:(\.json)?$>", ) app.add_route( JsonDataView.as_view(self, "plugins.json", self.plugins), "/-/plugins<as_format:(\.json)?$>", ) app.add_route( JsonDataView.as_view(self, "config.json", lambda: self.config), "/-/config<as_format:(\.json)?$>", ) app.add_route(DatabaseView.as_view(self), "/<db_name:[^/\.]+?><as_format:(\.jsono?|\.csv)?$>") app.add_route(DatabaseDownload.as_view(self), "/<db_name:[^/]+?><as_db:(\.db)$>") app.add_route( TableView.as_view(self), "/<db_name:[^/]+>/<table_and_format:[^/]+?$>", ) app.add_route( RowView.as_view(self), "/<db_name:[^/]+>/<table:[^/]+?>/<pk_path:[^/]+?><as_format:(\.jsono?)?$>", ) self.register_custom_units() @app.exception(Exception) def on_exception(request, exception): title = None help = None if isinstance(exception, NotFound): status = 404 info = {} message = exception.args[0] elif isinstance(exception, InvalidUsage): status = 405 info = {} message = exception.args[0] elif isinstance(exception, DatasetteError): status = exception.status info = exception.error_dict message = exception.message if exception.messagge_is_html: message = Markup(message) title = exception.title else: status = 500 info = {} message = str(exception) traceback.print_exc() templates = ["500.html"] if status != 500: templates = ["{}.html".format(status)] + templates info.update({ "ok": False, "error": message, "status": status, "title": title }) if request.path.split("?")[0].endswith(".json"): return response.json(info, status=status) else: template = self.jinja_env.select_template(templates) return response.html(template.render(info), status=status) return app
def init_app(self, app, path='templates.yaml'): """Initializes Ask app by setting configuration variables, loading templates, and maps Ask route to a flask view. The Ask instance is given the following configuration variables by calling on Flask's configuration: `ASK_APPLICATION_ID`: Turn on application ID verification by setting this variable to an application ID or a list of allowed application IDs. By default, application ID verification is disabled and a warning is logged. This variable should be set in production to ensure requests are being sent by the applications you specify. Default: None `ASK_VERIFY_REQUESTS`: Enables or disables Alexa request verification, which ensures requests sent to your skill are from Amazon's Alexa service. This setting should not be disabled in production. It is useful for mocking JSON requests in automated tests. Default: True `ASK_VERIFY_TIMESTAMP_DEBUG`: Turn on request timestamp verification while debugging by setting this to True. Timestamp verification helps mitigate against replay attacks. It relies on the system clock being synchronized with an NTP server. This setting should not be enabled in production. Default: False `ASK_PRETTY_DEBUG_LOGS`: Add tabs and linebreaks to the Alexa request and response printed to the debug log. This improves readability when printing to the console, but breaks formatting when logging to CloudWatch. Default: False `ASK_INTERACTION_MODEL_FILE`: When this path is set, a JSON interaction model compatible with ASK JSON Editor When None : no interaction model is generated. Default: None `ASK_IM_INVOCATION_NAME`: When this name is set, it is used as invocation name in generated interaction model, when None invocation name is a placeholder that needs to be filled by user. Default: None """ if self._route is None: raise TypeError( "route is a required argument when app is not None") self.app = app app.ask = self app.add_url_rule(self._route, view_func=self._flask_view_func, methods=['POST']) app.jinja_loader = ChoiceLoader( [app.jinja_loader, YamlLoader(app, path)]) self._resolve_im_path(app)
def app(self): "Returns an ASGI app function that serves the whole of Datasette" default_templates = str(app_root / "datasette" / "templates") template_paths = [] if self.template_dir: template_paths.append(self.template_dir) plugin_template_paths = [ plugin["templates_path"] for plugin in get_plugins() if plugin["templates_path"] ] template_paths.extend(plugin_template_paths) template_paths.append(default_templates) template_loader = ChoiceLoader([ FileSystemLoader(template_paths), # Support {% extends "default:table.html" %}: PrefixLoader({"default": FileSystemLoader(default_templates)}, delimiter=":"), ]) self.jinja_env = Environment(loader=template_loader, autoescape=True, enable_async=True) self.jinja_env.filters["escape_css_string"] = escape_css_string self.jinja_env.filters[ "quote_plus"] = lambda u: urllib.parse.quote_plus(u) self.jinja_env.filters["escape_sqlite"] = escape_sqlite self.jinja_env.filters["to_css_class"] = to_css_class # pylint: disable=no-member pm.hook.prepare_jinja2_environment(env=self.jinja_env) self.register_renderers() routes = [] def add_route(view, regex): routes.append((regex, view)) # Generate a regex snippet to match all registered renderer file extensions renderer_regex = "|".join(r"\." + key for key in self.renderers.keys()) add_route(IndexView.as_asgi(self), r"/(?P<as_format>(\.jsono?)?$)") # TODO: /favicon.ico and /-/static/ deserve far-future cache expires add_route(favicon, "/favicon.ico") add_route(asgi_static(app_root / "datasette" / "static"), r"/-/static/(?P<path>.*)$") for path, dirname in self.static_mounts: add_route(asgi_static(dirname), r"/" + path + "/(?P<path>.*)$") # Mount any plugin static/ directories for plugin in get_plugins(): if plugin["static_path"]: add_route( asgi_static(plugin["static_path"]), "/-/static-plugins/{}/(?P<path>.*)$".format( plugin["name"]), ) # Support underscores in name in addition to hyphens, see https://github.com/simonw/datasette/issues/611 add_route( asgi_static(plugin["static_path"]), "/-/static-plugins/{}/(?P<path>.*)$".format( plugin["name"].replace("-", "_")), ) add_route( JsonDataView.as_asgi(self, "metadata.json", lambda: self._metadata), r"/-/metadata(?P<as_format>(\.json)?)$", ) add_route( JsonDataView.as_asgi(self, "versions.json", self.versions), r"/-/versions(?P<as_format>(\.json)?)$", ) add_route( JsonDataView.as_asgi(self, "plugins.json", self.plugins), r"/-/plugins(?P<as_format>(\.json)?)$", ) add_route( JsonDataView.as_asgi(self, "config.json", lambda: self._config), r"/-/config(?P<as_format>(\.json)?)$", ) add_route( JsonDataView.as_asgi(self, "threads.json", self.threads), r"/-/threads(?P<as_format>(\.json)?)$", ) add_route( JsonDataView.as_asgi(self, "databases.json", self.connected_databases), r"/-/databases(?P<as_format>(\.json)?)$", ) add_route(DatabaseDownload.as_asgi(self), r"/(?P<db_name>[^/]+?)(?P<as_db>\.db)$") add_route( DatabaseView.as_asgi(self), r"/(?P<db_name>[^/]+?)(?P<as_format>" + renderer_regex + r"|.jsono|\.csv)?$", ) add_route( TableView.as_asgi(self), r"/(?P<db_name>[^/]+)/(?P<table_and_format>[^/]+?$)", ) add_route( RowView.as_asgi(self), r"/(?P<db_name>[^/]+)/(?P<table>[^/]+?)/(?P<pk_path>[^/]+?)(?P<as_format>" + renderer_regex + r")?$", ) self.register_custom_units() async def setup_db(): # First time server starts up, calculate table counts for immutable databases for dbname, database in self.databases.items(): if not database.is_mutable: await database.table_counts(limit=60 * 60 * 1000) asgi = AsgiLifespan(AsgiTracer(DatasetteRouter(self, routes)), on_startup=setup_db) for wrapper in pm.hook.asgi_wrapper(datasette=self): asgi = wrapper(asgi) return asgi
def generate_xia2_html(xinfo, filename="xia2.html", params=None, args=[]): assert params is None or len(args) == 0 if params is None: from xia2.Modules.Analysis import phil_scope interp = phil_scope.command_line_argument_interpreter() params, unhandled = interp.process_and_fetch( args, custom_processor="collect_remaining") params = params.extract() xia2_txt = os.path.join(os.path.abspath(os.path.curdir), "xia2.txt") assert os.path.isfile(xia2_txt), xia2_txt with open(xia2_txt, "r") as f: xia2_output = html.escape(f.read()) styles = {} columns = [] columns.append([ "", "Wavelength (Å)", "Resolution range (Å)", "Completeness (%)", "Multiplicity", "CC-half", "I/sigma", "Rmerge(I)", # anomalous statistics "Anomalous completeness (%)", "Anomalous multiplicity", ]) individual_dataset_reports = {} for cname, xcryst in xinfo.get_crystals().items(): reflection_files = xcryst.get_scaled_merged_reflections() for wname, unmerged_mtz in reflection_files["mtz_unmerged"].items(): xwav = xcryst.get_xwavelength(wname) from xia2.Modules.MultiCrystalAnalysis import batch_phil_scope scope = phil.parse(batch_phil_scope) scaler = xcryst._scaler try: for si in scaler._sweep_information.values(): batch_params = scope.extract().batch[0] batch_params.id = si["sname"] batch_params.range = si["batches"] params.batch.append(batch_params) except AttributeError: for si in scaler._sweep_handler._sweep_information.values(): batch_params = scope.extract().batch[0] batch_params.id = si.get_sweep_name() batch_params.range = si.get_batch_range() params.batch.append(batch_params) report_path = xinfo.path.joinpath(cname, "report") report_path.mkdir(parents=True, exist_ok=True) report = Report.from_unmerged_mtz(unmerged_mtz, params, report_dir=str(report_path)) xtriage_success, xtriage_warnings, xtriage_danger = None, None, None if params.xtriage_analysis: try: ( xtriage_success, xtriage_warnings, xtriage_danger, ) = report.xtriage_report() except Exception as e: params.xtriage_analysis = False logger.debug("Exception running xtriage:") logger.debug(e, exc_info=True) ( overall_stats_table, merging_stats_table, stats_plots, ) = report.resolution_plots_and_stats() d = {} d["merging_statistics_table"] = merging_stats_table d["overall_statistics_table"] = overall_stats_table individual_dataset_reports[wname] = d json_data = {} if params.xtriage_analysis: json_data["xtriage"] = (xtriage_success + xtriage_warnings + xtriage_danger) json_data.update(stats_plots) json_data.update(report.batch_dependent_plots()) json_data.update(report.intensity_stats_plots(run_xtriage=False)) json_data.update(report.pychef_plots()) json_data.update(report.pychef_plots(n_bins=1)) from scitbx.array_family import flex max_points = 500 for g in ( "scale_rmerge_vs_batch", "completeness_vs_dose", "rcp_vs_dose", "scp_vs_dose", "rd_vs_batch_difference", ): for i, data in enumerate(json_data[g]["data"]): x = data["x"] n = len(x) if n > max_points: step = n // max_points sel = (flex.int_range(n) % step) == 0 data["x"] = list(flex.int(data["x"]).select(sel)) data["y"] = list(flex.double(data["y"]).select(sel)) resolution_graphs = OrderedDict((k + "_" + wname, json_data[k]) for k in ( "cc_one_half", "i_over_sig_i", "second_moments", "wilson_intensity_plot", "completeness", "multiplicity_vs_resolution", ) if k in json_data) if params.include_radiation_damage: batch_graphs = OrderedDict((k + "_" + wname, json_data[k]) for k in ( "scale_rmerge_vs_batch", "i_over_sig_i_vs_batch", "completeness_vs_dose", "rcp_vs_dose", "scp_vs_dose", "rd_vs_batch_difference", )) else: batch_graphs = OrderedDict((k + "_" + wname, json_data[k]) for k in ("scale_rmerge_vs_batch", "i_over_sig_i_vs_batch")) misc_graphs = OrderedDict((k, json_data[k]) for k in ( "cumulative_intensity_distribution", "l_test", "multiplicities", ) if k in json_data) for k, v in report.multiplicity_plots().items(): misc_graphs[k + "_" + wname] = {"img": v} d["resolution_graphs"] = resolution_graphs d["batch_graphs"] = batch_graphs d["misc_graphs"] = misc_graphs d["xtriage"] = { "success": xtriage_success, "warnings": xtriage_warnings, "danger": xtriage_danger, } merging_stats = report.merging_stats merging_stats_anom = report.merging_stats_anom overall = merging_stats.overall overall_anom = merging_stats_anom.overall outer_shell = merging_stats.bins[-1] outer_shell_anom = merging_stats_anom.bins[-1] column = [ wname, str(xwav.get_wavelength()), "%.2f - %.2f (%.2f - %.2f)" % (overall.d_max, overall.d_min, outer_shell.d_max, outer_shell.d_min), "%.2f (%.2f)" % (overall.completeness * 100, outer_shell.completeness * 100), f"{overall.mean_redundancy:.2f} ({outer_shell.mean_redundancy:.2f})", f"{overall.cc_one_half:.4f} ({outer_shell.cc_one_half:.4f})", "%.2f (%.2f)" % (overall.i_over_sigma_mean, outer_shell.i_over_sigma_mean), f"{overall.r_merge:.4f} ({outer_shell.r_merge:.4f})", # anomalous statistics "%.2f (%.2f)" % ( overall_anom.anom_completeness * 100, outer_shell_anom.anom_completeness * 100, ), "%.2f (%.2f)" % (overall_anom.mean_redundancy, outer_shell_anom.mean_redundancy), ] columns.append(column) table = [[c[i] for c in columns] for i in range(len(columns[0]))] from cctbx import sgtbx space_groups = xcryst.get_likely_spacegroups() space_groups = [ sgtbx.space_group_info(symbol=str(symbol)) for symbol in space_groups ] space_group = space_groups[0].symbol_and_number() alternative_space_groups = [ sg.symbol_and_number() for sg in space_groups[1:] ] unit_cell = str(report.intensities.unit_cell()) # reflection files for cname, xcryst in xinfo.get_crystals().items(): # hack to replace path to reflection files with DataFiles directory data_dir = os.path.join(os.path.abspath(os.path.curdir), "DataFiles") g = glob.glob(os.path.join(data_dir, "*")) reflection_files = xcryst.get_scaled_merged_reflections() for k, rfile in reflection_files.items(): if isinstance(rfile, str): for datafile in g: if os.path.basename(datafile) == os.path.basename(rfile): reflection_files[k] = datafile break else: for kk in rfile: for datafile in g: if os.path.basename(datafile) == os.path.basename( rfile[kk]): reflection_files[k][kk] = datafile break headers = ["Dataset", "File name"] merged_mtz = reflection_files["mtz"] mtz_files = [ headers, [ "All datasets", '<a href="%s">%s</a>' % (os.path.relpath(merged_mtz), os.path.basename(merged_mtz)), ], ] for wname, unmerged_mtz in reflection_files["mtz_unmerged"].items(): mtz_files.append([ wname, '<a href="%s">%s</a>' % (os.path.relpath(unmerged_mtz), os.path.basename(unmerged_mtz)), ]) sca_files = [headers] if "sca" in reflection_files: for wname, merged_sca in reflection_files["sca"].items(): sca_files.append([ wname, '<a href="%s">%s</a>' % (os.path.relpath(merged_sca), os.path.basename(merged_sca)), ]) unmerged_sca_files = [headers] if "sca_unmerged" in reflection_files: for wname, unmerged_sca in reflection_files["sca_unmerged"].items( ): unmerged_sca_files.append([ wname, '<a href="%s">%s</a>' % ( os.path.relpath(unmerged_sca), os.path.basename(unmerged_sca), ), ]) # other files other_files = [] other_files.append(["File name", "Description"]) for other_file, description in sorted([ ("xia2.cif", "Crystallographic information file"), ("xia2.mmcif", "Macromolecular crystallographic information file"), ("shelxt.hkl", "merged structure factors for SHELXT"), ("shelxt.ins", "SHELXT instruction file"), ] + [(fn, "XPREP input file") for fn in os.listdir(os.path.join(data_dir)) if fn.endswith(".p4p")]): if os.path.exists(os.path.join(data_dir, other_file)): other_files.append([ '<a href="DataFiles/{filename}">{filename}</a>'.format( filename=other_file), description, ]) # log files log_files_table = [] log_dir = os.path.join(os.path.abspath(os.path.curdir), "LogFiles") g = glob.glob(os.path.join(log_dir, "*.log")) for logfile in g: html_file = make_logfile_html(logfile) html_file = os.path.splitext(logfile)[0] + ".html" if os.path.exists(html_file): log_files_table.append([ os.path.basename(logfile), '<a href="%s">original</a>' % os.path.relpath(logfile), '<a href="%s">html</a>' % os.path.relpath(html_file), ]) else: log_files_table.append([ os.path.basename(logfile), '<a href="%s">original</a>' % os.path.relpath(logfile), " ", ]) references = { cdict["acta"]: cdict.get("url") for cdict in Citations.get_citations_dicts() } from jinja2 import Environment, ChoiceLoader, PackageLoader loader = ChoiceLoader([ PackageLoader("xia2", "templates"), PackageLoader("dials", "templates") ]) env = Environment(loader=loader) template = env.get_template("xia2.html") html_source = template.render( page_title="xia2 processing report", xia2_output=xia2_output, space_group=space_group, alternative_space_groups=alternative_space_groups, unit_cell=unit_cell, overall_stats_table=table, cc_half_significance_level=params.cc_half_significance_level, mtz_files=mtz_files, sca_files=sca_files, unmerged_sca_files=unmerged_sca_files, other_files=other_files, log_files_table=log_files_table, individual_dataset_reports=individual_dataset_reports, references=references, styles=styles, ) with open("%s-report.json" % os.path.splitext(filename)[0], "w") as fh: json.dump(json_data, fh, indent=2) with open(filename, "wb") as f: f.write(html_source.encode("utf-8", "xmlcharrefreplace"))
app.config["DEBUG"] = True if not TESTING["status"]: SC, jwt = config_auth(app) else: logger.warning("TESTING: No auth will be enabled.") # Apply wrappers to the app that will compress responses and enable CORS. Compress(app) CORS(app) # The directory path to this location (works in any file system). HERE = Path(__file__).parent.absolute() # Instantiate a jinja2 env. env = Environment( loader=ChoiceLoader([app.jinja_loader, auth.jinja_loader, indra_loader])) # Overwrite url_for function in jinja to handle DEPLOYMENT prefix gracefully. def url_for(*args, **kwargs): """Generate a url for a given endpoint, applying the DEPLOYMENT prefix.""" res = base_url_for(*args, **kwargs) if DEPLOYMENT is not None: if not res.startswith(f"/{DEPLOYMENT}"): res = f"/{DEPLOYMENT}" + res return res env.globals.update(url_for=url_for)
from django.db.utils import DatabaseError from django.core.exceptions import ValidationError from mozdns.utils import get_zones from core.search.compiler.django_compile import compile_to_django from core.search.compiler.django_compile import search_type from core.search.compiler.invschema import SEARCH_SCHEMA, HELP_SEARCH_SCHEMA import simplejson as json from gettext import gettext as _ from jinja2 import Environment, PackageLoader, ChoiceLoader env = Environment(loader=ChoiceLoader([ PackageLoader('mozdns.record', 'templates'), PackageLoader('core.search', 'templates') ])) MAX_NUM_OBJECTS = 5000 def request_to_search(request): search = request.GET.get("search", None) adv_search = request.GET.get("advanced_search", "") if adv_search: if search: search += " AND " + adv_search else: search = adv_search return search
}, FHOST_MIME_BLACKLIST=[ "application/x-dosexec", "application/java-archive", "application/java-vm" ], FHOST_UPLOAD_BLACKLIST=None, NSFW_DETECT=False, NSFW_THRESHOLD=0.608, URL_ALPHABET= "DEQhd2uFteibPwq0SWBInTpA_jcZL5GKz3YCR14Ulk87Jors9vNHgfaOmMXy6Vx-", ) if not app.config["TESTING"]: app.config.from_pyfile("config.py") app.jinja_loader = ChoiceLoader([ FileSystemLoader(str(Path(app.instance_path) / "templates")), app.jinja_loader ]) if app.config["DEBUG"]: app.config["FHOST_USE_X_ACCEL_REDIRECT"] = False if app.config["NSFW_DETECT"]: from nsfw_detect import NSFWDetector nsfw = NSFWDetector() try: mimedetect = Magic(mime=True, mime_encoding=False) except: print("""Error: You have installed the wrong version of the 'magic' module. Please install python-magic.""") sys.exit(1)
def make_flask_stack(conf, **app_conf): """ This has to pass the flask app through all the same middleware that Pylons used """ root = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) debug = asbool(app_conf.get('debug', app_conf.get('DEBUG', False))) testing = asbool(app_conf.get('testing', app_conf.get('TESTING', False))) app = flask_app = CKANFlask(__name__) app.debug = debug app.testing = testing app.template_folder = os.path.join(root, 'templates') app.app_ctx_globals_class = CKAN_AppCtxGlobals app.url_rule_class = CKAN_Rule app.jinja_loader = ChoiceLoader([ app.jinja_loader, CkanextTemplateLoader() ]) # Update Flask config with the CKAN values. We use the common config # object as values might have been modified on `load_environment` if config: app.config.update(config) else: app.config.update(conf) app.config.update(app_conf) # Do all the Flask-specific stuff before adding other middlewares # Secret key needed for flask-debug-toolbar and sessions if not app.config.get('SECRET_KEY'): app.config['SECRET_KEY'] = config.get('beaker.session.secret') if not app.config.get('SECRET_KEY'): raise RuntimeError(u'You must provide a value for the secret key' ' with the SECRET_KEY config option') if debug: from flask_debugtoolbar import DebugToolbarExtension app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False DebugToolbarExtension(app) # Use Beaker as the Flask session interface class BeakerSessionInterface(SessionInterface): def open_session(self, app, request): if 'beaker.session' in request.environ: return request.environ['beaker.session'] def save_session(self, app, session, response): session.save() namespace = 'beaker.session.' session_opts = dict([(k.replace('beaker.', ''), v) for k, v in config.iteritems() if k.startswith(namespace)]) if (not session_opts.get('session.data_dir') and session_opts.get('session.type', 'file') == 'file'): cache_dir = app_conf.get('cache_dir') or app_conf.get('cache.dir') session_opts['session.data_dir'] = '{data_dir}/sessions'.format( data_dir=cache_dir) app.wsgi_app = SessionMiddleware(app.wsgi_app, session_opts) app.session_interface = BeakerSessionInterface() # Add Jinja2 extensions and filters extensions = [ 'jinja2.ext.do', 'jinja2.ext.with_', jinja_extensions.SnippetExtension, jinja_extensions.CkanExtend, jinja_extensions.CkanInternationalizationExtension, jinja_extensions.LinkForExtension, jinja_extensions.ResourceExtension, jinja_extensions.UrlForStaticExtension, jinja_extensions.UrlForExtension ] for extension in extensions: app.jinja_env.add_extension(extension) app.jinja_env.filters['empty_and_escape'] = \ jinja_extensions.empty_and_escape # Common handlers for all requests app.before_request(ckan_before_request) app.after_request(ckan_after_request) # Template context processors app.context_processor(helper_functions) app.context_processor(c_object) @app.context_processor def ungettext_alias(): u''' Provide `ungettext` as an alias of `ngettext` for backwards compatibility ''' return dict(ungettext=ungettext) # Babel app.config[u'BABEL_TRANSLATION_DIRECTORIES'] = os.path.join(root, u'i18n') app.config[u'BABEL_DOMAIN'] = 'ckan' babel = Babel(app) babel.localeselector(get_locale) @app.route('/hello', methods=['GET']) def hello_world(): return 'Hello World, this is served by Flask' @app.route('/hello', methods=['POST']) def hello_world_post(): return 'Hello World, this was posted to Flask' # Auto-register all blueprints defined in the `views` folder _register_core_blueprints(app) # Set up each IBlueprint extension as a Flask Blueprint for plugin in PluginImplementations(IBlueprint): if hasattr(plugin, 'get_blueprint'): app.register_extension_blueprint(plugin.get_blueprint()) # Start other middleware for plugin in PluginImplementations(IMiddleware): app = plugin.make_middleware(app, config) # Fanstatic if debug: fanstatic_config = { 'versioning': True, 'recompute_hashes': True, 'minified': False, 'bottom': True, 'bundle': False, } else: fanstatic_config = { 'versioning': True, 'recompute_hashes': False, 'minified': True, 'bottom': True, 'bundle': True, } root_path = config.get('ckan.root_path', None) if root_path: root_path = re.sub('/{{LANG}}', '', root_path) fanstatic_config['base_url'] = root_path app = Fanstatic(app, **fanstatic_config) for plugin in PluginImplementations(IMiddleware): try: app = plugin.make_error_log_middleware(app, config) except AttributeError: log.critical('Middleware class {0} is missing the method' 'make_error_log_middleware.' .format(plugin.__class__.__name__)) # Initialize repoze.who who_parser = WhoConfig(conf['here']) who_parser.parse(open(app_conf['who.config_file'])) app = PluggableAuthenticationMiddleware( app, who_parser.identifiers, who_parser.authenticators, who_parser.challengers, who_parser.mdproviders, who_parser.request_classifier, who_parser.challenge_decider, logging.getLogger('repoze.who'), logging.WARN, # ignored who_parser.remote_user_key ) # Update the main CKAN config object with the Flask specific keys # that were set here or autogenerated flask_config_keys = set(flask_app.config.keys()) - set(config.keys()) for key in flask_config_keys: config[key] = flask_app.config[key] # Add a reference to the actual Flask app so it's easier to access app._wsgi_app = flask_app return app
def init_app(self, app, plugins_base=None, plugins_folder="plugins"): self.plugins_folder = plugins_folder self.plugins_abspath = join( plugins_base or getattr(app, "root_path", getcwd()), self.plugins_folder, ) #: Scan and load plugins for :attr:`plugins_folder` and third-plugins self.logger.debug( "Start plugins initialization, local plugins path: %s, third party" "-plugins: %s" % (self.plugins_abspath, self.plugin_packages)) self.__scan_third_plugins() self.__scan_affiliated_plugins() #: Try to update `self.__plugins` #: #: ..versionadded:: 3.7.0 self.__preprocess_all_plugins() #: Analysis and run plugins. First, register template variable app.jinja_env.globals.update( emit_tep=self.emit_tep, emit_assets=self.emit_assets, emit_config=self.emit_config, emit_dcp=self._dcp_manager.emit, ) #: Custom add multiple template folders. #: Maybe you can use :class:`~jinja2.PackageLoader`. app.jinja_loader = ChoiceLoader([ app.jinja_loader, FileSystemLoader(self.__get_valid_tpl), ]) #: Add a static rule for plugins app.add_url_rule( self.static_url_path + "/<string:plugin_name>/<path:filename>", endpoint=self.static_endpoint, view_func=self._send_plugin_static_file, ) #: Register the hook extension point processor for hep, handler in iteritems(self.__het_allow_hooks): _deco_func = getattr(app, hep) _deco_func(handler) #: Register the blueprint extension point #: #: .. versionchanged:: 3.6.2 #: flask 2.0 nested blueprints, #: but only blueprints of other plugins can be nested _plugin_bps = {} # {name:{blueprint}, } _nested_bps = {} # {parent:[{blueprint}, ], } for bep in self.get_enabled_beps: bp = bep["blueprint"] parent = bep.get("parent") if parent: _nested_bps.setdefault(parent, []).append(bep) else: _plugin_bps[bp.name] = bep for parent, beps in iteritems(_nested_bps): if parent not in _plugin_bps: raise PEPError("No parent blueprint found named %s" % parent) pbp = _plugin_bps[parent]["blueprint"] for bep in beps: bp = bep["blueprint"] prefix = bep["prefix"] pbp.register_blueprint(bp, url_prefix=prefix) for bep in _plugin_bps.values(): bp = bep["blueprint"] prefix = bep["prefix"] app.register_blueprint(bp, url_prefix=prefix) #: Register the viewfunc extension point #: #: .. versionadded:: 3.1.0 #: #: .. versionchanged:: 3.6.0 #: allow blueprint name for vep in self.get_enabled_veps: rule, viewfunc, endpoint, options, _bp = vep if _bp: if _bp in app.blueprints: s = app.blueprints[_bp].make_setup_state(app, {}) s.add_url_rule(rule, endpoint, viewfunc, **options) else: raise PEPError( "The required blueprint({}) was not found when " "registering vep with {}".format(_bp, rule)) else: app.add_url_rule(rule, endpoint, viewfunc, **options) #: Register the class-based view extension point #: #: .. versionadded:: 3.5.0 for cvep in self.get_enabled_cveps: viewclass, options = cvep viewclass.register(app, **options) #: Register the template filters #: #: .. versionadded:: 3.2.0 for tf in self.get_enabled_filters: if tf and tf[0] not in app.jinja_env.filters: app.add_template_filter(tf[-1], tf[0]) #: Register the error handlers #: #: .. versionadded:: 3.2.0 for (err_code_exc, errview) in self.get_enabled_errhandlers: app.register_error_handler(err_code_exc, errview) #: Register the template context processors #: #: .. versionadded:: 3.2.0 app.template_context_processors[None].append( lambda: {k: v for tcp in self.get_enabled_tcps for k, v in iteritems(tcp)}) #: register extension with app app.extensions = getattr(app, "extensions", None) or {} app.extensions["pluginkit"] = self
login.login_view = 'auth.login' # Blueprints - подгрузка модулей, которые находятся в папках auth, sections и tasks from app.auth import bp as auth_bp from app.sections import bp as sections_bp from app.tasks import bp as tasks_bp from app.users import bp as users_bp app.register_blueprint(auth_bp) app.register_blueprint(sections_bp, url_prefix="/sections") app.register_blueprint(tasks_bp, url_prefix="/tasks") app.register_blueprint(users_bp) # Добавим путь для шаблонов динамических полей loader = FileSystemLoader("app/dynamic_fields/templates/") my_loader = ChoiceLoader([app.jinja_loader, loader]) app.jinja_loader = my_loader # Функция load_user необходима для LoginManager from app.models import Users @login.user_loader def load_user(id): return Users.query.get(int(id)) # Добавляем список языков и функцию сейчашнего времени в глобальные # переменные jinja, чтобы их можно было использовать в шаблонах app.jinja_env.globals.update(now=datetime.utcnow) app.jinja_env.globals['LANGUAGES'] = app.config['LANGUAGES']
Internal template writer - handles template rendering and blog setup. :copyright: Copyright 2011-2017 by Vlad Riscutia and contributors (see CONTRIBUTORS file) :license: FreeBSD, see LICENSE file ''' from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PackageLoader import os import shutil from tinkerer import paths, utils # jinja environment env = Environment(loader=ChoiceLoader([ # first choice is _templates subdir from blog root FileSystemLoader(paths.templates), # if template is not there, use tinkerer builtin PackageLoader("tinkerer", "__templates") ])) def render(template, destination, context={}, safe=False): ''' Renders the given template at the given destination with the given context. ''' with open(destination, "wb") as dest: dest.write(env.get_template(template).render(context).encode("utf8")) def render_safe(template, destination, context={}): ''' Similar to render but only renders the template if the destination doesn't
from chalice import Response from jinja2 import ChoiceLoader from jinja2 import Environment from jinja2 import FileSystemLoader jinja_env = Environment(loader=ChoiceLoader([ FileSystemLoader("chalicelib/templates"), ])) def add_template_filter(f, name=None): jinja_env.filters[name or f.__name__] = f def add_template_global(f, name=None): jinja_env.globals[name or f.__name__] = f def render_template(template_path, **context): template = jinja_env.get_or_select_template(template_path) return template.render(context) def render_to_response(template_path, **context): return Response( render_template(template_path, **context), status_code=200, headers={ "Content-Type": "text/html", "Access-Control-Allow-Origin": "*" },
def initialize(self, *args, **kwargs): """Load configuration settings.""" super().initialize(*args, **kwargs) self.load_config_file(self.config_file) # hook up tornado logging if self.debug: self.log_level = logging.DEBUG tornado.options.options.logging = logging.getLevelName(self.log_level) tornado.log.enable_pretty_logging() self.log = tornado.log.app_log self.init_pycurl() # initialize kubernetes config if self.builder_required: try: kubernetes.config.load_incluster_config() except kubernetes.config.ConfigException: kubernetes.config.load_kube_config() self.tornado_settings[ "kubernetes_client"] = self.kube_client = kubernetes.client.CoreV1Api( ) # times 2 for log + build threads self.build_pool = ThreadPoolExecutor(self.concurrent_build_limit * 2) # default executor for asyncifying blocking calls (e.g. to kubernetes, docker). # this should not be used for long-running requests self.executor = ThreadPoolExecutor(self.executor_threads) jinja_options = dict(autoescape=True, ) template_paths = [self.template_path] base_template_path = self._template_path_default() if base_template_path not in template_paths: # add base templates to the end, so they are looked up at last after custom templates template_paths.append(base_template_path) loader = ChoiceLoader([ # first load base templates with prefix PrefixLoader({'templates': FileSystemLoader([base_template_path])}, '/'), # load all templates FileSystemLoader(template_paths) ]) jinja_env = Environment(loader=loader, **jinja_options) if self.use_registry and self.builder_required: registry = DockerRegistry(self.docker_auth_host, self.docker_token_url, self.docker_registry_host) else: registry = None self.launcher = Launcher( parent=self, hub_url=self.hub_url, hub_api_token=self.hub_api_token, create_user=not self.auth_enabled, ) self.event_log = EventLog(parent=self) self.tornado_settings.update({ "docker_push_secret": self.docker_push_secret, "docker_image_prefix": self.docker_image_prefix, "debug": self.debug, 'launcher': self.launcher, 'appendix': self.appendix, "build_namespace": self.build_namespace, "builder_image_spec": self.builder_image_spec, 'build_node_selector': self.build_node_selector, 'build_pool': self.build_pool, 'log_tail_lines': self.log_tail_lines, 'per_repo_quota': self.per_repo_quota, 'repo_providers': self.repo_providers, 'use_registry': self.use_registry, 'registry': registry, 'traitlets_config': self.config, 'google_analytics_code': self.google_analytics_code, 'google_analytics_domain': self.google_analytics_domain, 'extra_footer_scripts': self.extra_footer_scripts, 'jinja2_env': jinja_env, 'build_memory_limit': self.build_memory_limit, 'build_docker_host': self.build_docker_host, 'base_url': self.base_url, "static_path": os.path.join(os.path.dirname(__file__), "static"), 'static_url_prefix': url_path_join(self.base_url, 'static/'), 'template_variables': self.template_variables, 'executor': self.executor, 'auth_enabled': self.auth_enabled, 'use_named_servers': self.use_named_servers, 'event_log': self.event_log }) if self.auth_enabled: self.tornado_settings['cookie_secret'] = os.urandom(32) handlers = [ (r'/metrics', MetricsHandler), (r"/build/([^/]+)/(.+)", BuildHandler), (r"/v2/([^/]+)/(.+)", ParameterizedMainHandler), (r"/repo/([^/]+)/([^/]+)(/.*)?", LegacyRedirectHandler), # for backward-compatible mybinder.org badge URLs # /assets/images/badge.svg (r'/assets/(images/badge\.svg)', tornado.web.StaticFileHandler, { 'path': self.tornado_settings['static_path'] }), # /badge.svg (r'/(badge\.svg)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), # /favicon_XXX.ico (r'/(favicon\_fail\.ico)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), (r'/(favicon\_success\.ico)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), (r'/(favicon\_building\.ico)', tornado.web.StaticFileHandler, { 'path': os.path.join(self.tornado_settings['static_path'], 'images') }), (r'/', MainHandler), (r'.*', Custom404), ] if self.extra_static_path: handlers.insert(-1, (re.escape(self.extra_static_url_prefix) + r"(.*)", tornado.web.StaticFileHandler, { 'path': self.extra_static_path })) handlers = self.add_url_prefix(self.base_url, handlers) if self.auth_enabled: oauth_redirect_uri = os.getenv('JUPYTERHUB_OAUTH_CALLBACK_URL') or \ url_path_join(self.base_url, 'oauth_callback') oauth_redirect_uri = urlparse(oauth_redirect_uri).path handlers.insert(-1, (oauth_redirect_uri, HubOAuthCallbackHandler)) self.tornado_app = tornado.web.Application(handlers, **self.tornado_settings)
from functools import wraps import json from jinja2 import Environment, PackageLoader, ChoiceLoader from twisted.internet import defer from klein import Klein from mongoengine import connect from supperfeed.build import Recipe from supperfeed.importer import importRecipe supperLoader = ChoiceLoader([ PackageLoader('supperfeed', '.'), # ... ]) env = Environment( loader=supperLoader, block_start_string='<%', block_end_string='%>', comment_start_string='<#', comment_end_string='#>', variable_start_string='<<', variable_end_string='>>', ) def jsonResponse(f): """
def create_app_ext(flask_config_file=None, flask_config_dict=None, moin_config_class=None, warn_default=True, **kwargs): """ Factory for moin wsgi apps :param flask_config_file: a flask config file name (may have a MOINCFG class), if not given, a config pointed to by MOINCFG env var will be loaded (if possible). :param flask_config_dict: a dict used to update flask config (applied after flask_config_file was loaded [if given]) :param moin_config_class: if you give this, it'll be instantiated as app.cfg, otherwise it'll use MOINCFG from flask config. If that also is not there, it'll use the DefaultConfig built into MoinMoin. :param warn_default: emit a warning if moin falls back to its builtin default config (maybe user forgot to specify MOINCFG?) :param kwargs: if you give additional keyword args, the keys/values will get patched into the moin configuration class (before its instance is created) """ clock = Clock() clock.start('create_app total') app = Flask('moin') clock.start('create_app load config') if flask_config_file: app.config.from_pyfile(path.abspath(flask_config_file)) else: if not app.config.from_envvar('MOINCFG', silent=True): # no MOINCFG env variable set, try stuff in cwd: flask_config_file = path.abspath('wikiconfig_local.py') if not path.exists(flask_config_file): flask_config_file = path.abspath('wikiconfig.py') if not path.exists(flask_config_file): # we should be here only because wiki admin is performing `moin create-instance` if 'create-instance' in sys.argv: config_path = path.dirname(config.__file__) flask_config_file = path.join(config_path, 'wikiconfig.py') else: flask_config_file = None else: logging.warning( "Use of wikiconfig_editme.py is deprecated, merge into wikiconfig.py." ) if flask_config_file: app.config.from_pyfile(path.abspath(flask_config_file)) if flask_config_dict: app.config.update(flask_config_dict) Config = moin_config_class if not Config: Config = app.config.get('MOINCFG') if not Config: if warn_default: logging.warning("using builtin default configuration") from moin.config.default import DefaultConfig as Config for key, value in kwargs.items(): setattr(Config, key, value) if Config.secrets is None: # reuse the secret configured for flask (which is required for sessions) Config.secrets = app.config.get('SECRET_KEY') app.cfg = Config() clock.stop('create_app load config') clock.start('create_app register') # register converters from werkzeug.routing import BaseConverter class ItemNameConverter(BaseConverter): """Like the default :class:`UnicodeConverter`, but it also matches slashes (except at the beginning AND end). This is useful for wikis and similar applications:: Rule('/<itemname:wikipage>') Rule('/<itemname:wikipage>/edit') """ regex = '[^/]+?(/[^/]+?)*' weight = 200 app.url_map.converters['itemname'] = ItemNameConverter # register modules, before/after request functions from moin.apps.frontend import frontend frontend.before_request(before_wiki) frontend.teardown_request(teardown_wiki) app.register_blueprint(frontend) from moin.apps.admin import admin admin.before_request(before_wiki) admin.teardown_request(teardown_wiki) app.register_blueprint(admin, url_prefix='/+admin') from moin.apps.feed import feed feed.before_request(before_wiki) feed.teardown_request(teardown_wiki) app.register_blueprint(feed, url_prefix='/+feed') from moin.apps.misc import misc misc.before_request(before_wiki) misc.teardown_request(teardown_wiki) app.register_blueprint(misc, url_prefix='/+misc') from moin.apps.serve import serve app.register_blueprint(serve, url_prefix='/+serve') clock.stop('create_app register') clock.start('create_app flask-cache') # the 'simple' caching uses a dict and is not thread safe according to the docs. cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(app) app.cache = cache clock.stop('create_app flask-cache') # init storage clock.start('create_app init backends') init_backends(app) clock.stop('create_app init backends') clock.start('create_app flask-babel') i18n_init(app) clock.stop('create_app flask-babel') # configure templates clock.start('create_app flask-theme') setup_themes(app) if app.cfg.template_dirs: app.jinja_env.loader = ChoiceLoader([ FileSystemLoader(app.cfg.template_dirs), app.jinja_env.loader, ]) app.register_error_handler(403, themed_error) clock.stop('create_app flask-theme') clock.stop('create_app total') del clock return app
def create_app(config_obj, configfiles=None, init_for_operation=True): ''' apply configuration object, then configuration files ''' global app app = Flask('members') app.config.from_object(config_obj) if configfiles: # backwards compatibility if type(configfiles) == str: configfiles = [configfiles] for configfile in configfiles: appconfig = getitems(configfile, 'app') app.config.update(appconfig) # tell jinja to remove linebreaks app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True # define product name (don't import nav until after app.jinja_env.globals['_productname'] set) app.jinja_env.globals['_productname'] = app.config['THISAPP_PRODUCTNAME'] app.jinja_env.globals['_productname_text'] = app.config['THISAPP_PRODUCTNAME_TEXT'] for configkey in ['SECURITY_EMAIL_SUBJECT_PASSWORD_RESET', 'SECURITY_EMAIL_SUBJECT_PASSWORD_CHANGE_NOTICE', 'SECURITY_EMAIL_SUBJECT_PASSWORD_NOTICE', ]: app.config[configkey] = app.config[configkey].format(productname=app.config['THISAPP_PRODUCTNAME_TEXT']) # initialize database from .model import db db.init_app(app) # initialize uploads if init_for_operation: init_uploads(app) # handle <interest> in URL - https://flask.palletsprojects.com/en/1.1.x/patterns/urlprocessors/ @app.url_value_preprocessor def pull_interest(endpoint, values): try: g.interest = values.pop('interest', None) except AttributeError: g.interest = None finally: if not g.interest: g.interest = request.args.get('interest', None) # add loutilities tables-assets for js/css/template loading # see https://adambard.com/blog/fresh-flask-setup/ # and https://webassets.readthedocs.io/en/latest/environment.html#webassets.env.Environment.load_path # loutilities.__file__ is __init__.py file inside loutilities; os.path.split gets package directory loutilitiespath = os.path.join(os.path.split(loutilities.__file__)[0], 'tables-assets', 'static') @app.route('/loutilities/static/<path:filename>') def loutilities_static(filename): return send_from_directory(loutilitiespath, filename) # bring in js, css assets here, because app needs to be created first from .assets import asset_env, asset_bundles with app.app_context(): # needs to be set before update_local_tables called and before UserSecurity() instantiated g.loutility = Application.query.filter_by(application=app.config['APP_LOUTILITY']).one() # update LocalUser and LocalInterest tables if init_for_operation: update_local_tables() # js/css files asset_env.append_path(app.static_folder) asset_env.append_path(loutilitiespath, '/loutilities/static') # templates loader = ChoiceLoader([ app.jinja_loader, PackageLoader('loutilities', 'tables-assets/templates') ]) app.jinja_loader = loader # initialize assets asset_env.init_app(app) asset_env.register(asset_bundles) # Set up Flask-Mail [configuration in <application>.cfg] and security mailer mail = Mail(app) def security_send_mail(subject, recipient, template, **context): # this may be called from view which doesn't reference interest # if so pick up user's first interest to get from_email address if not g.interest: g.interest = context['user'].interests[0].interest if context['user'].interests else None if g.interest: from_email = localinterest().from_email # use default if user didn't have any interests else: from_email = current_app.config['SECURITY_EMAIL_SENDER'] # copied from flask_security.utils.send_mail if isinstance(from_email, LocalProxy): from_email = from_email._get_current_object() ctx = ('security/email', template) html = render_template('%s/%s.html' % ctx, **context) text = render_template('%s/%s.txt' % ctx, **context) sendmail(subject, from_email, recipient, html=html, text=text) # Set up Flask-Security global user_datastore, security user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = UserSecurity(app, user_datastore, send_mail=security_send_mail) # activate views from .views import userrole as userroleviews from loutilities.user.views import bp as userrole app.register_blueprint(userrole) from .views.frontend import bp as frontend app.register_blueprint(frontend) from .views.admin import bp as admin app.register_blueprint(admin) # need to force app context else get # RuntimeError: Working outside of application context. # RuntimeError: Attempted to generate a URL without the application context being pushed. # see http://kronosapiens.github.io/blog/2014/08/14/understanding-contexts-in-flask.html with app.app_context(): # import navigation after views created from . import nav # turn on logging from .applogging import setlogging setlogging() # set up scoped session from sqlalchemy.orm import scoped_session, sessionmaker # see https://github.com/pallets/flask-sqlalchemy/blob/706982bb8a096220d29e5cef156950237753d89f/flask_sqlalchemy/__init__.py#L990 db.session = scoped_session(sessionmaker(autocommit=False, autoflush=False, binds=db.get_binds(app))) db.query = db.session.query_property() # handle favicon request for old browsers app.add_url_rule('/favicon.ico', endpoint='favicon', redirect_to=url_for('static', filename='favicon.ico')) # ---------------------------------------------------------------------- @app.before_request def before_request(): g.loutility = Application.query.filter_by(application=app.config['APP_LOUTILITY']).one() if current_user.is_authenticated: user = current_user email = user.email # used in layout.jinja2 app.jinja_env.globals['user_interests'] = sorted([{'interest': i.interest, 'description': i.description} for i in user.interests if g.loutility in i.applications], key=lambda a: a['description'].lower()) session['user_email'] = email else: # used in layout.jinja2 pubinterests = Interest.query.filter_by(public=True).all() app.jinja_env.globals['user_interests'] = sorted([{'interest': i.interest, 'description': i.description} for i in pubinterests if g.loutility in i.applications], key=lambda a: a['description'].lower()) session.pop('user_email', None) # ---------------------------------------------------------------------- @app.after_request def after_request(response): # # check if there are any changes needed to LocalUser table # userupdated = User.query.order_by(desc('updated_at')).first().updated_at # localuserupdated = LocalUser.query.order_by(desc('updated_at')).first().updated_at # interestupdated = Interest.query.order_by(desc('updated_at')).first().updated_at # localinterestupdated = LocalInterest.query.order_by(desc('updated_at')).first().updated_at # if userupdated > localuserupdated or interestupdated > localinterestupdated: # update_local_tables() if not app.config['DEBUG']: app.logger.info( '{}: {} {} {}'.format(request.remote_addr, request.method, request.url, response.status_code)) return response # app back to caller return app