add moderator support and approval workflow

graphs-n-shit
lza_menace 4 years ago
parent 91219f4309
commit d7bc4f4546

@ -7,9 +7,9 @@ from flask import Flask, request, session, redirect
from flask import render_template, flash, url_for
from flask_session import Session
from suchwow import config
from suchwow.models import Post, Profile, Comment, Notification, db
from suchwow.models import Post, Profile, Comment, Notification, db, Moderator
from suchwow.routes import auth, comment, post, profile, leaderboard
from suchwow.utils.decorators import login_required
from suchwow.utils.decorators import login_required, moderator_required
from suchwow.reddit import make_post
from suchwow.discord import post_discord_webhook
from suchwow import wownero
@ -37,13 +37,19 @@ def index():
flash("Wow, wtf hackerman. Cool it.")
page = 1
posts = Post.select().order_by(Post.timestamp.desc())
posts = Post.select().where(Post.approved==True).order_by(Post.timestamp.desc())
if submitter:
posts = posts.where(Post.submitter == submitter)
posts = posts.paginate(page, itp)
total_pages = Post.select().count() / itp
return render_template("index.html", posts=posts, page=page, total_pages=total_pages)
@app.route("/mod")
@moderator_required
def mod_queue():
posts = Post.select().where(Post.approved==False).order_by(Post.timestamp.asc())
return render_template("index.html", posts=posts)
@app.route("/about")
def about():
return render_template("about.html")
@ -60,7 +66,7 @@ def init():
makedirs(f"{config.DATA_FOLDER}/{i}", exist_ok=True)
# init db
db.create_tables([Post, Profile, Comment, Notification])
db.create_tables([Post, Profile, Comment, Notification, Moderator])
@app.cli.command("create_accounts")
def create_accounts():
@ -106,7 +112,7 @@ def payout_users():
@app.cli.command("delete_post")
@click.argument("post_id")
def delete_post(post_id):
def _delete_post(post_id):
post = Post.get(id=post_id)
save_path_base = path.join(app.config["DATA_FOLDER"], "uploads")
save_path = path.join(save_path_base, post.image_name)
@ -114,5 +120,25 @@ def delete_post(post_id):
remove(save_path)
print(f"Deleted post {post_id} and image {save_path}")
@app.cli.command("add_admin")
@click.argument("username")
def add_admin(username):
if not Moderator.filter(username=username):
m = Moderator(username=username)
m.save()
print(f"Added {username}")
else:
print("That moderator already exists")
@app.cli.command("remove_admin")
@click.argument("username")
def add_admin(username):
m = Moderator.filter(username=username).first()
if m:
m.delete_instance()
print(f"Deleted {username}")
else:
print("That moderator doesn't exist")
if __name__ == "__main__":
app.run()

@ -19,6 +19,14 @@ class Post(Model):
reddit_url = CharField(null=True)
to_reddit = BooleanField(default=False)
to_discord = BooleanField(default=False)
approved = BooleanField(default=False)
class Meta:
database = db
class Moderator(Model):
id = AutoField()
username = CharField(unique=True)
class Meta:
database = db

@ -6,8 +6,8 @@ from secrets import token_urlsafe
from suchwow import wownero
from suchwow import config
from suchwow.models import Post, Comment
from suchwow.utils.decorators import login_required, profile_required
from suchwow.utils.helpers import allowed_file
from suchwow.utils.decorators import login_required, profile_required, moderator_required
from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user
bp = Blueprint("post", "post")
@ -15,7 +15,7 @@ bp = Blueprint("post", "post")
@bp.route("/posts/top")
def top():
top_posts = {}
posts = Post.select()
posts = Post.select().where(Post.approved==True)
for post in posts:
transfers = []
incoming = wownero.Wallet().incoming_transfers(post.account_index)
@ -32,7 +32,10 @@ def read(id):
if Post.filter(id=id):
wallet = wownero.Wallet()
post = Post.get(id=id)
comments = Comment.select().where(Comment.post==post.id)
if not post.approved:
if not is_moderator(get_session_user()):
flash("That post has not been approved.")
return redirect("/")
if wallet.connected:
address = wallet.get_address(account=post.account_index)
transfers = wallet.transfers(account=post.account_index)
@ -43,7 +46,6 @@ def read(id):
"post/read.html",
post=post,
address=address,
comments=comments,
transfers=transfers
)
else:
@ -101,6 +103,19 @@ def create():
return redirect(url_for("post.read", id=post.id))
return render_template("post/create.html")
@bp.route("/post/<id>/approve")
@moderator_required
def approve(id):
post = Post.get(id=id)
if post:
post.approved = True
post.save()
flash("Approved")
return redirect(url_for("mod_queue"))
else:
flash("You can't approve this")
return redirect(url_for("index"))
@bp.route("/post/<id>/delete")
@login_required
def delete(id):

