mirror of
https://git.ari.lt/ari.lt/ari.lt.git
synced 2025-02-04 17:49:24 +01:00
minify html and css on load and add headers
Signed-off-by: Ari Archer <ari@ari.lt>
This commit is contained in:
parent
e6489ab8e6
commit
0be390fdec
4 changed files with 130 additions and 84 deletions
|
@ -8,3 +8,4 @@ markdown
|
||||||
jinja2
|
jinja2
|
||||||
MarkupSafe
|
MarkupSafe
|
||||||
bleach
|
bleach
|
||||||
|
web-mini
|
||||||
|
|
|
@ -6,14 +6,28 @@ import datetime
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
from functools import lru_cache
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
|
import web_mini
|
||||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
|
||||||
from . import util
|
from . import util
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache
|
||||||
|
def min_css(css: str) -> str:
|
||||||
|
"""minify css"""
|
||||||
|
return web_mini.css.minify_css(css)
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=64)
|
||||||
|
def min_html(html: str) -> str:
|
||||||
|
"""minify html"""
|
||||||
|
return web_mini.html.minify_html(html)
|
||||||
|
|
||||||
|
|
||||||
def create_app(name: str) -> flask.Flask:
|
def create_app(name: str) -> flask.Flask:
|
||||||
"""create ari.lt app"""
|
"""create ari.lt app"""
|
||||||
|
|
||||||
|
@ -65,7 +79,40 @@ def create_app(name: str) -> flask.Flask:
|
||||||
|
|
||||||
c.init_app(app)
|
c.init_app(app)
|
||||||
|
|
||||||
app.jinja_env.filters["markdown"] = util.markdown_to_html
|
app.jinja_env.filters["markdown"] = util.markdown_to_html # type: ignore
|
||||||
|
|
||||||
|
web_mini.compileall()
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def _(response: flask.Response) -> flask.Response:
|
||||||
|
"""minify resources and add headers"""
|
||||||
|
|
||||||
|
if not app.debug:
|
||||||
|
response.headers["Content-Security-Policy"] = "upgrade-insecure-requests"
|
||||||
|
response.headers["Strict-Transport-Security"] = (
|
||||||
|
"max-age=63072000; includeSubDomains; preload"
|
||||||
|
)
|
||||||
|
|
||||||
|
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
||||||
|
response.headers["X-Content-Type-Options"] = "nosniff"
|
||||||
|
response.headers["X-Permitted-Cross-Domain-Policies"] = "none"
|
||||||
|
|
||||||
|
if response.direct_passthrough:
|
||||||
|
return response
|
||||||
|
|
||||||
|
if response.content_type == "text/html; charset=utf-8":
|
||||||
|
minified_data: str = min_html(response.get_data(as_text=True))
|
||||||
|
elif response.content_type == "text/css; charset=utf-8":
|
||||||
|
minified_data: str = min_css(response.get_data(as_text=True))
|
||||||
|
else:
|
||||||
|
return response
|
||||||
|
|
||||||
|
return app.response_class( # type: ignore
|
||||||
|
response=minified_data,
|
||||||
|
status=response.status,
|
||||||
|
headers=dict(response.headers),
|
||||||
|
mimetype=response.mimetype,
|
||||||
|
)
|
||||||
|
|
||||||
@app.context_processor # type: ignore
|
@app.context_processor # type: ignore
|
||||||
def _() -> Any:
|
def _() -> Any:
|
||||||
|
|
|
@ -1,57 +1,57 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Ari::web -> {% block title %}Untitled{% endblock %}</title>
|
<title>Ari::web -> {% block title %}Untitled{% endblock %}</title>
|
||||||
|
|
||||||
<link rel="icon" href="{{ url_for("views.favicon") }}" sizes="128x128" type="image/vnd.microsoft.icon" />
|
<link rel="icon" href="{{ url_for("views.favicon") }}" sizes="128x128" type="image/vnd.microsoft.icon" />
|
||||||
|
|
||||||
<meta name="description" content="{% block description %}Description of an untitled page.{% endblock %}" />
|
<meta name="description" content="{% block description %}Description of an untitled page.{% endblock %}" />
|
||||||
<meta
|
<meta
|
||||||
name="keywords"
|
name="keywords"
|
||||||
content="ari archer, ari, archer, arija, arija a, ari-web, aw, open source, foss, developer, open source developer, website, python, c, blog, agpl, gpl, dev, lithuania, {% block keywords %}test{% endblock %}"
|
content="ari archer, ari, archer, arija, arija a, ari-web, aw, open source, foss, developer, open source developer, website, python, c, blog, agpl, gpl, dev, lithuania, {% block keywords %}test{% endblock %}"
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="robots"
|
name="robots"
|
||||||
content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"
|
content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"
|
||||||
/>
|
/>
|
||||||
<meta property="og:type" content="{% block type %}website{% endblock %}" />
|
<meta property="og:type" content="{% block type %}website{% endblock %}" />
|
||||||
|
|
||||||
<meta name="color-scheme" content="dark" />
|
<meta name="color-scheme" content="dark" />
|
||||||
<meta name="theme-color" content="{% block colour %}#121212{% endblock %}" />
|
<meta name="theme-color" content="{% block colour %}#121212{% endblock %}" />
|
||||||
|
|
||||||
<meta name="foss:src" content="{{ url_for("views.git") }}" />
|
<meta name="foss:src" content="{{ url_for("views.git") }}" />
|
||||||
<meta name="license" content="AGPL-3.0-or-later" />
|
<meta name="license" content="AGPL-3.0-or-later" />
|
||||||
|
|
||||||
<link rel="manifest" href="{{ url_for("views.manifest") }}" />
|
<link rel="manifest" href="{{ url_for("views.manifest") }}" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ url_for("static", filename="css/base.css") }}" type="text/css" referrerpolicy="no-referrer" />
|
<link rel="stylesheet" href="{{ url_for("static", filename="css/base.css") }}" type="text/css" referrerpolicy="no-referrer" />
|
||||||
|
|
||||||
{% block head %}{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
<article>
|
<article>
|
||||||
<header>{% block header %}{% endblock %}</header>
|
<header>{% block header %}{% endblock %}</header>
|
||||||
<main>
|
<main>
|
||||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
<details open>
|
<details open>
|
||||||
<summary>messages from the server</summary>
|
<summary>messages from the server</summary>
|
||||||
{% for category, message in messages %}
|
{% for category, message in messages %}
|
||||||
<div><b>[{{ category | escape }}] {{ message | escape }}</b></div>
|
<div><b>[{{ category | escape }}] {{ message | escape }}</b></div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</details>
|
</details>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% block main %}{% endblock %}
|
{% block main %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<i>The <a target="_blank" href="{{ url_for('views.git') }}">source code</a> and all content, except the Nerd Hack font (see <a target="_blank" href="{{ url_for("static", filename="fonts/LICENSE") }}">Nerd Hack font license</a>), are licensed under the <a target="_blank" href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL-3.0-or-later</a> by Ari Archer <<a target="_blank" href="mailto:ari@ari.lt">ari@ari.lt</a>> as a part of the <a href="{{ url_for("views.badge") }}" target="_blank">ari-web</a> project. Copyright 2019-{{ current_year }}.</i>
|
<i>The <a target="_blank" href="{{ url_for('views.git') }}">source code</a> and all content, except the Nerd Hack font (see <a target="_blank" href="{{ url_for("static", filename="fonts/LICENSE") }}">Nerd Hack font license</a>), are licensed under the <a target="_blank" href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL-3.0-or-later</a> by Ari Archer <<a target="_blank" href="mailto:ari@ari.lt">ari@ari.lt</a>> as a part of the <a href="{{ url_for("views.badge") }}" target="_blank">ari-web</a> project. Copyright 2019-{{ current_year }}.</i>
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -407,46 +407,46 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>TL;DR;</b> your email is stored and can be seen publicly. <b>Please check your mailbox to confirm your email after commenting.</b>
|
<b>TL;DR;</b> your email is stored and can be seen publicly. <b>Please check your mailbox to confirm your email after commenting.</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name:</label>
|
<label for="name">Name:</label>
|
||||||
<input required type="text" id="name" name="name" placeholder="Cool Person" />
|
<input required type="text" id="name" name="name" placeholder="Cool Person" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="website">Website (optional):</label>
|
<label for="website">Website (optional):</label>
|
||||||
<input type="url" id="website" name="website" placeholder="https://example.com/" />
|
<input type="url" id="website" name="website" placeholder="https://example.com/" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="email">Email:</label>
|
<label for="email">Email:</label>
|
||||||
<input required type="email" id="email" name="email" placeholder="me@example.com" />
|
<input required type="email" id="email" name="email" placeholder="me@example.com" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="comment">Comment (<a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet" target="_blank">markdown</a>):</label>
|
<label for="comment">Comment (<a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet" target="_blank">markdown</a>):</label>
|
||||||
<textarea required type="text" id="comment" name="comment" placeholder="Hello! I like your website - <https://ari.lt/>."></textarea>
|
<textarea required type="text" id="comment" name="comment" placeholder="Hello! I like your website - <https://ari.lt/>."></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="captcha">
|
<div class="captcha">
|
||||||
<img loading="lazy" width="240px" height="90" src="{{ url_for("views.captcha") }}?new" onclick="this.src=this.src+Math.floor(1000*Math.random())" alt="An image CAPTCHA" />
|
<img loading="lazy" width="240px" height="90" src="{{ url_for("views.captcha") }}?new" onclick="this.src=this.src+Math.floor(1000*Math.random())" alt="An image CAPTCHA" />
|
||||||
<i>Click the image above to reload and get a new CAPTCHA.</i>
|
<i>Click the image above to reload and get a new CAPTCHA.</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="captcha">CAPTCHA:</label>
|
<label for="captcha">CAPTCHA:</label>
|
||||||
<input required type="text" id="code" name="code" placeholder="Enter the CAPTCHA code above." />
|
<input required type="text" id="code" name="code" placeholder="Enter the CAPTCHA code above." />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="agree">Email Policy Agreement:</label>
|
<label for="agree">Email Policy Agreement:</label>
|
||||||
<input required type="checkbox" id="agree" name="agree" />
|
<input required type="checkbox" id="agree" name="agree" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit">Comment</button>
|
<button type="submit">Comment</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
@ -454,12 +454,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="comments">
|
<div id="comments">
|
||||||
{% for comment in comments %}
|
{% for comment in comments %}
|
||||||
<div id="gb-{{ comment.id }}">
|
<div id="gb-{{ comment.id }}">
|
||||||
<p><a href="#gb-{{ comment.id }}">#{{ comment.id }}:</a> <span>{{ comment.name | escape }}</span> {% if comment.website %} (<a target="_blank" href="{{ comment.website }}" rel="noopener noreferrer" target="_blank">{{ comment.website | escape }}</a>) {% endif %} <<i><a href="mailto:" style="color:#aaa" onclick="this.innerText=rc4('{{ b64encode(comment.email_ct).decode() }}','{{ b64encode(comment.key).decode() }}');this.href+=this.innerText;this.onclick=null;this.style='';return false">show email</a></i>> at <time>{{ comment.posted }} UTC</time> says...</p>
|
<p><a href="#gb-{{ comment.id }}">#{{ comment.id }}:</a> <span>{{ comment.name | escape }}</span> {% if comment.website %} (<a href="{{ comment.website }}" rel="noopener noreferrer" target="_blank">{{ comment.website | escape }}</a>) {% endif %} <<i><a href="mailto:" style="color:#aaa" onclick="this.innerText=rc4('{{ b64encode(comment.email_ct).decode() }}','{{ b64encode(comment.key).decode() }}');this.href+=this.innerText;this.onclick=null;this.style='';return false">show email</a></i>> at <time>{{ comment.posted }} UTC</time> says...</p>
|
||||||
<div>{{ comment.comment | markdown }}</div>
|
<div>{{ comment.comment | markdown }}</div>
|
||||||
</div>
|
</div>{% endfor %}
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Add table
Reference in a new issue