Skip to content

Commit d83c984

Browse files
gdixonthelostone-mc
authored andcommitted
Fixes offline-compression and updates static storage mechanism
1 parent 7f06998 commit d83c984

File tree

6 files changed

+40
-47
lines changed

6 files changed

+40
-47
lines changed

app/app/settings.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,15 +212,19 @@
212212
if ENV not in ['local', 'test', 'staging', 'preview']:
213213
# compress offline (use './manage.py compress' to build manifest.json)
214214
COMPRESS_OFFLINE = True
215-
# content based hashing
215+
# Allow for the full path (url) to be included in the manifest
216+
COMPRESS_INCLUDE_URLS = True
217+
# Allow the placeholder insertion to be skipped
218+
COMPRESS_SKIP_PLACEHOLDER = True
219+
# use content based hashing so that we always match between servers
216220
COMPRESS_CSS_HASHING_METHOD = 'content'
217-
# drop line comments
218-
LIBSASS_SOURCE_COMMENTS = False
219221
# minification of sass output
220222
COMPRESS_CSS_FILTERS = [
221223
'compressor.filters.css_default.CssAbsoluteFilter',
222224
'compressor.filters.cssmin.rCSSMinFilter'
223225
]
226+
# drop line comments
227+
LIBSASS_SOURCE_COMMENTS = False
224228

225229
SITE_ID = env.int('SITE_ID', default=1)
226230
WSGI_APPLICATION = env('WSGI_APPLICATION', default='app.wsgi.application')

app/app/static_storage.py

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,44 @@
11
# -*- coding: utf-8 -*-
22
"""Define the custom static storage to surpress bad URL references."""
33
import os
4+
from datetime import datetime
45
from os.path import basename
56
from secrets import token_hex
67

78
from django.conf import settings
9+
from django.contrib.staticfiles.storage import HashedFilesMixin
810
from django.core.files.storage import get_storage_class
9-
from django.contrib.staticfiles.storage import ManifestFilesMixin, HashedFilesMixin
1011

11-
from storages.backends.s3boto3 import S3Boto3Storage, SpooledTemporaryFile
12+
from storages.backends.s3boto3 import S3ManifestStaticStorage, S3StaticStorage
1213

1314

14-
class SilentFileStorage(ManifestFilesMixin, S3Boto3Storage):
15+
class SilentFileStorage(S3ManifestStaticStorage, S3StaticStorage):
1516
"""Define the static storage using S3 via boto3 with hashing.
1617
1718
If Django cannot find a referenced url in an asset, it will silently pass.
1819
1920
"""
2021

2122
location = settings.STATICFILES_LOCATION
23+
bucket_name = settings.AWS_STORAGE_BUCKET_NAME
24+
custom_domain = settings.AWS_S3_CUSTOM_DOMAIN
2225

2326
def __init__(self, *args, **kwargs):
24-
kwargs['bucket'] = settings.AWS_STORAGE_BUCKET_NAME
25-
kwargs['custom_domain'] = settings.AWS_S3_CUSTOM_DOMAIN
26-
# Init S3Boto3Storage and ManifestFilesMixin to send assets to S3
27+
# Init S3StaticStorage and S3ManifestStaticStorage to send assets to S3
2728
super(SilentFileStorage, self).__init__(*args, **kwargs)
2829
# Init CompressorFileStorage to save local copies for compressor
2930
self.local_storage = get_storage_class("compressor.storage.CompressorFileStorage")()
3031
# Init HashedFilesMixin to get filenames with hashes present
3132
self.local_hashes = HashedFilesMixin()
3233

