from flask import Flask, render_template, request, redirect, url_for # 🌟 IMPORT THE content from separate files. from content.posts import BLOG_POSTS from content.about_text import ABOUT, TITLE app = Flask(__name__) import csv import datetime import os, math COMMENT_FILE = 'content/comments.csv' MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024 # 5 Megabytes POSTS_PER_PAGE = 5 # posts per page limit here def get_comments_for_post(post_id): comments = [] if os.path.exists(COMMENT_FILE) and os.path.getsize(COMMENT_FILE) > MAX_FILE_SIZE_BYTES: return ["Comment section full.", 507] if not os.path.exists(COMMENT_FILE): return comments with open(COMMENT_FILE, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: if row['post_id'] == str(post_id): comments.append(row) return comments @app.route('/post//comment', methods=['POST']) def post_comment(post_id): # 1. Security: Check Honeypot if request.form.get('honeypot'): return redirect(url_for('post_detail', post_id=post_id)) # 2. Get Data author = request.form.get('author', 'Anonymous').strip() 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") }) return redirect(url_for('post_detail', post_id=post_id)) # --- Routes --- @app.route('/') def home(): page = request.args.get('page', 1, type=int) blog_title = TITLE # 2. Sort posts by ID newest first all_posts = sorted(BLOG_POSTS, key=lambda x: x['id'], reverse=True) # Calculate totals total_posts = len(all_posts) total_pages = math.ceil(total_posts / POSTS_PER_PAGE) # 3. Calculate start and end indices start = (page - 1) * POSTS_PER_PAGE end = start + POSTS_PER_PAGE # 4. Slice the list for the current page posts_to_show = all_posts[start:end] # 5. Determine if there is a next or previous page prev_url = url_for('home', page=page - 1) if page > 1 else None next_url = url_for('home', page=page + 1) if end < len(all_posts) else None return render_template('index.html', posts=posts_to_show, prev_url=prev_url, next_url=next_url, current_page=page, blog_title=blog_title, total_pages=total_pages) @app.route('/about') def about(): about_txt = ABOUT """Renders the About page.""" return render_template('about.html', about_txt = about_txt, blog_title = TITLE) @app.route('/post/') def post_detail(post_id): """Renders a single post detail page.""" # 1. Look up the post dictionary post = next((p for p in BLOG_POSTS if p['id'] == post_id), None) if post is None: return "Post not found", 404 #get comments 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"] = """
  • moved some web-based tools to localhost

    a testing page for blog preview and some string formatter...
    It's also my first time to correctly using git, to upload edited pages directly via rsync and synchronization via git.

  • Editing

    added a timeline component,
    but I have to generate a timeline html and paste it as text,
    then paste into content generation, and the upload to blog.

  • Packing blog in Docker

    uwsgi + flask -> caddy, gunicorn, flask, docker

  • moved all wiki pages into one repository

    have been using gitea's wiki page to take notes, which is a life-saver
    I made a script to pull all wiki pages into one repository, now I have a way to save all my notes.

  • scoop update vscode

    VS Code was always hanging for two months.

  • /root partition is full

    pacman -Sc doesnt work anymore
    I am confused very confused
    started to move gitea from /etc to /home
    accidentally deleted all gitea data...then recovered with a previous gitea dump

  • have another gitea instance, docker

    all repositories have a mirror now

  • Tailscale ip doesnt work

    system-wide caddy worked for https://ip
    but docked caddy didnt work for https://ip
    I have no clue...

  • language tool

    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.

  • """ # 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) if __name__ == '__main__': app.run(debug=True)