added API

This commit is contained in:
maaa 2023-07-09 00:44:53 +02:00
parent e753c26605
commit ed6ab7cea0
3 changed files with 217 additions and 10 deletions

175
main
View File

@ -125,6 +125,159 @@ def main():
else: else:
return render_template("main.html", posts=posts) return render_template("main.html", posts=posts)
@app.route("/api/frontpage", methods=("GET", "POST"))
def apifrontpage():
conn = get_db_connection()
posts = conn.execute("SELECT * FROM posts ORDER BY created DESC;").fetchall()
conn.close()
result = []
for post in posts:
comments = []
for comment in get_comments(post["id"]):
commentthing = {
"title": comment["textstr"],
"created": comment["created"],
"creator": {
"id": comment["creator"],
"username": get_user(comment["creator"])["username"]
}
}
comments.append(commentthing)
mainthing = {
"id": post["id"],
"created": post["created"],
"title": post["textstr"],
"imgurl": post["imageurl"],
"creator": {
"id": post["creator"],
"username": get_user(post["creator"])["username"]
},
"comments": comments
}
result.append(mainthing)
return result
@app.route("/api/userinfo", methods=("GET", "POST"))
def apiuserinfo():
usersession = request.cookies.get("session_DO_NOT_SHARE")
if usersession:
userCookie = get_session(usersession)
user = get_user(userCookie["id"])
datatemplate = {
"username": user["username"],
"id": user["id"],
"created": user["created"]
}
return datatemplate
else:
return {
"error": "no authentication"
}, 403
@app.route("/api/login", methods=("GET", "POST"))
def apilogin():
usersession = request.cookies.get("session_DO_NOT_SHARE")
if request.method == "POST":
data = request.get_json()
username = data["username"]
password = data["password"]
userID = check_username_taken(username)
user = get_user(userID)
if user == "error":
return {
"error": "wrong username or password"
}, 401
if not check_password_hash(user["password"], (password)):
return {
"error": "wrong username or password"
}, 401
randomCharacters = secrets.token_hex(512)
conn = get_db_connection()
conn.execute("INSERT INTO sessions (session, id) VALUES (?, ?)",
(randomCharacters, userID))
conn.commit()
conn.close()
return {
"key": randomCharacters
}, 100
@app.route("/api/post", methods=("GET", "POST"))
def apipost():
usersession = request.cookies.get("session_DO_NOT_SHARE")
if usersession:
if request.method == "POST":
data = request.get_json()
title = data["id"]
if title == "":
return {
"error": "no title"
}, 403
if "file" not in request.files:
return {
"error": "no file"
}, 403
file = request.files["file"]
if file.filename == "":
return {
"error": "no file"
}, 403
if not allowed_file(file.filename):
return {
"error": "invalid file format"
}, 403
filename = secure_filename(file.filename)
finalfilename = secrets.token_hex(64) + filename
file.save(os.path.join(UPLOAD_FOLDER, finalfilename))
imgurl = "/cdn/" + finalfilename
userCookie = get_session(usersession)
user = get_user(userCookie["id"])
if not user["banned"] == "0":
return {
"error": "banned",
"reason": user["banned"]
}, 403
conn = get_db_connection()
conn.execute("INSERT INTO posts (textstr, imageurl, creator, created) VALUES (?, ?, ?, ?)",
(title, imgurl, userCookie["id"], str(time.time())))
conn.commit()
conn.close()
return "success", 100
@app.route("/apidocs", methods=("GET", "POST"))
def apidocs():
usersession = request.cookies.get("session_DO_NOT_SHARE")
if usersession:
userCookie = get_session(usersession)
user = get_user(userCookie["id"])
return render_template("apidocs.html", userdata=user)
else:
return render_template("apidocs.html")
@app.route("/post", methods=("GET", "POST")) @app.route("/post", methods=("GET", "POST"))
def post(): def post():
usersession = request.cookies.get("session_DO_NOT_SHARE") usersession = request.cookies.get("session_DO_NOT_SHARE")
@ -178,7 +331,7 @@ def post():
return redirect(url_for("login")) return redirect(url_for("login"))
@app.route("/comment", methods=("GET", "POST")) @app.route("/api/comment", methods=("GET", "POST"))
def comment(): def comment():
usersession = request.cookies.get("session_DO_NOT_SHARE") usersession = request.cookies.get("session_DO_NOT_SHARE")
if usersession: if usersession:
@ -192,9 +345,10 @@ def comment():
user = get_user(userCookie["id"]) user = get_user(userCookie["id"])
if not user["banned"] == "0": if not user["banned"] == "0":
flash("Your account has been banned. Reason: " + return {
user["banned"]) "error": "banned",
return redirect(url_for("comment")) "reason": user["banned"]
}, 403
conn = get_db_connection() conn = get_db_connection()
conn.execute("INSERT INTO comments (textstr, post_id, creator, created) VALUES (?, ?, ?, ?)", conn.execute("INSERT INTO comments (textstr, post_id, creator, created) VALUES (?, ?, ?, ?)",
@ -202,13 +356,16 @@ def comment():
conn.commit() conn.commit()
conn.close() conn.close()
return "success" return "success", 100
else: else:
return """<img src="https://http.cat/images/400.jpg">""", 400 return {
"error": "https://http.cat/images/400.jpg"
}, 400
else: else:
flash("A burgercat account is required to post :3") return {
return redirect(url_for("login")) "error": "https://http.cat/images/401.jpg"
}, 401
@app.route("/cdn/<filename>", methods=("GET", "POST")) @app.route("/cdn/<filename>", methods=("GET", "POST"))
@ -357,7 +514,7 @@ def page_not_found(e):
@app.errorhandler(413) @app.errorhandler(413)
def page_not_found(e): def page_not_found(e):
return "Images can't be larger than 4MB", 413 return "Images can't be larger than " + str(UPLOAD_LIMIT) + "MB", 413
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -32,7 +32,7 @@ for (let i = 0; i < posts.length; i++) {
commentBurgerDiv.append(para) commentBurgerDiv.append(para)
} }
fetch("/comment", { fetch("/api/comment", {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
id: id, id: id,

50
templates/apidocs.html Normal file
View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>burgercat</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" type="text/css" href="/static/css/style.css" />
</head>
<body>
<div class="navbar">
<h1>burgercat</h1>
<a href="/">home</a>
<a href="/post">post</a>
<a class="selected" href="/apidocs">API</a>
{% if userdata %}
<a href="/settings/logout" class="right r">log out</a>
<a href="/settings" class="right">{{ userdata.username }}</a>
{% else %}
<a href="/signup" class="right r">sign up</a>
<a href="/login" class="right">log in</a>
{% endif %}
</div>
<script>
let timeStampElement
let unixTime
</script>
<div class="postDiv">
<div class="post">
<h2>burgercat API documentation</h2>
for API things that require authentication, you will need to set the <code>session_DO_NOT_SHARE</code> cookie. the key might expire after 180 days.<br><br>
GET <code>/api/frontpage</code> - returns frontpage<br><br>
POST <code>/api/post</code> - post ctas - authentication required<br>
<code>title</code>, being the title of the post and <code>file</code>, being an image file.<br>
Supported file extensions: "png", "apng", "jpg", "jpeg", "gif", "svg", "webp"<br><br>
POST <code>/api/comment</code> - comment on posts - authentication required<br>
<code>title</code>, being the title of the comment and <code>id</code>, being the ID of the post you want to comment on.<br><br>
POST <code>/api/login</code> - get authentication key<br>
<code>username</code>, being the username and <code>password</code>, being the password. Returns authentication key.<br><br>
GET <code>/api/userinfo</code> - authentication required - Returns user info, username, ID, and account creation date.
</div>
</div>
</body>
</html>