@ -30,7 +30,7 @@
{% endif %}
{% if page %}
{% if page > 1 %}
<a href="{% if request.args.submitter %}/?submitter={{ request.args.submitter }}&{% else %}/?{% endif %}page={{ page - 1 }}" style="padding:1em;">Back</a>
{% endif %}
@ -38,6 +38,7 @@
{% if page < total_pages and total_pages > 0 %}
<a href="{% if request.args.submitter %}/?submitter={{ request.args.submitter }}&{% else %}/?{% endif %}page={{ page + 1 }}" style="padding:1em;">Next</a>
{% endif %}
{% endif %}
<hr>
<h3>Leaderboards</h3>

@ -12,6 +12,9 @@
<!-- Post Info -->
<h1>{{ post.title }}</h1>
<p class="subtitle">{{ post.text }}</p>
{% if not post.approved %}
<a href="{{ url_for('post.approve', id=post.id) }}"><button type="button" name="button">Approve</button></a>
{% endif %}
<p class="subtext">Submitted by <i><u><a href="/?submitter={{ post.submitter }}">{{ post.submitter }}</a></u></i> at <i>{{ post.timestamp }}</i></p>
<br>
<img src="{{ url_for('post.uploaded_file', filename=post.image_name) }}" width=600/ style="margin-bottom:1em;border-radius:4px;">
@ -42,22 +45,8 @@
{% endif %}
<hr>
<!-- Comments -->
<h2>Comments</h2>
{% if comments %}
{% for comment in comments %}
<p id="comment{{ comment.id }}" class="comment">
<a href="{{ url_for('post.read', id=post.id, _external=True) }}#comment{{ comment.id }}">#{{ comment.id }}</a> - <i>{{ comment.commenter.username }}</i> - {{ comment.comment }}
</p>
{% endfor %}
{% else %}
<p>No comments yet.</p>
{% endif %}
{% endif %}
<a href="{{ url_for('comment.create', post_id=post.id) }}"><button class="btn btn-warning">Leave a Comment</button></a>
{#
{% if "auth" in session %}
{% if session.auth.preferred_username == post.submitter %}

@ -1,6 +1,6 @@
from flask import session, redirect, url_for
from flask import session, redirect, url_for, flash
from functools import wraps
from suchwow.models import Profile
from suchwow.models import Profile, Moderator
def login_required(f):
@ -11,6 +11,19 @@ def login_required(f):
return f(*args, **kwargs)
return decorated_function
def moderator_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if "auth" not in session or not session["auth"]:
return redirect(url_for("auth.login"))
m = Moderator.filter(username=session["auth"]["preferred_username"])
if m:
return f(*args, **kwargs)
else:
flash("You are not a moderator")
return redirect(url_for("index"))
return decorated_function
def profile_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):

@ -1,6 +1,19 @@
from flask import current_app
from flask import current_app, session
from suchwow.models import Moderator
def allowed_file(filename):
return "." in filename and \
filename.rsplit(".", 1)[1].lower() in current_app.config["ALLOWED_EXTENSIONS"]
def is_moderator(username):
m = Moderator.filter(username=username)
if m:
return True
else:
return False
def get_session_user():
if "auth" not in session or not session["auth"]:
return None
return session["auth"]["preferred_username"]

Loading…
Cancel
Save