suchwow/suchwow/routes/post.py

160 lines
6.2 KiB
Python

from datetime import datetime, timedelta
from os import path, remove
from io import BytesIO
from base64 import b64encode
from sys import audit
from qrcode import make as qrcode_make
from flask import render_template, Blueprint, request, session, flash
from flask import send_from_directory, redirect, url_for, current_app
from werkzeug.utils import secure_filename
from secrets import token_urlsafe
from suchwow import wownero
from suchwow import config
from suchwow.models import Post, Profile, Comment, Ban
from suchwow.utils.decorators import login_required, profile_required, moderator_required
from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user
from suchwow.utils.helpers import post_webhook, audit_event
from suchwow.discord import post_discord_webhook
bp = Blueprint("post", "post")
@bp.route("/post/<id>")
def read(id):
_address_qr = BytesIO()
qr_code = None
if Post.filter(id=id):
wallet = wownero.Wallet()
post = Post.get(id=id)
if not post.approved:
if not is_moderator(get_session_user()):
flash("That post has not been approved.", "is-warning")
return redirect("/")
if wallet.connected:
address = wallet.get_address(account=post.account_index)
transfers = wallet.transfers(account=post.account_index)
qr_uri = f'wownero:{address}?tx_description=suchwow%20post%20{post.id}'
address_qr = qrcode_make(qr_uri).save(_address_qr)
qr_code = b64encode(_address_qr.getvalue()).decode()
else:
address = "?"
transfers = "?"
return render_template(
"post/read.html",
post=post,
address=address,
transfers=transfers,
qr_code=qr_code
)
else:
flash("No meme there, brah", "is-warning")
return redirect(url_for("main.index"))
@bp.route("/post/create", methods=["GET", "POST"])
@login_required
@profile_required
def create():
submitter = get_session_user()
u = Profile.filter(username=submitter)
banned = Ban.filter(user=u).first()
if banned:
flash(f"You can't post: {banned.reason}", "is-danger")
return redirect("/")
if request.method == "POST":
post_title = request.form.get("title")
# check if the post request has the file part
if "file" not in request.files:
flash("You didn't upload a caliente meme, bro! You're fuckin up!", "is-danger")
return redirect(request.url)
file = request.files["file"]
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == "":
flash("You didn't upload a caliente meme, bro! You're fuckin up!", "is-danger")
return redirect(request.url)
if post_title == "":
flash("You didn't give your meme a spicy title, bro! You're fuckin up!", "is-danger")
return redirect(request.url)
if file and allowed_file(file.filename):
filename = "{}-{}".format(
token_urlsafe(12),
secure_filename(file.filename)
)
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
save_path = path.join(save_path_base, filename)
file.save(save_path)
try:
wallet = wownero.Wallet()
account_index = wallet.new_account()
in_use = Post.select().where(Post.account_index == account_index).first()
if in_use:
flash("Suchwow wallet is fucked up! Try again later.", "is-danger")
return redirect(request.url)
except:
flash("Suchwow wallet is fucked up! Try again later.", "is-danger")
return redirect(request.url)
post = Post(
title=post_title,
text=request.form.get("text", ""),
submitter=submitter,
image_name=filename,
account_index=account_index,
address_index=0
)
post.save()
post.save_thumbnail()
url = url_for('post.read', id=post.id, _external=True)
audit_event(f'Created new post {post.id}')
flash("New post created and pending approval!", "is-success")
return redirect(url_for("main.index"))
return render_template("post/create.html")
@bp.route("/post/<id>/approve")
@moderator_required
def approve(id):
post = Post.get(id=id)
url = url_for('post.read', id=post.id, _external=True)
if post:
if not post.approved:
post.approved = True
post.save()
flash("Approved", "is-success")
audit_event(f'Approved post {post.id}')
if current_app.config["DEBUG"] is False:
post_discord_webhook(post)
return redirect(url_for("mod.pending_posts"))
else:
flash("You can't approve this", "is-success")
return redirect(url_for("main.index"))
@bp.route("/post/<id>/delete")
@login_required
def delete(id):
filtered = Post.filter(id=id)
user = get_session_user()
is_mod = is_moderator(user)
if filtered:
post = filtered.first()
if user == post.submitter or is_mod:
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
save_path = path.join(save_path_base, post.image_name)
remove(save_path)
audit_event(f'Deleted post {post.id}')
post.delete_instance()
flash("Deleted that shit, brah!", "is-success")
if is_mod:
return redirect(url_for("mod.pending_posts"))
else:
return redirect(url_for("main.index"))
else:
flash("You can't delete a meme you don't own, brah", "is-warning")
return redirect(url_for("post.read", id=post.id))
else:
flash("No meme there, brah", "is-warning")
return redirect(url_for("main.index"))
@bp.route("/uploads/<path:filename>")
def uploaded_file(filename):
file_path = path.join(current_app.config["DATA_FOLDER"], "uploads")
return send_from_directory(file_path, filename)