comments
This commit is contained in:
parent
30575bcf20
commit
c548e8c406
120
main
120
main
|
@ -2,8 +2,10 @@
|
||||||
import os
|
import os
|
||||||
import configparser
|
import configparser
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
import time
|
||||||
import json
|
import json
|
||||||
import secrets
|
import secrets
|
||||||
|
from itertools import groupby
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from flask import Flask, render_template, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request
|
from flask import Flask, render_template, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request
|
||||||
|
@ -27,7 +29,7 @@ if SECRET_KEY == "placeholder":
|
||||||
print("[WARNING] Secret key is not set")
|
print("[WARNING] Secret key is not set")
|
||||||
|
|
||||||
if not os.path.exists(UPLOAD_FOLDER):
|
if not os.path.exists(UPLOAD_FOLDER):
|
||||||
print("[WARNING] Upload folder doesn't exist, creating one")
|
print("[WARNING] Upload folder doesn't exist, creating")
|
||||||
os.mkdir(UPLOAD_FOLDER)
|
os.mkdir(UPLOAD_FOLDER)
|
||||||
|
|
||||||
if not os.path.exists("database.db"):
|
if not os.path.exists("database.db"):
|
||||||
|
@ -55,6 +57,18 @@ def get_user(id):
|
||||||
return post
|
return post
|
||||||
|
|
||||||
|
|
||||||
|
def get_comments(id):
|
||||||
|
conn = get_db_connection()
|
||||||
|
post = conn.execute("SELECT * FROM comments WHERE post_id = ?",
|
||||||
|
(id,)).fetchall()
|
||||||
|
conn.close()
|
||||||
|
if post is None:
|
||||||
|
return "error"
|
||||||
|
return post
|
||||||
|
|
||||||
|
|
||||||
|
app.jinja_env.globals.update(getComments=get_comments)
|
||||||
|
|
||||||
def get_post(id):
|
def get_post(id):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
post = conn.execute("SELECT * FROM posts WHERE id = ?",
|
post = conn.execute("SELECT * FROM posts WHERE id = ?",
|
||||||
|
@ -100,8 +114,7 @@ def allowed_file(filename):
|
||||||
def main():
|
def main():
|
||||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
posts = conn.execute(
|
posts = conn.execute("SELECT * FROM posts ORDER BY created DESC;").fetchall()
|
||||||
"SELECT * FROM posts ORDER BY created DESC;").fetchall()
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
if usersession:
|
if usersession:
|
||||||
|
@ -111,7 +124,6 @@ def main():
|
||||||
else:
|
else:
|
||||||
return render_template("main.html", posts=posts)
|
return render_template("main.html", posts=posts)
|
||||||
|
|
||||||
|
|
||||||
@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")
|
||||||
|
@ -120,20 +132,20 @@ def post():
|
||||||
title = request.form["title"]
|
title = request.form["title"]
|
||||||
if title == "":
|
if title == "":
|
||||||
flash("Text required :3")
|
flash("Text required :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("post"))
|
||||||
|
|
||||||
if "file" not in request.files:
|
if "file" not in request.files:
|
||||||
flash("No file selected :3")
|
flash("No file selected :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("post"))
|
||||||
|
|
||||||
file = request.files["file"]
|
file = request.files["file"]
|
||||||
if file.filename == "":
|
if file.filename == "":
|
||||||
flash("No file selected :3")
|
flash("No file selected :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("post"))
|
||||||
|
|
||||||
if not allowed_file(file.filename):
|
if not allowed_file(file.filename):
|
||||||
flash("File is not an image!")
|
flash("File is not an image!")
|
||||||
return redirect(request.url)
|
return redirect(url_for("post"))
|
||||||
|
|
||||||
filename = secure_filename(file.filename)
|
filename = secure_filename(file.filename)
|
||||||
finalfilename = secrets.token_hex(64) + filename
|
finalfilename = secrets.token_hex(64) + filename
|
||||||
|
@ -147,16 +159,14 @@ def post():
|
||||||
if not user["banned"] == "0":
|
if not user["banned"] == "0":
|
||||||
flash("Your account has been banned. Reason: " +
|
flash("Your account has been banned. Reason: " +
|
||||||
user["banned"])
|
user["banned"])
|
||||||
return redirect(request.url)
|
return redirect(url_for("post"))
|
||||||
|
|
||||||
print(userCookie)
|
|
||||||
|
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("INSERT INTO posts (textstr, imageurl, creator) VALUES (?, ?, ?)",
|
conn.execute("INSERT INTO posts (textstr, imageurl, creator, created) VALUES (?, ?, ?, ?)",
|
||||||
(title, imgurl, userCookie["id"]))
|
(title, imgurl, userCookie["id"], str(time.time())))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return redirect("/")
|
return redirect(url_for("main"))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
userCookie = get_session(usersession)
|
userCookie = get_session(usersession)
|
||||||
|
@ -164,7 +174,40 @@ def post():
|
||||||
return render_template("post.html", userdata=user)
|
return render_template("post.html", userdata=user)
|
||||||
else:
|
else:
|
||||||
flash("A burgercat account is required to post :3")
|
flash("A burgercat account is required to post :3")
|
||||||
return redirect("/login")
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/comment", methods=("GET", "POST"))
|
||||||
|
def comment():
|
||||||
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
|
if usersession:
|
||||||
|
if request.method == "POST":
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
uid = data["id"]
|
||||||
|
title = data["title"]
|
||||||
|
|
||||||
|
userCookie = get_session(usersession)
|
||||||
|
user = get_user(userCookie["id"])
|
||||||
|
|
||||||
|
if not user["banned"] == "0":
|
||||||
|
flash("Your account has been banned. Reason: " +
|
||||||
|
user["banned"])
|
||||||
|
return redirect(url_for("comment"))
|
||||||
|
|
||||||
|
conn = get_db_connection()
|
||||||
|
conn.execute("INSERT INTO comments (textstr, post_id, creator, created) VALUES (?, ?, ?, ?)",
|
||||||
|
(title, uid, userCookie["id"], str(time.time())))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return "success"
|
||||||
|
|
||||||
|
else:
|
||||||
|
return """<img src="https://http.cat/images/400.jpg">""", 400
|
||||||
|
else:
|
||||||
|
flash("A burgercat account is required to post :3")
|
||||||
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/cdn/<filename>", methods=("GET", "POST"))
|
@app.route("/cdn/<filename>", methods=("GET", "POST"))
|
||||||
|
@ -179,29 +222,29 @@ def cdn(filename):
|
||||||
def signup():
|
def signup():
|
||||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
if usersession:
|
if usersession:
|
||||||
return redirect("/")
|
return redirect(url_for("main"))
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if not check_username_taken(request.form["username"]) == "error":
|
if not check_username_taken(request.form["username"]) == "error":
|
||||||
flash("Username already taken :3")
|
flash("Username already taken :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("signup"))
|
||||||
|
|
||||||
if not request.form["username"].isalnum():
|
if not request.form["username"].isalnum():
|
||||||
flash("Username must be alphanumeric :3")
|
flash("Username must be alphanumeric :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("signup"))
|
||||||
|
|
||||||
if not len(request.form["password"]) > int(PASSWORD_REQUIREMENT):
|
if not len(request.form["password"]) > int(PASSWORD_REQUIREMENT):
|
||||||
flash("Password must contain at least " + PASSWORD_REQUIREMENT + " characters")
|
flash("Password must contain at least " + PASSWORD_REQUIREMENT + " characters")
|
||||||
return redirect(request.url)
|
return redirect(url_for("signup"))
|
||||||
|
|
||||||
hashedpassword = generate_password_hash(request.form["password"])
|
hashedpassword = generate_password_hash(request.form["password"])
|
||||||
|
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("INSERT INTO users (username, password) VALUES (?, ?)",
|
conn.execute("INSERT INTO users (username, password, created) VALUES (?, ?, ?)",
|
||||||
(request.form["username"], hashedpassword))
|
(request.form["username"], hashedpassword, str(time.time())))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
return redirect("/login")
|
return redirect(url_for("login"))
|
||||||
else:
|
else:
|
||||||
return render_template("signup.html")
|
return render_template("signup.html")
|
||||||
|
|
||||||
|
@ -210,18 +253,18 @@ def signup():
|
||||||
def login():
|
def login():
|
||||||
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
usersession = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
if usersession:
|
if usersession:
|
||||||
return redirect("/")
|
redirect(url_for("main"))
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
userID = check_username_taken(request.form["username"])
|
userID = check_username_taken(request.form["username"])
|
||||||
user = get_user(userID)
|
user = get_user(userID)
|
||||||
|
|
||||||
if user == "error":
|
if user == "error":
|
||||||
flash("Wrong username or password :3")
|
flash("Wrong username or password :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
if not check_password_hash(user["password"], (request.form["password"])):
|
if not check_password_hash(user["password"], (request.form["password"])):
|
||||||
flash("Wrong username or password :3")
|
flash("Wrong username or password :3")
|
||||||
return redirect(request.url)
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
randomCharacters = secrets.token_hex(512)
|
randomCharacters = secrets.token_hex(512)
|
||||||
|
|
||||||
|
@ -267,7 +310,7 @@ def remove(postid):
|
||||||
else:
|
else:
|
||||||
return "nice try"
|
return "nice try"
|
||||||
else:
|
else:
|
||||||
return redirect("/login")
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
@app.route("/listusers", methods=("GET", "POST"))
|
@app.route("/listusers", methods=("GET", "POST"))
|
||||||
def listusers():
|
def listusers():
|
||||||
|
@ -286,32 +329,39 @@ def listusers():
|
||||||
|
|
||||||
return thing
|
return thing
|
||||||
else:
|
else:
|
||||||
return "nice try"
|
return """<img src="https://http.cat/images/403.jpg">"""
|
||||||
else:
|
else:
|
||||||
return redirect("/login")
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/settings/logout", methods=("GET", "POST"))
|
@app.route("/settings/logout", methods=("GET", "POST"))
|
||||||
def logout():
|
def logout():
|
||||||
resp = redirect("/")
|
resp = redirect(url_for("main"))
|
||||||
session = request.cookies.get("session_DO_NOT_SHARE")
|
session = request.cookies.get("session_DO_NOT_SHARE")
|
||||||
resp.delete_cookie("session_DO_NOT_SHARE")
|
resp.delete_cookie("session_DO_NOT_SHARE")
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
@app.errorhandler(500)
|
||||||
|
def page_not_found(e):
|
||||||
|
return """<img src="https://http.cat/images/500.jpg">""", 500
|
||||||
|
|
||||||
|
@app.errorhandler(400)
|
||||||
|
def page_not_found(e):
|
||||||
|
return """<img src="https://http.cat/images/400.jpg">""", 400
|
||||||
|
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def page_not_found(e):
|
||||||
|
return """<img src="https://http.cat/images/404.jpg">""", 404
|
||||||
|
|
||||||
@app.errorhandler(413)
|
@app.errorhandler(413)
|
||||||
def page_not_found(e):
|
def page_not_found(e):
|
||||||
return "the server decided to commit die"
|
return "Images can't be larger than 4MB", 413
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(413)
|
|
||||||
def page_not_found(e):
|
|
||||||
return "Images can't be larger than 4MB"
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from waitress import serve
|
from waitress import serve
|
||||||
print("[INFO] Server started")
|
print("[INFO] Server started")
|
||||||
serve(app, host=HOST, port=PORT)
|
serve(app, host=HOST, port=PORT)
|
||||||
|
#app.run(host=HOST, port=PORT, debug=True)
|
||||||
print("[INFO] Server stopped")
|
print("[INFO] Server stopped")
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
burger social media
|
|
||||||
|
|
||||||
self hosting:
|
|
||||||
- git clone https://codeberg.org/burger-software/burgercat
|
|
||||||
- cd burgercat
|
|
||||||
- python init_db
|
|
||||||
- python main
|
|
|
@ -1,2 +1,3 @@
|
||||||
flask
|
flask
|
||||||
werkzeug
|
werkzeug
|
||||||
|
waitress
|
13
schema.sql
13
schema.sql
|
@ -1,10 +1,11 @@
|
||||||
DROP TABLE IF EXISTS users;
|
DROP TABLE IF EXISTS users;
|
||||||
DROP TABLE IF EXISTS posts;
|
DROP TABLE IF EXISTS posts;
|
||||||
|
DROP TABLE IF EXISTS comments;
|
||||||
DROP TABLE IF EXISTS sessions;
|
DROP TABLE IF EXISTS sessions;
|
||||||
|
|
||||||
CREATE TABLE users (
|
CREATE TABLE users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created TEXT NOT NULL,
|
||||||
username TEXT NOT NULL,
|
username TEXT NOT NULL,
|
||||||
password TEXT NOT NULL,
|
password TEXT NOT NULL,
|
||||||
banned TEXT NOT NULL DEFAULT 0,
|
banned TEXT NOT NULL DEFAULT 0,
|
||||||
|
@ -13,12 +14,20 @@ CREATE TABLE users (
|
||||||
|
|
||||||
CREATE TABLE posts (
|
CREATE TABLE posts (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created TEXT NOT NULL,
|
||||||
creator TEXT NOT NULL,
|
creator TEXT NOT NULL,
|
||||||
imageurl TEXT NOT NULL,
|
imageurl TEXT NOT NULL,
|
||||||
textstr TEXT NOT NULL
|
textstr TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE comments (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
post_id INTEGER NOT NULL,
|
||||||
|
created TEXT NOT NULL,
|
||||||
|
creator TEXT NOT NULL,
|
||||||
|
textstr TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE sessions (
|
CREATE TABLE sessions (
|
||||||
session TEXT PRIMARY KEY NOT NULL,
|
session TEXT PRIMARY KEY NOT NULL,
|
||||||
id INTEGER NOT NULL
|
id INTEGER NOT NULL
|
||||||
|
|
|
@ -22,6 +22,9 @@ body {
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
border-bottom-width: 2px;
|
border-bottom-width: 2px;
|
||||||
}
|
}
|
||||||
|
.postDiv {
|
||||||
|
padding-top: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
.accountform {
|
.accountform {
|
||||||
margin-left: 20%;
|
margin-left: 20%;
|
||||||
|
@ -85,6 +88,41 @@ body {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.post button {
|
||||||
|
background-color: rgb(250, 250, 250);
|
||||||
|
border: solid;
|
||||||
|
border-color: rgb(197, 197, 197);
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
}
|
||||||
|
.post button:hover {
|
||||||
|
border-color: #f1b739;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post .commentdiv input {
|
||||||
|
background-color: rgb(250, 250, 250);
|
||||||
|
border: solid;
|
||||||
|
border-color: rgb(197, 197, 197);
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-top: 5px;
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
}
|
||||||
|
.post hr {
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
border-color: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
.post .commentsdiv {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.post .username {
|
.post .username {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
@ -92,3 +130,7 @@ body {
|
||||||
.post .date {
|
.post .date {
|
||||||
color: rgb(175, 175, 175);
|
color: rgb(175, 175, 175);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
const posts = document.getElementsByClassName("post")
|
||||||
|
for (let i = 0; i < posts.length; i++) {
|
||||||
|
let post = posts[i]
|
||||||
|
let commentButton = post.children["commentButton"]
|
||||||
|
let commentId = post.children["commentId"]
|
||||||
|
let commentDiv = post.children["commentDiv"]
|
||||||
|
let commentBox = commentDiv.children["commentBox"]
|
||||||
|
let commentSave = commentDiv.children["commentDivSave"]
|
||||||
|
let commentCancel = commentDiv.children["commentDivCancel"]
|
||||||
|
|
||||||
|
commentButton.addEventListener("click", (e) => {
|
||||||
|
commentDiv.classList.remove("hidden")
|
||||||
|
commentBox.value = ""
|
||||||
|
});
|
||||||
|
commentCancel.addEventListener("click", (e) => {
|
||||||
|
commentDiv.classList.add("hidden")
|
||||||
|
});
|
||||||
|
commentSave.addEventListener("click", (e) => {
|
||||||
|
console.log(commentId.innerHTML)
|
||||||
|
title = String(commentBox.value)
|
||||||
|
id = String(commentId.innerHTML)
|
||||||
|
|
||||||
|
fetch("/comment", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: id,
|
||||||
|
title: title,
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((json) => console.log(json));
|
||||||
|
|
||||||
|
commentDiv.classList.add("hidden")
|
||||||
|
});
|
||||||
|
}
|
|
@ -23,12 +23,16 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br><br><br><br><br><br>
|
<script>
|
||||||
|
let timeStampElement
|
||||||
|
let unixTime
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="postDiv">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
<div class="post">
|
<div class="post" id="post">
|
||||||
<p class="username">{{ getUser(post["creator"])["username"] }}</p>
|
<p class="username">{{ getUser(post["creator"])["username"] }}</p>
|
||||||
<p class="date">{{ post["created"] }}</p>
|
<p class="date" id='timestamp_{{post["id"]}}'> </p>
|
||||||
{% if userdata %}
|
{% if userdata %}
|
||||||
{% if userdata.administrator == 1 %}
|
{% if userdata.administrator == 1 %}
|
||||||
<a class="date" href='/remove/{{post["id"]}}'>Remove post</a>
|
<a class="date" href='/remove/{{post["id"]}}'>Remove post</a>
|
||||||
|
@ -37,9 +41,58 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<img loading="lazy" src='{{ post["imageurl"] }}'>
|
<img loading="lazy" src='{{ post["imageurl"] }}'>
|
||||||
<p class="text">{{ post["textstr"] }}</p>
|
<p class="text">{{ post["textstr"] }}</p>
|
||||||
|
<div class="commentsdiv">
|
||||||
|
{% for comment in getComments(post["id"]) %}
|
||||||
|
<p>{{ getUser(comment["creator"])["username"] }}: {{ comment.textstr }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<p id="commentId" class="hidden">{{ post.id }}</p>
|
||||||
|
<button id="commentButton" class="comment">comment</button>
|
||||||
|
<div id="commentDiv" class="commentdiv hidden">
|
||||||
|
<input id="commentBox" type="text" placeholder="content">
|
||||||
|
<button id="commentDivSave">save</button>
|
||||||
|
<button id="commentDivCancel">cancel</button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function time2TimeAgo(ts) {
|
||||||
|
var d = new Date();
|
||||||
|
var nowTs = Math.floor(d.getTime() / 1000);
|
||||||
|
var seconds = nowTs - ts;
|
||||||
|
|
||||||
|
var interval = seconds / 31536000;
|
||||||
|
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " years ago";
|
||||||
|
}
|
||||||
|
interval = seconds / 2592000;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " months ago";
|
||||||
|
}
|
||||||
|
interval = seconds / 86400;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " days ago";
|
||||||
|
}
|
||||||
|
interval = seconds / 3600;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " hours ago";
|
||||||
|
}
|
||||||
|
interval = seconds / 60;
|
||||||
|
if (interval > 1) {
|
||||||
|
return Math.floor(interval) + " minutes ago";
|
||||||
|
}
|
||||||
|
return Math.floor(seconds) + " seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
timeStampElement = document.getElementById('timestamp_{{post["id"]}}')
|
||||||
|
unixTime = '{{post["created"]}}'
|
||||||
|
|
||||||
|
timeStampElement.innerHTML = time2TimeAgo(unixTime)
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/js/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -54,8 +54,6 @@
|
||||||
<li>Advertising is not allowed</li>
|
<li>Advertising is not allowed</li>
|
||||||
<li>Do not post links</li>
|
<li>Do not post links</li>
|
||||||
<li>Do not create alt-accounts to evade bans</li>
|
<li>Do not create alt-accounts to evade bans</li>
|
||||||
<br>
|
|
||||||
In general, just be a good person.
|
|
||||||
</ul>
|
</ul>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,13 +23,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br><br><br><br><br><br>
|
<br><br><br><br><br><br><br>
|
||||||
<div class="post">
|
<div class="post">
|
||||||
{% if userdata.administrator == 1 %}
|
{% if userdata.administrator == 1 %}
|
||||||
Administrator<br><br>
|
Administrator<br><br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Logged in as {{ userdata.username }}<br>
|
Logged in as {{ userdata.username }}
|
||||||
Your user ID is {{ userdata.id }}
|
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href="/settings/logout">Log out</a>
|
<a href="/settings/logout">Log out</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in New Issue