mirror of
https://git.wownero.com/lza_menace/suchwow.git
synced 2024-08-15 01:03:19 +00:00
updating routes for the new models
This commit is contained in:
parent
b635e39e04
commit
da874c3994
11 changed files with 186 additions and 211 deletions
124
suchwow/cli.py
124
suchwow/cli.py
|
@ -23,73 +23,73 @@ def init():
|
||||||
db.create_tables([User, Post, AuditEvent, TipSent, TipReceived, Vote])
|
db.create_tables([User, Post, AuditEvent, TipSent, TipReceived, Vote])
|
||||||
|
|
||||||
|
|
||||||
@bp.cli.command("post_reddit")
|
# @bp.cli.command("post_reddit")
|
||||||
@click.argument('last_hours')
|
# @click.argument('last_hours')
|
||||||
def post_reddit(last_hours):
|
# def post_reddit(last_hours):
|
||||||
posts = Post.select().where(
|
# posts = Post.select().where(
|
||||||
Post.approved==True,
|
# Post.approved==True,
|
||||||
Post.to_reddit==False
|
# Post.to_reddit==False
|
||||||
).order_by(Post.timestamp.asc())
|
# ).order_by(Post.timestamp.asc())
|
||||||
for p in posts:
|
# for p in posts:
|
||||||
if p.hours_elapsed() < int(last_hours):
|
# if p.hours_elapsed() < int(last_hours):
|
||||||
if not p.to_reddit:
|
# if not p.to_reddit:
|
||||||
_p = make_post(p)
|
# _p = make_post(p)
|
||||||
if _p:
|
# if _p:
|
||||||
p.to_reddit = True
|
# p.to_reddit = True
|
||||||
p.save()
|
# p.save()
|
||||||
return
|
# return
|
||||||
|
|
||||||
|
|
||||||
@bp.cli.command("create_accounts")
|
# @bp.cli.command("create_accounts")
|
||||||
def create_accounts():
|
# def create_accounts():
|
||||||
wallet = wownero.Wallet()
|
# wallet = wownero.Wallet()
|
||||||
for post in Post.select():
|
# for post in Post.select():
|
||||||
if post.account_index not in wallet.accounts():
|
# if post.account_index not in wallet.accounts():
|
||||||
account = wallet.new_account()
|
# account = wallet.new_account()
|
||||||
print(f"Created account {account}")
|
# print(f"Created account {account}")
|
||||||
|
|
||||||
|
|
||||||
@bp.cli.command("payout_users")
|
# @bp.cli.command("payout_users")
|
||||||
def payout_users():
|
# def payout_users():
|
||||||
wallet = wownero.Wallet()
|
# wallet = wownero.Wallet()
|
||||||
_fa = wownero.from_atomic
|
# _fa = wownero.from_atomic
|
||||||
_aw = wownero.as_wownero
|
# _aw = wownero.as_wownero
|
||||||
for post in Post.select():
|
# for post in Post.select():
|
||||||
try:
|
# try:
|
||||||
submitter = Profile.get(username=post.submitter)
|
# submitter = Profile.get(username=post.submitter)
|
||||||
balances = wallet.balances(post.account_index)
|
# balances = wallet.balances(post.account_index)
|
||||||
url = url_for('post.read', id=post.id, _external=True)
|
# url = url_for('post.read', id=post.id, _external=True)
|
||||||
if balances[1] > 0.05:
|
# if balances[1] > 0.05:
|
||||||
print(f"Post #{post.id} has {balances[1]} funds unlocked and ready to send. Sweeping all funds to user's address ({submitter.address}).")
|
# print(f"Post #{post.id} has {balances[1]} funds unlocked and ready to send. Sweeping all funds to user's address ({submitter.address}).")
|
||||||
sweep = wallet.sweep_all(account=post.account_index, dest_address=submitter.address)
|
# sweep = wallet.sweep_all(account=post.account_index, dest_address=submitter.address)
|
||||||
print(sweep)
|
# print(sweep)
|
||||||
if "tx_hash_list" in sweep:
|
# if "tx_hash_list" in sweep:
|
||||||
amount = 0
|
# amount = 0
|
||||||
for amt in sweep["amount_list"]:
|
# for amt in sweep["amount_list"]:
|
||||||
amount += int(amt)
|
# amount += int(amt)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
print(f"Failed because: {e}")
|
# print(f"Failed because: {e}")
|
||||||
|
|
||||||
|
|
||||||
@bp.cli.command("show")
|
# @bp.cli.command("show")
|
||||||
@click.argument("post_id")
|
# @click.argument("post_id")
|
||||||
def post_id(post_id):
|
# def post_id(post_id):
|
||||||
p = Post.filter(id=post_id).first()
|
# p = Post.filter(id=post_id).first()
|
||||||
if p:
|
# if p:
|
||||||
print(p.show())
|
# print(p.show())
|
||||||
else:
|
# else:
|
||||||
print("That post doesn't exist")
|
# print("That post doesn't exist")
|
||||||
|
|
||||||
|
|
||||||
@bp.cli.command("load_cache")
|
# @bp.cli.command("load_cache")
|
||||||
def load_cache():
|
# def load_cache():
|
||||||
current_app.logger.info('loading top posters into cache')
|
# current_app.logger.info('loading top posters into cache')
|
||||||
get_top_posters()
|
# get_top_posters()
|
||||||
current_app.logger.info('done')
|
# current_app.logger.info('done')
|
||||||
current_app.logger.info('loading latest tipped into cache')
|
# current_app.logger.info('loading latest tipped into cache')
|
||||||
get_latest_tipped_posts()
|
# get_latest_tipped_posts()
|
||||||
current_app.logger.info('done')
|
# current_app.logger.info('done')
|
||||||
for i in [1, 3, 7, 30, 9999]:
|
# for i in [1, 3, 7, 30, 9999]:
|
||||||
current_app.logger.info(f'loading top posts last {i} days into cache')
|
# current_app.logger.info(f'loading top posts last {i} days into cache')
|
||||||
get_top_posts(i)
|
# get_top_posts(i)
|
||||||
current_app.logger.info('done')
|
# current_app.logger.info('done')
|
|
@ -21,6 +21,7 @@ WALLET_PROTO = getenv('WALLET_PROTO', 'http') #
|
||||||
WALLET_RPC_USER = getenv('WALLET_RPC_USER', 'suchwow') #
|
WALLET_RPC_USER = getenv('WALLET_RPC_USER', 'suchwow') #
|
||||||
WALLET_RPC_PASS = getenv('WALLET_RPC_PASS', 'suchwow') #
|
WALLET_RPC_PASS = getenv('WALLET_RPC_PASS', 'suchwow') #
|
||||||
WALLET_PASS = getenv('WALLET_PASS', 'zzzzzzz') # You specify all these wallet details in .env
|
WALLET_PASS = getenv('WALLET_PASS', 'zzzzzzz') # You specify all these wallet details in .env
|
||||||
|
WALLET_ACCOUNT = getenv('WALLET_ACCOUNT', 0)
|
||||||
|
|
||||||
# Optional for posting to Reddit
|
# Optional for posting to Reddit
|
||||||
PRAW_CLIENT_SECRET = getenv('PRAW_CLIENT_SECRET', None)
|
PRAW_CLIENT_SECRET = getenv('PRAW_CLIENT_SECRET', None)
|
||||||
|
|
|
@ -2,6 +2,8 @@ from flask import Blueprint
|
||||||
from arrow import get as arrow_get
|
from arrow import get as arrow_get
|
||||||
|
|
||||||
from suchwow.models import Moderator
|
from suchwow.models import Moderator
|
||||||
|
from suchwow.wownero import from_atomic as _from_atomic
|
||||||
|
from suchwow.wownero import as_wownero
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint('filters', 'filters')
|
bp = Blueprint('filters', 'filters')
|
||||||
|
@ -16,6 +18,10 @@ def shorten_address(a):
|
||||||
def humanize(d):
|
def humanize(d):
|
||||||
return arrow_get(d).humanize()
|
return arrow_get(d).humanize()
|
||||||
|
|
||||||
|
@bp.app_template_filter('from_atomic')
|
||||||
|
def from_atomic(a):
|
||||||
|
return as_wownero(_from_atomic(a))
|
||||||
|
|
||||||
@bp.app_template_filter('is_moderator')
|
@bp.app_template_filter('is_moderator')
|
||||||
def is_moderator(s):
|
def is_moderator(s):
|
||||||
m = Moderator.select().where(Moderator.username == s)
|
m = Moderator.select().where(Moderator.username == s)
|
||||||
|
|
|
@ -2,7 +2,7 @@ from math import ceil
|
||||||
|
|
||||||
from flask import Blueprint, request, render_template, flash
|
from flask import Blueprint, request, render_template, flash
|
||||||
|
|
||||||
from suchwow.models import Post, Profile, Moderator
|
from suchwow._models import Post, User
|
||||||
from suchwow.utils.helpers import get_latest_tipped_posts
|
from suchwow.utils.helpers import get_latest_tipped_posts
|
||||||
|
|
||||||
bp = Blueprint('main', 'main')
|
bp = Blueprint('main', 'main')
|
||||||
|
@ -31,7 +31,11 @@ def index():
|
||||||
|
|
||||||
posts = Post.select().where(Post.approved==True).order_by(Post.timestamp.desc())
|
posts = Post.select().where(Post.approved==True).order_by(Post.timestamp.desc())
|
||||||
if submitter:
|
if submitter:
|
||||||
posts = posts.where(Post.submitter==submitter)
|
user = Post.select().where(Post.username == submitter).first()
|
||||||
|
if not user:
|
||||||
|
flash('That user does not exist!', 'is-warning')
|
||||||
|
else:
|
||||||
|
posts = posts.where(Post.user == user)
|
||||||
|
|
||||||
paginated_posts = posts.paginate(page, itp)
|
paginated_posts = posts.paginate(page, itp)
|
||||||
total_pages = ceil(posts.count() / itp)
|
total_pages = ceil(posts.count() / itp)
|
||||||
|
@ -46,5 +50,5 @@ def index():
|
||||||
|
|
||||||
@bp.route("/about")
|
@bp.route("/about")
|
||||||
def about():
|
def about():
|
||||||
mods = Profile.select().join(Moderator, on=(Profile.username == Moderator.username))
|
mods = User.select().where(User.moderator == True)
|
||||||
return render_template("about.html", mods=mods)
|
return render_template("about.html", mods=mods)
|
|
@ -1,6 +1,6 @@
|
||||||
from flask import Blueprint, render_template, redirect, url_for, flash, request
|
from flask import Blueprint, render_template, redirect, url_for, flash, request
|
||||||
|
|
||||||
from suchwow.models import AuditEvent, Post, Profile, Moderator, Ban, get_ban_reason
|
from suchwow._models import AuditEvent, Post, User, get_ban_reason
|
||||||
from suchwow.utils.decorators import moderator_required
|
from suchwow.utils.decorators import moderator_required
|
||||||
from suchwow.utils.helpers import get_session_user, audit_event
|
from suchwow.utils.helpers import get_session_user, audit_event
|
||||||
from suchwow import config
|
from suchwow import config
|
||||||
|
@ -13,8 +13,8 @@ bp = Blueprint("mod", "mod")
|
||||||
def main():
|
def main():
|
||||||
live_posts = Post.select().where(Post.approved == True).count()
|
live_posts = Post.select().where(Post.approved == True).count()
|
||||||
pending_posts = Post.select().where(Post.approved == False).count()
|
pending_posts = Post.select().where(Post.approved == False).count()
|
||||||
active_posters = Profile.select().join(Post, on=Post.submitter == Profile.username).distinct().count()
|
active_posters = User.select().join(Post, on=Post.user).distinct().count()
|
||||||
mods = Moderator.select().count()
|
mods = User.select().where(User.moderator == True).count()
|
||||||
return render_template(
|
return render_template(
|
||||||
'mod/main.html',
|
'mod/main.html',
|
||||||
live_posts=live_posts,
|
live_posts=live_posts,
|
||||||
|
@ -37,73 +37,76 @@ def pending_posts():
|
||||||
@bp.route('/mods/manage', methods=['GET', 'POST'])
|
@bp.route('/mods/manage', methods=['GET', 'POST'])
|
||||||
@moderator_required
|
@moderator_required
|
||||||
def manage_mods():
|
def manage_mods():
|
||||||
to_delete = request.args.get('delete')
|
to_remove = request.args.get('delete')
|
||||||
if to_delete:
|
if to_remove:
|
||||||
m = Moderator.select().where(Moderator.username == to_delete).first()
|
u = User.select().where(User.username == to_remove).first()
|
||||||
if not m:
|
if not u.moderator:
|
||||||
flash('No moderator exists with that name', 'is-danger')
|
flash('That user is not a moderator', 'is-danger')
|
||||||
elif m.username == get_session_user():
|
elif u.username == get_session_user():
|
||||||
flash('Cannot remove yourself.', 'is-danger')
|
flash('Cannot remove yourself.', 'is-danger')
|
||||||
elif m.username == config.SUPER_ADMIN:
|
elif u.username == config.SUPER_ADMIN:
|
||||||
flash('Cannot delete super admin you son-of-a-bitch.', 'is-danger')
|
flash('Cannot delete super admin you son-of-a-bitch.', 'is-danger')
|
||||||
else:
|
else:
|
||||||
m.delete_instance()
|
u.moderator = False
|
||||||
audit_event(f'Deleted {to_delete} from mods')
|
u.save()
|
||||||
flash(f'Removed {to_delete} from mods!', 'is-success')
|
audit_event(f'Removed {to_remove} from mods')
|
||||||
|
flash(f'Removed {to_remove} from mods!', 'is-success')
|
||||||
return redirect(url_for('mod.manage_mods'))
|
return redirect(url_for('mod.manage_mods'))
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
to_add = request.form.get('username', None)
|
to_add = request.form.get('username', None)
|
||||||
if to_add:
|
if to_add:
|
||||||
u = Profile.select().where(Profile.username == to_add).first()
|
u = User.select().where(User.username == to_add).first()
|
||||||
if not u:
|
if not u:
|
||||||
flash('That user does not appear to exist (no profile setup yet)', 'is-danger')
|
flash('That user does not appear to exist', 'is-danger')
|
||||||
elif Moderator.select().where(Moderator.username == to_add).first():
|
elif u.moderator:
|
||||||
flash(f'{to_add} is already a mod, ya dingus.', 'is-warning')
|
flash(f'{to_add} is already a mod, ya dingus.', 'is-warning')
|
||||||
else:
|
else:
|
||||||
m = Moderator(username=to_add)
|
u.moderator = True
|
||||||
m.save()
|
u.save()
|
||||||
audit_event(f'Added {to_add} to mods')
|
audit_event(f'Added {to_add} to mods')
|
||||||
flash(f'Added {to_add} to mods!', 'is-success')
|
flash(f'Added {to_add} to mods!', 'is-success')
|
||||||
mods = Profile.select().join(Moderator, on=(Profile.username == Moderator.username))
|
mods = User.select().where(User.moderator == True)
|
||||||
return render_template('mod/manage.html', mods=mods)
|
return render_template('mod/manage.html', mods=mods)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/mods/bans', methods=['GET', 'POST'])
|
@bp.route('/mods/bans', methods=['GET', 'POST'])
|
||||||
@moderator_required
|
@moderator_required
|
||||||
def manage_bans():
|
def manage_bans():
|
||||||
to_delete = request.args.get('delete')
|
to_unban = request.args.get('delete')
|
||||||
if to_delete:
|
if to_unban:
|
||||||
ban = Ban.select().join(Profile).where(Profile.username == to_delete).first()
|
u = User.select().where(User.username == to_unban).first()
|
||||||
if not ban:
|
if not u.banned:
|
||||||
flash('No ban exists for that user', 'is-danger')
|
flash('No ban exists for that user', 'is-danger')
|
||||||
elif ban.user == get_session_user():
|
elif u.username == get_session_user():
|
||||||
flash('Cannot ban yourself.', 'is-danger')
|
flash('Cannot ban yourself.', 'is-danger')
|
||||||
elif ban.user == config.SUPER_ADMIN:
|
elif u.username == config.SUPER_ADMIN:
|
||||||
flash('Cannot ban super admin you son-of-a-bitch.', 'is-danger')
|
flash('Cannot ban super admin you son-of-a-bitch.', 'is-danger')
|
||||||
else:
|
else:
|
||||||
ban.delete_instance()
|
u.banned = False
|
||||||
audit_event(f'Removed ban on {to_delete}')
|
u.save()
|
||||||
flash(f'Unbanned {to_delete}!', 'is-success')
|
audit_event(f'Removed ban on {to_unban}')
|
||||||
|
flash(f'Unbanned {to_unban}!', 'is-success')
|
||||||
return redirect(url_for('mod.manage_bans'))
|
return redirect(url_for('mod.manage_bans'))
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
to_add = request.form.get('username', None)
|
to_ban = request.form.get('username', None)
|
||||||
if to_add:
|
if to_ban:
|
||||||
u = Profile.select().where(Profile.username == to_add).first()
|
u = User.select().where(User.username == to_ban).first()
|
||||||
if not u:
|
if not u:
|
||||||
flash('That user does not appear to exist (no profile setup yet)', 'is-danger')
|
flash('That user does not appear to exist', 'is-danger')
|
||||||
elif Ban.select().join(Profile).where(Profile.username == to_add).first():
|
elif u.banned:
|
||||||
flash(f'{to_add} is already banned, ya dingus.', 'is-warning')
|
flash(f'{to_ban} is already banned, ya dingus.', 'is-warning')
|
||||||
elif to_add == config.SUPER_ADMIN:
|
elif u.username == config.SUPER_ADMIN:
|
||||||
flash('Cannot ban the super admin you son-of-a-bitch.', 'is-danger')
|
flash('Cannot ban the super admin you son-of-a-bitch.', 'is-danger')
|
||||||
else:
|
else:
|
||||||
reason = request.form.get('reason')
|
reason = request.form.get('reason')
|
||||||
if not reason:
|
if not reason:
|
||||||
reason = get_ban_reason()
|
reason = get_ban_reason()
|
||||||
ban = Ban(user=u, reason=reason)
|
u.banned = True
|
||||||
ban.save()
|
u.ban_reason = reason
|
||||||
audit_event(f'Banned {to_add} ({reason})')
|
u.save()
|
||||||
flash(f'Banned {to_add}!', 'is-success')
|
audit_event(f'Banned {to_ban} ({reason})')
|
||||||
bans = Ban.select()
|
flash(f'Banned {to_ban}!', 'is-success')
|
||||||
|
bans = User.select().where(User.banned == True)
|
||||||
return render_template('mod/bans.html', bans=bans)
|
return render_template('mod/bans.html', bans=bans)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ from flask import render_template, Blueprint, request, flash
|
||||||
from flask import send_from_directory, redirect, url_for, current_app
|
from flask import send_from_directory, redirect, url_for, current_app
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
from suchwow import wownero
|
from suchwow import wownero, config
|
||||||
from suchwow.models import Post, Profile, Comment, Ban
|
from suchwow._models import User, Post, TipReceived
|
||||||
from suchwow.utils.decorators import login_required, profile_required, moderator_required
|
from suchwow.utils.decorators import login_required, address_required, moderator_required
|
||||||
from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user
|
from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user
|
||||||
from suchwow.utils.helpers import audit_event
|
from suchwow.utils.helpers import audit_event
|
||||||
from suchwow.discord import post_discord_webhook
|
from suchwow.discord import post_discord_webhook
|
||||||
|
@ -22,28 +22,21 @@ bp = Blueprint("post", "post")
|
||||||
def read(id):
|
def read(id):
|
||||||
_address_qr = BytesIO()
|
_address_qr = BytesIO()
|
||||||
qr_code = None
|
qr_code = None
|
||||||
if Post.filter(id=id):
|
post = Post.select().where(Post.id == id).first()
|
||||||
wallet = wownero.Wallet()
|
if post:
|
||||||
post = Post.get(id=id)
|
|
||||||
if not post.approved:
|
if not post.approved:
|
||||||
if not is_moderator(get_session_user()):
|
if not is_moderator(get_session_user()):
|
||||||
flash("That post has not been approved.", "is-warning")
|
flash("That post has not been approved.", "is-warning")
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
if wallet.connected:
|
qr_uri = f'wownero:{post.address}?tx_description=suchwow%20post%20{post.id}'
|
||||||
address = wallet.get_address(account=post.account_index)
|
qrcode_make(qr_uri).save(_address_qr)
|
||||||
transfers = wallet.transfers(account=post.account_index)
|
qr_code = b64encode(_address_qr.getvalue()).decode()
|
||||||
qr_uri = f'wownero:{address}?tx_description=suchwow%20post%20{post.id}'
|
tips = TipReceived.select().where(TipReceived.post == post).order_by(TipReceived.timestamp.desc())
|
||||||
address_qr = qrcode_make(qr_uri).save(_address_qr)
|
|
||||||
qr_code = b64encode(_address_qr.getvalue()).decode()
|
|
||||||
else:
|
|
||||||
address = "?"
|
|
||||||
transfers = "?"
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"post/read.html",
|
"post/read.html",
|
||||||
post=post,
|
post=post,
|
||||||
address=address,
|
qr_code=qr_code,
|
||||||
transfers=transfers,
|
tips=tips
|
||||||
qr_code=qr_code
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
flash("No meme there, brah", "is-warning")
|
flash("No meme there, brah", "is-warning")
|
||||||
|
@ -51,13 +44,11 @@ def read(id):
|
||||||
|
|
||||||
@bp.route("/post/create", methods=["GET", "POST"])
|
@bp.route("/post/create", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
@profile_required
|
@address_required
|
||||||
def create():
|
def create():
|
||||||
submitter = get_session_user()
|
u = User.select().where(User.username == get_session_user()).first()
|
||||||
u = Profile.filter(username=submitter)
|
if u.banned:
|
||||||
banned = Ban.filter(user=u).first()
|
flash(f"You can't post: {u.ban_reason}", "is-danger")
|
||||||
if banned:
|
|
||||||
flash(f"You can't post: {banned.reason}", "is-danger")
|
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
post_title = request.form.get("title")
|
post_title = request.form.get("title")
|
||||||
|
@ -82,37 +73,34 @@ def create():
|
||||||
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
|
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
|
||||||
save_path = path.join(save_path_base, filename)
|
save_path = path.join(save_path_base, filename)
|
||||||
file.save(save_path)
|
file.save(save_path)
|
||||||
try:
|
wallet_found = False
|
||||||
|
while wallet_found is False:
|
||||||
wallet = wownero.Wallet()
|
wallet = wownero.Wallet()
|
||||||
account_index = wallet.new_account()
|
address_idx, address = wallet.new_address(config.WALLET_ACCOUNT)
|
||||||
in_use = Post.select().where(Post.account_index == account_index).first()
|
in_use = Post.select().where(Post.address == address).first()
|
||||||
if in_use:
|
if in_use:
|
||||||
flash("Suchwow wallet is fucked up! Try again later.", "is-danger")
|
continue
|
||||||
return redirect(request.url)
|
wallet_found = True
|
||||||
except:
|
post = Post(
|
||||||
flash("Suchwow wallet is fucked up! Try again later.", "is-danger")
|
title=post_title,
|
||||||
return redirect(request.url)
|
text=request.form.get("text", ""),
|
||||||
post = Post(
|
user=u,
|
||||||
title=post_title,
|
image_name=filename,
|
||||||
text=request.form.get("text", ""),
|
account_index=config.WALLET_ACCOUNT,
|
||||||
submitter=submitter,
|
address_index=address_idx,
|
||||||
image_name=filename,
|
address=address
|
||||||
account_index=account_index,
|
)
|
||||||
address_index=0
|
post.save()
|
||||||
)
|
post.save_thumbnail()
|
||||||
post.save()
|
audit_event(f'Created new post {post.id}')
|
||||||
post.save_thumbnail()
|
flash("New post created and pending approval!", "is-success")
|
||||||
url = url_for('post.read', id=post.id, _external=True)
|
return redirect(url_for("main.index"))
|
||||||
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")
|
return render_template("post/create.html")
|
||||||
|
|
||||||
@bp.route("/post/<id>/approve")
|
@bp.route("/post/<id>/approve")
|
||||||
@moderator_required
|
@moderator_required
|
||||||
def approve(id):
|
def approve(id):
|
||||||
post = Post.get(id=id)
|
post = Post.select().where(Post.id == id).first()
|
||||||
url = url_for('post.read', id=post.id, _external=True)
|
|
||||||
if post:
|
if post:
|
||||||
if not post.approved:
|
if not post.approved:
|
||||||
post.approved = True
|
post.approved = True
|
||||||
|
@ -129,12 +117,10 @@ def approve(id):
|
||||||
@bp.route("/post/<id>/delete")
|
@bp.route("/post/<id>/delete")
|
||||||
@login_required
|
@login_required
|
||||||
def delete(id):
|
def delete(id):
|
||||||
filtered = Post.filter(id=id)
|
post = Post.select().where(Post.id == id).first()
|
||||||
user = get_session_user()
|
user = User.select().where(User.username == get_session_user()).first()
|
||||||
is_mod = is_moderator(user)
|
if post:
|
||||||
if filtered:
|
if user == post.user or user.moderator:
|
||||||
post = filtered.first()
|
|
||||||
if user == post.submitter or is_mod:
|
|
||||||
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
|
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
|
||||||
save_path = path.join(save_path_base, post.image_name)
|
save_path = path.join(save_path_base, post.image_name)
|
||||||
try:
|
try:
|
||||||
|
@ -144,7 +130,7 @@ def delete(id):
|
||||||
audit_event(f'Deleted post {post.id}')
|
audit_event(f'Deleted post {post.id}')
|
||||||
post.delete_instance()
|
post.delete_instance()
|
||||||
flash("Deleted that shit, brah!", "is-success")
|
flash("Deleted that shit, brah!", "is-success")
|
||||||
if is_mod:
|
if user.moderator:
|
||||||
return redirect(url_for("mod.pending_posts"))
|
return redirect(url_for("mod.pending_posts"))
|
||||||
else:
|
else:
|
||||||
return redirect(url_for("main.index"))
|
return redirect(url_for("main.index"))
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
Your browser does not support the video tag.
|
Your browser does not support the video tag.
|
||||||
</video>
|
</video>
|
||||||
{% else %}
|
{% else %}
|
||||||
<img alt="SuchWow #{{ post.id }} - {{ post.title }} by {{ post.submitter }}" src="{{ url_for('post.uploaded_file', filename=post.thumbnail_name) }}" />
|
<img alt="SuchWow #{{ post.id }} - {{ post.title }} by {{ post.user.username }}" src="{{ url_for('post.uploaded_file', filename=post.thumbnail_name) }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
{% for ban in bans %}
|
{% for ban in bans %}
|
||||||
<article class="message" style="width: 30%; margin: 2em auto;">
|
<article class="message" style="width: 30%; margin: 2em auto;">
|
||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
<p>{{ ban.user.username }}</p>
|
<p>{{ ban.username }}</p>
|
||||||
<a href="?delete={{ ban.user.username }}" class="delete"></a>
|
<a href="?delete={{ ban.username }}" class="delete"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="message-body">
|
<div class="message-body">
|
||||||
{{ ban.reason }}
|
{{ ban.ban_reason }}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
<li class="is-active"><a href="#" aria-current="page">Post {{ post.id }}</a></li>
|
<li class="is-active"><a href="#" aria-current="page">Post {{ post.id }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
{% if post.hidden %}
|
|
||||||
<h2>You cannot see this post</h2>
|
|
||||||
{% else %}
|
|
||||||
<!-- Post Info -->
|
<!-- Post Info -->
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -24,15 +21,14 @@
|
||||||
<a href="{{ url_for('post.approve', id=post.id) }}" class="button is-success">Approve</a>
|
<a href="{{ url_for('post.approve', id=post.id) }}" class="button is-success">Approve</a>
|
||||||
<a href="{{ url_for('post.delete', id=post.id) }}" class="button is-danger">Reject</a>
|
<a href="{{ url_for('post.delete', id=post.id) }}" class="button is-danger">Reject</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="mt-2">Submitted by <i><u><a href="/?submitter={{ post.submitter }}">{{ post.submitter }}</a></u></i> at <i>{{ post.timestamp }}</i></p>
|
<p class="mt-2">Submitted by <i><u><a href="/?submitter={{ post.user.username }}">{{ post.user.username }}</a></u></i> at <i>{{ post.timestamp }}</i></p>
|
||||||
<!-- <img src="{{ url_for('post.uploaded_file', filename=post.image_name) }}" width=600/ style="border-radius:4px;"> -->
|
|
||||||
{% if post.get_image_path().endswith('mp4') %}
|
{% if post.get_image_path().endswith('mp4') %}
|
||||||
<video style="max-height: 100vh!important;" controls>
|
<video style="max-height: 100vh!important;" controls>
|
||||||
<source src="{{ url_for('post.uploaded_file', filename=post.image_name) }}" type="video/mp4">
|
<source src="{{ url_for('post.uploaded_file', filename=post.image_name) }}" type="video/mp4">
|
||||||
Your browser does not support the video tag.
|
Your browser does not support the video tag.
|
||||||
</video>
|
</video>
|
||||||
{% else %}
|
{% else %}
|
||||||
<img alt="SuchWow #{{ post.id }} - {{ post.title }} by {{ post.submitter }}" src="{{ url_for('post.uploaded_file', filename=post.image_name) }}" />
|
<img alt="SuchWow #{{ post.id }} - {{ post.title }} by {{ post.user.username }}" src="{{ url_for('post.uploaded_file', filename=post.image_name) }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -40,52 +36,30 @@
|
||||||
<!-- Payments -->
|
<!-- Payments -->
|
||||||
<section class="section content">
|
<section class="section content">
|
||||||
<h3>Payments</h3>
|
<h3>Payments</h3>
|
||||||
<p style="word-break:break-all;">Vote for this post by sending WOW to the following address:<br><i>{{ address }}</i></p>
|
<p style="word-break:break-all;">Vote for this post by sending WOW to the following address:<br><i>{{ post.address }}</i></p>
|
||||||
{% if qr_code %}
|
{% if qr_code %}
|
||||||
<img src="data:image/png;base64,{{ qr_code }}" width=180 class="center"><br /><br />
|
<img src="data:image/png;base64,{{ qr_code }}" width=180 class="center"><br /><br />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column content">
|
<div class="column content">
|
||||||
<h4>WOW Received</h4>
|
<h4>{{ tips | sum(attribute='amount') | from_atomic }} WOW Received</h4>
|
||||||
{% if transfers.in %}
|
{% if tips %}
|
||||||
<ul>
|
<ul>
|
||||||
{% for transfer in transfers.in %}
|
{% for tip in tips %}
|
||||||
{% if transfer.amount > 0 %}
|
<li class="is-small" style="font-size:.8em;">
|
||||||
<li>
|
{{ tip.amount | from_atomic }} WOW
|
||||||
{{ transfer.amount / 100000000000 }} WOW
|
(<a href="https://explore.wownero.com/tx/{{ tip.txid }}" target="_blank">{{ tip.txid | shorten_address }}</a>)
|
||||||
(<a href="https://wownero.club/transaction/{{ transfer.txid }}" target="_blank">{{ transfer.txid | shorten_address }}</a>)
|
- {{ tip.timestamp | humanize }}
|
||||||
- {{ transfer.timestamp | humanize }}
|
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>No WOW received yet. Show this post some love!</p>
|
<p>No WOW received yet. Show this post some love!</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="column content">
|
|
||||||
<h4>WOW Sent</h4>
|
|
||||||
{% if transfers.out %}
|
|
||||||
<ul>
|
|
||||||
{% for transfer in transfers.out %}
|
|
||||||
<li>
|
|
||||||
{{ transfer.amount / 100000000000 }} WOW
|
|
||||||
(<a href="https://wownero.club/transaction/{{ transfer.txid }}" target="_blank">{{ transfer.txid | shorten_address }}</a>)
|
|
||||||
- {{ transfer.timestamp | humanize }}
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% else %}
|
|
||||||
<p>No payouts yet.</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if config.DEBUG %}
|
{% if config.DEBUG %}
|
||||||
{{ post.show() }}
|
{{ post.show() }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from flask import session, redirect, url_for, flash
|
from flask import session, redirect, url_for, flash
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from suchwow.models import Profile, Moderator
|
from suchwow._models import User
|
||||||
|
|
||||||
|
|
||||||
def login_required(f):
|
def login_required(f):
|
||||||
|
@ -16,19 +16,19 @@ def moderator_required(f):
|
||||||
def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
if "auth" not in session or not session["auth"]:
|
if "auth" not in session or not session["auth"]:
|
||||||
return redirect(url_for("auth.login"))
|
return redirect(url_for("auth.login"))
|
||||||
m = Moderator.filter(username=session["auth"]["preferred_username"])
|
u = User.select().where(User.username == session["auth"]["preferred_username"]).first()
|
||||||
if m:
|
if u.moderator:
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
flash("You are not a moderator", "is-warning")
|
flash("You are not a moderator", "is-warning")
|
||||||
return redirect(url_for("main.index"))
|
return redirect(url_for("main.index"))
|
||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
def profile_required(f):
|
def address_required(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
un = session["auth"]["preferred_username"]
|
u = User.select().where(User.username == session["auth"]["preferred_username"]).first()
|
||||||
if not Profile.filter(username=un):
|
if not u.address:
|
||||||
url = "{}?redirect={}".format(
|
url = "{}?redirect={}".format(
|
||||||
url_for("profile.edit"),
|
url_for("profile.edit"),
|
||||||
url_for("post.create")
|
url_for("post.create")
|
||||||
|
|
|
@ -4,7 +4,8 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
from flask import session
|
from flask import session
|
||||||
|
|
||||||
from suchwow.models import Moderator, Post, AuditEvent, Profile
|
from suchwow._models import AuditEvent, User
|
||||||
|
from suchwow.models import Moderator, Post, Profile
|
||||||
from suchwow.wownero import Wallet, from_atomic
|
from suchwow.wownero import Wallet, from_atomic
|
||||||
from suchwow import config
|
from suchwow import config
|
||||||
|
|
||||||
|
@ -20,12 +21,12 @@ def is_moderator(username):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_profile():
|
def get_current_user():
|
||||||
p = Profile.filter(username=get_session_user()).first()
|
u = User.select().where(User.username == get_session_user()).first()
|
||||||
return p
|
return u
|
||||||
|
|
||||||
def audit_event(event):
|
def audit_event(event):
|
||||||
e = AuditEvent(user=get_profile(), action=event)
|
e = AuditEvent(user=get_current_user(), action=event)
|
||||||
e.save()
|
e.save()
|
||||||
|
|
||||||
def get_session_user():
|
def get_session_user():
|
||||||
|
|
Loading…
Reference in a new issue