diff --git a/util.py b/util.py index 61bb424..d7c9e11 100644 --- a/util.py +++ b/util.py @@ -1,11 +1,48 @@ import datetime +import os import random import re -from functools import wraps +import time +from functools import wraps, update_wrapper from flask import abort from flask_login import current_user, login_required from passlib.hash import bcrypt +from redis import from_url + +redis = from_url(os.getenv("REDIS_URL")) + + +def cache(expire_in=120, uid=None): + def decorator(f): + def cache_function(*args, **kwargs): + arg_collection = list(args) + sorted(kwargs.items()) + key = 'cache/%s/%s' % (f.__name__, arg_collection) + if uid is not None: + key = '%s/%s' % (key, uid()) + with redis.pipeline() as p: + p.get(key) + result = p.execute()[0] + if result is None: + result = f(*args, **kwargs) + p.set(key, result) + p.expireat(key, int(time.time() + expire_in)) + p.execute() + return result + + return update_wrapper(cache_function, f) + + return decorator + + +def uncache(function_name=None, args=None, uid=None): + if not function_name: return + key = 'cache/%s/%s' % (function_name, args) + if uid is not None: + key = '%s/%s' % (key, uid) + with redis.pipeline() as p: + p.delete(key) + p.execute() def isoformat(seconds): diff --git a/views/events.py b/views/events.py index e16c674..e6ed567 100644 --- a/views/events.py +++ b/views/events.py @@ -7,7 +7,7 @@ import config from forms import EventForm from models import db, Event -from util import admin_required, isoformat +from util import admin_required, isoformat, cache, uncache blueprint = Blueprint('events', __name__, template_folder='templates') @@ -21,6 +21,7 @@ def events_create(): event_create_form.populate_obj(new_event) db.session.add(new_event) db.session.commit() + uncache(function_name=events_owned.__name__, args=[], uid=current_user.id) return redirect(url_for('.events_owned')) return render_template('events/create.html', event_create_form=event_create_form) @@ -139,6 +140,7 @@ def events_unapproved(page_number=1): @blueprint.route('/owned') @blueprint.route('/owned/page/') +@cache(uid=lambda: current_user.id) @login_required def events_owned(page_number=1): if page_number <= 0: @@ -199,5 +201,6 @@ def events_remove(event_id): if current_user != event.owner: abort(403) event.removed = True + uncache(function_name=events_owned.__name__, args=[], uid=current_user.id) db.session.commit() return redirect(url_for('.events_owned'))