def test_register_filter(): """Test registration of custom filters. """ # Needs to be a ``Filter`` subclass. assert_raises(ValueError, register_filter, object) # A name is required. class MyFilter(Filter): name = None def output(self, *a, **kw): pass assert_raises(ValueError, register_filter, MyFilter) # We should be able to register a filter with a name. MyFilter.name = 'foo' register_filter(MyFilter) # A filter should be able to override a pre-registered filter of the same # name. class OverrideMyFilter(Filter): name = 'foo' def output(self, *a, **kw): pass register_filter(OverrideMyFilter) assert_true(isinstance(get_filter('foo'), OverrideMyFilter))
def register_scss_bundle(scss, assets=None, output=None, prefix='', compile_to='', name=''): """ Function to automate registartion SCSS bundles """ SCSSFilter.base_assets_dir = assets.directory SCSSFilter.base_scss_dir = os.path.join( SCSSFilter.base_assets_dir, prefix ) register_filter(SCSSFilter) widget_scss = SCSSBundle( *scss, compile_dir=compile_to, filters='scssfilter', output=output, prefix=prefix ) assets.register(name, widget_scss) return widget_scss
def test_register_filter(): """Test registration of custom filters. """ # Needs to be a ``Filter`` subclass. assert_raises(ValueError, register_filter, object) # A name is required. class MyFilter(Filter): name = None def output(self, *a, **kw): pass assert_raises(ValueError, register_filter, MyFilter) # The same filter cannot be registered under multiple names. MyFilter.name = 'foo' register_filter(MyFilter) MyFilter.name = 'bar' register_filter(MyFilter) # But the same name cannot be registered multiple times. assert_raises(KeyError, register_filter, MyFilter) # A filter needs to have at least one of the input or output methods. class BrokenFilter(Filter): name = 'broken' assert_raises(TypeError, register_filter, BrokenFilter)
def webassets(ctx, debug=False, expire=True, replace=False): # Register our custom webassets filter. register_filter(ConsoleLogFilter) #-------------------------------------------------------------------------- # Load webassets environment. env = YAMLLoader('./webassets.yaml').load_environment() env.debug = debug env.url_expire = expire #-------------------------------------------------------------------------- # Generate css/js urls. css_urls = [env['external-css'], env['internal-css']] css_urls = [url_to_link(url) for urls in css_urls for url in urls.urls()] js_urls = [env['external-js'], env['internal-js']] js_urls = [url_to_script(url) for urls in js_urls for url in urls.urls()] print() print('* URLs css:') print(''.join((i.lstrip() for i in css_urls))) print('* URLs js:') print(''.join((i.lstrip() for i in js_urls))) if replace: sedplaceholder('wtee/templates/base.html', '<!-- WEBASSETS CSS -->', css_urls) sedplaceholder('wtee/templates/base.html', '<!-- WEBASSETS JS -->', js_urls)
def test_register_filter(): """Test registration of custom filters. """ # Needs to be a ``Filter`` subclass. assert_raises(ValueError, register_filter, object) # A name is required. class MyFilter(Filter): name = None def output(self, *a, **kw): pass assert_raises(ValueError, register_filter, MyFilter) # We should be able to register a filter with a name. MyFilter.name = "foo" register_filter(MyFilter) # A filter should be able to override a pre-registered filter of the same # name. class OverrideMyFilter(Filter): name = "foo" def output(self, *a, **kw): pass register_filter(OverrideMyFilter) assert_true(isinstance(get_filter("foo"), OverrideMyFilter))
def test_register_filter(): """Test registration of custom filters. """ # Needs to be a ``Filter`` subclass. assert_raises(ValueError, register_filter, object) # A name is required. class MyFilter(Filter): name = None def output(self, *a, **kw): pass assert_raises(ValueError, register_filter, MyFilter) # The same filter cannot be registered under multiple names. MyFilter.name = "foo" register_filter(MyFilter) MyFilter.name = "bar" register_filter(MyFilter) # But the same name cannot be registered multiple times. assert_raises(KeyError, register_filter, MyFilter) # A filter needs to have at least one of the input or output methods. class BrokenFilter(Filter): name = "broken" assert_raises(TypeError, register_filter, BrokenFilter)
def initialize(self): loader = FileSystemLoader([ self.settings['template_path'], self.settings['snippet_path']]) assets_env = AssetsEnvironment(self.settings['static_path'], self.static_url('')) register_filter(LibSass) self.template_env = JinjaEnvironment( loader=loader, extensions=[AssetsExtension]) self.template_env.assets_environment = assets_env self.template_env.filters['stylesheet_tag'] = self.stylesheet_tag self.template_env.filters['javascript_tag'] = self.javascript_tag self.template_env.filters['theme_image_url'] = self.theme_image_url self.template_env.globals = self.get_globals() self.site = self.settings['site']
def __init__(self, name, dist, bundles=None, output_dir=None, watch=False, reload=False, refresh=False, manifest='', mapping=None, reloader_service=None, services_service=None, **config): """Initialization """ services_service(super(WebAssets, self).__init__, name, dist, bundles=bundles, output_dir=output_dir, watch=watch, reload=reload, refresh=refresh, manifest=manifest, mapping=mapping, **config) manifest = 'json:{}'.format(manifest) if manifest else None self.environment = Env(directory=output_dir, auto_build=False, manifest=manifest, url_mapping=mapping or {}, **config) self.reload = reload self.refresh = refresh self.reloader = reloader_service if watch else None filter.register_filter(TypeScript) filter.register_filter(BabelJSX) filter.register_filter(BabelJS) filter.register_filter(CompileLess) if bundles: bundles = reference.load_object(bundles)[0] if callable(bundles): bundles = services_service(bundles, self) for name, bundle in bundles.items(): self.environment.register(name, bundle) bundle.get_version() self.bundles = bundles
def webassets(ctx, debug=False, expire=True, replace=False): # Register our custom webassets filter. register_filter(ConsoleLogFilter) #-------------------------------------------------------------------------- # Copy fonts to webassets dir. print('* Copying fonts to %s' % ASSETDIR) fonts = [ 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.eot', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.svg', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.ttf', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.woff', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.woff2', ] run('rsync -v {} {}'.format(' '.join(fonts), ASSETDIR / 'fonts')) #-------------------------------------------------------------------------- # Load webassets environment. env = YAMLLoader('./webassets.yaml').load_environment() env.debug = debug env.url_expire = expire #-------------------------------------------------------------------------- # Generate css/js urls. css_urls = [env['external-css'], env['selectize-css'], env['internal-css']] css_urls = [url_to_link(url) for urls in css_urls for url in urls.urls()] js_urls = [env['external-js'], env['internal-js']] js_urls = [url_to_script(url) for urls in js_urls for url in urls.urls()] print() print('* URLs css:') print(''.join((i.lstrip() for i in css_urls))) print('* URLs js:') print(''.join((i.lstrip() for i in js_urls))) if replace: sedplaceholder('tailon/templates/base.html', '<!-- WEBASSETS CSS -->', css_urls) sedplaceholder('tailon/templates/base.html', '<!-- WEBASSETS JS -->', js_urls)
def test_register_filter(): """Test registration of custom filters. """ # Needs to be a ``Filter`` subclass. assert_raises(ValueError, register_filter, object) # A name is required. class MyFilter(Filter): name = None def output(self, *a, **kw): pass assert_raises(ValueError, register_filter, MyFilter) # The same filter cannot be registered under multiple names. MyFilter.name = 'foo' register_filter(MyFilter) MyFilter.name = 'bar' register_filter(MyFilter) # But the same name cannot be registered multiple times. assert_raises(KeyError, register_filter, MyFilter)
def webassets(debug=False, expire=True, replace=False): # Register our custom webassets filter. register_filter(ConsoleLogFilter) #-------------------------------------------------------------------------- # Copy fonts to webassets dir. print('* Copying fonts to %s' % ASSETDIR) fonts = [ 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.eot', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.svg', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.ttf', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.woff', 'tailon/assets/vendor/components-font-awesome/fonts/fontawesome-webfont.woff2', ] run('rsync -v {} {}'.format(' '.join(fonts), ASSETDIR / 'fonts')) #-------------------------------------------------------------------------- # Load webassets environment. env = YAMLLoader('./webassets.yaml').load_environment() env.debug = debug env.url_expire = expire #-------------------------------------------------------------------------- # Generate css/js urls. css_urls = [env['external-css'], env['selectize-css'], env['internal-css']] css_urls = [url_to_link(url) for urls in css_urls for url in urls.urls()] js_urls = [env['external-js'], env['internal-js']] js_urls = [url_to_script(url) for urls in js_urls for url in urls.urls()] print() print('* URLs css:') print(''.join((i.lstrip() for i in css_urls))) print('* URLs js:') print(''.join((i.lstrip() for i in js_urls))) if replace: sedplaceholder('tailon/templates/base.html', '<!-- WEBASSETS CSS -->', css_urls) sedplaceholder('tailon/templates/base.html', '<!-- WEBASSETS JS -->', js_urls)
def init_assets_environment(app, include_dependencies=True, auto_build=True): """Configure Flask webassets.""" # Configuration must be set directly on Flask.config because Environment # needs to have a Flask application in the context in order to do that. app.config['ASSETS_AUTO_BUILD'] = auto_build # We need a r.js version which supports stdout (https://github.com/jrburke/r.js/pull/620). app.config['RJS_BIN'] = path.join(app.config['STATIC_ROOT'], 'js', 'vendor', 'r.js') app.config['RJS_EXTRA_ARGS'] = read_config(path.join(app.config['DATA_ROOT'], 'r.js.conf')) register_filter(RJS) # 'less' requires lessc and node.js (see package.json). css_layout = Bundle(path.join('css', 'less', 'layout.less'), output=path.join('css', 'layout.min.css'), filters='less, cssmin', depends=files(path.join(app.static_folder, 'css', 'less'), '*.less')) css_errors = Bundle(path.join('css', 'less', 'errors.less'), output=path.join('css', 'errors.min.css'), filters='less, cssmin') # 'rjs' requires r.js and node.js. js_rjs = Bundle(path.join('js', 'build', 'main.js'), output=path.join('js', 'main.min.js'), filters='rjs', depends=files(path.join(app.static_folder, 'js', 'build'), '*.js')) # Hack: exclude dependencies in order to enable caching (this is a webassets issue). if not include_dependencies: css_layout.depends = [] css_errors.depends = [] js_rjs.depends = [] assets_env.register('css_layout', css_layout) assets_env.register('css_errors', css_errors) assets_env.register('js_rjs', js_rjs) assets_env.init_app(app)
def register_template_bundle(files, namespace='KHARKIVPYTPL', name=None, output=None, assets=None ): TemplateFilter.base_assets_dir = assets.directory TemplateFilter.namespace = namespace, TemplateFilter.base_templates_dir = os.path.join( TemplateFilter.base_assets_dir, UNDERSCORE_TEMPLATES_DIR ) register_filter(TemplateFilter) filters = ['underscore_templates'] widget_templates = AlwaysUpdatedBundle( *files, filters=filters, output=output ) assets.register(name, widget_templates) return widget_templates
def includeme(config): config.add_route('home', '/', use_global_views=True) config.add_route('embed', '/embed.js') config.add_route('token', '/api/token') config.add_route('users', '/api/u') config.add_route('api', '/api/*subpath') config.add_route('app', '/app') config.add_route('login', '/login') config.add_route('logout', '/logout') config.add_route('register', '/register') config.add_route('forgot', '/forgot') config.scan(__name__) config.include('pyramid_webassets') # wrap coffeescript output in a closure config.get_webassets_env().config['coffee_no_bare'] = True # register our backported cleancss filter until webassets 0.8 is released register_filter(CleanCSS) add_webassets(config)
def initialize(self): loader = FileSystemLoader([ self.settings['template_path'], self.settings['snippet_path']]) assets_env = AssetsEnvironment( self.settings['static_path'], self.static_url('')) register_filter(LibSass) self.template_env = JinjaEnvironment( loader=loader, extensions=[AssetsExtension], bytecode_cache=FileSystemBytecodeCache()) self.template_env.assets_environment = assets_env self.template_env.filters['stylesheet_tag'] = self.stylesheet_tag self.template_env.filters['javascript_tag'] = self.javascript_tag self.template_env.filters['theme_image_url'] = self.theme_image_url self.template_env.filters['strftime'] = self.strftime self.template_env.globals.update(self.get_globals()) self.site = self.settings['site'] self.client = tornado.httpclient.AsyncHTTPClient()
self.sass = sass if not self.style: self.style = 'nested' def input(self, _in, out, **kwargs): source_path = kwargs['source_path'] out.write( # http://hongminhee.org/libsass-python/sass.html#sass.compile self.sass.compile( filename=source_path, output_style=self.style, include_paths=(self.includes if self.includes else []), )) register_filter(FixedLibSass) assets = Environment() styles = Bundle( 'scss/styles.scss', 'octicons/octicons.css', filters='fixedlibsass,datauri', output='css/styles.%(version)s.css', depends=('**/*.scss'), ) assets.register('styles', styles)
For those to be registered automatically, make sure the main django_assets namespace imports this file. """ from django.template import Template, Context from webassets import six from webassets.filter import Filter, register_filter class TemplateFilter(Filter): """ Will compile all source files as Django templates. """ name = 'template' max_debug_level = None def __init__(self, context=None): super(TemplateFilter, self).__init__() self.context = context def input(self, _in, out, source_path, output_path, **kw): t = Template(_in.read(), origin='django-assets', name=source_path) rendered = t.render(Context(self.context if self.context else {})) if not six.PY3: rendered = rendered.encode('utf-8') out.write(rendered) register_filter(TemplateFilter)
class RootController(TGController): @expose() def index(self): return page(dict( g=tg.app_globals )).render() config = AppConfig(minimal=True, root_controller=RootController()) config.renderers = ['kajiki'] config.serve_static = True config.paths['static_files'] = 'static' from webassets.filter import register_filter from dukpy.webassets import BabelJSX register_filter(BabelJSX) import tgext.webassets as wa wa.plugme( config, options={ 'babel_modules_loader': 'umd' }, bundles={ 'bundle.js': wa.Bundle( 'js/react.js', 'js/react-dom.js', wa.Bundle( 'js/HelloWorld.jsx', filters='babeljsx', ),
def _setup_assets(self): global app global assets global pluginManager util.flask.fix_webassets_cache() util.flask.fix_webassets_filtertool() base_folder = settings().getBaseFolder("generated") # clean the folder if settings().getBoolean(["devel", "webassets", "clean_on_startup"]): import shutil for entry in ("webassets", ".webassets-cache"): path = os.path.join(base_folder, entry) self._logger.debug("Deleting {path}...".format(**locals())) if os.path.isdir(path): shutil.rmtree(path, ignore_errors=True) elif os.path.isfile(path): try: os.remove(path) except: self._logger.exception("Exception while trying to delete {entry} from {base_folder}".format(**locals())) AdjustedEnvironment = type(Environment)(Environment.__name__, (Environment,), dict( resolver_class=util.flask.PluginAssetResolver )) class CustomDirectoryEnvironment(AdjustedEnvironment): @property def directory(self): return base_folder assets = CustomDirectoryEnvironment(app) assets.debug = not settings().getBoolean(["devel", "webassets", "bundle"]) UpdaterType = type(util.flask.SettingsCheckUpdater)(util.flask.SettingsCheckUpdater.__name__, (util.flask.SettingsCheckUpdater,), dict( updater=assets.updater )) assets.updater = UpdaterType enable_gcodeviewer = settings().getBoolean(["gcodeViewer", "enabled"]) enable_timelapse = (settings().get(["webcam", "snapshot"]) and settings().get(["webcam", "ffmpeg"])) preferred_stylesheet = settings().get(["devel", "stylesheet"]) dynamic_assets = util.flask.collect_plugin_assets( enable_gcodeviewer=enable_gcodeviewer, enable_timelapse=enable_timelapse, preferred_stylesheet=preferred_stylesheet ) js_libs = [ "js/lib/jquery/jquery.min.js", "js/lib/modernizr.custom.js", "js/lib/lodash.min.js", "js/lib/sprintf.min.js", "js/lib/knockout.js", "js/lib/knockout.mapping-latest.js", "js/lib/babel.js", "js/lib/avltree.js", "js/lib/bootstrap/bootstrap.js", "js/lib/bootstrap/bootstrap-modalmanager.js", "js/lib/bootstrap/bootstrap-modal.js", "js/lib/bootstrap/bootstrap-slider.js", "js/lib/bootstrap/bootstrap-tabdrop.js", "js/lib/jquery/jquery.ui.core.js", "js/lib/jquery/jquery.ui.widget.js", "js/lib/jquery/jquery.ui.mouse.js", "js/lib/jquery/jquery.flot.js", "js/lib/jquery/jquery.iframe-transport.js", "js/lib/jquery/jquery.fileupload.js", "js/lib/jquery/jquery.slimscroll.min.js", "js/lib/jquery/jquery.qrcode.min.js", "js/lib/moment-with-locales.min.js", "js/lib/pusher.color.min.js", "js/lib/detectmobilebrowser.js", "js/lib/md5.min.js", "js/lib/pnotify.min.js", "js/lib/bootstrap-slider-knockout-binding.js", "js/lib/loglevel.min.js", "js/lib/sockjs-0.3.4.min.js" ] js_app = dynamic_assets["js"] + [ "js/app/dataupdater.js", "js/app/helpers.js", "js/app/main.js", ] css_libs = [ "css/bootstrap.min.css", "css/bootstrap-modal.css", "css/bootstrap-slider.css", "css/bootstrap-tabdrop.css", "css/font-awesome.min.css", "css/jquery.fileupload-ui.css", "css/pnotify.min.css" ] css_app = list(dynamic_assets["css"]) if len(css_app) == 0: css_app = ["empty"] less_app = list(dynamic_assets["less"]) if len(less_app) == 0: less_app = ["empty"] from webassets.filter import register_filter, Filter from webassets.filter.cssrewrite.base import PatternRewriter import re class LessImportRewrite(PatternRewriter): name = "less_importrewrite" patterns = { "import_rewrite": re.compile("(@import(\s+\(.*\))?\s+)\"(.*)\";") } def import_rewrite(self, m): import_with_options = m.group(1) import_url = m.group(3) if not import_url.startswith("http:") and not import_url.startswith("https:") and not import_url.startswith("/"): import_url = "../less/" + import_url return "{import_with_options}\"{import_url}\";".format(**locals()) class JsDelimiterBundle(Filter): name = "js_delimiter_bundler" options = {} def input(self, _in, out, **kwargs): out.write(_in.read()) out.write("\n;\n") register_filter(LessImportRewrite) register_filter(JsDelimiterBundle) js_libs_bundle = Bundle(*js_libs, output="webassets/packed_libs.js", filters="js_delimiter_bundler") if settings().getBoolean(["devel", "webassets", "minify"]): js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="rjsmin, js_delimiter_bundler") else: js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="js_delimiter_bundler") css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css") css_app_bundle = Bundle(*css_app, output="webassets/packed_app.css", filters="cssrewrite") all_less_bundle = Bundle(*less_app, output="webassets/packed_app.less", filters="cssrewrite, less_importrewrite") assets.register("js_libs", js_libs_bundle) assets.register("js_app", js_app_bundle) assets.register("css_libs", css_libs_bundle) assets.register("css_app", css_app_bundle) assets.register("less_app", all_less_bundle)
from __future__ import absolute_import from webassets.filter import Filter from react import jsx __all__ = ("JSXFilter",) class JSXFilter(Filter): """Transforms the jsx to js Requires the ``react-python`` package from https://github.com/reactjs/react-python """ name = "jsx" def setup(self): try: import react except ImportError: raise EnvironmentError('The "pyreact" package is not installed.') else: self.react = react def output(self, _in, out, **kw): transformer = self.react.jsx.JSXTransformer() out.write(transformer.transform_string(_in.read())) from webassets.filter import register_filter register_filter(JSXFilter)
""" name = 'jinja2' max_debug_level = None def __init__(self, context=None): super(Jinja2Filter, self).__init__() self.context = context or {} def input(self, _in, out, source_path, output_path, **kw): out.write(render_template_string(_in.read(), **self.context)) # Override the built-in ``jinja2`` filter that ships with ``webassets``. This # custom filter uses Flask's ``render_template_string`` function to provide all # the standard Flask template context variables. register_filter(Jinja2Filter) class FlaskConfigStorage(ConfigStorage): """Uses the config object of a Flask app as the backend: either the app instance bound to the extension directly, or the current Flask app on the stack. Also provides per-application defaults for some values. Note that if no app is available, this config object is basically unusable - this is by design; this could also let the user set defaults by writing to a container not related to any app, which would be used as a fallback if a current app does not include a key. However, at least for now, I specifically made the choice to keep things simple and not allow global across-app defaults.
from subprocess import check_output from flask import Flask from flask.ext.assets import Environment, Bundle from webassets.filter import Filter, register_filter class CoffeeifyFilter(Filter): name = 'coffeeify' def input(self, _in, out, **kwargs): path = kwargs['source_path'] out.write(check_output(['browserify', '-t', 'coffeeify', path])) def output(self, _in, out, **kwargs): out.write(_in.read()) register_filter(CoffeeifyFilter) app = Flask(__name__) assets = Environment(app) # api = restful.Api(app) # api.add_resource(Page, '/pages/<int:page_id>') js = Bundle('coffee/main.coffee', filters=['coffeeify'], output='main.js') assets.register('js_all', js) import plant_api.views
def register(): register_filter(BabelJSX)
name = 'libsass' def input(self, _in, out, **kw): """ Based on the pyscss filter. Makes sure that the ``include_paths`` parameter includes the directory of the source file. """ source_path = kw['source_path'] include_paths = [os.path.dirname(source_path)] out.write(sass.compile(string=_in.read(), include_paths=include_paths)) register_filter(LibSassFilter) class BrowserifyFilter(ExternalTool): """ webassets_ filter for Browserify_. .. _webassets: https://webassets.readthedocs.org/ .. _Browserify: http://browserify.org """ name = 'browserify' method = 'open' options = { 'binary': 'BROWSERIFY_BIN', 'coffeescript': 'BROWSERIFY_COFFEESCRIPT',
output=source, output_path=filepath) buf.seek(0) # now process '@includes' directives in included file self.input(buf, out, source=rel_filename, source_path=abs_filename, output=source, output_path=filepath) if end < len(line): out.write(line[end:]) else: out.write('\n') register_filter(ImportCSSFilter) class LessImportFilter(Filter): """ This filter outputs `@import` statements for listed files. This allows to generate a single less file for application, where abilian properties can be overridden by application. """ name = 'less_import' options = { 'run_in_debug': 'LESS_RUN_IN_DEBUG', # use same option as less filter } max_debug_level = None logger = logging.getLogger(__name__ + '.LessImportFilter')
An input filter for webassets that bundles CoffeeScript or JavaScript using Browserify. """ name = 'browserify' max_debug_level = None extra_args = None def input(self, in_, out, **kw): args = [_locate_npm_bin('browserify'), '--extension=.coffee', '--transform', 'coffeeify'] if self.get_config('debug'): args.append('-d') args.append(kw['source_path']) self.subprocess(args, out) register_filter(Browserify) # The release versions of webassets upstream don't support extra arguments yet. class CleanCSS(ExternalTool): """ Minify CSS using `Clean-css <https://github.com/GoalSmashers/clean-css/>`_. """ name = 'cleancss' options = { 'binary': _locate_npm_bin('cleancss'), 'extra_args': '--skip-advanced --skip-rebase', } def run(self, _in, out, extra_args):
def create_app(config=None, debug=False): ''' Inicializa la aplicación Flask. Carga los siguientes módulos: - index: página de inicio - page: páginas estáticas - user: gestión del usuario - files: búsqueda y obtención de ficheros - status: servicio de monitorización de la aplicación Y además, inicializa los siguientes servicios: - Configuración: carga valores por defecto y modifica con el @param config - Web Assets: compilación y compresión de recursos estáticos - i18n: detección de idioma en la URL y catálogos de mensajes - Cache y auth: Declarados en el módulo services - Files: Clases para acceso a datos ''' app = Flask(__name__) app.config.from_object(defaults) app.debug = debug # Configuración if config: app.config.from_object(config) # Modo de appweb appmode = app.config["APPWEB_MODE"] # Gestión centralizada de errores if app.config["SENTRY_DSN"]: sentry.init_app(app) logging.getLogger().setLevel(logging.DEBUG if debug else logging.INFO) # Configuración dependiente de la versión del código revision_filename_path = os.path.join(os.path.dirname(app.root_path), "revision") if os.path.exists(revision_filename_path): f = open(revision_filename_path, "r") data = f.read() f.close() revisions = tuple( tuple(i.strip() for i in line.split("#")[0].split()) for line in data.strip().split("\n") if line.strip() and not line.strip().startswith("#")) revision_hash = md5(data).hexdigest() app.config.update( CACHE_KEY_PREFIX = "%s%s/" % ( app.config["CACHE_KEY_PREFIX"] if "CACHE_KEY_PREFIX" in app.config else "", revision_hash ), REVISION_HASH = revision_hash, REVISION = revisions ) else: app.config.update( REVISION_HASH = None, REVISION = () ) # Registra filtros de plantillas register_filters(app) # Registra valores/funciones para plantillas app.jinja_env.globals["u"] = u # proteccion CSRF csrf.init_app(app) # Blueprints if appmode == "search": app.register_blueprint(files) elif appmode == "extras": app.register_blueprint(extras) else: logging.error("No se ha especificado modo en la configuración. Blueprints sin cargar.") # Web Assets dir_static = app.static_folder # shortcut scss.config.LOAD_PATHS = [os.path.abspath('%s/../..' % dir_static)] for subdir in ['%s/%s' % (dir_static, x) for x in ['gen', 'torrents/gen']]: if not os.path.isdir(subdir): os.makedirs(subdir) app.assets = Environment(app) app.assets.debug = app.debug app.assets.versions = "hash" register_filter(JsSlimmer) register_filter(CssSlimmer) app.assets.register( 'css_torrents', Bundle('torrents/css/torrents.scss', filters='pyscss', output='torrents/gen/torrents.css', debug=False), filters='css_slimmer', output='torrents/gen/torrents.css') if appmode == "search": app.assets.register( 'js_appweb', Bundle('prototype.js', 'event.simulate.js', 'chosen.proto.min.js','appweb.js', filters='rjsmin', output='gen/appweb.js')) else: app.assets.register( 'js_appweb', Bundle('prototype.js', filters='rjsmin', output='gen/appweb.js')) # Traducciones babel.init_app(app) @babel.localeselector def get_locale(): return "en" # Autenticación auth.setup_app(app) auth.user_loader(User.current_user) auth.anonymous_user = User.current_user # Cache cache.init_app(app) # Acceso a bases de datos filesdb.init_app(app) pagesdb.init_app(app) feedbackdb.init_app(app) entitiesdb.init_app(app) usersdb.init_app(app) plugindb.init_app(app) # Servicio de búsqueda @app.before_first_request def init_process(): if not eventmanager.is_alive(): # Fallback inicio del eventManager eventmanager.start() # Profiler profiler.init_app(app, feedbackdb) eventmanager.once(searchd.init_app, hargs=(app, filesdb, entitiesdb, profiler)) # Refresco de conexiones eventmanager.once(filesdb.load_servers_conn) eventmanager.interval(app.config["FOOCONN_UPDATE_INTERVAL"], filesdb.load_servers_conn) eventmanager.interval(app.config["FOOCONN_UPDATE_INTERVAL"], entitiesdb.connect) @app.url_value_preprocessor def pull_lang_code(endpoint, values): if values is None: g.lang = "en" else: g.lang = values.pop('lang', "en") @app.url_defaults def add_language_code(endpoint, values): if not 'lang' in values and app.url_map.is_endpoint_expecting(endpoint, 'lang'): values['lang'] = g.lang @app.before_request def before_request(): # No preprocesamos la peticiones a static if request.path.startswith("/static/"): return init_g(app) # ignora peticiones sin blueprint if request.blueprint is None and len(request.path)>1 and request.path.endswith("/"): if "?" in request.url: root = request.url_root[:-1] path = request.path.rstrip("/") query = request.url.decode("utf-8") query = query[query.find(u"?"):] return redirect(root+path+query, 301) return redirect(request.url.rstrip("/"), 301) @app.after_request def after_request(response): response.headers["X-UA-Compatible"] = "IE=edge" return response # Páginas de error errors = { 404: ("Page not found", "The requested address does not exists."), 410: ("Page not available", "The requested address is no longer available."), 500: ("An error happened", "We had some problems displaying this page. Maybe later we can show it to you."), 503: ("Service unavailable", "This page is temporarily unavailable. Please try again later.") } @allerrors(app, 400, 401, 403, 404, 405, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 500, 501, 502, 503) def all_errors(e): error = e.code if hasattr(e,"code") else 500 title, description = errors[error if error in errors else 500] init_g(app) return render_template('error.html', code=str(error), title=title, description=description), error return app
from webassets.filter import register_filter, ExternalTool class Buble(ExternalTool): name = 'buble' max_debug_level = None options = { 'binary': 'BUBLE_BIN', 'extra_args': 'BABEL_EXTRA_ARGS', 'run_in_debug': 'BABEL_RUN_IN_DEBUG', } def setup(self): super(Buble, self).setup() if self.run_in_debug is False: # Disable running in debug mode for this instance. self.max_debug_level = False def input(self, _in, out, **kw): args = [self.binary or 'buble'] if self.extra_args: args.extend(self.extra_args) return self.subprocess(args, out, _in) register_filter(Buble)
) elif stderr: print("jade filter has warnings:", stderr) # Add a bit of JavaScript that will place our compiled Jade function # into an object on the `window` object. Jade files are keyed by their # basename. key = os.path.splitext(os.path.basename(kwargs["source_path"]))[0] preamble = "window['%s']['%s'] = " % (self.js_var, key) out.write("%s%s" % (preamble, stdout.strip())) def output(self, _in, out, **kwargs): """ Prepend Jade runtime and initialize template variable. """ if self.jade_runtime: with open(self.jade_runtime) as file: runtime = "".join(file.readlines()) else: runtime = "" # JavaScript code to initialize the window-level object that will hold # our compiled Jade templates as functions init = "if(!window['%s']) { window['%s'] = {}; }" % (self.js_var, self.js_var) out.write("%s\n%s\n%s" % (runtime, init, _in.read())) register_filter(Jade)
def setup_class(cls): from webassets.filter import register_filter register_filter(BabelJS) register_filter(TypeScript)
from unittest import TestCase from webassets.filter import register_filter from webassets.test import TempEnvironmentHelper from webassets_rollup import Rollup register_filter(Rollup) class RollupFilterTestCase(TempEnvironmentHelper, TestCase): default_files = { 'main.js': 'import { cube } from "./maths.js"; console.log(cube(5));', 'maths.js': 'export function cube ( x ) { return x * x * x; }' } def setUp(self): super(RollupFilterTestCase, self).setup() def test_rollup_filter(self): self.mkbundle('main.js', filters='rollup', output='bundle.js').build() assert 'cube(5)' in self.get('bundle.js')
def setup_class(cls): from webassets.filter import register_filter register_filter(CompileLess)
args = [self.binary or 'browserify'] args.append(kwargs['source_path']) if self.get_config('debug'): args.append('-d') if self.extra_args is not None: if isinstance(self.extra_args, string_types): self.extra_args = self.extra_args.split() args.extend(self.extra_args) self.subprocess(args, out) register_filter(Browserify) # The release versions of webassets upstream don't support extra arguments yet. class CleanCSS(ExternalTool): """ Minify css using `Clean-css <https://github.com/GoalSmashers/clean-css/>`_. Clean-css is an external tool written for NodeJS; this filter assumes that the ``cleancss`` executable is in the path. Otherwise, you may define a ``CLEANCSS_BIN`` setting. Additional options may be passed to ``cleancss`` binary using the setting ``CLEANCSS_EXTRA_ARGS``, which expects a list of strings. """
def replace_url(self, url): parsed = urlparse(url) if parsed.scheme or parsed.netloc: return url elif parsed.path.startswith('/'): # Prefix absolute urls with the base path. Like this we avoid # the mess that comes with relative URLs in CSS while still # supporting Indico running in a subdirectory (e.g. /indico) return self.base_url_path + url else: return super(IndicoCSSRewrite, self).replace_url(url) # XXX: DO NOT move this to decorators. this function returns None, # so super() calls using the decorated class name fail... register_filter(CSSCompressor) register_filter(IndicoCSSRewrite) def _get_htdocs_path(): return os.path.join(get_root_path('indico'), 'htdocs') def configure_pyscss(environment): base_url_path = urlparse(config.BASE_URL).path environment.config['PYSCSS_STYLE'] = 'compact' environment.config['PYSCSS_DEBUG_INFO'] = False environment.config['PYSCSS_STATIC_URL'] = '{0}/static/'.format(base_url_path) environment.config['PYSCSS_LOAD_PATHS'] = [ os.path.join(_get_htdocs_path(), 'sass', 'lib', 'compass'), os.path.join(_get_htdocs_path(), 'sass')
from standardweb import app class React(Filter): name = 'react' max_debug_level = None def output(self, _in, out, **kw): content = _in.read() transformer = JSXTransformer() js = transformer.transform_string(content) out.write(js) register_filter(React) env = Environment(app) bundles = { 'css_all': Bundle(Bundle( 'css/lib/font-awesome.min.css', 'css/lib/tipsy.css', 'css/lib/bbcode.css', ), Bundle( 'css/local/ansi.less', 'css/local/base.less', 'css/local/colors.less', 'css/local/fonts.less', 'css/local/layouts.less',
# -*- coding: utf-8 -*- from flask_assets import Bundle, Environment from webassets.filter import register_filter from webassets_browserify import Browserify register_filter(Browserify) css = Bundle("libs/bootstrap/dist/css/bootstrap.css", filters="cssmin", output="public/css/common.css") other_css = Bundle("sass/style.sass", filters=["sass"], output="public/css/style.css") js = Bundle("libs/jQuery/dist/jquery.js", "libs/bootstrap/dist/js/bootstrap.js", "js/plugins.js", filters='jsmin', output="public/js/common.js") dashboard_js_deps = Bundle("libs/jQuery/dist/jquery.js", output="public/js/dashboard_libs.js") overview_js = Bundle("coffee/charts.coffee", "coffee/overview.coffee", filters=['coffeescript'], output="public/js/overview.js") overview_css = Bundle("sass/overview.sass", filters=['sass'],
class AngularTemplatesFilter(Filter): name = "angular_templates" input_template = "$templateCache.put('%s', '%s');" output_template = "(function() { var module; try { module = angular.module('templates'); } catch (error) { module = angular.module('templates', []); } module.run(['$templateCache', function($templateCache) { %s }]); })();" def output(self, _in, out, **kwargs): out.write(self.output_template % _in.read()) def input(self, _in, out, **kwargs): path = os.path.abspath(kwargs['source_path']) path = os.path.relpath(path, app.root_path) data = _in.read().replace("\n", "\\n") out.write(self.input_template % (path, data)) register_filter(AngularTemplatesFilter) env = Environment(app) env.register('all_js', Bundle( 'support/js/vendor/angular.min.js', 'support/js/vendor/jquery.min.js', 'support/js/vendor/jquery.gridster.min.js' ), Bundle( 'support/templates/*.html', '../widgets/**/*.html', filters='angular_templates'
from webassets.filter import Filter, register_filter from standardweb import app class React(Filter): name = 'react' max_debug_level = None def output(self, _in, out, **kw): content = _in.read() transformer = JSXTransformer() js = transformer.transform_string(content) out.write(js) register_filter(React) env = Environment(app) bundles = { 'css_all': Bundle( Bundle( 'css/lib/font-awesome.min.css', 'css/lib/tipsy.css', 'css/lib/bbcode.css', ), Bundle( 'css/local/ansi.less', 'css/local/base.less', 'css/local/colors.less', 'css/local/fonts.less', 'css/local/layouts.less',
name = 'cssversion' max_debug_level = 'merge' def replace_url(self, url): parsed = urlparse(url) if parsed.scheme: return url else: dirname = path.dirname(self.output_path) filepath = path.join(dirname, parsed.path) filepath = path.normpath(path.abspath(filepath)) resolved = self.env.resolver.resolve_source_to_url(filepath, url) relative = urlpath.relpath(self.output_url, resolved) return relative register_filter(CSSVersion) def Uglify(*names, **kw): kw.setdefault('filters', 'uglifyjs') return Bundle(*names, **kw) def Coffee(*names, **kw): kw.setdefault('filters', 'coffeescript') return Bundle(*names, **kw) def SCSS(*names, **kw): kw.setdefault('filters', 'compass,cssrewrite,cssversion,cleancss') return Bundle(*names, **kw)
def create_app(config=None, debug=False): ''' Inicializa la aplicación Flask. Carga los siguientes módulos: - index: página de inicio - page: páginas estáticas - user: gestión del usuario - files: búsqueda y obtención de ficheros - status: servicio de monitorización de la aplicación Y además, inicializa los siguientes servicios: - Configuración: carga valores por defecto y modifica con el @param config - Web Assets: compilación y compresión de recursos estáticos - i18n: detección de idioma en la URL y catálogos de mensajes - Cache y auth: Declarados en el módulo services - Files: Clases para acceso a datos ''' app = Flask(__name__) app.config.from_object(defaults) app.debug = debug # Configuración if config: app.config.from_object(config) # Modo de appweb appmode = app.config["APPWEB_MODE"] # Gestión centralizada de errores if app.config["SENTRY_DSN"]: sentry.init_app(app) logging.getLogger().setLevel(logging.DEBUG if debug else logging.INFO) # Configuración dependiente de la versión del código revision_filename_path = os.path.join(os.path.dirname(app.root_path), "revision") if os.path.exists(revision_filename_path): f = open(revision_filename_path, "r") data = f.read() f.close() revisions = tuple( tuple(i.strip() for i in line.split("#")[0].split()) for line in data.strip().split("\n") if line.strip() and not line.strip().startswith("#")) revision_hash = md5(data).hexdigest() app.config.update(CACHE_KEY_PREFIX="%s%s/" % (app.config["CACHE_KEY_PREFIX"] if "CACHE_KEY_PREFIX" in app.config else "", revision_hash), REVISION_HASH=revision_hash, REVISION=revisions) else: app.config.update(REVISION_HASH=None, REVISION=()) # Registra filtros de plantillas register_filters(app) # Registra valores/funciones para plantillas app.jinja_env.globals["u"] = u # proteccion CSRF csrf.init_app(app) # Blueprints if appmode == "search": app.register_blueprint(files) elif appmode == "extras": app.register_blueprint(extras) else: logging.error( "No se ha especificado modo en la configuración. Blueprints sin cargar." ) # Web Assets scss.config.LOAD_PATHS = [ os.path.dirname(os.path.dirname(app.static_folder)) ] if not os.path.isdir(app.static_folder + "/gen"): os.mkdir(app.static_folder + "/gen") if not os.path.isdir(app.static_folder + "/blubster/gen"): os.mkdir(app.static_folder + "/blubster/gen") if not os.path.isdir(app.static_folder + "/foofind/gen"): os.mkdir(app.static_folder + "/foofind/gen") app.assets = assets = Environment(app) assets.debug = app.debug assets.versions = "hash" register_filter(JsSlimmer) register_filter(CssSlimmer) assets.register('css_blubster', Bundle('blubster/css/blubster.scss', filters='pyscss', output='blubster/gen/blubster.css', debug=False, depends='appweb.scss'), filters='css_slimmer', output='blubster/gen/blubster.css') assets.register('css_foofind', Bundle('foofind/css/foofind.scss', filters='pyscss', output='foofind/gen/foofind.css', debug=False), filters='css_slimmer', output='foofind/gen/foofind.css') # Traducciones babel.init_app(app) @babel.localeselector def get_locale(): return "en" # Autenticación auth.setup_app(app) auth.user_loader(User.current_user) auth.anonymous_user = User.current_user # Cache cache.init_app(app) # Acceso a bases de datos filesdb.init_app(app) pagesdb.init_app(app) feedbackdb.init_app(app) entitiesdb.init_app(app) usersdb.init_app(app) plugindb.init_app(app) # Servicio de búsqueda @app.before_first_request def init_process(): if not eventmanager.is_alive(): # Fallback inicio del eventManager eventmanager.start() # Profiler profiler.init_app(app, feedbackdb) eventmanager.once(searchd.init_app, hargs=(app, filesdb, entitiesdb, profiler)) # Refresco de conexiones eventmanager.once(filesdb.load_servers_conn) eventmanager.interval(app.config["FOOCONN_UPDATE_INTERVAL"], filesdb.load_servers_conn) eventmanager.interval(app.config["FOOCONN_UPDATE_INTERVAL"], entitiesdb.connect) @app.url_value_preprocessor def pull_lang_code(endpoint, values): if values is None: g.lang = "en" else: g.lang = values.pop('lang', "en") @app.url_defaults def add_language_code(endpoint, values): if not 'lang' in values and app.url_map.is_endpoint_expecting( endpoint, 'lang'): values['lang'] = g.lang @app.before_request def before_request(): # No preprocesamos la peticiones a static if request.path.startswith("/static/"): return init_g(app) # ignora peticiones sin blueprint if request.blueprint is None and len( request.path) > 1 and request.path.endswith("/"): if "?" in request.url: root = request.url_root[:-1] path = request.path.rstrip("/") query = request.url.decode("utf-8") query = query[query.find(u"?"):] return redirect(root + path + query, 301) return redirect(request.url.rstrip("/"), 301) @app.after_request def after_request(response): response.headers["X-UA-Compatible"] = "IE=edge" return response # Páginas de error errors = { 404: ("Page not found", "The requested address does not exists."), 410: ("Page not available", "The requested address is no longer available."), 500: ("An error happened", "We had some problems displaying this page. Maybe later we can show it to you." ), 503: ("Service unavailable", "This page is temporarily unavailable. Please try again later.") } @allerrors(app, 400, 401, 403, 404, 405, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 500, 501, 502, 503) def all_errors(e): error = e.code if hasattr(e, "code") else 500 title, description = errors[error if error in errors else 500] init_g(app) return render_template('error.html', code=str(error), title=title, description=description), error return app
def _setup_assets(self): global app global assets global pluginManager util.flask.fix_webassets_cache() util.flask.fix_webassets_filtertool() base_folder = settings().getBaseFolder("generated") # clean the folder if settings().getBoolean(["devel", "webassets", "clean_on_startup"]): import shutil import errno import sys for entry in ("webassets", ".webassets-cache"): path = os.path.join(base_folder, entry) # delete path if it exists if os.path.isdir(path): try: self._logger.debug("Deleting {path}...".format(**locals())) shutil.rmtree(path) except: self._logger.exception("Error while trying to delete {path}, leaving it alone".format(**locals())) continue # re-create path self._logger.debug("Creating {path}...".format(**locals())) error_text = "Error while trying to re-create {path}, that might cause errors with the webassets cache".format(**locals()) try: os.makedirs(path) except OSError as e: if e.errno == errno.EACCES: # that might be caused by the user still having the folder open somewhere, let's try again after # waiting a bit import time for n in range(3): time.sleep(0.5) self._logger.debug("Creating {path}: Retry #{retry} after {time}s".format(path=path, retry=n+1, time=(n + 1)*0.5)) try: os.makedirs(path) break except: if self._logger.isEnabledFor(logging.DEBUG): self._logger.exception("Ignored error while creating directory {path}".format(**locals())) pass else: # this will only get executed if we never did # successfully execute makedirs above self._logger.exception(error_text) continue else: # not an access error, so something we don't understand # went wrong -> log an error and stop self._logger.exception(error_text) continue except: # not an OSError, so something we don't understand # went wrong -> log an error and stop self._logger.exception(error_text) continue self._logger.info("Reset webasset folder {path}...".format(**locals())) AdjustedEnvironment = type(Environment)(Environment.__name__, (Environment,), dict( resolver_class=util.flask.PluginAssetResolver )) class CustomDirectoryEnvironment(AdjustedEnvironment): @property def directory(self): return base_folder assets = CustomDirectoryEnvironment(app) assets.debug = not settings().getBoolean(["devel", "webassets", "bundle"]) UpdaterType = type(util.flask.SettingsCheckUpdater)(util.flask.SettingsCheckUpdater.__name__, (util.flask.SettingsCheckUpdater,), dict( updater=assets.updater )) assets.updater = UpdaterType enable_gcodeviewer = settings().getBoolean(["gcodeViewer", "enabled"]) preferred_stylesheet = settings().get(["devel", "stylesheet"]) dynamic_assets = util.flask.collect_plugin_assets( enable_gcodeviewer=enable_gcodeviewer, preferred_stylesheet=preferred_stylesheet ) js_libs = [ "js/lib/jquery/jquery.min.js", "js/lib/modernizr.custom.js", "js/lib/lodash.min.js", "js/lib/sprintf.min.js", "js/lib/knockout-3.4.0.js", "js/lib/knockout.mapping-latest.js", "js/lib/babel.js", "js/lib/avltree.js", "js/lib/bootstrap/bootstrap.js", "js/lib/bootstrap/bootstrap-modalmanager.js", "js/lib/bootstrap/bootstrap-modal.js", "js/lib/bootstrap/bootstrap-slider.js", "js/lib/bootstrap/bootstrap-tabdrop.js", "js/lib/jquery/jquery.ui.core.js", "js/lib/jquery/jquery.ui.widget.js", "js/lib/jquery/jquery.ui.mouse.js", "js/lib/jquery/jquery.flot.js", "js/lib/jquery/jquery.iframe-transport.js", "js/lib/jquery/jquery.fileupload.js", "js/lib/jquery/jquery.slimscroll.min.js", "js/lib/jquery/jquery.qrcode.min.js", "js/lib/moment-with-locales.min.js", "js/lib/pusher.color.min.js", "js/lib/detectmobilebrowser.js", "js/lib/md5.min.js", "js/lib/pnotify.min.js", "js/lib/bootstrap-slider-knockout-binding.js", "js/lib/loglevel.min.js", "js/lib/sockjs-0.3.4.min.js" ] js_app = dynamic_assets["js"] + [ "js/app/dataupdater.js", "js/app/helpers.js", "js/app/main.js", ] css_libs = [ "css/bootstrap.min.css", "css/bootstrap-modal.css", "css/bootstrap-slider.css", "css/bootstrap-tabdrop.css", "css/font-awesome.min.css", "css/jquery.fileupload-ui.css", "css/pnotify.min.css" ] css_app = list(dynamic_assets["css"]) if len(css_app) == 0: css_app = ["empty"] less_app = list(dynamic_assets["less"]) if len(less_app) == 0: less_app = ["empty"] from webassets.filter import register_filter, Filter from webassets.filter.cssrewrite.base import PatternRewriter import re class LessImportRewrite(PatternRewriter): name = "less_importrewrite" patterns = { "import_rewrite": re.compile("(@import(\s+\(.*\))?\s+)\"(.*)\";") } def import_rewrite(self, m): import_with_options = m.group(1) import_url = m.group(3) if not import_url.startswith("http:") and not import_url.startswith("https:") and not import_url.startswith("/"): import_url = "../less/" + import_url return "{import_with_options}\"{import_url}\";".format(**locals()) class JsDelimiterBundle(Filter): name = "js_delimiter_bundler" options = {} def input(self, _in, out, **kwargs): out.write(_in.read()) out.write("\n;\n") register_filter(LessImportRewrite) register_filter(JsDelimiterBundle) js_libs_bundle = Bundle(*js_libs, output="webassets/packed_libs.js", filters="js_delimiter_bundler") if settings().getBoolean(["devel", "webassets", "minify"]): js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="rjsmin, js_delimiter_bundler") else: js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="js_delimiter_bundler") css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css") css_app_bundle = Bundle(*css_app, output="webassets/packed_app.css", filters="cssrewrite") all_less_bundle = Bundle(*less_app, output="webassets/packed_app.less", filters="cssrewrite, less_importrewrite") assets.register("js_libs", js_libs_bundle) assets.register("js_app", js_app_bundle) assets.register("css_libs", css_libs_bundle) assets.register("css_app", css_app_bundle) assets.register("less_app", all_less_bundle)
from flask.ext.assets import Environment, Bundle from webassets.filter import register_filter from webassets_libsass import LibSass register_filter(LibSass) assets = Environment() css = Bundle( 'css/main.scss', filters='libsass,cssmin', output='main.min.css', depends=['css/*.scss', 'css/*/*.scss']) assets.register('css', css) js = Bundle( 'js/vendor/jquery-1.11.3.min.js', 'js/vendor/underscore-min.js', Bundle( 'js/dd.js', 'js/admin/home.js', 'js/admin/bio.js', 'js/admin/gigs.js', 'js/admin/music.js', filters='rjsmin'), output='main.min.js') assets.register('js', js)
def replace_url(self, url): parsed = urlparse(url) if parsed.scheme or parsed.netloc: return url elif parsed.path.startswith('/'): # Prefix absolute urls with the base path. Like this we avoid # the mess that comes with relative URLs in CSS while still # supporting Indico running in a subdirectory (e.g. /indico) return self.base_url_path + url else: return super(IndicoCSSRewrite, self).replace_url(url) # XXX: DO NOT move this to decorators. this function returns None, # so super() calls using the decorated class name fail... register_filter(CSSCompressor) register_filter(IndicoCSSRewrite) def _get_htdocs_path(): return os.path.join(get_root_path('indico'), 'htdocs') def configure_pyscss(environment): base_url_path = urlparse(config.BASE_URL).path environment.config['PYSCSS_STYLE'] = 'compact' environment.config['PYSCSS_DEBUG_INFO'] = False environment.config['PYSCSS_STATIC_URL'] = '{0}/static/'.format( base_url_path) environment.config['PYSCSS_LOAD_PATHS'] = [ os.path.join(_get_htdocs_path(), 'sass', 'lib', 'compass'),
def _setup_assets(self): global app global assets global pluginManager util.flask.fix_webassets_cache() util.flask.fix_webassets_filtertool() base_folder = settings().getBaseFolder("generated") # clean the folder if settings().getBoolean(["devel", "webassets", "clean_on_startup"]): import shutil import errno import sys for entry in ("webassets", ".webassets-cache"): path = os.path.join(base_folder, entry) # delete path if it exists if os.path.isdir(path): try: self._logger.debug("Deleting {path}...".format(**locals())) shutil.rmtree(path) except: self._logger.exception("Error while trying to delete {path}, leaving it alone".format(**locals())) continue # re-create path self._logger.debug("Creating {path}...".format(**locals())) error_text = "Error while trying to re-create {path}, that might cause errors with the webassets cache".format(**locals()) try: os.makedirs(path) except OSError as e: if e.errno == errno.EACCES: # that might be caused by the user still having the folder open somewhere, let's try again after # waiting a bit import time for n in xrange(3): time.sleep(0.5) self._logger.debug("Creating {path}: Retry #{retry} after {time}s".format(path=path, retry=n+1, time=(n + 1)*0.5)) try: os.makedirs(path) break except: if self._logger.isEnabledFor(logging.DEBUG): self._logger.exception("Ignored error while creating directory {path}".format(**locals())) pass else: # this will only get executed if we never did # successfully execute makedirs above self._logger.exception(error_text) continue else: # not an access error, so something we don't understand # went wrong -> log an error and stop self._logger.exception(error_text) continue except: # not an OSError, so something we don't understand # went wrong -> log an error and stop self._logger.exception(error_text) continue self._logger.info("Reset webasset folder {path}...".format(**locals())) AdjustedEnvironment = type(Environment)(Environment.__name__, (Environment,), dict( resolver_class=util.flask.PluginAssetResolver )) class CustomDirectoryEnvironment(AdjustedEnvironment): @property def directory(self): return base_folder assets = CustomDirectoryEnvironment(app) assets.debug = not settings().getBoolean(["devel", "webassets", "bundle"]) UpdaterType = type(util.flask.SettingsCheckUpdater)(util.flask.SettingsCheckUpdater.__name__, (util.flask.SettingsCheckUpdater,), dict( updater=assets.updater )) assets.updater = UpdaterType enable_gcodeviewer = settings().getBoolean(["gcodeViewer", "enabled"]) preferred_stylesheet = settings().get(["devel", "stylesheet"]) dynamic_assets = util.flask.collect_plugin_assets( enable_gcodeviewer=enable_gcodeviewer, preferred_stylesheet=preferred_stylesheet ) js_libs = [ "js/lib/jquery/jquery.min.js", "js/lib/modernizr.custom.js", "js/lib/lodash.min.js", "js/lib/sprintf.min.js", "js/lib/knockout.js", "js/lib/knockout.mapping-latest.js", "js/lib/babel.js", "js/lib/avltree.js", "js/lib/bootstrap/bootstrap.js", "js/lib/bootstrap/bootstrap-modalmanager.js", "js/lib/bootstrap/bootstrap-modal.js", "js/lib/bootstrap/bootstrap-slider.js", "js/lib/bootstrap/bootstrap-tabdrop.js", "js/lib/jquery/jquery.ui.core.js", "js/lib/jquery/jquery.ui.widget.js", "js/lib/jquery/jquery.ui.mouse.js", "js/lib/jquery/jquery.flot.js", "js/lib/jquery/jquery.iframe-transport.js", "js/lib/jquery/jquery.fileupload.js", "js/lib/jquery/jquery.slimscroll.min.js", "js/lib/jquery/jquery.qrcode.min.js", "js/lib/moment-with-locales.min.js", "js/lib/pusher.color.min.js", "js/lib/detectmobilebrowser.js", "js/lib/md5.min.js", "js/lib/pnotify.min.js", "js/lib/bootstrap-slider-knockout-binding.js", "js/lib/loglevel.min.js", "js/lib/sockjs-0.3.4.min.js" ] js_app = dynamic_assets["js"] + [ "js/app/dataupdater.js", "js/app/helpers.js", "js/app/main.js", ] css_libs = [ "css/bootstrap.min.css", "css/bootstrap-modal.css", "css/bootstrap-slider.css", "css/bootstrap-tabdrop.css", "css/font-awesome.min.css", "css/jquery.fileupload-ui.css", "css/pnotify.min.css" ] css_app = list(dynamic_assets["css"]) if len(css_app) == 0: css_app = ["empty"] less_app = list(dynamic_assets["less"]) if len(less_app) == 0: less_app = ["empty"] from webassets.filter import register_filter, Filter from webassets.filter.cssrewrite.base import PatternRewriter import re class LessImportRewrite(PatternRewriter): name = "less_importrewrite" patterns = { "import_rewrite": re.compile("(@import(\s+\(.*\))?\s+)\"(.*)\";") } def import_rewrite(self, m): import_with_options = m.group(1) import_url = m.group(3) if not import_url.startswith("http:") and not import_url.startswith("https:") and not import_url.startswith("/"): import_url = "../less/" + import_url return "{import_with_options}\"{import_url}\";".format(**locals()) class JsDelimiterBundle(Filter): name = "js_delimiter_bundler" options = {} def input(self, _in, out, **kwargs): out.write(_in.read()) out.write("\n;\n") register_filter(LessImportRewrite) register_filter(JsDelimiterBundle) js_libs_bundle = Bundle(*js_libs, output="webassets/packed_libs.js", filters="js_delimiter_bundler") if settings().getBoolean(["devel", "webassets", "minify"]): js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="rjsmin, js_delimiter_bundler") else: js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="js_delimiter_bundler") css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css") css_app_bundle = Bundle(*css_app, output="webassets/packed_app.css", filters="cssrewrite") all_less_bundle = Bundle(*less_app, output="webassets/packed_app.less", filters="cssrewrite, less_importrewrite") assets.register("js_libs", js_libs_bundle) assets.register("js_app", js_app_bundle) assets.register("css_libs", css_libs_bundle) assets.register("css_app", css_app_bundle) assets.register("less_app", all_less_bundle)
out_fp.write(tmp_fp.read()) else: out.write(stdout.decode('utf-8')) finally: if output_file.created: os.unlink(output_file.filename) if input_file.created: os.unlink(input_file.filename) try: shutil.rmtree(tmpdir) except OSError: pass register_filter(UglifyJSSourceMap) def add_jinja2_ext(pelican): """Add Webassets to Jinja2 extensions in Pelican settings.""" if 'JINJA_ENVIRONMENT' in pelican.settings: # pelican 3.7+ pelican.settings['JINJA_ENVIRONMENT']['extensions'].append( AssetsExtension) else: pelican.settings['JINJA_EXTENSIONS'].append(AssetsExtension) def create_assets_env(generator): """Define the assets environment and pass it to the generator."""
Flask contexts. """ name = 'jinja2' max_debug_level = None def __init__(self, context=None): super(Jinja2Filter, self).__init__() self.context = context or {} def input(self, _in, out, source_path, output_path, **kw): out.write(render_template_string(_in.read(), **self.context)) # Override the built-in ``jinja2`` filter that ships with ``webassets``. This # custom filter uses Flask's ``render_template_string`` function to provide all # the standard Flask template context variables. register_filter(Jinja2Filter) class FlaskConfigStorage(ConfigStorage): """Uses the config object of a Flask app as the backend: either the app instance bound to the extension directly, or the current Flask app on the stack. Also provides per-application defaults for some values. Note that if no app is available, this config object is basically unusable - this is by design; this could also let the user set defaults by writing to a container not related to any app, which would be used as a fallback if a current app does not include a key. However, at least for now, I specifically made the choice to keep things simple and not allow global across-app defaults.
migrate = Migrate(app, db) manager = Manager(app) manager.add_command("db", MigrateCommand) # init SeaSurf seasurf = SeaSurf(app) # init flask CDN CDN(app) # init flask HTMLMIN HTMLMIN(app) # init assets environment assets = Environment(app) register_filter(BabiliFilter) class MiniJSONEncoder(JSONEncoder): """Minify JSON output.""" item_separator = ',' key_separator = ':' def default(self, obj): if isinstance(obj, datetime): return obj.isoformat()+"Z" # Let the base class default method raise the TypeError return JSONEncoder.default(self, obj) app.json_encoder = MiniJSONEncoder
if bundle is not None: bundles.append((name, version, bundle)) else: raise AssetNotFound(namespec) return bundles def require(self, *namespecs): """Return a bundle of the requested assets and their dependencies.""" blacklist = set([n[1:] for n in namespecs if n.startswith('!')]) not_blacklist = [n for n in namespecs if not n.startswith('!')] return Bundle(*[bundle for name, version, bundle in self._require_recursive(*not_blacklist) if name not in blacklist]) class UglipyJS(Filter): """ Minifies Javascript using UgliPyJS, the Python wrapper for UglifyJS. """ name = 'uglipyjs' def setup(self): import uglipyjs self.uglipyjs = uglipyjs def output(self, _in, out, **kw): out.write(six.text_type(self.uglipyjs.compile(_in.read()), 'utf-8')) register_filter(UglipyJS)
from flask import Blueprint, Flask from flask_assets import Bundle, Environment from flask_cors import CORS, cross_origin from flask_login import LoginManager from flask_migrate import Migrate from flask_oauthlib.client import OAuth from flask_restful import Api from flask_sqlalchemy import SQLAlchemy from webassets.filter import register_filter from webassets_browserify import Browserify from config import Config register_filter(Browserify) db = SQLAlchemy() api = Api() assets = Environment() login_manager = LoginManager() oauth = OAuth() spotify = oauth.remote_app( 'Spotify OAuth', consumer_key=Config.SPOTIFY_CLIENT_ID, consumer_secret=Config.SPOTIFY_CLIENT_SECRET, request_token_params={'scope': 'user-read-email'}, base_url='https://api.spotify.com/', request_token_url=None, access_token_method='POST', access_token_url='https://accounts.spotify.com/api/token', authorize_url='https://accounts.spotify.com/authorize',
def setup_class(cls): from webassets.filter import register_filter register_filter(BabelJSX)
def setup_class(cls): from webassets.filter import register_filter register_filter(CompileVueTemplate)
__all__ = ('PySCSSFilter',) class PySCSSFilter(Filter): """Compiles `Scss <http://sass-lang.org/>`_ markup to real CSS. Requires the ``pyScss`` package (http://pypi.python.org/pypi/pyScss/). Run: $ pip install pyScss """ name = 'apyscss' def setup(self): try: from scss.compiler import Compiler except ImportError: raise EnvironmentError('The "pyScss" package is not installed.') else: search_path = [ path.join(path.abspath(path.dirname(__file__)), 'static', 'scss') ] self.compiler = Compiler(search_path=search_path) def input(self, _in, out, **kw): out.write(self.compiler.compile_string(_in.read())) register_filter(PySCSSFilter)
# -*- coding: utf-8 -*- """ Assets bundles """ from webassets import Bundle # Register custom webasset filter for RCssMin minifier from webassets.filter import register_filter from rcssmin_webassets_filter import RCSSMin register_filter(RCSSMin) """ BASE BUNDLES, contains common app/components bundles, do not register your main bundles here. However you can comment/uncomment some app files for your needs. """ AVALAIBLE_BUNDLES = { # App bundle for Modernizr 'modernizr_f6_js': Bundle( "js/foundation6/vendor/modernizr.js", filters='closure_js', output='js/modernizr_f6.min.js' ), # Bundle for Foundation JAVASCRIPT stuff 'foundation6_js': Bundle( "js/foundation6/vendor/jquery.js", #"js/foundation6/vendor/motion-ui.js", "js/foundation6/vendor/what-input.js", 'js/foundation6/foundation/plugins/foundation.core.js', 'js/foundation6/foundation/plugins/foundation.util.box.js',
'load_paths': 'SASS_LOAD_PATHS', 'style': 'SASS_STYLE' } max_debug_level = None def _apply_sass(self, _in, out, cd=None): # Switch to source file directory if asked, so that this directory # is by default on the load path. We could pass it via -I, but then # files in the (undefined) wd could shadow the correct files. orig_cwd = os.getcwd() child_cwd = orig_cwd if cd: child_cwd = cd args = [self.binary or 'sass', '--stdin', '--style', self.style or 'expanded'] if (self.ctx.environment.debug if self.debug_info is None else self.debug_info): args.append('--trace') args.append('--no-quiet') for path in self.load_paths or []: if os.path.isabs(path): abs_path = path else: abs_path = self.resolve_path(path) args.extend(['-I', abs_path]) return self.subprocess(args, out, _in, cwd=child_cwd) register_filter(Sass)