def find(path=None): if path is None: folders = set() for blueprint in app.blueprints.values(): if blueprint.static_folder is not None: folders.update([blueprint.static_folder]) folders.update([app.static_folder]) return folders else: for rule in app.url_map.iter_rules(): if '.' in rule.endpoint: with_blueprint = True blueprint_name = rule.endpoint.rsplit('.', 1)[0] if blueprint_name not in app.blueprints: continue blueprint = app.blueprints[blueprint_name] data = rule.match(u('{subdomain}|{path}').format( subdomain=blueprint.subdomain or '', path=path, )) else: with_blueprint = False data = rule.match(u('|{0}').format(path)) if data: static_folder = blueprint.static_folder \ if with_blueprint and blueprint.static_folder is not None \ else app.static_folder return os.path.join(static_folder, data['filename']) raise IOError(2, u('File not found {0}.').format(path))
def find(path=None): if path is None: folders = set() for blueprint in app.blueprints.values(): if blueprint.static_folder is not None: folders.update([blueprint.static_folder]) folders.update([app.static_folder]) return folders else: for rule in app.url_map.iter_rules(): if '.' in rule.endpoint: with_blueprint = True blueprint_name = rule.endpoint.rsplit('.', 1)[0] if blueprint_name not in app.blueprints: continue blueprint = app.blueprints[blueprint_name] data = rule.match( u('{subdomain}|{path}').format( subdomain=blueprint.subdomain or '', path=path, )) else: with_blueprint = False data = rule.match(u('|{0}').format(path)) if data: static_folder = blueprint.static_folder \ if with_blueprint and blueprint.static_folder is not None \ else app.static_folder return os.path.join(static_folder, data['filename']) raise IOError(2, u('File not found {0}.').format(path))
def render_element(self, filename, type): """Returns an html element pointing to filename as a string. """ if type.lower() == 'css': return u('<link type="text/css" rel="stylesheet" href="{0}" />').format(filename) elif type.lower() == 'js': return u('<script type="text/javascript" src="{0}"></script>').format(filename) else: raise RuntimeError(u('Unsupported type of compression {0}').format(type))
def _display_block(self, compression_type, caller): html = caller() html_hash = self.compressor.make_hash(html) filename = os.path.join(u('{hash}.{extension}').format( hash=html_hash, extension=compression_type, )) static_prefix = u(self.compressor.config.compressor_static_prefix) return self.compressor.render_element(os.path.join(static_prefix, filename), compression_type)
def render_element(self, filename, type): """Returns an html element pointing to filename as a string. """ if type.lower() == 'css': return u('<link type="text/css" rel="stylesheet" href="{0}" />' ).format(filename) elif type.lower() == 'js': return u('<script type="text/javascript" src="{0}"></script>' ).format(filename) else: raise RuntimeError( u('Unsupported type of compression {0}').format(type))
def compile(cls, what, mimetype='text/less', cwd=None, uri_cwd=None, debug=None): args = [] if not debug: args += ['--compress'] if cwd: args += ['-ru'] args += ['--include-path={}'.format(cwd)] if uri_cwd: if not uri_cwd.endswith('/'): uri_cwd += '/' args += ['--rootpath={}'.format(uri_cwd)] if cls.extra_args: args.extend(cls.extra_args) args += ['-'] args.insert(0, cls.binary) try: handler = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None) except OSError as e: msg = '{0} encountered an error when executing {1}: {2}'.format( cls.__name__, cls.binary, u(e), ) if e.errno == errno.ENOENT: msg += ' Make sure {0} is in your PATH.'.format(cls.binary) raise InvalidCompressorError(msg) if isinstance(what, file): what = what.read() (stdout, stderr) = handler.communicate(input=utf8_encode(what)) stdout = u(stdout) if handler.returncode == 0: return stdout else: raise RuntimeError('Test this :S %s' % stderr)
def compile(cls, what, mimetype='text/less', cwd=None, uri_cwd=None, debug=None): args = ['lessc'] if not debug: args += ['--compress'] if cwd: args += ['-ru'] args += ['--include-path={}'.format(cwd)] if uri_cwd: if not uri_cwd.endswith('/'): uri_cwd += '/' args += ['--rootpath={}'.format(uri_cwd)] args += ['-'] handler = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None) if isinstance(what, file): what = what.read() (stdout, stderr) = handler.communicate(input=utf8_encode(what)) stdout = u(stdout) if handler.returncode == 0: return stdout else: raise RuntimeError('Test this :S %s' % stderr)
def compile(cls, what, mimetype='text/sass', cwd=None, uri_cwd=None, debug=None): args = ['sass', '-s'] if mimetype == 'text/scss': args.append('--scss') if cwd: args += ['-I', cwd] handler = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None) if isinstance(what, file): what = what.read() (stdout, stderr) = handler.communicate(input=utf8_encode(what)) stdout = u(stdout) if handler.returncode == 0: return stdout else: raise RuntimeError('Test this :S %s' % stderr)
def compile(cls, what, mimetype='text/coffeescript', cwd=None, uri_cwd=None, debug=None): args = ['coffee', '--compile', '--stdio'] handler = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None) if isinstance(what, file): what = what.read() (stdout, stderr) = handler.communicate(input=utf8_encode(what)) stdout = u(stdout) if not debug: stdout = jsmin(stdout) if handler.returncode == 0: return stdout else: raise RuntimeError('Test this :S %s' % stderr)
def find_compilable_tags(self, soup): tags = ['link', 'style', 'script'] for tag in soup.find_all(tags): # don't compress externally hosted assets src = tag.get('src') or tag.get('href') if src and (src.startswith('http') or src.startswith('//')): continue if tag.get('type') is None: if tag.name == 'script': tag['type'] = 'text/javascript' if tag.name == 'style': tag['type'] = 'text/css' else: tag['type'] == tag['type'].lower() if tag.get('type') is None: raise RuntimeError( u('Tags to be compressed must have a type attribute: {0}'). format(u(tag))) yield tag
def find_file(self, path): if callable(self.config.compressor_source_dirs): filename = self.config.compressor_source_dirs(path) if os.path.exists(filename): return filename else: if isinstance(self.config.compressor_source_dirs, basestring): dirs = [self.config.compressor_source_dirs] else: dirs = self.config.compressor_source_dirs for d in dirs: if self.config.compressor_static_prefix_precompress is not None and path.startswith('/'): path = path.replace(self.config.compressor_static_prefix_precompress, '', 1).lstrip(os.sep).lstrip('/') filename = os.path.join(d, path) if os.path.exists(filename): return filename raise IOError(2, u('File not found {0}').format(path))
def find_compilable_tags(self, soup): tags = ['link', 'style', 'script'] for tag in soup.find_all(tags): # don't compress externally hosted assets src = tag.get('src') or tag.get('href') if src and (src.startswith('http') or src.startswith('//')): continue if tag.get('type') is None: if tag.name == 'script': tag['type'] = 'text/javascript' if tag.name == 'style': tag['type'] = 'text/css' else: tag['type'] == tag['type'].lower() if tag.get('type') is None: raise RuntimeError(u('Tags to be compressed must have a type attribute: {0}').format(u(tag))) yield tag
def compile(cls, what, mimetype="text/coffeescript", cwd=None, uri_cwd=None, debug=None): args = ["coffee", "--compile", "--stdio"] handler = subprocess.Popen( args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, cwd=None ) if isinstance(what, file): what = what.read() (stdout, stderr) = handler.communicate(input=utf8_encode(what)) stdout = u(stdout) if not debug: stdout = jsmin(stdout) if handler.returncode == 0: return stdout else: raise RuntimeError("Test this :S %s" % stderr)
def find_file(self, path): if callable(self.config.compressor_source_dirs): filename = self.config.compressor_source_dirs(path) if os.path.exists(filename): return filename else: if isinstance(self.config.compressor_source_dirs, basestring): dirs = [self.config.compressor_source_dirs] else: dirs = self.config.compressor_source_dirs for d in dirs: if self.config.compressor_static_prefix_precompress is not None and path.startswith( '/'): path = path.replace(self.config.compressor_static_prefix_precompress, '', 1).\ lstrip(os.sep).lstrip('/') filename = os.path.join(d, path) if os.path.exists(filename): return filename raise IOError(2, u('File not found {0}').format(path))
def compress(self, html, compression_type): if not self.config.compressor_enabled: return html compression_type = compression_type.lower() html_hash = self.make_hash(html) if not os.path.exists(u(self.config.compressor_output_dir)): os.makedirs(u(self.config.compressor_output_dir)) cached_file = os.path.join( u(self.config.compressor_output_dir), u('{hash}.{extension}').format( hash=html_hash, extension=compression_type, ), ) if os.path.exists(cached_file): filename = os.path.join( u(self.config.compressor_static_prefix), os.path.basename(cached_file), ) return self.render_element(filename, compression_type) assets = OrderedDict() soup = BeautifulSoup(html, PARSER) for count, c in enumerate(self.find_compilable_tags(soup)): url = c.get('src') or c.get('href') if url: filename = os.path.basename(u(url)).split('.', 1)[0] uri_cwd = os.path.join(u(self.config.compressor_static_prefix), os.path.dirname(u(url))) text = open(self.find_file(u(url)), 'r', encoding='utf-8') cwd = os.path.dirname(text.name) else: filename = u('inline{0}').format(count) uri_cwd = None text = c.string cwd = None mimetype = c['type'].lower() try: compressor = self.config.compressor_classes[mimetype] except KeyError: msg = u('Unsupported type of compression {0}').format(mimetype) raise RuntimeError(msg) text = self.get_contents(text) compressed = compressor.compile(text, mimetype=mimetype, cwd=cwd, uri_cwd=uri_cwd, debug=self.config.compressor_debug) if not self.config.compressor_debug: outfile = cached_file else: outfile = os.path.join( u(self.config.compressor_output_dir), u('{hash}-{filename}.{extension}').format( hash=html_hash, filename=filename, extension=compression_type, ), ) if assets.get(outfile) is None: assets[outfile] = u('') assets[outfile] += u("\n") + compressed blocks = u('') for outfile, asset in assets.items(): with open(outfile, 'w', encoding='utf-8') as fh: fh.write(asset) filename = os.path.join( u(self.config.compressor_static_prefix), os.path.basename(outfile), ) blocks += self.render_element(filename, compression_type) return blocks
def get_contents(self, src): if isinstance(src, file): return u(src.read()) else: return u(src)
def _display_block(self, compression_type, caller): html = caller() html_hash = self.compressor.make_hash(html) filename = os.path.join(u("{hash}.{extension}").format(hash=html_hash, extension=compression_type)) static_prefix = u(self.compressor.config.compressor_static_prefix) return self.compressor.render_element(os.path.join(static_prefix, filename), compression_type)
def compress(self, html, compression_type): if not self.config.compressor_enabled: return html compression_type = compression_type.lower() html_hash = self.make_hash(html) if not os.path.exists(u(self.config.compressor_output_dir)): os.makedirs(u(self.config.compressor_output_dir)) cached_file = os.path.join( u(self.config.compressor_output_dir), u('{hash}.{extension}').format( hash=html_hash, extension=compression_type, ), ) if os.path.exists(cached_file): filename = os.path.join( u(self.config.compressor_static_prefix), os.path.basename(cached_file), ) return self.render_element(filename, compression_type) assets = OrderedDict() soup = BeautifulSoup(html) for count, c in enumerate(self.find_compilable_tags(soup)): url = c.get('src') or c.get('href') if url: filename = os.path.basename(u(url)).split('.', 1)[0] uri_cwd = os.path.join(u(self.config.compressor_static_prefix), os.path.dirname(u(url))) text = open(self.find_file(u(url)), 'r', encoding='utf-8') cwd = os.path.dirname(text.name) else: filename = u('inline{0}').format(count) uri_cwd = None text = c.string cwd = None mimetype = c['type'].lower() try: compressor = self.config.compressor_classes[mimetype] except KeyError: msg = u('Unsupported type of compression {0}').format(mimetype) raise RuntimeError(msg) text = self.get_contents(text) compressed = compressor.compile(text, mimetype=mimetype, cwd=cwd, uri_cwd=uri_cwd, debug=self.config.compressor_debug) if not self.config.compressor_debug: outfile = cached_file else: outfile = os.path.join( u(self.config.compressor_output_dir), u('{hash}-{filename}.{extension}').format( hash=html_hash, filename=filename, extension=compression_type, ), ) if assets.get(outfile) is None: assets[outfile] = u('') assets[outfile] += u("\n") + compressed blocks = u('') for outfile, asset in assets.items(): with open(outfile, 'w', encoding='utf-8') as fh: fh.write(asset) filename = os.path.join( u(self.config.compressor_static_prefix), os.path.basename(outfile), ) blocks += self.render_element(filename, compression_type) return blocks