Esempio n. 1
0
 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)})
Esempio n. 2
0
 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)})
Esempio n. 3
0
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
Esempio n. 4
0
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()))
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
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()))
Esempio n. 8
0
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()))