changed to package
This commit is contained in:
parent
0799deb727
commit
d88466f28e
20
Dockerfile
20
Dockerfile
|
|
@ -4,11 +4,7 @@
|
||||||
FROM python:3.11.0-alpine AS builder
|
FROM python:3.11.0-alpine AS builder
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
# python3 \
|
git
|
||||||
# py3-pip \
|
|
||||||
git \
|
|
||||||
# build-base \
|
|
||||||
# curl
|
|
||||||
|
|
||||||
ENV POETRY_VERSION=2.2.0
|
ENV POETRY_VERSION=2.2.0
|
||||||
RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" # --break-system-packages is not needed
|
RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" # --break-system-packages is not needed
|
||||||
|
|
@ -18,24 +14,18 @@ ENV POETRY_NO_INTERACTION=1
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN git clone https://git.stefan.works/stefan/website.git .
|
RUN git clone https://git.stefan.works/stefan/website.git .
|
||||||
RUN poetry install --only main ## --no-root
|
RUN poetry install --only main # --no-root
|
||||||
|
|
||||||
|
RUN poetry run python -m scripts.patch_flask_frozen
|
||||||
|
|
||||||
# RUN poetry run python -m scripts/patch_flask_frozen
|
|
||||||
RUN poetry run patch-frozen
|
|
||||||
RUN poetry run python freezer.py
|
RUN poetry run python freezer.py
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
# Runtime stage
|
# Runtime stage
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
FROM alpine:3.20
|
FROM nginx:alpine
|
||||||
|
|
||||||
RUN apk add --no-cache nginx
|
|
||||||
|
|
||||||
RUN rm -rf /usr/share/nginx/html/* \
|
|
||||||
&& mkdir -p /run/nginx
|
|
||||||
|
|
||||||
COPY --from=builder /app/build /usr/share/nginx/html
|
COPY --from=builder /app/build /usr/share/nginx/html
|
||||||
COPY container-nginx.conf /etc/nginx/nginx.conf
|
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
|
|
||||||
30
freezer.py
30
freezer.py
|
|
@ -1,13 +1,31 @@
|
||||||
from flask_frozen import Freezer
|
|
||||||
from start_site import app
|
from start_site import app
|
||||||
|
|
||||||
freezer = Freezer(app)
|
# Runtime patch for Flask >= 2.3
|
||||||
|
|
||||||
#@freezer.register_generator
|
import flask_frozen
|
||||||
#def errorhandler():
|
|
||||||
# yield "/404"
|
if not hasattr(flask_frozen.Freezer, "_original_generate_all_urls"):
|
||||||
|
flask_frozen.Freezer._original_generate_all_urls = flask_frozen.Freezer._generate_all_urls
|
||||||
|
|
||||||
|
def _patched_generate_all_urls(self):
|
||||||
|
if not hasattr(self.app.url_map, "charset"):
|
||||||
|
setattr(self.app.url_map, "charset", "utf-8")
|
||||||
|
|
||||||
|
return self._original_generate_all_urls()
|
||||||
|
|
||||||
|
flask_frozen.Freezer._generate_all_urls = _patched_generate_all_urls
|
||||||
|
|
||||||
|
|
||||||
|
from flask_frozen import Freezer
|
||||||
|
# from start_site import app
|
||||||
|
|
||||||
|
freezer = Freezer(app)
|
||||||
|
|
||||||
|
# @freezer.register_generator
|
||||||
|
# def errorhandler():
|
||||||
|
# yield "/404"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
freezer.freeze()
|
freezer.freeze()
|
||||||
#freezer.run(debug=True)
|
# #freezer.run(debug=True)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "website"
|
name = "website"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
packages = [
|
||||||
|
{ include = "start_site" }
|
||||||
|
]
|
||||||
description = "Stefan's Blog"
|
description = "Stefan's Blog"
|
||||||
authors = ["stefan <mail@stefan.works>"]
|
authors = ["stefan <mail@stefan.works>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
@ -17,7 +20,6 @@ Pygments = "^2.12.0"
|
||||||
python-markdown-math = "*"
|
python-markdown-math = "*"
|
||||||
toml = "*"
|
toml = "*"
|
||||||
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def patch_flask_frozen():
|
def patch_flask_frozen():
|
||||||
try:
|
try:
|
||||||
import flask_frozen
|
import flask_frozen
|
||||||
|
|
@ -23,7 +22,8 @@ def patch_flask_frozen():
|
||||||
|
|
||||||
for i, line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
if "url_encoding = self.app.url_map.charset" in line:
|
if "url_encoding = self.app.url_map.charset" in line:
|
||||||
lines[i] = " url_encoding = 'utf-8' # patched charset\n"
|
indent = line[: len(line) - len(line.lstrip())]
|
||||||
|
lines[i] = f"{indent}url_encoding = getattr(self.app.url_map, 'charset', 'utf-8') # patched\n"
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
|
|
@ -36,3 +36,4 @@ def patch_flask_frozen():
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
patch_flask_frozen()
|
patch_flask_frozen()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import toml
|
||||||
|
from datetime import datetime
|
||||||
|
import pytz
|
||||||
|
from flask import Flask, url_for, render_template, send_from_directory
|
||||||
|
from flask import make_response
|
||||||
|
from feedgen.feed import FeedGenerator
|
||||||
|
from flaskext.markdown import Markdown
|
||||||
|
import markdown
|
||||||
|
import markdown.extensions.fenced_code
|
||||||
|
import markdown.extensions.codehilite
|
||||||
|
import markdown.extensions.toc
|
||||||
|
from markdown.extensions.toc import TocExtension
|
||||||
|
from pygments.formatters import HtmlFormatter
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
Markdown(app)
|
||||||
|
|
||||||
|
meta_data = {
|
||||||
|
root[len("./blog/") :]: datetime.strptime(
|
||||||
|
open(os.path.join(root, "index.md"), encoding="UTF-8").readline().rstrip(),
|
||||||
|
"%Y-%m-%d",
|
||||||
|
)
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk("./blog")
|
||||||
|
|
||||||
|
if "index.md" in files
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
app.config["blog"] = toml.load("settings.toml")
|
||||||
|
content_path = app.config["blog"]["content"]["path"]
|
||||||
|
highlight_style = app.config["blog"]["content"]["style"]
|
||||||
|
STYLESHEET = "stylesheet.css"
|
||||||
|
STYLESHEET_AUTO_COMPLETE = "auto-complete.css"
|
||||||
|
project_name = app.config["blog"]["project"]["name"]
|
||||||
|
project_title = app.config["blog"]["project"]["title"]
|
||||||
|
|
||||||
|
app.config["blog"]["style"] = toml.load("style.toml")
|
||||||
|
colors = app.config["blog"]["style"][highlight_style]
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def index(_paths=meta_data):
|
||||||
|
"""Main Site."""
|
||||||
|
sorted_meta_data = dict(
|
||||||
|
sorted(meta_data.items(), reverse=True, key=lambda item: item[1])
|
||||||
|
)
|
||||||
|
|
||||||
|
return render_template("index.html", colors=colors, _paths=sorted_meta_data)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/blog/<blog_item>/index.html")
|
||||||
|
def blog(blog_item, _date=meta_data):
|
||||||
|
"""Blog Pages."""
|
||||||
|
md_file_path = os.path.join(f"blog/{blog_item}/index.md")
|
||||||
|
with open(md_file_path, "r") as _f:
|
||||||
|
md_file = _f.read()
|
||||||
|
md_extensions = [
|
||||||
|
"toc",
|
||||||
|
TocExtension(toc_class="", title=""),
|
||||||
|
"fenced_code",
|
||||||
|
"codehilite",
|
||||||
|
"tables",
|
||||||
|
"mdx_math",
|
||||||
|
]
|
||||||
|
|
||||||
|
md_configs = {"mdx_math": {"enable_dollar_delimiter": True}}
|
||||||
|
md = markdown.Markdown(extensions=md_extensions, extension_configs=md_configs)
|
||||||
|
|
||||||
|
html = md.convert(md_file)
|
||||||
|
|
||||||
|
formatter = HtmlFormatter(style=highlight_style, full=True, cssclass="codehilite")
|
||||||
|
css_string = formatter.get_style_defs()
|
||||||
|
md_css_string = "<style>" + css_string + "</style>"
|
||||||
|
md_template = md_css_string + html
|
||||||
|
res = render_template(
|
||||||
|
"blog.html",
|
||||||
|
# toc=md.toc,
|
||||||
|
md_doc=md_template,
|
||||||
|
colors=colors,
|
||||||
|
stylesheet=STYLESHEET,
|
||||||
|
# stylesheet_auto_complete=STYLESHEET_AUTO_COMPLETE,
|
||||||
|
project_name=project_name,
|
||||||
|
project_title=project_title,
|
||||||
|
# tree=cut_path_tree(
|
||||||
|
# #rem_readme(content_path, make_tree(content_path)),
|
||||||
|
# make_tree(content_path),
|
||||||
|
# content_path,
|
||||||
|
# ".md" # )
|
||||||
|
_date=meta_data[blog_item],
|
||||||
|
)
|
||||||
|
response = make_response(res)
|
||||||
|
response.headers["Content-Type"] = "text/html; charset=utf-8"
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
# return render_template(
|
||||||
|
# f"blog/{blog_item}/index.html",
|
||||||
|
# _date=meta_data[blog_item]
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/about.html")
|
||||||
|
def about():
|
||||||
|
"""About Page."""
|
||||||
|
|
||||||
|
return render_template("about.html", colors=colors)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/contact.html")
|
||||||
|
def contact():
|
||||||
|
"""Contact Page."""
|
||||||
|
|
||||||
|
return render_template("contact.html", colors=colors)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/rss.xml")
|
||||||
|
def rss(_items=meta_data):
|
||||||
|
"""RSS Feed.
|
||||||
|
Generates RSS feed as XML
|
||||||
|
"""
|
||||||
|
# rss_feed = []
|
||||||
|
_tz = pytz.timezone("Europe/Berlin")
|
||||||
|
_fg = FeedGenerator()
|
||||||
|
_fg.title("Website of Stefan Friese")
|
||||||
|
_fg.description("test")
|
||||||
|
_fg.language("en-us")
|
||||||
|
# _fg.author({'name': "Stefan Friese", 'email': 'stefan@stefan.works'})
|
||||||
|
_fg.link(href="https://stefan.works", rel="self")
|
||||||
|
|
||||||
|
for key in meta_data.keys():
|
||||||
|
_fe = _fg.add_entry()
|
||||||
|
_fe.id(f"https://stefan.works/blog/{key}/index.html")
|
||||||
|
_fe.title(key)
|
||||||
|
# _fe.description("test")
|
||||||
|
# _fe.author({'name': "Stefan Friese", 'email': 'stefan@stefan.works'})
|
||||||
|
_fe.link(href=f"https://stefan.works/blog/{key}/index.html")
|
||||||
|
_fe.pubDate(pubDate=_tz.localize(meta_data[key]))
|
||||||
|
_fg.rss_str(pretty=True)
|
||||||
|
_fg.rss_file("./static/rss.xml")
|
||||||
|
|
||||||
|
return send_from_directory(os.path.join(app.root_path, "static"), "rss.xml")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/favicon.ico")
|
||||||
|
def favicon():
|
||||||
|
"""Provides favicon."""
|
||||||
|
|
||||||
|
return send_from_directory(os.path.join(app.root_path, "static"), "favicon.ico")
|
||||||
|
|
||||||
|
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def page_not_found(_error):
|
||||||
|
"""Error Handling.
|
||||||
|
Error 404
|
||||||
|
"""
|
||||||
|
|
||||||
|
return render_template("/status_code/404.html", colors=colors), 404
|
||||||
|
|
||||||
|
|
||||||
|
@app.errorhandler(400)
|
||||||
|
def bad_request(_error):
|
||||||
|
"""Error Handling.
|
||||||
|
Error 400
|
||||||
|
"""
|
||||||
|
|
||||||
|
return render_template("/status_code/400.html", colors=colors), 400
|
||||||
|
|
||||||
|
|
||||||
|
@app.errorhandler(500)
|
||||||
|
def internal_server_error(_error):
|
||||||
|
"""Error Handling.
|
||||||
|
Error 500
|
||||||
|
"""
|
||||||
|
|
||||||
|
return render_template("/status_code/500.html", colors=colors), 500
|
||||||
|
|
||||||
|
|
||||||
|
with app.test_request_context():
|
||||||
|
print(url_for("index"))
|
||||||
|
# print(url_for("about"))
|
||||||
|
# print(url_for("contact"))
|
||||||
|
# print(url_for("rss"))
|
||||||
|
# print(url_for("static", filename="stylesheet.css"))
|
||||||
|
# print(meta_data)
|
||||||
|
# print(url_for("blog", blog_item="first_blog"))
|
||||||
Loading…
Reference in New Issue