From a9596734e42907feffa3c3f6fc93f09c6a6c5640 Mon Sep 17 00:00:00 2001 From: gabriel Date: Tue, 23 Sep 2025 00:45:03 +0200 Subject: [PATCH] Added main backend components --- config-uwsgi.ini | 14 ++ server.py | 375 +++++++++++++++++++++++++++++++++++++++++++++++ wsgi.py | 5 + 3 files changed, 394 insertions(+) create mode 100644 config-uwsgi.ini create mode 100755 server.py create mode 100644 wsgi.py diff --git a/config-uwsgi.ini b/config-uwsgi.ini new file mode 100644 index 0000000..9d5c77e --- /dev/null +++ b/config-uwsgi.ini @@ -0,0 +1,14 @@ +[uwsgi] +module = wsgi:app + +plugins = python3 + +socket = /tmp/myapp.sock +chmod-socket = 660 +chown-socket = www-data:www-data +vacuum = true +buffer-size=32768 +master = true +processes = 4 +logto = /var/log/nginx/%n.log +die-on-term = true diff --git a/server.py b/server.py new file mode 100755 index 0000000..c756d57 --- /dev/null +++ b/server.py @@ -0,0 +1,375 @@ +#!/bin/python3 + +from flask import Flask, request, render_template, Response, send_file, g, url_for, redirect, make_response +from random import randint +import requests +import datetime +import smtplib +import flask +import time +import os +import json + +app = Flask(__name__, static_url_path="", static_folder="static", template_folder="templates") + +app.config['msgTime'] = datetime.datetime.now() +app.config['reloadTime'] = datetime.datetime.now() + + +weekday = [ + "Mon", "Tue", "Wed", "Thu", + "Fri", "Sat", "Sun" +] + +def getIpInfo(ip): + try: + endpoint = f'https://ipinfo.io/{ip}/json' + response = requests.get(endpoint, verify = True) + + if response.status_code != 200: + return None + + return response.json() + except: + return None + + +def logConnection(req:request, site:str): + + scraper = False + ipInfo = getIpInfo(request.remote_addr); + + logStr = f"{ req.remote_addr } connected on '{ time.asctime() }' to '{ site }' with user-agent '{ req.user_agent }'" + + logFile = open(f"log/{datetime.datetime.now().strftime('%d.%m.%Y')}.log", "a") + + try: + logStr += f"\n^\tIP Country: '{ipInfo['country']}'\t" + logStr += f"Region: '{ipInfo['region']}'\t" + logStr += f"City: '{ipInfo['city']}'\t" + logStr += f"Org: '{ipInfo['org']}'\t" + + for i in app.config["config"]["blacklist"]: + if ipInfo['org'].lower().find(i.lower()) != -1: + scraper = True + logFile.write("Scraper detected, redirecting that fucko\n") + + logStr += f"Hostname: '{ipInfo['hostname']}'" + + + except: + logStr += "\n^\tError with IP-Info getter" + + logFile.write(f"{logStr}\n\n") + logFile.close() + + if scraper: + flask.abort(406) + +def generateNavbar(selectedElement): + return render_template("inline/navbar.html", navContent=app.config["config"]["navbar"], navSel=selectedElement, + randomQuote=app.config["quote"][0], + todos=app.config["todo"], + updates=app.config["updates"], + rndShit=app.config["random"][randint(0, len(app.config["random"])-1)]) + + +def generateFooter(): + updTime = datetime.datetime.fromtimestamp(os.path.getmtime("static/docs/config.json")) + timeStr = f"{updTime.day}.{updTime.month}.{updTime.year} ({weekday[updTime.weekday()]})" + + return render_template("inline/footer.html", buttons=app.config["config"]["buttons"], updated=timeStr) + + +def generateStyle(): + style = """ + + """ + + return style + +def getMultiples(i) -> str: #lol + ret = "s" + if i == 1: + ret = "" + return ret + + +@app.errorhandler(406) +def not_found_error(error): + return render_template("scraper.html"), 406 + +@app.before_request +def reload_jsons(anyway=False): + + try: + test = app.config["config"]["navbar"] + except: + anyway = True + + if anyway or (datetime.datetime.now() - app.config['reloadTime']).seconds > 5: + todoRaw = open("static/docs/todo.json", "r") + app.config["todo"] = json.load(todoRaw)["todo"] + + randomRaw = open("static/docs/random.json", "r") + app.config["random"] = json.load(randomRaw)["rnd"] + + quoteRaw = open("static/docs/lessons.json", "r") + app.config["quote"] = json.load(quoteRaw)["lessons"] + + funRaw = open("static/docs/funfacts.json", "r") + app.config["fun"] = json.load(funRaw)["funfacts"] + + updatesRaw = open("static/docs/updates.json", "r") + app.config["updates"] = json.load(updatesRaw)["updates"] + + photobookRaw = open("static/docs/photobook.json", "r") + app.config["photobook"] = json.load(photobookRaw)["photobook"] + + configRaw = open("static/docs/config.json", "r") + app.config["config"] = json.load(configRaw) + + passwordRaw = open("static/docs/mailpassword", "r") + app.config["password"] = passwordRaw.readlines()[0].replace("\n", "") + + todoRaw.close() + randomRaw.close() + quoteRaw.close() + funRaw.close() + updatesRaw.close() + photobookRaw.close() + configRaw.close() + passwordRaw.close() + + app.config["reloadTime"] = datetime.datetime.now() + + print("Reloaded JSON's") + + if not anyway: + if request.method == "POST": + if "test" in request.form: + print("bruh") + + +@app.route("/", methods=["GET", "POST"]) +def homepage(): + logConnection(request, "homepage"); + + diff = datetime.datetime.now() - datetime.datetime(2006, 3, 30) + error = "" + textinput = "" + TEXTLEN = app.config["config"]["Textlength"] + RATELIM = app.config["config"]["Ratelimit"] + + if request.method == "POST": + textinput = request.form["textvalue"] + + if "send" in request.form: + if (datetime.datetime.now() - app.config['msgTime']).seconds < RATELIM: + waitTime = RATELIM - ((datetime.datetime.now() - app.config['msgTime']).seconds) + error = f"Messages are rate limited. Please wait {waitTime} second{getMultiples(waitTime)} before trying again." + + elif len(textinput) > TEXTLEN : + remChars = len(textinput) - TEXTLEN + error = f"Your text is too long. Trim by {remChars} char{getMultiples(remChars)}." + + elif len(textinput) < 3: + error = "Too short lol" + + else: + msg = open(f"messages/{datetime.datetime.now().strftime('%d.%m.%Y - %H:%M:%S')} : {request.remote_addr}", "w") + + txt = f"IP: '{request.remote_addr}' with user-agent '{request.user_agent}' wrote:\n\n----------\n\n{textinput}\n\n--------\n\n" + msg.write(txt) + + info = "" + try: + info = getIpInfo(request.remote_addr) + msg.write(str(info)) + except: + None + + msg.close(); + + + s = smtplib.SMTP("mail.weingardt.dev", 587) + s.starttls() + s.login("messages", app.config["password"]) + + try: + s.sendmail("messages@weingardt.dev", "gabriel@weingardt.dev", f"Subject: NEW MESSAGE FUCKO\n\n{txt}\n\n{info}") + except: + s.sendmail("messages@weingardt.dev", "gabriel@weingardt.dev", f"Subject: NEW MESSAGE BUT KINDOF BROKEN\n\nIdk, failed to send mail but u got a message") + + s.quit() + + textinput = "" + error = "Message send!" + + app.config['msgTime'] = datetime.datetime.now() + + elif "clear" in request.form: + textinput = "" + error = "" + + + return render_template("home.html", style=generateStyle(), navbar=generateNavbar("Home"), footer=generateFooter(), + lol="nope", errorValue=error, textvalue=textinput, textlength=TEXTLEN, ageinsert=f"{int(diff.days / 30 / 12)}") + + +@app.route("/me") +def me(): + logConnection(request, "me"); + + # Epic Birthday leak + diff = datetime.datetime.now() - datetime.datetime(2006, 3, 30) + + return render_template("me.html", style=generateStyle(), navbar=generateNavbar("Me"), footer=generateFooter(), + ageinsert=f"{int(diff.days / 30 / 12)}", + funfact=app.config["fun"][randint(0, len(app.config["fun"])-1)]) + + + +@app.route("/photobook/") +def photobook(pagenr="0"): + def generateContent(index) -> str: + ret = "" + style = "photo" + + if len(app.config["photobook"][index]) == 4: + style = app.config["photobook"][index][3] + + for i in app.config["photobook"][index][2]: + ret += f'' + + + return ret + + pagecarry = int(pagenr.split("&")[0]) + + nextDisabled = "" + previousDisabled = "" + + if pagenr.find("++") != -1: + return redirect(url_for("photobook", pagenr=str(pagecarry + 1))) + elif pagenr.find("--") != -1: + return redirect(url_for("photobook", pagenr=str(pagecarry - 1))) + elif pagenr.find("rnd") != -1: + return redirect(url_for("photobook", pagenr=str(randint(0, int(((len(app.config["photobook"]) - 1 )/2)) )))) + + logConnection(request, f"photobook/{pagecarry}") + + if pagecarry < 1: + previousDisabled = "disabled" + if pagecarry >= (len(app.config["photobook"])/2) - 1: + nextDisabled = "disabled" + + leftDate = "" + rightDate = "" + leftDesc = "" + rightDesc = "" + leftContent = "" + rightContent= "" + + for i in range(pagecarry*2, (pagecarry*2)+2): + if i >= len(app.config["photobook"]): + break + + if i % 2 == 0: + leftDate = app.config["photobook"][i][0] + leftDesc = app.config["photobook"][i][1] + leftContent = generateContent(i) + else: + rightDate = app.config["photobook"][i][0] + rightDesc = app.config["photobook"][i][1] + rightContent = generateContent(i) + + return render_template("photobook.html", nextDisabled=nextDisabled, previousDisabled=previousDisabled, + pageLeftDate=leftDate, pageRightDate=rightDate, + pageLeftDesc=leftDesc, pageRightDesc=rightDesc, + contentLeftInsert=leftContent, contentRightInsert=rightContent) + +@app.route("/photobook") +def photobook_redirect(): + return redirect(url_for("photobook", pagenr="0")) + +@app.route("/info") +def info(): + logConnection(request, "info") + return render_template("info.html", style=generateStyle(), navbar=generateNavbar("Info"), footer=generateFooter()) + + +@app.route("/ls7") +def ls7(): + logConnection(request, "ls7.html") + return render_template("ls7.html") + + +@app.route("/projects") +def projects(): + logConnection(request, "projects") + return render_template("projects.html", style=generateStyle(), navbar=generateNavbar("Projects"), footer=generateFooter()) + + +@app.route("/posts") +def posts(): + logConnection(request, "posts") + return render_template("posts.html", style=generateStyle(), navbar=generateNavbar("Posts"), footer=generateFooter()) + + +@app.route("/misc") +def misc(): + logConnection(request, "misc") + return render_template("misc.html", style=generateStyle(), navbar=generateNavbar("Misc"), footer=generateFooter()) + +@app.route("/lessons") +def lessons(): + logConnection(request, "lessons") + + return render_template("lessons.html", style=generateStyle(), randomQuote=app.config["quote"]) + +@app.route("/ssup") +def ssup(): + logConnection(request, "ssup") + + return render_template("ssup.html", style=generateStyle(), navbar=generateNavbar("Projects"), footer=generateFooter()) + +@app.route("/changestyle", methods=["GET","POST"]) +def changeStyle(): + resp = make_response("Set style cookie") + + if request.method == "POST": + if "change" in request.form: + print(request.form["stylebox"]) + #resp.set_cookie("style", request.form["stylebox"]) + + return resp + + +if __name__ == "__main__": + reload_jsons(True) + app.run(host="0.0.0.0") diff --git a/wsgi.py b/wsgi.py new file mode 100644 index 0000000..eb345d9 --- /dev/null +++ b/wsgi.py @@ -0,0 +1,5 @@ +from server import app, reload_jsons + +if __name__ == "__main__": + reload_jsons(True) + app.run()