fix: Add escape char for curl rendering and format python files
All checks were successful
Build Docker / BuildImage (push) Successful in 1m6s
Check Code Quality / RuffCheck (push) Successful in 1m20s

This commit is contained in:
2025-11-21 23:05:40 +11:00
parent 51c4416d4d
commit e489764ff8
17 changed files with 461 additions and 309 deletions

View File

@@ -6,7 +6,7 @@ import re
from functools import lru_cache
from tools import isCLI, getClientIP, getHandshakeScript
app = Blueprint('blog', __name__, url_prefix='/blog')
app = Blueprint("blog", __name__, url_prefix="/blog")
@lru_cache(maxsize=32)
@@ -14,11 +14,13 @@ def list_page_files():
blog_pages = os.listdir("data/blog")
# Sort pages by modified time, newest first
blog_pages.sort(
key=lambda x: os.path.getmtime(os.path.join("data/blog", x)), reverse=True)
key=lambda x: os.path.getmtime(os.path.join("data/blog", x)), reverse=True
)
# Remove .md extension
blog_pages = [page.removesuffix(".md")
for page in blog_pages if page.endswith(".md")]
blog_pages = [
page.removesuffix(".md") for page in blog_pages if page.endswith(".md")
]
return blog_pages
@@ -28,7 +30,7 @@ def get_blog_content(date):
"""Get and cache blog content."""
if not os.path.exists(f"data/blog/{date}.md"):
return None
with open(f"data/blog/{date}.md", "r") as f:
return f.read()
@@ -37,7 +39,8 @@ def get_blog_content(date):
def render_markdown_to_html(content):
"""Convert markdown to HTML with caching."""
html = markdown.markdown(
content, extensions=['sane_lists', 'codehilite', 'fenced_code'])
content, extensions=["sane_lists", "codehilite", "fenced_code"]
)
# Add target="_blank" to all links
html = html.replace('<a href="', '<a target="_blank" href="')
html = html.replace("<h4", "<h4 style='margin-bottom:0px;'")
@@ -65,18 +68,18 @@ def render_page(date, handshake_scripts=None):
def fix_numbered_lists(html):
soup = BeautifulSoup(html, 'html.parser')
soup = BeautifulSoup(html, "html.parser")
# Find the <p> tag containing numbered steps
paragraphs = soup.find_all('p')
paragraphs = soup.find_all("p")
for p in paragraphs:
content = p.decode_contents() # type: ignore
# Check for likely numbered step structure
if re.search(r'1\.\s', content):
if re.search(r"1\.\s", content):
# Split into pre-list and numbered steps
# Match: <br>, optional whitespace, then a number and dot
parts = re.split(r'(?:<br\s*/?>)?\s*(\d+)\.\s', content)
parts = re.split(r"(?:<br\s*/?>)?\s*(\d+)\.\s", content)
# Result: [pre-text, '1', step1, '2', step2, ..., '10', step10]
pre_text = parts[0].strip()
@@ -85,10 +88,9 @@ def fix_numbered_lists(html):
# Assemble the ordered list
ol_items = []
for i in range(0, len(steps), 2):
if i+1 < len(steps):
step_html = steps[i+1].strip()
ol_items.append(
f"<li style='list-style: auto;'>{step_html}</li>")
if i + 1 < len(steps):
step_html = steps[i + 1].strip()
ol_items.append(f"<li style='list-style: auto;'>{step_html}</li>")
# Build the final list HTML
ol_html = "<ol>\n" + "\n".join(ol_items) + "\n</ol>"
@@ -97,7 +99,7 @@ def fix_numbered_lists(html):
new_html = f"{pre_text}<br />\n{ol_html}" if pre_text else ol_html
# Replace old <p> with parsed version
new_fragment = BeautifulSoup(new_html, 'html.parser')
new_fragment = BeautifulSoup(new_html, "html.parser")
p.replace_with(new_fragment)
break # Only process the first matching <p>
@@ -134,16 +136,23 @@ def index():
blog_pages = list_page_files()
# Create a html list of pages
blog_pages = [
{"name": page.replace("_", " "), "url": f"/blog/{page}", "download": f"/blog/{page}.md"} for page in blog_pages
{
"name": page.replace("_", " "),
"url": f"/blog/{page}",
"download": f"/blog/{page}.md",
}
for page in blog_pages
]
# Render the template
return jsonify({
"status": 200,
"message": "Check out my various blog postsa",
"ip": getClientIP(request),
"blogs": blog_pages
}), 200
return jsonify(
{
"status": 200,
"message": "Check out my various blog postsa",
"ip": getClientIP(request),
"blogs": blog_pages,
}
), 200
@app.route("/<path:path>")
@@ -158,14 +167,16 @@ def path(path):
# Get the title from the file name
title = path.replace("_", " ")
return jsonify({
"status": 200,
"message": f"Blog post: {title}",
"ip": getClientIP(request),
"title": title,
"content": content,
"download": f"/blog/{path}.md"
}), 200
return jsonify(
{
"status": 200,
"message": f"Blog post: {title}",
"ip": getClientIP(request),
"title": title,
"content": content,
"download": f"/blog/{path}.md",
}
), 200
@app.route("/<path:path>.md")
@@ -175,4 +186,4 @@ def path_md(path):
return render_template("404.html"), 404
# Return the raw markdown file
return content, 200, {'Content-Type': 'text/plain; charset=utf-8'}
return content, 200, {"Content-Type": "text/plain; charset=utf-8"}