<s> import hashlib <EOL> import time <EOL> from django . core . cache import cache <EOL> from django . core . cache . backends . base import BaseCache <EOL> from brake . backends import BaseBackend <EOL> CACHE_PREFIX = '<STR_LIT>' <EOL> IP_PREFIX = '<STR_LIT>' <EOL> KEY_TEMPLATE = '<STR_LIT>' <EOL> PERIOD_PREFIX = '<STR_LIT>' <EOL> class CacheBackend ( BaseBackend ) : <EOL> def get_ip ( self , request ) : <EOL> """<STR_LIT>""" <EOL> return request . META [ '<STR_LIT>' ] <EOL> def _keys ( self , func_name , request , ip = True , field = None , period = None ) : <EOL> keys = [ ] <EOL> if ip : <EOL> keys . append ( KEY_TEMPLATE % ( <EOL> func_name , PERIOD_PREFIX , period , <EOL> IP_PREFIX , self . get_ip ( request ) <EOL> ) ) <EOL> if field is not None : <EOL> if not isinstance ( field , ( list , tuple ) ) : <EOL> field = [ field ] <EOL> for f in field : <EOL> val = getattr ( request , request . method ) . get ( f ) <EOL> if val : <EOL> val = hashlib . sha1 ( val . encode ( '<STR_LIT:utf-8>' ) ) . hexdigest ( ) <EOL> keys . append ( '<STR_LIT>' % ( <EOL> func_name , PERIOD_PREFIX , period , f , val <EOL> ) ) <EOL> return [ <EOL> CACHE_PREFIX + k for k in keys <EOL> ] <EOL> def count ( self , func_name , request , ip = True , field = None , period = <NUM_LIT> ) : <EOL> """<STR_LIT>""" <EOL> counters = dict ( ( key , ( <NUM_LIT:1> , time . time ( ) + period ) ) for key in self . _keys ( <EOL> func_name , request , ip , field , period ) ) <EOL> counters . update ( cache . get_many ( counters . keys ( ) ) ) <EOL> for key , value in counters . items ( ) : <EOL> if isinstance ( value , tuple ) : <EOL> count , expiration = value <EOL> else : <EOL> count = value <EOL> expiration = time . time ( ) + period <EOL> count += <NUM_LIT:1> <EOL> cache . set ( key , ( count , expiration ) , timeout = int ( expiration - time . time ( ) ) ) <EOL> def limit ( self , func_name , request , <EOL> ip = True , field = None , count = <NUM_LIT:5> , period = None ) : <EOL> """<STR_LIT>""" <EOL> counters = cache . get_many ( <EOL> self . _keys ( func_name , request , ip , field , period ) <EOL> ) <EOL> limits = [ ] <EOL> for counter in counters : <EOL> ratelimited_by = '<STR_LIT>' <EOL> if '<STR_LIT>' in counter : <EOL> ratelimited_by = '<STR_LIT>' <EOL> current_count = counters [ counter ] <EOL> if isinstance ( current_count , tuple ) : <EOL> current_count = current_count [ <NUM_LIT:0> ] <EOL> if current_count > count : <EOL> limits . append ( { <EOL> '<STR_LIT>' : ratelimited_by , <EOL> '<STR_LIT>' : period , <EOL> '<STR_LIT>' : field , <EOL> '<STR_LIT:count>' : current_count , <EOL> '<STR_LIT>' : counter , <EOL> '<STR_LIT>' : self . get_ip ( request ) <EOL> } ) <EOL> return limits </s>
