def clean(self): compiler = Compiler(search_path=getattr(settings, 'SASS_SEARCH_PATHS', []), output_style='compressed' if self.minify else 'nested') try: self.output = compiler.compile_string(self.source) except (ValueError, SassSyntaxError) as e: import traceback ; traceback.print_exc() raise ValidationError({'source': str(e)})
def clean(self): compiler = Compiler( search_path=getattr(settings, 'SASS_SEARCH_PATHS', []), output_style='compressed' if self.minify else 'nested') try: self.output = compiler.compile_string(self.source) except (ValueError, SassSyntaxError) as e: import traceback traceback.print_exc() raise ValidationError({'source': str(e)})
class ScssMangler(Mangler): ''' Mangle SASS/SCSS. ''' def __init__(self, target, extensions=None, include_paths=None): super().__init__(target) self.extensions = extensions or ['.sass', '.scss'] self.include_paths = include_paths or [] self.compiler = Compiler(search_path=self.include_paths) def can_process(self, file_obj): return file_obj.current_name.suffix in self.extensions def process_file(self, file_obj): content = self.compiler.compile_string(file_obj.str) self.target.delete(file_obj.current_name) file_obj.str = content file_obj.current_name = file_obj.current_name.with_suffix('.css') yield file_obj
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()))
def parse_import_path(self, path): url_base = self.url_base url_map = self.url_map path = normalize_path(path) if path.find('!') >= 0 : path = path.split('!') prefix = path[0] if prefix in url_map: path = normalize_path(url_base + url_map[prefix] + path[1]) else: raise Exception('prefix not found ! (' + prefix + ')') else: path = url_base + path if os.path.isfile(path): fileext = os.path.splitext(path)[1] if fileext == '.js' and jsx: with open(path) as handler: content = handler.read().decode('utf-8') if self._match_jsx_notation(content): temp = tempfile.mkstemp(fileext) self._tempfile.append(temp) jsx.transform(path, temp[1]) path = temp[1] if fileext == '.scss' and SCSSCompiler: compiler = SCSSCompiler(search_path=(self.scss_root,)) temp = tempfile.mkstemp('.css') self._tempfile.append(temp) with open(path) as handler: content = handler.read().decode('utf-8') content = compiler.compile_string(content) os.write(temp[0], content.encode('utf-8')) path = temp[1] return path
def parse_import_path(self, path): url_base = self.url_base url_map = self.url_map path = normalize_path(path) if path.find('!') >= 0: path = path.split('!') prefix = path[0] if prefix in url_map: path = normalize_path(url_base + url_map[prefix] + path[1]) else: raise Exception('prefix not found ! (' + prefix + ')') else: path = url_base + path if os.path.isfile(path): fileext = os.path.splitext(path)[1] if fileext == '.js' and jsx: with open(path) as handler: content = handler.read() if self._match_jsx_notation(content): temp = tempfile.mkstemp(fileext) self._tempfile.append(temp) jsx.transform(path, temp[1]) path = temp[1] if fileext == '.scss' and SCSSCompiler: compiler = SCSSCompiler(search_path=(self.scss_root, )) temp = tempfile.mkstemp('.css') self._tempfile.append(temp) with open(path) as handler: content = handler.read() content = compiler.compile_string(content) os.write(temp[0], content.encode('utf-8')) path = temp[1] return path
class Scss(object): ''' Main and only class for Flask-Scss. It is in charge on the discovery of .scss files and compiles them every time they are modified. Any application that wants to use Flask-Scss must create a instance of this class ''' def __init__(self, app, static_dir=None, asset_dir=None, load_paths=None): ''' See :ref:`scss_discovery_rules` and :ref:`static_discovery_rules` for more information about the impact of ``static_dir`` and ``asset_dir`` parameters. Parameters here has preedence over Parameters found in the application config. :param app: Your Flask Application :param static_dir: The path to the ``static`` directory of your application (optional) :param asset_dir: The path to the ``assets`` directory where Flask-Scss will search ``.scss`` files (optional) :param load_paths: A list of folders to add to pyScss load_paths (for ex., the path to a library like Compass) ''' if not load_paths: load_paths = [] self.app = app self.asset_dir = self.set_asset_dir(asset_dir) self.static_dir = self.set_static_dir(static_dir) self.assets = {} self.partials = {} load_path_list = ([self.asset_dir] if self.asset_dir else []) \ + (load_paths or app.config.get('SCSS_LOAD_PATHS', [])) # pyScss.log = app.logger self.compiler = Compiler(search_path=load_path_list) if self.app.testing or self.app.debug: self.set_hooks() def set_asset_dir(self, asset_dir): asset_dir = asset_dir \ or self.app.config.get('SCSS_ASSET_DIR', None) \ or op.join(self.app.root_path, 'assets') if op.exists(op.join(asset_dir, 'scss')): return op.join(asset_dir, 'scss') if op.exists(asset_dir): return asset_dir return None def set_static_dir(self, static_dir): static_dir = static_dir \ or self.app.config.get('SCSS_STATIC_DIR', None) \ or op.join(self.app.root_path, self.app.static_folder) if op.exists(op.join(static_dir, 'css')): return op.join(static_dir, 'css') if op.exists(static_dir): return static_dir return None def set_hooks(self): if self.asset_dir is None: self.app.logger.warning("The asset directory cannot be found." "Flask-Scss extension has been disabled") return if self.static_dir is None: self.app.logger.warning("The static directory cannot be found." "Flask-Scss extension has been disabled") return self.app.logger.info("Pyscss loaded!") self.app.before_request(self.update_scss) def discover_scss(self): for folder, _, files in os.walk(self.asset_dir): for filename in fnmatch.filter(files, '*.scss'): src_path = op.join(folder, filename) if filename.startswith('_') and src_path not in self.partials: self.partials[src_path] = op.getmtime(src_path) elif src_path not in self.partials and src_path not in self.assets: dest_path = src_path.replace( self.asset_dir, self.static_dir ).replace('.scss', '.css') self.assets[src_path] = dest_path def partials_have_changed(self): res = False for partial, old_mtime in self.partials.items(): cur_mtime = op.getmtime(partial) if cur_mtime > old_mtime: res = True self.partials[partial] = cur_mtime return res def update_scss(self): self.discover_scss() if self.partials_have_changed(): for asset, dest_path in self.assets.items(): self.compile_scss(asset, dest_path) return for asset, dest_path in self.assets.items(): dest_mtime = op.getmtime(dest_path) \ if op.exists(dest_path) \ else -1 if op.getmtime(asset) > dest_mtime: self.compile_scss(asset, dest_path) def compile_scss(self, asset, dest_path): self.app.logger.info("[flask-pyscss] refreshing %s" % (dest_path,)) if not os.path.exists(op.dirname(dest_path)): os.makedirs(op.dirname(dest_path)) with codecs.open(dest_path, 'w', 'utf-8') as file_out: with open(asset) as file_in: file_out.write(self.compiler.compile_string(file_in.read()))
class Scss(object): ''' Main and only class for Flask-Scss. It is in charge on the discovery of .scss files and compiles them every time they are modified. Any application that wants to use Flask-Scss must create a instance of this class ''' def __init__(self, app, static_dir=None, asset_dir=None, load_paths=None): ''' See :ref:`scss_discovery_rules` and :ref:`static_discovery_rules` for more information about the impact of ``static_dir`` and ``asset_dir`` parameters. Parameters here has preedence over Parameters found in the application config. :param app: Your Flask Application :param static_dir: The path to the ``static`` directory of your application (optional) :param asset_dir: The path to the ``assets`` directory where Flask-Scss will search ``.scss`` files (optional) :param load_paths: A list of folders to add to pyScss load_paths (for ex., the path to a library like Compass) ''' if not load_paths: load_paths = [] self.app = app self.asset_dir = self.set_asset_dir(asset_dir) self.static_dir = self.set_static_dir(static_dir) self.assets = {} self.partials = {} load_path_list = ([self.asset_dir] if self.asset_dir else []) \ + (load_paths or app.config.get('SCSS_LOAD_PATHS', [])) # pyScss.log = app.logger self.compiler = Compiler(search_path=load_path_list) if self.app.testing or self.app.debug: self.set_hooks() def set_asset_dir(self, asset_dir): asset_dir = asset_dir \ or self.app.config.get('SCSS_ASSET_DIR', None) \ or op.join(self.app.root_path, 'assets') if op.exists(op.join(asset_dir, 'scss')): return op.join(asset_dir, 'scss') if op.exists(asset_dir): return asset_dir return None def set_static_dir(self, static_dir): static_dir = static_dir \ or self.app.config.get('SCSS_STATIC_DIR', None) \ or op.join(self.app.root_path, self.app.static_folder) if op.exists(op.join(static_dir, 'css')): return op.join(static_dir, 'css') if op.exists(static_dir): return static_dir return None def set_hooks(self): if self.asset_dir is None: self.app.logger.warning("The asset directory cannot be found." "Flask-Scss extension has been disabled") return if self.static_dir is None: self.app.logger.warning("The static directory cannot be found." "Flask-Scss extension has been disabled") return self.app.logger.info("Pyscss loaded!") self.app.before_request(self.update_scss) def discover_scss(self): for folder, _, files in os.walk(self.asset_dir): for filename in fnmatch.filter(files, '*.scss'): src_path = op.join(folder, filename) if filename.startswith('_') and src_path not in self.partials: self.partials[src_path] = op.getmtime(src_path) elif src_path not in self.partials and src_path not in self.assets: dest_path = src_path.replace(self.asset_dir, self.static_dir).replace( '.scss', '.css') self.assets[src_path] = dest_path def partials_have_changed(self): res = False for partial, old_mtime in self.partials.items(): cur_mtime = op.getmtime(partial) if cur_mtime > old_mtime: res = True self.partials[partial] = cur_mtime return res def update_scss(self): self.discover_scss() if self.partials_have_changed(): for asset, dest_path in self.assets.items(): self.compile_scss(asset, dest_path) return for asset, dest_path in self.assets.items(): dest_mtime = op.getmtime(dest_path) \ if op.exists(dest_path) \ else -1 if op.getmtime(asset) > dest_mtime: self.compile_scss(asset, dest_path) def compile_scss(self, asset, dest_path): self.app.logger.info("[flask-pyscss] refreshing %s" % (dest_path, )) if not os.path.exists(op.dirname(dest_path)): os.makedirs(op.dirname(dest_path)) with codecs.open(dest_path, 'w', 'utf-8') as file_out: with open(asset) as file_in: file_out.write(self.compiler.compile_string(file_in.read()))