112 lines
3.4 KiB
Python
112 lines
3.4 KiB
Python
import os
|
|
import psycopg2
|
|
from flask import Flask, request, redirect, url_for, render_template_string
|
|
|
|
app = Flask(__name__)
|
|
|
|
DB_HOST = os.environ.get("DB_HOST", "postgres-service")
|
|
DB_PORT = os.environ.get("DB_PORT", "5432")
|
|
DB_NAME = os.environ.get("DB_NAME", "notesdb")
|
|
DB_USER = os.environ.get("DB_USER", "notesuser")
|
|
DB_PASS = os.environ.get("DB_PASS", "notespass")
|
|
|
|
HTML = """
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Notes App</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; max-width: 600px; margin: 40px auto; padding: 0 20px; }
|
|
h1 { color: #333; }
|
|
form { margin-bottom: 30px; }
|
|
textarea { width: 100%%; height: 80px; padding: 8px; font-size: 14px; box-sizing: border-box; }
|
|
button { padding: 8px 20px; background: #0066cc; color: white; border: none; cursor: pointer; font-size: 14px; }
|
|
button:hover { background: #0052a3; }
|
|
.note { border: 1px solid #ddd; padding: 12px; margin-bottom: 10px; border-radius: 4px; }
|
|
.note small { color: #888; }
|
|
.delete { background: #cc0000; float: right; padding: 4px 10px; font-size: 12px; }
|
|
.delete:hover { background: #aa0000; }
|
|
.error { color: red; margin-bottom: 10px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>📝 Notes App</h1>
|
|
{% if error %}<p class="error">{{ error }}</p>{% endif %}
|
|
<form method="POST" action="/add">
|
|
<textarea name="content" placeholder="Write a note..." required></textarea><br><br>
|
|
<button type="submit">Add Note</button>
|
|
</form>
|
|
<h2>Notes ({{ notes|length }})</h2>
|
|
{% for note in notes %}
|
|
<div class="note">
|
|
<form method="POST" action="/delete/{{ note[0] }}" style="display:inline">
|
|
<button class="delete" type="submit">Delete</button>
|
|
</form>
|
|
<p>{{ note[1] }}</p>
|
|
<small>{{ note[2] }}</small>
|
|
</div>
|
|
{% endfor %}
|
|
{% if not notes %}<p>No notes yet.</p>{% endif %}
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
def get_conn():
|
|
return psycopg2.connect(
|
|
host=DB_HOST, port=DB_PORT,
|
|
dbname=DB_NAME, user=DB_USER, password=DB_PASS
|
|
)
|
|
|
|
def init_db():
|
|
conn = get_conn()
|
|
cur = conn.cursor()
|
|
cur.execute("""
|
|
CREATE TABLE IF NOT EXISTS notes (
|
|
id SERIAL PRIMARY KEY,
|
|
content TEXT NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
""")
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
|
|
@app.route("/")
|
|
def index():
|
|
try:
|
|
init_db()
|
|
conn = get_conn()
|
|
cur = conn.cursor()
|
|
cur.execute("SELECT id, content, created_at FROM notes ORDER BY created_at DESC")
|
|
notes = cur.fetchall()
|
|
cur.close()
|
|
conn.close()
|
|
return render_template_string(HTML, notes=notes, error=None)
|
|
except Exception as e:
|
|
return render_template_string(HTML, notes=[], error=f"DB error: {e}")
|
|
|
|
@app.route("/add", methods=["POST"])
|
|
def add():
|
|
content = request.form.get("content", "").strip()
|
|
if content:
|
|
conn = get_conn()
|
|
cur = conn.cursor()
|
|
cur.execute("INSERT INTO notes (content) VALUES (%s)", (content,))
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
return redirect(url_for("index"))
|
|
|
|
@app.route("/delete/<int:note_id>", methods=["POST"])
|
|
def delete(note_id):
|
|
conn = get_conn()
|
|
cur = conn.cursor()
|
|
cur.execute("DELETE FROM notes WHERE id = %s", (note_id,))
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
return redirect(url_for("index"))
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="0.0.0.0", port=5000)
|