roverdotcom/django-inlinecss

Fails with remote backends (eg S3)

Opened this issue · 5 comments

We use django-storages and S3/Cloudfront for our static resources due to the direct open call in https://github.com/roverdotcom/django-inlinecss/blob/master/django_inlinecss/templatetags/inlinecss.py#L30

File "django/template/base.py", line 830, in render
bit = self.render_node(node, context)
File "django/template/base.py", line 844, in render_node
return node.render(context)
File "django_inlinecss/templatetags/inlinecss.py", line 28, in render
expanded_path = staticfiles_storage.path(path)
File "django/core/files/storage.py", line 85, in path
raise NotImplementedError("This backend doesn't support absolute paths.")

Using staticfiles_storage.open (https://docs.djangoproject.com/en/dev/ref/files/storage/#django.core.files.storage.Storage.open) rather than path() + open is a possible solution

I've run into this as well - any other workarounds?

I was just perusing the project to see if I wanted to try it. Haven't run into the problem but it seems like it's because the file is not stored locally. Maybe then the cached s3 storage would work around it?

from storages.backends.s3boto import S3BotoStorage
class CachedS3BotoStorage(S3BotoStorage):
    """
    S3 storage backend that saves the files both remotely and locally.

    See http://django_compressor.readthedocs.org/en/latest/remote-storages/
    """
    def __init__(self, *args, **kwargs):
        super(CachedS3BotoStorage, self).__init__(*args, **kwargs)
        self.local_storage = get_storage_class(
            "django.core.files.storage.FileSystemStorage")()

    def save(self, name, content):
        name = super(CachedS3BotoStorage, self).save(name, content)
        self.local_storage._save(name, content)
        return name

@raverdotcom any update on this?

Fixed it by including local storage backend as well

class CachedS3BotoStorage(S3BotoStorage):
    """
    S3 storage backend that saves the files locally, too.

    It's needed for static files and django-compressor to get along :)
    """
    def __init__(self, *args, **kwargs):
        super(CachedS3BotoStorage, self).__init__(*args, **kwargs)
        self.local_storage = get_storage_class(
            "compressor.storage.CompressorFileStorage")()

    def save(self, name, content):
        """Save both on S3 and locally."""
        name = super(CachedS3BotoStorage, self).save(name, content)
        self.local_storage._save(name, content)
        return name

    def path(self, name):
        """
        Return absolute path as saved in local stoarge backend.

        Required by django-inlinecss.
        """
        return self.local_storage.path(name)

Adding that path() method to the cached storage backend causes other css files not to build for me.

This seems to be the right solution:

lukeburden@f3d74c1

staticfiles_storage.path() seems the wrong thing to use to find the css file. Finders are for finding static files. Many of the other recent forks of this project explore other ways of always using finders too. Here's where it was added. cc40f4b and 7771f98 Doesn't make sense to me.