from __future__ import absolute_import import os from pathlib import PurePath from django.utils.six.moves import StringIO from django.conf import settings from django.contrib.staticfiles.storage import staticfiles_storage from scss import Compiler, config from scss.extension.compass import CompassExtension from scss.source import SourceFile from .extension.django import DjangoExtension from .utils import find_all_files, get_file_and_storage # TODO: It's really gross to modify this global settings variable. # This is where PyScss is supposed to find the image files for making sprites. config.STATIC_ROOT = find_all_files config.STATIC_URL = staticfiles_storage.url('scss/') # This is where PyScss places the sprite files. config.ASSETS_ROOT = os.path.join(settings.STATIC_ROOT, 'scss', 'assets') # PyScss expects a trailing slash. config.ASSETS_URL = staticfiles_storage.url('scss/assets/') class DjangoScssCompiler(Compiler): def __init__(self, **kwargs): kwargs.setdefault('extensions', (DjangoExtension, CompassExtension)) if not os.path.exists(config.ASSETS_ROOT): os.makedirs(config.ASSETS_ROOT) super(DjangoScssCompiler, self).__init__(**kwargs) def compile(self, *paths): compilation = self.make_compilation() for path in paths: path = PurePath(path) if path.is_absolute(): path = path.relative_to('/') filename, storage = get_file_and_storage(str(path)) with storage.open(filename) as f: source = SourceFile.from_file(f, origin=path.parent, relpath=PurePath(path.name)) compilation.add_source(source) return self.call_and_catch_errors(compilation.run) def compile_string(self, string, filename=None): compilation = self.make_compilation() if filename is not None: f = StringIO(string) filename = PurePath(filename) source = SourceFile.from_file(f, origin=filename.parent, relpath=PurePath(filename.name)) else: source = SourceFile.from_string(string) compilation.add_source(source) return self.call_and_catch_errors(compilation.run)