Source code for flask_cache_manifest.extension

import logging
import json
import os

from flask import request, url_for

EXT_NAME = "Flask-Cache-Manifest"


[docs] class FlaskCacheManifest(object):
[docs] def __init__(self, app=None): """ Constructor function for FlaskCacheManifest. It will call :func:`FlaskCacheManifest.init_app` automatically if the app parameter is provided. :param app: A Flask application. :type app: flask.Flask """ self.app = app self.manifests = {} if app is not None: self.init_app(app)
[docs] def init_app(self, app): """ Initializes the extension and loads the various :code:`cache_manifest.json` files. It adds :func:`hashed_url_for` to the template globals for use in Jinja templates. :param app: A Flask application. :type app: flask.Flask """ self.app = app app.config.setdefault('CACHE_MANIFEST_REPLACE_URL_FOR', False) self.load_manifest("static", app) for endpoint, blueprint in app.blueprints.items(): self.load_manifest(f"{endpoint}.static", blueprint) app.add_template_global(self.hashed_url_for, name='hashed_url_for') if app.config['CACHE_MANIFEST_REPLACE_URL_FOR']: app.add_template_global(self.hashed_url_for, name='url_for')
[docs] def load_manifest(self, endpoint, scaffold): """ Called automatically during :any:`init_app` but can be called manually to load blueprints after the initialization. :param endpoint: The endpoint the blueprint is registered as. :type endpoint: str :param scaffold: A Flask application or a registered blueprint. :type scaffold: flask.Blueprint """ if not scaffold.has_static_folder: return manifest_path = os.path.join(scaffold._static_folder, "cache_manifest.json") try: with scaffold.open_resource(manifest_path, "r") as f: self.manifests[endpoint] = json.load(f) except json.JSONDecodeError: logging.warning( f"{EXT_NAME} | Couldn't decode file: {manifest_path}") except PermissionError: logging.warning( f"{EXT_NAME} | Couldn't access file: {manifest_path}") except (FileNotFoundError, Exception): pass
[docs] def hashed_url_for(self, endpoint, **values): """ Generate a URL to the given endpoint with the given values by Extending the functionality of Flask's :func:`url_for()<flask.url_for>`. Arguments will be forwarded to url_for, with the only :code:`values['filename']` being mutated to the appropriate hashed filename. :param endpoint: The endpoint of the URL (name of the function). :type endpoint: str :param values: The variable arguments of the URL rule. :type _values: any :param _external: If set to ``True``, an absolute URL is generated. Server address can be changed via ``SERVER_NAME`` configuration variable which falls back to the `Host` header, then to the IP and port of the request. :type _external: bool, optional :param _scheme: A string specifying the desired URL scheme. The `_external` parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default behavior uses the same scheme as the current request, or ``PREFERRED_URL_SCHEME`` from the :ref:`app configuration <flask.config>` if no request context is available. As of Werkzeug 0.10, this also can be set to an empty string to build protocol-relative URLs. :type _scheme: str, optional :param _anchor: If provided this is added as anchor to the URL. :type _anchor: str, optional :param _method: If provided this explicitly specifies an HTTP method. :type _method: str, optional :rtype: str """ if request is not None: blueprint_name = request.blueprint if endpoint[:1] == ".": if blueprint_name is not None: endpoint = f"{blueprint_name}{endpoint}" else: endpoint = endpoint[1:] manifest = self.manifests.get(endpoint, {}) filename = values.get("filename", None) values['filename'] = manifest.get(filename, filename) return url_for(endpoint, **values)