data cleaned
This commit is contained in:
271
app.py
271
app.py
@@ -1,4 +1,6 @@
|
|||||||
from flask import Flask, render_template, request, redirect, url_for
|
from flask import Flask, render_template, request, redirect, url_for
|
||||||
|
from content.posts import BLOG_POSTS
|
||||||
|
from content.logic import get_enriched_post, get_comments_for_post, save_comment
|
||||||
|
|
||||||
# 🌟 IMPORT THE content from separate files.
|
# 🌟 IMPORT THE content from separate files.
|
||||||
from content.posts import BLOG_POSTS
|
from content.posts import BLOG_POSTS
|
||||||
@@ -14,52 +16,29 @@ COMMENT_FILE = 'content/comments.csv'
|
|||||||
MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024 # 5 Megabytes
|
MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024 # 5 Megabytes
|
||||||
POSTS_PER_PAGE = 5 # posts per page limit here
|
POSTS_PER_PAGE = 5 # posts per page limit here
|
||||||
|
|
||||||
def get_comments_for_post(post_id):
|
"""
|
||||||
comments = []
|
import os
|
||||||
if os.path.exists(COMMENT_FILE) and os.path.getsize(COMMENT_FILE) > MAX_FILE_SIZE_BYTES:
|
from flask import send_from_directory
|
||||||
return ["Comment section full.", 507]
|
|
||||||
if not os.path.exists(COMMENT_FILE):
|
@app.route('/content/images/<path:filename>')
|
||||||
return comments
|
def custom_static(filename):
|
||||||
|
# This serves files from your private submodule folder
|
||||||
with open(COMMENT_FILE, 'r', encoding='utf-8') as f:
|
return send_from_directory('content/images', filename)
|
||||||
reader = csv.DictReader(f)
|
"""
|
||||||
for row in reader:
|
|
||||||
if row['post_id'] == str(post_id):
|
|
||||||
comments.append(row)
|
|
||||||
return comments
|
|
||||||
|
|
||||||
@app.route('/post/<int:post_id>/comment', methods=['POST'])
|
@app.route('/post/<int:post_id>/comment', methods=['POST'])
|
||||||
def post_comment(post_id):
|
def post_comment(post_id):
|
||||||
# 1. Security: Check Honeypot
|
# Honeypot stays in app.py (it's a web-security concern)
|
||||||
if request.form.get('honeypot'):
|
if request.form.get('honeypot'):
|
||||||
return redirect(url_for('post_detail', post_id=post_id))
|
return redirect(url_for('post_detail', post_id=post_id))
|
||||||
|
|
||||||
# 2. Get Data
|
author = request.form.get('author')
|
||||||
author = request.form.get('author', 'Anonymous').strip()
|
content = request.form.get('content')
|
||||||
content = request.form.get('content', '').strip()
|
|
||||||
|
|
||||||
# 3. Validation (Keep it lightweight)
|
|
||||||
if not content or len(content) > 1000: # Max 1000 chars to save disk/RAM
|
|
||||||
return redirect(url_for('post_detail', post_id=post_id))
|
|
||||||
|
|
||||||
# 4. Save to CSV
|
|
||||||
file_exists = os.path.isfile(COMMENT_FILE)
|
|
||||||
# check max size
|
|
||||||
if file_exists and os.path.getsize(COMMENT_FILE) > MAX_FILE_SIZE_BYTES:
|
|
||||||
return
|
|
||||||
|
|
||||||
with open(COMMENT_FILE, 'a', newline='', encoding='utf-8') as f:
|
|
||||||
writer = csv.DictWriter(f, fieldnames=['post_id', 'author', 'content', 'date'])
|
|
||||||
if not file_exists:
|
|
||||||
writer.writeheader()
|
|
||||||
|
|
||||||
writer.writerow({
|
|
||||||
'post_id': post_id,
|
|
||||||
'author': author[:50], # Truncate long names
|
|
||||||
'content': content,
|
|
||||||
'date': datetime.datetime.now().strftime("%B %d, %Y at %I:%M %p")
|
|
||||||
})
|
|
||||||
|
|
||||||
|
# Just call the logic function
|
||||||
|
success = save_comment(post_id, author, content)
|
||||||
|
|
||||||
|
# Optional: You could flash a message if success is False
|
||||||
return redirect(url_for('post_detail', post_id=post_id))
|
return redirect(url_for('post_detail', post_id=post_id))
|
||||||
# --- Routes ---
|
# --- Routes ---
|
||||||
|
|
||||||
@@ -105,217 +84,19 @@ def about():
|
|||||||
return render_template('about.html', about_txt = about_txt, blog_title = TITLE)
|
return render_template('about.html', about_txt = about_txt, blog_title = TITLE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/post/<int:post_id>')
|
@app.route('/post/<int:post_id>')
|
||||||
def post_detail(post_id):
|
def post_detail(post_id):
|
||||||
"""Renders a single post detail page."""
|
# One call to get the data + the extra logic (templates/timelines)
|
||||||
|
post = get_enriched_post(post_id, BLOG_POSTS)
|
||||||
|
|
||||||
# 1. Look up the post dictionary
|
if not post:
|
||||||
post = next((p for p in BLOG_POSTS if p['id'] == post_id), None)
|
|
||||||
|
|
||||||
if post is None:
|
|
||||||
return "Post not found", 404
|
return "Post not found", 404
|
||||||
#get comments
|
|
||||||
comments = get_comments_for_post(post_id)
|
comments = get_comments_for_post(post_id)
|
||||||
if post["id"] == 8:
|
|
||||||
post["template"] = "components/christmas_post.html"
|
|
||||||
|
|
||||||
if post["id"] == 10:
|
|
||||||
|
|
||||||
post["template"] = "components/timeline.html"
|
|
||||||
post["timeline"] = """
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('movedsomewebbasedtoolstolocalhost', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-13
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
moved some web-based tools to localhost
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="movedsomewebbasedtoolstolocalhost">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
a testing page for blog preview and some string formatter...<br>It's also my first time to correctly using git, to upload edited pages directly via rsync and synchronization via git.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('Editing', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-13
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
Editing
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="Editing">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
added a timeline component,<br>but I have to generate a timeline html and paste it as text,<br>then paste into content generation, and the upload to blog.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('PackingbloginDocker', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-12
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
Packing blog in Docker
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="PackingbloginDocker">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
uwsgi + flask -> caddy, gunicorn, flask, docker
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('movedallwikipagesintoonerepository', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-12
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
moved all wiki pages into one repository
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="movedallwikipagesintoonerepository">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
have been using gitea's wiki page to take notes, which is a life-saver<br>I made a script to pull all wiki pages into one repository, now I have a way to save all my notes.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('scoopupdatevscode', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-12
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
scoop update vscode
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="scoopupdatevscode">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
VS Code was always hanging for two months.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('rootpartitionisfull', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-11
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
/root partition is full
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="rootpartitionisfull">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
pacman -Sc doesnt work anymore<br>I am confused very confused<br>started to move gitea from /etc to /home<br>accidentally deleted all gitea data...then recovered with a previous gitea dump
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('haveanothergiteainstancedocker', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-11
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
have another gitea instance, docker
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="haveanothergiteainstancedocker">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
all repositories have a mirror now
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('Tailscaleipdoesntwork', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-11
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
Tailscale ip doesnt work
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="Tailscaleipdoesntwork">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
system-wide caddy worked for https://ip <br>but docked caddy didnt work for https://ip<br>I have no clue...
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="tw-mb-10 tw-ml-10 tw-list-none tw-relative">
|
|
||||||
<button
|
|
||||||
onclick="toggleTimeline('languagetool', this)"
|
|
||||||
class="timeline-button">
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<time class="tw-block tw-mb-1 tw-text-sm tw-font-normal tw-leading-none tw-text-gray-400">
|
|
||||||
2026-03-11
|
|
||||||
</time>
|
|
||||||
|
|
||||||
<h3 class="tw-text-lg tw-font-semibold tw-text-gray-900 tw-mt-0 tw-mb-1">
|
|
||||||
language tool
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div id="languagetool">
|
|
||||||
<p class="tw-text-base tw-font-normal tw-text-gray-500 tw-m-0">
|
|
||||||
trying to use language tool, which helps with spelling but it doesnt work well for grammar checking, also the current setting should be fixed, I am not sure if I am running locally or querying via API.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
# 2. Pass the post dictionary (with the raw HTML content) directly to the template
|
|
||||||
return render_template('post_detail.html', post=post, comments=comments, blog_title = TITLE)
|
return render_template('post_detail.html', post=post, comments=comments, blog_title = TITLE)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
2
content
2
content
Submodule content updated: 3f26965bf0...f2bf62144f
Reference in New Issue
Block a user