33-
def _save_content(self, obj, content, parameters):
34-
"""Create a clone of the content file to avoid premature closure.
35-
36-
When this is passed to boto3 it wrongly closes the file upon upload
37-
where as the storage backend expects it to still be open.
38-
39-
"""
40-
# Seek our content back to the start
41-
content.seek(0, os.SEEK_SET)
42-
43-
# Create a temporary file that will write to disk after a specified size
44-
content_autoclose = SpooledTemporaryFile()
45-
46-
# Write our original content into our copy that will be closed by boto3
47-
content_autoclose.write(content.read())
48-
49-
# Upload the object which will auto close the content_autoclose instance
50-
super(SilentFileStorage, self)._save_content(obj, content_autoclose, parameters)
51-
52-
# Cleanup if this is fixed upstream our duplicate should always close
53-
if not content_autoclose.closed:
54-
content_autoclose.close()
55-
5634
def save(self, name, content):
57-
# record the clean file content (pre gzip)
35+
"""Save both a local and a remote copy of the given file"""
36+
# Record the clean file content (pre gzip)
5837
file_content = content.file
5938
# Save remote copy to S3
60-
super(SilentFileStorage, self).save(name, content)
61-
# Only save .scss and .js files locally
62-
if ".scss" in name or ".js" in name:
39+
super(SilentFileStorage, self).save(name, content)
40+
# Only save files that are part of the compress blocks locally
41+
if ".scss" in name or ".js" in name or ".css" in name:
6342
# restore the clean file_content
6443
content.file = file_content
6544
# Save a local copy for compressor
@@ -68,6 +47,19 @@ def save(self, name, content):
6847
self.local_storage._save(self.local_hashes.hashed_name(name, content), content)
6948
return name
7049

50+
def exists(self, name):
51+
"""Check if the named file exists in S3 storage"""
52+
# Check file exists on S3
53+
exists = super(SilentFileStorage, self).exists(name)
54+
# This is a hack to get a status report during S3ManifestStaticStorage._postProcess
55+
print("INFO " + datetime.now().strftime("%Y-%m-%d %H:%M:%S") +
56+
" - Checking for matching file hash on S3 - " + name + ": " + (
57+
"Skipping based on matching file hashes" if exists else "Hashes did not match"
58+
)
59+
)
60+
return exists
61+
62+
7163
def url(self, name, force=True):
7264
"""Handle catching bad URLs and return the name if route is unavailable."""
7365
try:
@@ -84,17 +76,13 @@ def _url(self, hashed_name_func, name, force=True, hashed_files=None):
8476
return name
8577

8678

87-
class MediaFileStorage(S3Boto3Storage):
79+
class MediaFileStorage(S3StaticStorage):
8880
"""Define the media storage backend for user uploaded/stored files."""
8981

9082
location = settings.MEDIAFILES_LOCATION
83+
bucket_name = settings.MEDIA_BUCKET
84+
custom_domain = settings.MEDIA_CUSTOM_DOMAIN
9185

9286
def __init__(self, *args, **kwargs):
93-
kwargs['bucket'] = settings.MEDIA_BUCKET
94-
kwargs['custom_domain'] = settings.MEDIA_CUSTOM_DOMAIN
9587
# Save media to S3 only (we dont need an additional local copy)
9688
super(MediaFileStorage, self).__init__(*args, **kwargs)
97-
98-
99-
def get_salted_path(instance, filename):
100-
return f'assets/{token_hex(16)[:15]}/{basename(filename)}'

app/assets/v2/scss/test1.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
$bg-color: green;
1+
$bg-color: rgb(49, 230, 49);
22

33
@import './test2.scss';

app/assets/v2/scss/test2.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
body {
22
background: $bg-color;
33
& > div:after {
4+
font-weight: bold;
45
content: "working"
56
}
6-
}
7+
}

app/retail/templates/home/sass_experiment.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<div></div>
2323
{% compress js file testing %}
2424
<script>
25-
alert('testing');
25+
alert('This has been changed: working');
2626
</script>
2727
{% endcompress %}
2828
</body>

requirements/base.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ watchdog==0.9.0
5858
Werkzeug[watchdog]==0.15.5
5959
imageio
6060
boto3==1.7.81
61-
django-storages==1.6.6
61+
django-storages==1.11.1
6262
easy-thumbnails==2.5
6363
eth-account==0.2.2
6464
django-classy-tags==0.8.0

0 commit comments

Comments
 (0)