Merge pull request #1 from EndenDragon/redislite

Redislite
This commit is contained in:
Jeremy "EndenDragon" Zhang 2017-04-21 23:13:00 -07:00 committed by GitHub
commit f22bc439e7
11 changed files with 57 additions and 21 deletions

4
.gitignore vendored
View File

@ -90,3 +90,7 @@ ENV/
# Project specifc # Project specifc
config.py config.py
redislite.db
redislite.db.settings
tmp/*
!tmp/.gitinclude

View File

@ -1,8 +1,8 @@
flask flask
flask-sqlalchemy flask-sqlalchemy
cachetools
Flask-Cache
flask_limiter flask_limiter
requests_oauthlib requests_oauthlib
mysql-python mysql-python
Flask-SSLify Flask-SSLify
redislite
beaker

2
run.py
View File

@ -32,4 +32,4 @@ def init_debug():
if __name__ == "__main__": if __name__ == "__main__":
init_debug() init_debug()
app.run(host="0.0.0.0",port=3000,debug=True) app.run(host="0.0.0.0",port=3000,debug=True,processes=3)

View File

@ -2,7 +2,7 @@ from config import config
from database import db from database import db
from flask import Flask, render_template, request, session, url_for, redirect, jsonify from flask import Flask, render_template, request, session, url_for, redirect, jsonify
from flask_sslify import SSLify from flask_sslify import SSLify
from titanembeds.utils import cache, rate_limiter from titanembeds.utils import rate_limiter, cache
import blueprints.api import blueprints.api
import blueprints.user import blueprints.user
import blueprints.embed import blueprints.embed
@ -15,10 +15,10 @@ app.config['SQLALCHEMY_DATABASE_URI'] = config['database-uri']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Suppress the warning/no need this on for now. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Suppress the warning/no need this on for now.
app.config['RATELIMIT_HEADERS_ENABLED'] = True app.config['RATELIMIT_HEADERS_ENABLED'] = True
app.config['SQLALCHEMY_POOL_RECYCLE'] = 250 app.config['SQLALCHEMY_POOL_RECYCLE'] = 250
app.config['RATELIMIT_STORAGE_URL'] = 'redislite://redislite.db'
app.secret_key = config['app-secret'] app.secret_key = config['app-secret']
db.init_app(app) db.init_app(app)
cache.init_app(app, config={'CACHE_TYPE': 'simple'})
rate_limiter.init_app(app) rate_limiter.init_app(app)
sslify = SSLify(app, permanent=True) sslify = SSLify(app, permanent=True)

View File

@ -114,7 +114,7 @@ def format_post_content(message):
message = "**<{}#{}>** {}".format(session['username'], session['discriminator'], message) # I would like to do a @ mention, but i am worried about notif spam message = "**<{}#{}>** {}".format(session['username'], session['discriminator'], message) # I would like to do a @ mention, but i am worried about notif spam
return message return message
@cache.cached(timeout=60, key_prefix=make_guildchannels_cache_key) @cache.cache(make_guildchannels_cache_key, expires=60)
def get_guild_channels(guild_id): def get_guild_channels(guild_id):
if user_unauthenticated(): if user_unauthenticated():
member_roles = [guild_id] #equivilant to @everyone role member_roles = [guild_id] #equivilant to @everyone role

View File

@ -5,3 +5,4 @@ from guilds import Guilds
from unauthenticated_users import UnauthenticatedUsers from unauthenticated_users import UnauthenticatedUsers
from unauthenticated_bans import UnauthenticatedBans from unauthenticated_bans import UnauthenticatedBans
from authenticated_users import AuthenticatedUsers from authenticated_users import AuthenticatedUsers
from custom_redislite import LimitsRedisLite

View File

@ -0,0 +1,25 @@
import urlparse
from limits.storage import Storage
from redislite import Redis
class LimitsRedisLite(Storage): # For Python Limits
STORAGE_SCHEME = "redislite"
def __init__(self, uri, **options):
self.redis_instance = Redis(urlparse.urlparse(uri).netloc)
def check(self):
return True
def get_expiry(self, key):
return self.redis_instance.ttl(key)
def incr(self, key, expiry, elastic_expiry=False):
if self.redis_instance.exists(key):
self.redis_instance.set(key, int(self.redis_instance.get(key))+1)
else:
self.redis_instance.set(key, 1)
self.redis_instance.expire(key, expiry)
return
def get(self, key):
return int(self.redis_instance.get(key))

View File

@ -3,11 +3,9 @@ import sys
import time import time
import json import json
from functools import partial from functools import partial
from cachetools import cached, TTLCache from titanembeds.utils import cache
from cachetools.keys import hashkey
_DISCORD_API_BASE = "https://discordapp.com/api/v6" _DISCORD_API_BASE = "https://discordapp.com/api/v6"
cache = TTLCache(200, 200)
def json_or_text(response): def json_or_text(response):
text = response.text text = response.text
@ -122,7 +120,7 @@ class DiscordREST:
r = self.request("GET", _endpoint) r = self.request("GET", _endpoint)
return r return r
@cached(cache, key=partial(hashkey, 'get_guild_member')) @cache.cache('get_guild_member', expire=200)
def get_guild_member(self, guild_id, user_id): def get_guild_member(self, guild_id, user_id):
_endpoint = "/guilds/{guild_id}/members/{user_id}".format(guild_id=guild_id, user_id=user_id) _endpoint = "/guilds/{guild_id}/members/{user_id}".format(guild_id=guild_id, user_id=user_id)
r = self.request("GET", _endpoint) r = self.request("GET", _endpoint)
@ -160,7 +158,7 @@ class DiscordREST:
r = self.request("GET", _endpoint) r = self.request("GET", _endpoint)
return r return r
@cached(cache, key=partial(hashkey, 'list_all_guild_members')) @cache.cache('list_all_guild_members', expire=200)
def list_all_guild_members(self, guild_id): def list_all_guild_members(self, guild_id):
_endpoint = "/guilds/{guild_id}/members".format(guild_id=guild_id) _endpoint = "/guilds/{guild_id}/members".format(guild_id=guild_id)
count = 1 count = 1
@ -183,7 +181,7 @@ class DiscordREST:
# User # User
##################### #####################
@cached(cache, key=partial(hashkey, 'get_all_guilds')) @cache.cache('get_all_guilds', expire=100)
def get_all_guilds(self): def get_all_guilds(self):
_endpoint = "/users/@me/guilds" _endpoint = "/users/@me/guilds"
params = {} params = {}
@ -206,7 +204,7 @@ class DiscordREST:
# Widget Handler # Widget Handler
##################### #####################
@cached(cache, key=partial(hashkey, 'get_widget')) @cache.cache('get_widget', expire=200)
def get_widget(self, guild_id): def get_widget(self, guild_id):
_endpoint = _DISCORD_API_BASE + "/servers/{guild_id}/widget.json".format(guild_id=guild_id) _endpoint = _DISCORD_API_BASE + "/servers/{guild_id}/widget.json".format(guild_id=guild_id)
embed = self.get_guild_embed(guild_id) embed = self.get_guild_embed(guild_id)

View File

@ -42,7 +42,7 @@ def get_current_authenticated_user():
def user_has_permission(permission, index): def user_has_permission(permission, index):
return bool((int(permission) >> index) & 1) return bool((int(permission) >> index) & 1)
@cache.cached(timeout=120, key_prefix=make_guilds_cache_key) @cache.cache(make_guilds_cache_key, expire=120)
def get_user_guilds(): def get_user_guilds():
req = discordrest_from_user("/users/@me/guilds") req = discordrest_from_user("/users/@me/guilds")
return req return req

View File

@ -1,15 +1,23 @@
from beaker.cache import CacheManager
from beaker.util import parse_cache_config_options
from titanembeds.database import db, Guilds from titanembeds.database import db, Guilds
from titanembeds.discordrest import DiscordREST
from flask import request, session from flask import request, session
from flask.ext.cache import Cache
from flask_limiter import Limiter from flask_limiter import Limiter
from config import config from config import config
import random import random
import string import string
import hashlib import hashlib
cache_opts = {
'cache.type': 'file',
'cache.data_dir': 'tmp/cachedata',
'cache.lock_dir': 'tmp/cachelock'
}
cache = CacheManager(**parse_cache_config_options(cache_opts))
from titanembeds.discordrest import DiscordREST
discord_api = DiscordREST(config['bot-token']) discord_api = DiscordREST(config['bot-token'])
cache = Cache()
def get_client_ipaddr(): def get_client_ipaddr():
if "X-Real-IP" in request.headers: # pythonanywhere specific if "X-Real-IP" in request.headers: # pythonanywhere specific

0
tmp/.gitinclude Normal file
View File