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
|
||||
MarkupSafe
|
||||
bleach
|
||||
web-mini
|
||||
|
|
|
@ -6,14 +6,28 @@ import datetime
|
|||
import os
|
||||
import sys
|
||||
from base64 import b64encode
|
||||
from functools import lru_cache
|
||||
from typing import Any
|
||||
|
||||
import flask
|
||||
import web_mini
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
|
||||
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:
|
||||
"""create ari.lt app"""
|
||||
|
||||
|
@ -65,7 +79,40 @@ def create_app(name: str) -> flask.Flask:
|
|||
|
||||
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
|
||||
def _() -> Any:
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ari::web -> {% block title %}Untitled{% endblock %}</title>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<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="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 %}"
|
||||
/>
|
||||
<meta
|
||||
name="robots"
|
||||
content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"
|
||||
/>
|
||||
<meta property="og:type" content="{% block type %}website{% endblock %}" />
|
||||
<meta name="description" content="{% block description %}Description of an untitled page.{% endblock %}" />
|
||||
<meta
|
||||
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 %}"
|
||||
/>
|
||||
<meta
|
||||
name="robots"
|
||||
content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"
|
||||
/>
|
||||
<meta property="og:type" content="{% block type %}website{% endblock %}" />
|
||||
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<meta name="theme-color" content="{% block colour %}#121212{% endblock %}" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<meta name="theme-color" content="{% block colour %}#121212{% endblock %}" />
|
||||
|
||||
<meta name="foss:src" content="{{ url_for("views.git") }}" />
|
||||
<meta name="license" content="AGPL-3.0-or-later" />
|
||||
<meta name="foss:src" content="{{ url_for("views.git") }}" />
|
||||
<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 %}
|
||||
</head>
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% block body %}{% endblock %}
|
||||
<article>
|
||||
<header>{% block header %}{% endblock %}</header>
|
||||
<main>
|
||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||
{% if messages %}
|
||||
<details open>
|
||||
<summary>messages from the server</summary>
|
||||
{% for category, message in messages %}
|
||||
<div><b>[{{ category | escape }}] {{ message | escape }}</b></div>
|
||||
{% endfor %}
|
||||
</details>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% block main %}{% endblock %}
|
||||
</main>
|
||||
<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>
|
||||
</footer>
|
||||
</article>
|
||||
</body>
|
||||
<body>
|
||||
{% block body %}{% endblock %}
|
||||
<article>
|
||||
<header>{% block header %}{% endblock %}</header>
|
||||
<main>
|
||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||
{% if messages %}
|
||||
<details open>
|
||||
<summary>messages from the server</summary>
|
||||
{% for category, message in messages %}
|
||||
<div><b>[{{ category | escape }}] {{ message | escape }}</b></div>
|
||||
{% endfor %}
|
||||
</details>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% block main %}{% endblock %}
|
||||
</main>
|
||||
<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>
|
||||
</footer>
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -407,46 +407,46 @@
|
|||
</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>
|
||||
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input required type="text" id="name" name="name" placeholder="Cool Person" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input required type="text" id="name" name="name" placeholder="Cool Person" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="website">Website (optional):</label>
|
||||
<input type="url" id="website" name="website" placeholder="https://example.com/" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="website">Website (optional):</label>
|
||||
<input type="url" id="website" name="website" placeholder="https://example.com/" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email:</label>
|
||||
<input required type="email" id="email" name="email" placeholder="me@example.com" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">Email:</label>
|
||||
<input required type="email" id="email" name="email" placeholder="me@example.com" />
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<textarea required type="text" id="comment" name="comment" placeholder="Hello! I like your website - <https://ari.lt/>."></textarea>
|
||||
</div>
|
||||
<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>
|
||||
<textarea required type="text" id="comment" name="comment" placeholder="Hello! I like your website - <https://ari.lt/>."></textarea>
|
||||
</div>
|
||||
|
||||
<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" />
|
||||
<i>Click the image above to reload and get a new CAPTCHA.</i>
|
||||
</div>
|
||||
<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" />
|
||||
<i>Click the image above to reload and get a new CAPTCHA.</i>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="captcha">CAPTCHA:</label>
|
||||
<input required type="text" id="code" name="code" placeholder="Enter the CAPTCHA code above." />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="captcha">CAPTCHA:</label>
|
||||
<input required type="text" id="code" name="code" placeholder="Enter the CAPTCHA code above." />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="agree">Email Policy Agreement:</label>
|
||||
<input required type="checkbox" id="agree" name="agree" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="agree">Email Policy Agreement:</label>
|
||||
<input required type="checkbox" id="agree" name="agree" />
|
||||
</div>
|
||||
|
||||
<button type="submit">Comment</button>
|
||||
<button type="submit">Comment</button>
|
||||
</form>
|
||||
|
||||
<div align="center">
|
||||
|
@ -454,12 +454,10 @@
|
|||
</div>
|
||||
|
||||
<div id="comments">
|
||||
{% for comment in comments %}
|
||||
<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>
|
||||
<div>{{ comment.comment | markdown }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for comment in comments %}
|
||||
<div id="gb-{{ comment.id }}">
|
||||
<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>{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
Loading…
Add table
Reference in a new issue