commit 3f102522029fdabe021571220cf985d085b79c8205315f025b1ef5ed36e44833
Author: Cybrkyd <git@cybrkyd.com>
Date: Thu May 28 10:56:10 2026 +0100
First commit
diff --git a/budget.py b/budget.py
new file mode 100644
index 0000000..5020da2
--- /dev/null
+++ b/budget.py
@@ -0,0 +1,109 @@
+ from http.server import BaseHTTPRequestHandler, HTTPServer
+ from urllib.parse import parse_qs
+ import sqlite3
+ from datetime import datetime
+
+ DB = "budget.db"
+
+
+ def init_db():
+ with sqlite3.connect(DB) as conn:
+ conn.execute("""
+ CREATE TABLE IF NOT EXISTS entries (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ amount REAL NOT NULL,
+ created_at TEXT NOT NULL
+ )
+ """)
+
+
+ def get_balance():
+ with sqlite3.connect(DB) as conn:
+ cur = conn.execute("SELECT COALESCE(SUM(amount), 0) FROM entries")
+ return cur.fetchone()[0]
+
+
+ def get_month_total():
+ now = datetime.now()
+ start = datetime(now.year, now.month, 1)
+ end = datetime(now.year + (now.month // 12), ((now.month % 12) + 1), 1)
+
+ with sqlite3.connect(DB) as conn:
+ cur = conn.execute("""
+ SELECT COALESCE(SUM(amount), 0)
+ FROM entries
+ WHERE created_at >= ? AND created_at < ?
+ """, (start.isoformat(), end.isoformat()))
+ return cur.fetchone()[0]
+
+
+ HTML = """
+ <!doctype html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <title>Budget Tracker</title>
+ </head>
+ <body>
+
+ <h1>Budget Tracker</h1>
+
+ <form method="POST" action="/add">
+ <input name="amount" type="number" step="0.01" placeholder="Amount (+ or -)" required>
+ <button type="submit">Add</button>
+ </form>
+
+ <h2>All Time Balance</h2>
+ <p>{balance:.2f}</p>
+
+ <h2>This Month</h2>
+ <p>{month:.2f}</p>
+
+ </body>
+ </html>
+ """
+
+
+ class Handler(BaseHTTPRequestHandler):
+ def do_GET(self):
+ if self.path != "/":
+ self.send_error(404)
+ return
+
+ balance = get_balance()
+ month = get_month_total()
+
+ page = HTML.format(balance=balance, month=month)
+
+ self.send_response(200)
+ self.send_header("Content-type", "text/html")
+ self.end_headers()
+ self.wfile.write(page.encode())
+
+ def do_POST(self):
+ if self.path != "/add":
+ self.send_error(404)
+ return
+
+ length = int(self.headers["Content-Length"])
+ body = self.rfile.read(length).decode()
+ data = parse_qs(body)
+
+ amount = float(data["amount"][0])
+
+ with sqlite3.connect(DB) as conn:
+ conn.execute(
+ "INSERT INTO entries(amount, created_at) VALUES (?, ?)",
+ (amount, datetime.now().isoformat())
+ )
+
+ self.send_response(303)
+ self.send_header("Location", "/")
+ self.end_headers()
+
+
+ if __name__ == "__main__":
+ init_db()
+ print("Running on http://localhost:8080")
+ HTTPServer(("localhost", 8080), Handler).serve_forever()
+