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()