mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-23 07:46:23 -04:00
Use asset fingerprinter to serve images
This means we can cache them forever, and only invalidate the cache when the image changes.
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
import codecs
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
@@ -37,11 +36,11 @@ class AssetFingerprinter(object):
|
|||||||
|
|
||||||
def get_asset_fingerprint(self, asset_file_path):
|
def get_asset_fingerprint(self, asset_file_path):
|
||||||
return hashlib.md5(
|
return hashlib.md5(
|
||||||
self.get_asset_file_contents(asset_file_path).encode('utf-8')
|
self.get_asset_file_contents(asset_file_path)
|
||||||
).hexdigest()
|
).hexdigest()
|
||||||
|
|
||||||
def get_asset_file_contents(self, asset_file_path):
|
def get_asset_file_contents(self, asset_file_path):
|
||||||
with codecs.open(asset_file_path, encoding='utf-8') as asset_file:
|
with open(asset_file_path, 'rb') as asset_file:
|
||||||
contents = asset_file.read()
|
contents = asset_file.read()
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
{% for option in form.options %}
|
{% for option in form.options %}
|
||||||
<div class="column-one-quarter">
|
<div class="column-one-quarter">
|
||||||
<label for="{{ option.id }}">
|
<label for="{{ option.id }}">
|
||||||
<img src="{{ asset_path }}images/branding-options/{{ option.data }}.png" alt="" class="bordered-image bottom-gutter-1-3">
|
<img src="{{ asset_url('images/branding-options/{}.png'.format(option.data)) }}" alt="" class="bordered-image bottom-gutter-1-3">
|
||||||
</label>
|
</label>
|
||||||
{{ radio(option) }}
|
{{ radio(option) }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="column-half">
|
<div class="column-half">
|
||||||
<img src="{{ asset_path }}images/product/01-templates.svg" alt="">
|
<img src="{{ asset_url('images/product/01-templates.svg') }}" alt="">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="column-half">
|
<div class="column-half">
|
||||||
<img
|
<img
|
||||||
src="{{ asset_path }}images/product/02-reporting.svg"
|
src="{{ asset_url('images/product/02-reporting.svg') }}"
|
||||||
alt="A screenshot of GOV.UK Notify showing counts of emails and text messages sent"
|
alt="A screenshot of GOV.UK Notify showing counts of emails and text messages sent"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
phone numbers and Notify sends the messages.
|
phone numbers and Notify sends the messages.
|
||||||
</p>
|
</p>
|
||||||
<img
|
<img
|
||||||
src="{{ asset_path }}images/product/03-spreadsheet.svg"
|
src="{{ asset_url('images/product/03-spreadsheet.svg') }}"
|
||||||
alt="A screenshot of a spreadsheet with columns for email address, name and colour"
|
alt="A screenshot of a spreadsheet with columns for email address, name and colour"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
back office system.
|
back office system.
|
||||||
</p>
|
</p>
|
||||||
<img
|
<img
|
||||||
src="{{ asset_path }}images/product/04-api.svg"
|
src="{{ asset_url('images/product/04-api.svg') }}"
|
||||||
alt="A screenshot of some computer code with a notify.send_email function"
|
alt="A screenshot of some computer code with a notify.send_email function"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="column-half">
|
<div class="column-half">
|
||||||
<img
|
<img
|
||||||
src="{{ asset_path }}images/product/team.jpg"
|
src="{{ asset_url('images/product/team.jpg') }}"
|
||||||
alt="A photo of the GOV.UK Notify team gathered around a big screen. One team member is pointing at a graph on the screen."
|
alt="A photo of the GOV.UK Notify team gathered around a big screen. One team member is pointing at a graph on the screen."
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<h2 id="messagedeliveryandfailure" class="heading-medium">Sending messages</h2>
|
<h2 id="messagedeliveryandfailure" class="heading-medium">Sending messages</h2>
|
||||||
<p>When you send a message, it moves through different states in Notify.</p>
|
<p>When you send a message, it moves through different states in Notify.</p>
|
||||||
<img
|
<img
|
||||||
src="{{ asset_path }}images/message-sending-flow.svg"
|
src="{{ asset_url('images/message-sending-flow.svg') }}"
|
||||||
alt="A picture of the sending flow of messages in Notify, showing the three states of Sending, Delivered, And Failed. Also shows the next
|
alt="A picture of the sending flow of messages in Notify, showing the three states of Sending, Delivered, And Failed. Also shows the next
|
||||||
steps when messages fail, deleting data and trying a new channel for permanent failures, and trying again or trying a new channel for
|
steps when messages fail, deleting data and trying a new channel for permanent failures, and trying again or trying a new channel for
|
||||||
temporary failures"
|
temporary failures"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class TestAssetFingerprint(object):
|
|||||||
body {
|
body {
|
||||||
font-family: nta;
|
font-family: nta;
|
||||||
}
|
}
|
||||||
"""
|
""".encode('utf-8')
|
||||||
asset_fingerprinter = AssetFingerprinter(
|
asset_fingerprinter = AssetFingerprinter(
|
||||||
asset_root='/suppliers/static/'
|
asset_root='/suppliers/static/'
|
||||||
)
|
)
|
||||||
@@ -27,7 +27,7 @@ class TestAssetFingerprint(object):
|
|||||||
get_file_content_mock = mocker.patch.object(AssetFingerprinter, 'get_asset_file_contents')
|
get_file_content_mock = mocker.patch.object(AssetFingerprinter, 'get_asset_file_contents')
|
||||||
get_file_content_mock.return_value = """
|
get_file_content_mock.return_value = """
|
||||||
document.write('Hello world!');
|
document.write('Hello world!');
|
||||||
"""
|
""".encode('utf-8')
|
||||||
fingerprinter = AssetFingerprinter()
|
fingerprinter = AssetFingerprinter()
|
||||||
fingerprinter.get_url('javascripts/application.js')
|
fingerprinter.get_url('javascripts/application.js')
|
||||||
fingerprinter.get_asset_file_contents.assert_called_with(
|
fingerprinter.get_asset_file_contents.assert_called_with(
|
||||||
@@ -40,7 +40,7 @@ class TestAssetFingerprint(object):
|
|||||||
body {
|
body {
|
||||||
font-family: nta;
|
font-family: nta;
|
||||||
}
|
}
|
||||||
"""
|
""".encode('utf-8')
|
||||||
asset_fingerprinter = AssetFingerprinter()
|
asset_fingerprinter = AssetFingerprinter()
|
||||||
assert (
|
assert (
|
||||||
asset_fingerprinter.get_asset_fingerprint('application.css') ==
|
asset_fingerprinter.get_asset_fingerprint('application.css') ==
|
||||||
@@ -56,11 +56,11 @@ class TestAssetFingerprint(object):
|
|||||||
body {
|
body {
|
||||||
font-family: nta;
|
font-family: nta;
|
||||||
}
|
}
|
||||||
"""
|
""".encode('utf-8')
|
||||||
css_hash = asset_fingerprinter.get_asset_fingerprint('application.css')
|
css_hash = asset_fingerprinter.get_asset_fingerprint('application.css')
|
||||||
get_file_content_mock.return_value = """
|
get_file_content_mock.return_value = """
|
||||||
document.write('Hello world!');
|
document.write('Hello world!');
|
||||||
"""
|
""".encode('utf-8')
|
||||||
js_hash = asset_fingerprinter.get_asset_fingerprint('application.js')
|
js_hash = asset_fingerprinter.get_asset_fingerprint('application.js')
|
||||||
assert (
|
assert (
|
||||||
js_hash != css_hash
|
js_hash != css_hash
|
||||||
@@ -72,7 +72,7 @@ class TestAssetFingerprint(object):
|
|||||||
body {
|
body {
|
||||||
font-family: nta;
|
font-family: nta;
|
||||||
}
|
}
|
||||||
"""
|
""".encode('utf-8')
|
||||||
fingerprinter = AssetFingerprinter()
|
fingerprinter = AssetFingerprinter()
|
||||||
assert (
|
assert (
|
||||||
fingerprinter.get_url('application.css') ==
|
fingerprinter.get_url('application.css') ==
|
||||||
|
|||||||
Reference in New Issue
Block a user