screenshare/venv/lib/python3.12/site-packages/flask_bootstrap/__init__.py
2024-11-29 18:15:30 +00:00

199 lines
6.0 KiB
Python

#!/usr/bin/env python
# coding=utf8
import re
from flask import Blueprint, current_app, url_for
try:
from wtforms.fields import HiddenField
except ImportError:
def is_hidden_field_filter(field):
raise RuntimeError('WTForms is not installed.')
else:
def is_hidden_field_filter(field):
return isinstance(field, HiddenField)
from .forms import render_form
__version__ = '3.3.7.1.dev1'
BOOTSTRAP_VERSION = re.sub(r'^(\d+\.\d+\.\d+).*', r'\1', __version__)
JQUERY_VERSION = '1.12.4'
HTML5SHIV_VERSION = '3.7.3'
RESPONDJS_VERSION = '1.4.2'
class CDN(object):
"""Base class for CDN objects."""
def get_resource_url(self, filename):
"""Return resource url for filename."""
raise NotImplementedError
class StaticCDN(object):
"""A CDN that serves content from the local application.
:param static_endpoint: Endpoint to use.
:param rev: If ``True``, honor ``BOOTSTRAP_QUERYSTRING_REVVING``.
"""
def __init__(self, static_endpoint='static', rev=False):
self.static_endpoint = static_endpoint
self.rev = rev
def get_resource_url(self, filename):
extra_args = {}
if self.rev and current_app.config['BOOTSTRAP_QUERYSTRING_REVVING']:
extra_args['bootstrap'] = __version__
return url_for(self.static_endpoint, filename=filename, **extra_args)
class WebCDN(object):
"""Serves files from the Web.
:param baseurl: The baseurl. Filenames are simply appended to this URL.
"""
def __init__(self, baseurl):
self.baseurl = baseurl
def get_resource_url(self, filename):
return self.baseurl + filename
class ConditionalCDN(object):
"""Serves files from one CDN or another, depending on whether a
configuration value is set.
:param confvar: Configuration variable to use.
:param primary: CDN to use if the configuration variable is ``True``.
:param fallback: CDN to use otherwise.
"""
def __init__(self, confvar, primary, fallback):
self.confvar = confvar
self.primary = primary
self.fallback = fallback
def get_resource_url(self, filename):
if current_app.config[self.confvar]:
return self.primary.get_resource_url(filename)
return self.fallback.get_resource_url(filename)
def bootstrap_find_resource(filename, cdn, use_minified=None, local=True):
"""Resource finding function, also available in templates.
Tries to find a resource, will force SSL depending on
``BOOTSTRAP_CDN_FORCE_SSL`` settings.
:param filename: File to find a URL for.
:param cdn: Name of the CDN to use.
:param use_minified': If set to ``True``/``False``, use/don't use
minified. If ``None``, honors
``BOOTSTRAP_USE_MINIFIED``.
:param local: If ``True``, uses the ``local``-CDN when
``BOOTSTRAP_SERVE_LOCAL`` is enabled. If ``False``, uses
the ``static``-CDN instead.
:return: A URL.
"""
config = current_app.config
if None == use_minified:
use_minified = config['BOOTSTRAP_USE_MINIFIED']
if use_minified:
filename = '%s.min.%s' % tuple(filename.rsplit('.', 1))
cdns = current_app.extensions['bootstrap']['cdns']
resource_url = cdns[cdn].get_resource_url(filename)
if resource_url.startswith('//') and config['BOOTSTRAP_CDN_FORCE_SSL']:
resource_url = 'https:%s' % resource_url
return resource_url
class Bootstrap(object):
def __init__(self, app=None):
if app is not None:
self.init_app(app)
def init_app(self, app):
app.config.setdefault('BOOTSTRAP_USE_MINIFIED', True)
app.config.setdefault('BOOTSTRAP_CDN_FORCE_SSL', False)
app.config.setdefault('BOOTSTRAP_QUERYSTRING_REVVING', True)
app.config.setdefault('BOOTSTRAP_SERVE_LOCAL', False)
app.config.setdefault('BOOTSTRAP_LOCAL_SUBDOMAIN', None)
blueprint = Blueprint(
'bootstrap',
__name__,
template_folder='templates',
static_folder='static',
static_url_path=app.static_url_path + '/bootstrap',
subdomain=app.config['BOOTSTRAP_LOCAL_SUBDOMAIN'])
# add the form rendering template filter
blueprint.add_app_template_filter(render_form)
app.register_blueprint(blueprint)
app.jinja_env.globals['bootstrap_is_hidden_field'] =\
is_hidden_field_filter
app.jinja_env.globals['bootstrap_find_resource'] =\
bootstrap_find_resource
app.jinja_env.add_extension('jinja2.ext.do')
if not hasattr(app, 'extensions'):
app.extensions = {}
local = StaticCDN('bootstrap.static', rev=True)
static = StaticCDN()
def lwrap(cdn, primary=static):
return ConditionalCDN('BOOTSTRAP_SERVE_LOCAL', primary, cdn)
bootstrap = lwrap(
WebCDN('//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/%s/' %
BOOTSTRAP_VERSION), local)
jquery = lwrap(
WebCDN('//cdnjs.cloudflare.com/ajax/libs/jquery/%s/' %
JQUERY_VERSION), local)
html5shiv = lwrap(
WebCDN('//cdnjs.cloudflare.com/ajax/libs/html5shiv/%s/' %
HTML5SHIV_VERSION))
respondjs = lwrap(
WebCDN('//cdnjs.cloudflare.com/ajax/libs/respond.js/%s/' %
RESPONDJS_VERSION))
app.extensions['bootstrap'] = {
'cdns': {
'local': local,
'static': static,
'bootstrap': bootstrap,
'jquery': jquery,
'html5shiv': html5shiv,
'respond.js': respondjs,
},
}
# setup support for flask-nav
renderers = app.extensions.setdefault('nav_renderers', {})
renderer_name = (__name__ + '.nav', 'BootstrapRenderer')
renderers['bootstrap'] = renderer_name
# make bootstrap the default renderer
renderers[None] = renderer_name