From 113af08502febf6688d8edb61ebb4b319da2739a Mon Sep 17 00:00:00 2001 From: lza_menace Date: Tue, 8 Jun 2021 08:31:11 -0700 Subject: [PATCH] load leaderboards into cache in advance --- suchwow/app.py | 11 ++++++++ suchwow/routes/leaderboard.py | 44 ++--------------------------- suchwow/utils/helpers.py | 53 ++++++++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/suchwow/app.py b/suchwow/app.py index def5955..881edb1 100644 --- a/suchwow/app.py +++ b/suchwow/app.py @@ -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.utils.decorators import login_required, moderator_required 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.discord import post_discord_webhook from suchwow import wownero, filters @@ -166,6 +167,16 @@ def post_id(post_id): else: 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__": app.run() diff --git a/suchwow/routes/leaderboard.py b/suchwow/routes/leaderboard.py index dc6ec9e..015a239 100644 --- a/suchwow/routes/leaderboard.py +++ b/suchwow/routes/leaderboard.py @@ -5,38 +5,18 @@ from flask import send_from_directory, redirect, url_for, current_app from werkzeug.utils import secure_filename from suchwow import wownero 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.route("/leaderboards/top_posters") def 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 = 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 - + top_posters = get_top_posters() return render_template("leaderboard.html", posters=top_posters) @bp.route("/leaderboards/top_posts") def top_posts(): - top_posts = [] days = request.args.get('days', 1) try: days = int(days) @@ -46,23 +26,5 @@ def top_posts(): 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) - + posts = get_top_posts(days) return render_template("post/top.html", posts=posts, days=days) diff --git a/suchwow/utils/helpers.py b/suchwow/utils/helpers.py index a9313d8..87bad3d 100644 --- a/suchwow/utils/helpers.py +++ b/suchwow/utils/helpers.py @@ -5,7 +5,7 @@ from requests import post as r_post from json import dumps from flask import session, current_app from suchwow.models import Moderator, Post -from suchwow.wownero import Wallet +from suchwow.wownero import Wallet, from_atomic from suchwow import config @@ -68,6 +68,57 @@ def get_latest_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 def rw_cache(key_name, data=None, diff_seconds=3600):