103 lines
2.5 KiB
Python
103 lines
2.5 KiB
Python
import os
|
|
import time
|
|
import psycopg2
|
|
from flask import Flask, render_template, request, redirect, url_for
|
|
|
|
app = Flask(__name__)
|
|
|
|
DB_HOST = os.environ.get("DB_HOST", "postgres-service.todo-app.svc.cluster.local")
|
|
DB_NAME = os.environ.get("DB_NAME", "tododb")
|
|
DB_USER = os.environ.get("DB_USER", "postgres")
|
|
DB_PASS = os.environ.get("DB_PASS", "postgres123")
|
|
|
|
|
|
def get_db():
|
|
for attempt in range(10):
|
|
try:
|
|
conn = psycopg2.connect(
|
|
host=DB_HOST, database=DB_NAME, user=DB_USER, password=DB_PASS
|
|
)
|
|
return conn
|
|
except psycopg2.OperationalError:
|
|
time.sleep(2)
|
|
raise Exception("Cannot connect to database after 10 attempts")
|
|
|
|
|
|
def init_db():
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
cur.execute("""
|
|
CREATE TABLE IF NOT EXISTS todos (
|
|
id SERIAL PRIMARY KEY,
|
|
title TEXT NOT NULL,
|
|
done BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""")
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
|
|
|
|
@app.before_request
|
|
def setup():
|
|
# Only run once
|
|
pass
|
|
|
|
|
|
@app.route("/")
|
|
def index():
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT id, title, done, created_at FROM todos ORDER BY id DESC")
|
|
todos = cur.fetchall()
|
|
cur.close()
|
|
conn.close()
|
|
done_count = sum(1 for t in todos if t[2])
|
|
return render_template("index.html", todos=todos, done_count=done_count, total=len(todos))
|
|
|
|
|
|
@app.route("/add", methods=["POST"])
|
|
def add():
|
|
title = request.form.get("title", "").strip()
|
|
if title:
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
cur.execute("INSERT INTO todos (title, done) VALUES (%s, FALSE)", (title,))
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
return redirect(url_for("index"))
|
|
|
|
|
|
@app.route("/toggle/<int:todo_id>")
|
|
def toggle(todo_id):
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
cur.execute("UPDATE todos SET done = NOT done WHERE id = %s", (todo_id,))
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
return redirect(url_for("index"))
|
|
|
|
|
|
@app.route("/delete/<int:todo_id>")
|
|
def delete(todo_id):
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
cur.execute("DELETE FROM todos WHERE id = %s", (todo_id,))
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
return redirect(url_for("index"))
|
|
|
|
|
|
@app.route("/health")
|
|
def health():
|
|
return {"status": "ok"}, 200
|
|
|
|
|
|
if __name__ == "__main__":
|
|
init_db()
|
|
app.run(host="0.0.0.0", port=5000, debug=False)
|