summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/builder/sanitizer.py60
-rw-r--r--app/lib/templatetags/templatetags/amp.py39
-rw-r--r--design/sass/_writing_details.scss18
-rw-r--r--design/templates/details/entry.amp14
4 files changed, 114 insertions, 17 deletions
diff --git a/app/builder/sanitizer.py b/app/builder/sanitizer.py
new file mode 100644
index 0000000..8512f4f
--- /dev/null
+++ b/app/builder/sanitizer.py
@@ -0,0 +1,60 @@
+from bs4 import BeautifulSoup
+
+
+class Sanitizer(object):
+ blacklisted_tags = []
+ blacklisted_attributes = []
+ blacklisted_protocols = []
+
+ def __init__(self, tags=None, attributes=None, protocols=None):
+ if tags:
+ self.blacklisted_tags = tags
+ if attributes:
+ self.blacklisted_attributes = attributes
+ if protocols:
+ self.blacklisted_protocols = protocols
+
+ def strip(self, content=None):
+ """Strip HTML content to meet standards of output type.
+ Meant to be subclassed for each converter.
+
+ Keyword arguments:
+ content -- subset of an HTML document. (ie. contents of a body tag)
+ """
+ if not content:
+ content = self.content
+ return content
+
+ soup = BeautifulSoup(content, "lxml")
+ self.strip_tags(soup)
+ self.strip_attributes(soup)
+
+ output = soup.body.decode_contents()
+ return output
+
+ def strip_tags(self, soup):
+ if self.blacklisted_tags:
+ [x.extract() for x in soup.find_all(self.blacklisted_tags)]
+
+ def strip_attributes_extra(self, node):
+ pass
+
+ def strip_attributes(self, soup):
+ if not (self.blacklisted_attributes or self.blacklisted_protocols):
+ return
+
+ for node in soup.body.find_all(True):
+ attributes = node.attrs.keys()
+ if not attributes:
+ continue
+
+ for attr in self.blacklisted_attributes:
+ if attr in attributes:
+ del node.attrs[attr]
+
+ self.strip_attributes_extra(node)
+
+ if 'href' in attributes:
+ protocol = node['href'].split(':')[0]
+ if protocol in self.blacklisted_protocols:
+ del node['href'] \ No newline at end of file
diff --git a/app/lib/templatetags/templatetags/amp.py b/app/lib/templatetags/templatetags/amp.py
new file mode 100644
index 0000000..9c6f118
--- /dev/null
+++ b/app/lib/templatetags/templatetags/amp.py
@@ -0,0 +1,39 @@
+from django import template
+from PIL import Image
+from io import BytesIO
+try:
+ import Image
+ import ImageFile
+except ImportError:
+ try:
+ from PIL import Image
+ from PIL import ImageFile
+ except ImportError:
+ raise ImportError("Could not import the Python Imaging Library.")
+
+import requests
+from bs4 import BeautifulSoup
+from builder.sanitizer import Sanitizer
+
+register = template.Library()
+
+
+def remove_img_tags(text):
+ soup = BeautifulSoup(text, 'xml')
+ for img in soup.find_all('img'):
+ r = requests.get(img['src'])
+ i = Image.open(BytesIO(r.content))
+ width, height = i.size
+ try:
+ new_tag = soup.new_tag("amp-img", alt=img["alt"], width=width, height=height, src=img['src'], srcset=img['srcset'])
+ except:
+ new_tag = soup.new_tag("amp-img", alt=img["alt"], width=width, height=height, src=img['src'])
+ img.replace_with(new_tag)
+ return soup.prettify()
+
+
+def do_amp(text):
+ bs = remove_img_tags(text)
+ return Sanitizer().strip(bs)
+
+register.filter('amp', do_amp)
diff --git a/design/sass/_writing_details.scss b/design/sass/_writing_details.scss
index 53b3aca..c7a57b0 100644
--- a/design/sass/_writing_details.scss
+++ b/design/sass/_writing_details.scss
@@ -153,20 +153,25 @@
.footnote {
@include constrain_narrow();
margin: 1em auto 0 auto;
- padding:0;
- list-style-position:inside;
+ padding: 0;
list-style-type: none;
- &:before {
+ &:before, &:after {
+ @include faded_line_after;
@include breakpoint(beta) {
- @include faded_line_after;
margin-bottom: 2em;
}
}
p {
font-size: 0.875em;
- line-height: 1.4
+ line-height: 1.4;
}
hr {display: none;}
+ ol {
+ padding-left: 1em;
+ @include breakpoint(alpha) {
+ margin-left: 1em;
+ }
+ }
}
.dark .footnote:before {
@include light_faded_line_after;
@@ -352,7 +357,8 @@ display: block;
.comments--header {
font-family: Helvetica Neue, Helvetica, sans-serif;
line-height: 6em;
- @include fontsize(24);
+ @include fontsize(16);
+ font-style: italic;
&:before {
@include faded_line_after;
margin-top: 2em;
diff --git a/design/templates/details/entry.amp b/design/templates/details/entry.amp
index 6305d46..32b6d36 100644
--- a/design/templates/details/entry.amp
+++ b/design/templates/details/entry.amp
@@ -1,4 +1,5 @@
{% load typogrify_tags %}
+{% load amp %}
<!doctype html>
<html amp lang="en">
<head>
@@ -45,7 +46,6 @@
},
"publisher": {
"@type": "Person",
- "name": "Jeremy Keith",
"name": "Scott Gilbertson"
"logo": {
"@type": "ImageObject",
@@ -137,8 +137,6 @@ hr {
border-bottom: 0.0625rem dotted #ccc;
}
</style>
-<script async custom-element="amp-audio" src="https://cdn.ampproject.org/v0/amp-audio-0.1.js"></script>
-<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
<style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
@@ -146,8 +144,7 @@ hr {
<nav>
<a href="https://luxagraf.net/">
-<amp-img src="https://adactio.com/skins/default/images/logo.png" srcset="https://adactio.com/skins/default/images/logox2.png 2x" alt="adactio" width="240" height="53" layout="fixed"></amp-img>
-</a>
+luxagraf</a>
</nav>
<main class="h-entry">
@@ -158,15 +155,10 @@ hr {
<p class="p-author author hide" itemprop="author"><span class="byline-author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Scott Gilbertson</span></span></p>
<aside class="p-location h-adr adr post--location" itemprop="contentLocation" itemscope itemtype="http://schema.org/Place">
{% if object.country.name == "United States" %}<span class="p-locality locality">{{object.location.name|smartypants|safe}}</span>, <a class="p-region region" href="/jrnl/united-states/" title="travel writing from the United States">{{object.state.name|safe}}</a>, <span class="p-country-name">U.S.</span>{%else%}<span class="p-region">{{object.location.name|smartypants|safe}}</span>, <a class="p-country-name country-name" href="/jrnl/{{object.country.slug}}/" title="travel writing from {{object.country.name}}">{{object.country.name|safe}}</a>{%endif%}
- <span style="display: none;" itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates">
- <data itemprop="latitude" class="p-latitude" value="{{object.latitude}}">{{object.latitude}}</data>
- <data itemprop="longitude" class="p-longitude" value="{{object.longitude}}">{{object.longitude}}</data>
- </span>
- {% with object.get_template_name_display as t %}{%if t == "single" or t == "single-dark" %} &ndash;&nbsp;<a href="" onclick="showMap({{object.latitude}}, {{object.longitude}}, { type:'point', lat:'{{object.latitude}}', lon:'{{object.longitude}}'}); return false;" title="see a map">Map</a>{%endif%}{%endwith%}
</aside>
</header>
<div id="article" class="e-content entry-content post--body post--body--{% with object.template_name as t %}{%if t == 0 or t == 2 %}single{%endif%}{%if t == 1 or t == 3 %}double{%endif%}{%endwith%}" itemprop="articleBody">
- {{object.body_html|safe|smartypants|widont}}
+ {{object.body_html|amp|safe}}
</div>
</article>
</main>