load leaderboards into cache in advance

pull/4/head
lza_menace 3 years ago
parent ea02ed1185
commit 113af08502

@ -13,6 +13,7 @@ from suchwow.models import Post, Profile, Comment, Notification, db, Moderator
from suchwow.routes import auth, comment, post, profile, leaderboard, api from suchwow.routes import auth, comment, post, profile, leaderboard, api
from suchwow.utils.decorators import login_required, moderator_required from suchwow.utils.decorators import login_required, moderator_required
from suchwow.utils.helpers import post_webhook, get_latest_tipped_posts from suchwow.utils.helpers import post_webhook, get_latest_tipped_posts
from suchwow.utils.helpers import get_top_posters, get_top_posts
from suchwow.reddit import make_post from suchwow.reddit import make_post
from suchwow.discord import post_discord_webhook from suchwow.discord import post_discord_webhook
from suchwow import wownero, filters from suchwow import wownero, filters
@ -166,6 +167,16 @@ def post_id(post_id):
else: else:
print("That post doesn't exist") print("That post doesn't exist")
@app.cli.command("load_cache")
def load_cache():
app.logger.info('loading top posters into cache')
get_top_posters()
app.logger.info('done')
for i in [1, 3, 7, 30]:
app.logger.info(f'loading top posts last {i} days into cache')
get_top_posts(i)
app.logger.info('done')
if __name__ == "__main__": if __name__ == "__main__":
app.run() app.run()

@ -5,38 +5,18 @@ 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
from suchwow.models import Post from suchwow.models import Post
from suchwow.utils.helpers import rw_cache from suchwow.utils.helpers import rw_cache, get_top_posters, get_top_posts
bp = Blueprint("leaderboard", "leaderboard") bp = Blueprint("leaderboard", "leaderboard")
@bp.route("/leaderboards/top_posters") @bp.route("/leaderboards/top_posters")
def top_posters(): def top_posters():
top_posters = {} top_posters = get_top_posters()
posts = rw_cache('top_posters')
if not posts:
posts = Post.select().where(Post.approved==True)
for post in posts:
transfers = []
incoming = wownero.Wallet().incoming_transfers(post.account_index)
if "transfers" in incoming:
for xfer in incoming["transfers"]:
transfers.append(wownero.from_atomic(xfer["amount"]))
total = sum(transfers)
if post.submitter not in top_posters:
top_posters[post.submitter] = {"amount": 0, "posts": []}
top_posters[post.submitter]["amount"] += float(total)
top_posters[post.submitter]["posts"].append(post)
rw_cache('top_posters', top_posters)
else:
top_posters = posts
return render_template("leaderboard.html", posters=top_posters) return render_template("leaderboard.html", posters=top_posters)
@bp.route("/leaderboards/top_posts") @bp.route("/leaderboards/top_posts")
def top_posts(): def top_posts():
top_posts = []
days = request.args.get('days', 1) days = request.args.get('days', 1)
try: try:
days = int(days) days = int(days)
@ -46,23 +26,5 @@ def top_posts():
if days not in [1, 3, 7, 30]: if days not in [1, 3, 7, 30]:
days = 7 days = 7
hours = 24 * days posts = get_top_posts(days)
diff = datetime.now() - timedelta(hours=hours)
key_name = f'top_posts_{str(hours)}'
posts = rw_cache(key_name)
if not posts:
posts = Post.select().where(
Post.approved==True,
Post.timestamp > diff
).order_by(
Post.timestamp.desc()
)
for post in posts:
p = post.show()
if isinstance(p['received_wow'], float):
top_posts.append(p)
posts = rw_cache(key_name, top_posts)
return render_template("post/top.html", posts=posts, days=days) return render_template("post/top.html", posts=posts, days=days)

@ -5,7 +5,7 @@ from requests import post as r_post
from json import dumps from json import dumps
from flask import session, current_app from flask import session, current_app
from suchwow.models import Moderator, Post from suchwow.models import Moderator, Post
from suchwow.wownero import Wallet from suchwow.wownero import Wallet, from_atomic
from suchwow import config from suchwow import config
@ -68,6 +68,57 @@ def get_latest_tipped_posts():
return tipped_posts return tipped_posts
def get_top_posters():
top_posters = {}
posts = rw_cache('top_posters')
if not posts:
posts = Post.select().where(Post.approved==True)
for post in posts:
transfers = []
incoming = Wallet().incoming_transfers(post.account_index)
if "transfers" in incoming:
for xfer in incoming["transfers"]:
transfers.append(from_atomic(xfer["amount"]))
total = sum(transfers)
if post.submitter not in top_posters:
top_posters[post.submitter] = {"amount": 0, "posts": []}
top_posters[post.submitter]["amount"] += float(total)
top_posters[post.submitter]["posts"].append(post)
rw_cache('top_posters', top_posters)
else:
top_posters = posts
return top_posters
def get_top_posts(days=1):
top_posts = []
try:
days = int(days)
except:
days = 1
if days not in [1, 3, 7, 30]:
days = 7
hours = 24 * days
diff = datetime.now() - timedelta(hours=hours)
key_name = f'top_posts_{str(hours)}'
posts = rw_cache(key_name)
if not posts:
posts = Post.select().where(
Post.approved==True,
Post.timestamp > diff
).order_by(
Post.timestamp.desc()
)
for post in posts:
p = post.show()
if isinstance(p['received_wow'], float):
top_posts.append(p)
posts = rw_cache(key_name, top_posts)
return posts
# Use hacky filesystem cache since i dont feel like shipping redis # Use hacky filesystem cache since i dont feel like shipping redis
def rw_cache(key_name, data=None, diff_seconds=3600): def rw_cache(key_name, data=None, diff_seconds=3600):