From bf9a37e95268a9a5151f6ce056873fbf75fbc384 Mon Sep 17 00:00:00 2001 From: aggie Date: Thu, 11 Dec 2025 09:30:21 -0500 Subject: [PATCH] heee --- .editorconfig | 4 + .gitignore | 7 ++ .prettierrc | 4 + app.py | 135 +++++++++++++++++++++++++ last.id | 1 + requirements.txt | 4 + send_to_discord.py | 42 ++++++++ start.sh | 4 + static/draw.html | 84 ++++++++++++++++ static/draw.js | 83 +++++++++++++++ static/index.html | 229 ++++++++++++++++++++++++++++++++++++++++++ static/praises.html | 0 static/style.css | 40 ++++++++ static/thank-you.html | 16 +++ 14 files changed, 653 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 app.py create mode 100644 last.id create mode 100644 requirements.txt create mode 100644 send_to_discord.py create mode 100644 start.sh create mode 100644 static/draw.html create mode 100644 static/draw.js create mode 100644 static/index.html create mode 100644 static/praises.html create mode 100644 static/style.css create mode 100644 static/thank-you.html diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a9bef16 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.{py,html,css,js}] +indent_style = space +indent_size = 4 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f85ba6d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +database.db +.env +__pycache__/ +static/draws/* +/venv +/venv/ +/venv/* diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..cc4e915 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "trailingComma": "es5", + "semi": false +} diff --git a/app.py b/app.py new file mode 100644 index 0000000..46f94f2 --- /dev/null +++ b/app.py @@ -0,0 +1,135 @@ +import os +import subprocess +import sqlite3 +import requests +from dotenv import load_dotenv +from flask import Flask, redirect, request, jsonify, abort, render_template +from flask_talisman import Talisman + + +DATABASE = "database.db" +ALLOWED_EXTENSIONS = {"png", "webp"} + +env = load_dotenv() +SECRET_TOKEN = os.getenv("SECRET_TOKEN") +ENV = os.getenv("ENV") + +app = Flask( + __name__, static_url_path="/", static_folder="static", template_folder="static" +) +app.config["UPLOAD_FOLDER"] = "static/draws/" +app.config["MAX_CONTENT_LENGTH"] = 16 * 1000 * 1000 + + +def init_db(): + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute( + """CREATE TABLE IF NOT EXISTS posts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + content TEXT NOT NULL + )""" + ) + cursor.execute( + """CREATE TABLE IF NOT EXISTS draws ( + id INTEGER PRIMARY KEY AUTOINCREMENT + )""" + ) + conn.commit() + conn.close() + + +@app.route("/") +def index(): + return app.send_static_file("index.html") + + +@app.route("/praise", methods=["POST"]) +def create_post(): + if not request.json: + return jsonify({"error": "The request is not JSON"}), 400 + + content = request.json.get("content") + + if not content: + return jsonify({"error": "Content is required"}), 400 + + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("INSERT INTO posts (content) VALUES (?)", (content,)) + conn.commit() + post_id = cursor.lastrowid + conn.close() + + return jsonify({"id": post_id, "content": content}), 201 + + +@app.route("/praise-with-presets", methods=["POST"]) +def create_post_but_for_losers(): + a = request.form.get("a") + b = request.form.get("b") + c = request.form.get("c") + d = request.form.get("action") + + # WONTFIX cause funny + content = f"{a} {b} {c} {d}".strip() + + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("INSERT INTO posts (content) VALUES (?)", (content,)) + conn.commit() + conn.close() + + return redirect("/thank-you.html") + + +@app.route("/praises", methods=["GET"]) +def get_posts(): + auth_token = request.headers.get("Authorization") + if auth_token != SECRET_TOKEN: + abort(403) + + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("SELECT * FROM posts") + posts = [{"id": row[0], "content": row[1]} for row in cursor.fetchall()] + conn.close() + + return jsonify(posts), 200 + + +@app.route("/draw", methods=["GET", "POST"]) +def create_draw(): + if request.method == "GET": + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("SELECT * FROM draws") + images = cursor.fetchall() + conn.close() + return render_template("draw.html", images=images) + + if "image" not in request.files: + return jsonify({"error": "Content is requried"}), 400 + image = request.files["image"] + + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("INSERT INTO draws DEFAULT VALUES") + id = cursor.lastrowid + + os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) + path = os.path.join(app.config["UPLOAD_FOLDER"], f"{id}.png") + image.save(path) + conn.commit() + conn.close() + + return redirect(request.url) + + +if __name__ == "__main__": + init_db() + if ENV == "production": + Talisman(app, force_https=True) + subprocess.run(["gunicorn", "-w", "4", "-b", "0.0.0.0:3697", "app:app"]) + else: + app.run(host="0.0.0.0", port=3697) diff --git a/last.id b/last.id new file mode 100644 index 0000000..c793025 --- /dev/null +++ b/last.id @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..604c388 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +Flask +gunicorn>=20.0.4 +flask_talisman +python-dotenv diff --git a/send_to_discord.py b/send_to_discord.py new file mode 100644 index 0000000..7bf6c8d --- /dev/null +++ b/send_to_discord.py @@ -0,0 +1,42 @@ +import sqlite3 +import time +import requests +import os +from dotenv import load_dotenv + +load_dotenv() + +WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL") +DATABASE = "database.db" + +def send_to_discord(message): + if not WEBHOOK_URL: + print("No webhook set") + return + requests.post(WEBHOOK_URL, json={"content": message}) + +def main(): + last_id = 0 + + + if os.path.exists("last.id"): + with open("last.id", "r") as f: + last_id = int(f.read().strip()) + + while True: + conn = sqlite3.connect(DATABASE) + cursor = conn.cursor() + cursor.execute("SELECT id, content FROM posts WHERE id > ?", (last_id,)) + rows = cursor.fetchall() + conn.close() + + for post_id, content in rows: + send_to_discord(f"New praise #{post_id}: {content}") + last_id = post_id + with open("last.id", "w") as f: + f.write(str(last_id)) + + time.sleep(5) + +if __name__ == "__main__": + main() diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..dafb3f4 --- /dev/null +++ b/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash +pip3 install -r requirements.txt +python3 app.py +# gunicorn -w 4 -b 0.0.0.0:3000 app:app diff --git a/static/draw.html b/static/draw.html new file mode 100644 index 0000000..7bd9450 --- /dev/null +++ b/static/draw.html @@ -0,0 +1,84 @@ + + + + + + + Draw something for meow-d + + + + + + +

draw something for me!!

+
+ + +
+ + + + +
+ + +
+ + +
+
+ +
+

submssions

+
+ {% for image in images %} + + {% endfor %} +
+
+ + + diff --git a/static/draw.js b/static/draw.js new file mode 100644 index 0000000..ae201b6 --- /dev/null +++ b/static/draw.js @@ -0,0 +1,83 @@ +const canvas = document.getElementById("draw-canvas") +const ctx = canvas.getContext("2d") + +const width = canvas.clientWidth +const height = canvas.clientHeight +canvas.width = Math.floor(width * devicePixelRatio) +canvas.height = Math.floor(height * devicePixelRatio) +ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0) + +ctx.lineWidth = 2 +ctx.lineCap = "round" +ctx.lineJoin = "round" + +let prevX = null +let prevY = null +let isPainting = false + +canvas.addEventListener("mousedown", (e) => { + isPainting = true + draw(e) +}) +window.addEventListener("mouseup", () => (isPainting = false)) +canvas.addEventListener("mousemove", draw) +canvas.addEventListener("mouseenter", (e) => { + prevX = e.offsetX + prevY = e.offsetY +}) + +canvas.addEventListener("touchstart", (e) => { + e.preventDefault() + isPainting = true + draw(e) +}) +window.addEventListener("touchend", () => { + isPainting = false +}) +canvas.addEventListener("touchmove", (e) => { + e.preventDefault() + draw(e) +}) + +function draw(e) { + if (prevX == null || prevY == null || !isPainting) { + prevX = e.offsetX + prevY = e.offsetY + return + } + + let currentX = e.offsetX + let currentY = e.offsetY + + ctx.beginPath() + ctx.moveTo(prevX, prevY) + ctx.lineTo(currentX, currentY) + ctx.stroke() + + prevX = currentX + prevY = currentY +} + +function clearCanvas() { + isPainting = false + ctx.clearRect(0, 0, canvas.width, canvas.height) +} + +function saveImage() { + const dataURL = canvas.toDataURL() + const link = document.createElement("a") + link.href = dataURL + link.download = "canvas.png" + link.click() +} + +function submitImage() { + canvas.toBlob((image) => { + const input = document.getElementById("image-input") + const file = new File([image], "image.png", { type: "image/png" }) + const dataTransfer = new DataTransfer() + dataTransfer.items.add(file) + input.files = dataTransfer.files + document.getElementById("image-form").submit() + }) +} diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..e710083 --- /dev/null +++ b/static/index.html @@ -0,0 +1,229 @@ + + + + + + + Please Praise Me!!! + + + + +

pwease... praise me......

+i did not make this site originally; here's the code +
+

or: draw something for me!

+
+ +
+

send me stuff ;3

+

all fields are optional

+
+ + + +
+
+ + + + diff --git a/static/praises.html b/static/praises.html new file mode 100644 index 0000000..e69de29 diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..02cc287 --- /dev/null +++ b/static/style.css @@ -0,0 +1,40 @@ +body { + font-family: Arial, sans-serif; + max-width: 800px; + margin: 0 auto; + padding: 1em; +} + +code { + background-color: #f4f4f4; + border: 1px solid #ddd; + border-radius: 4px; + display: block; + margin: 1em 0; + padding: 1em; + overflow-x: auto; + white-space: pre-wrap; +} + +h2 { + margin-top: 4em; +} + +#a { + width: 200px; +} + +.dropdowns { + display: flex; + flex-wrap: wrap; + gap: 0.2em; + margin-bottom: 1em; +} + +.dropdowns select { + flex-grow: 1; +} + +.spacer { + flex-grow: 1; +} diff --git a/static/thank-you.html b/static/thank-you.html new file mode 100644 index 0000000..27b3eb8 --- /dev/null +++ b/static/thank-you.html @@ -0,0 +1,16 @@ + + + + + + + thank you!! + + + + +

asljfasdfadf thanks <3 aldjfldsjfa

+

praise me more..?

+ + +