<s> import cgi <EOL> import functools <EOL> from django . core . exceptions import ImproperlyConfigured <EOL> from django . conf import settings <EOL> from django . core . cache import cache , DEFAULT_CACHE_ALIAS <EOL> from django . utils . encoding import iri_to_uri <EOL> from django . utils . cache import ( <EOL> get_cache_key , <EOL> learn_cache_key , <EOL> patch_response_headers , <EOL> get_max_age <EOL> ) <EOL> from six import string_types , callable <EOL> from six . moves . urllib . parse import urlencode <EOL> from fancy_cache . utils import md5 <EOL> REMEMBERED_URLS_KEY = '<STR_LIT>' <EOL> LONG_TIME = <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT:30> <EOL> class RequestPath ( object ) : <EOL> def __init__ ( self , request , only_get_keys , forget_get_keys ) : <EOL> self . request = request <EOL> self . only_get_keys = only_get_keys <EOL> self . forget_get_keys = forget_get_keys <EOL> assert not ( self . only_get_keys and self . forget_get_keys ) <EOL> self . _prev_get_full_path = request . get_full_path <EOL> def __enter__ ( self ) : <EOL> if self . only_get_keys is not None : <EOL> self . request . get_full_path = functools . partial ( <EOL> self . get_full_path , <EOL> self . request , <EOL> self . only_get_keys , <EOL> True <EOL> ) <EOL> if self . forget_get_keys is not None : <EOL> self . request . get_full_path = functools . partial ( <EOL> self . get_full_path , <EOL> self . request , <EOL> self . forget_get_keys , <EOL> False <EOL> ) <EOL> def __exit__ ( self , exc_type , exc_value , traceback ) : <EOL> if self . only_get_keys is not None or self . forget_get_keys is not None : <EOL> self . request . get_full_path = self . _prev_get_full_path <EOL> def get_full_path ( self , this , keys , is_only_keys ) : <EOL> """<STR_LIT>""" <EOL> qs = this . META . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> parsed = cgi . parse_qs ( qs ) <EOL> if is_only_keys : <EOL> keep = dict ( ( k , parsed [ k ] ) for k in parsed if k in keys ) <EOL> else : <EOL> keep = dict ( ( k , parsed [ k ] ) for k in parsed if k not in keys ) <EOL> qs = urlencode ( keep , True ) <EOL> return '<STR_LIT>' % ( this . path , ( '<STR_LIT:?>' + iri_to_uri ( qs ) ) if qs else '<STR_LIT>' ) <EOL> class UpdateCacheMiddleware ( object ) : <EOL> """<STR_LIT>""" <EOL> def process_response ( self , request , response ) : <EOL> """<STR_LIT>""" <EOL> if ( <EOL> not hasattr ( request , '<STR_LIT>' ) or <EOL> not request . _cache_update_cache <EOL> ) : <EOL> return response <EOL> if request . method != '<STR_LIT:GET>' : <EOL> return response <EOL> if not response . status_code == <NUM_LIT:200> : <EOL> return response <EOL> timeout = get_max_age ( response ) <EOL> if timeout is None : <EOL> timeout = self . cache_timeout <EOL> elif timeout == <NUM_LIT:0> : <EOL> return response <EOL> if self . patch_headers : <EOL> patch_response_headers ( response , timeout ) <EOL> if timeout : <EOL> if callable ( self . key_prefix ) : <EOL> key_prefix = self . key_prefix ( request ) <EOL> else : <EOL> key_prefix = self . key_prefix <EOL> if self . post_process_response : <EOL> response = self . post_process_response ( <EOL> response , <EOL> request <EOL> ) <EOL> with RequestPath ( request , self . only_get_keys , self . forget_get_keys ) : <EOL> cache_key = learn_cache_key ( <EOL> request , <EOL> response , <EOL> timeout , <EOL> key_prefix <EOL> ) <EOL> if self . remember_all_urls : <EOL> self . remember_url ( request , cache_key , timeout ) <EOL> cache . set ( cache_key , response , timeout ) <EOL> if self . post_process_response_always : <EOL> response = self . post_process_response_always ( <EOL> response , <EOL> request <EOL> ) <EOL> return response <EOL> def remember_url ( self , request , cache_key , timeout ) : <EOL> url = request . get_full_path ( ) <EOL> remembered_urls = cache . get ( REMEMBERED_URLS_KEY , { } ) <EOL> remembered_urls [ url ] = cache_key <EOL> cache . set ( <EOL> REMEMBERED_URLS_KEY , <EOL> remembered_urls , <EOL> LONG_TIME <EOL> ) <EOL> class FetchFromCacheMiddleware ( object ) : <EOL> """<STR_LIT>""" <EOL> def process_request ( self , request ) : <EOL> """<STR_LIT>""" <EOL> response = self . _process_request ( request ) <EOL> if self . remember_stats_all_urls : <EOL> cache_key = request . get_full_path ( ) <EOL> if response is None : <EOL> cache_key += '<STR_LIT>' <EOL> else : <EOL> cache_key += '<STR_LIT>' <EOL> cache_key = md5 ( cache_key ) <EOL> if cache . get ( cache_key ) is None : <EOL> cache . set ( cache_key , <NUM_LIT:0> , LONG_TIME ) <EOL> cache . incr ( cache_key ) <EOL> return response <EOL> def _process_request ( self , request ) : <EOL> if self . cache_anonymous_only : <EOL> if not hasattr ( request , '<STR_LIT:user>' ) : <EOL> raise ImproperlyConfigured ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> if request . method not in ( '<STR_LIT:GET>' , '<STR_LIT>' ) : <EOL> request . _cache_update_cache = False <EOL> return None <EOL> if self . cache_anonymous_only and request . user . is_authenticated ( ) : <EOL> request . _cache_update_cache = False <EOL> return None <EOL> if callable ( self . key_prefix ) : <EOL> key_prefix = self . key_prefix ( request ) <EOL> if key_prefix is None : <EOL> request . _cache_update_cache = False <EOL> return None <EOL> else : <EOL> key_prefix = self . key_prefix <EOL> with RequestPath ( request , self . only_get_keys , self . forget_get_keys ) : <EOL> cache_key = get_cache_key ( request , key_prefix ) <EOL> if cache_key is None : <EOL> request . _cache_update_cache = True <EOL> return None <EOL> response = cache . get ( cache_key , None ) <EOL> if response is None : <EOL> request . _cache_update_cache = True <EOL> return None <EOL> request . _cache_update_cache = False <EOL> if self . post_process_response_always : <EOL> response = self . post_process_response_always ( <EOL> response , <EOL> request = request <EOL> ) <EOL> return response <EOL> class CacheMiddleware ( UpdateCacheMiddleware , FetchFromCacheMiddleware ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( <EOL> self , <EOL> cache_timeout = settings . CACHE_MIDDLEWARE_SECONDS , <EOL> key_prefix = settings . CACHE_MIDDLEWARE_KEY_PREFIX , <EOL> cache_anonymous_only = getattr ( <EOL> settings , <EOL> '<STR_LIT>' , <EOL> False <EOL> ) , <EOL> patch_headers = False , <EOL> post_process_response = None , <EOL> post_process_response_always = None , <EOL> only_get_keys = None , <EOL> forget_get_keys = None , <EOL> remember_all_urls = getattr ( <EOL> settings , <EOL> '<STR_LIT>' , <EOL> False <EOL> ) , <EOL> remember_stats_all_urls = getattr ( <EOL> settings , <EOL> '<STR_LIT>' , <EOL> False <EOL> ) , <EOL> ** kwargs <EOL> ) : <EOL> self . patch_headers = patch_headers <EOL> self . cache_timeout = cache_timeout <EOL> self . key_prefix = key_prefix <EOL> self . cache_anonymous_only = cache_anonymous_only <EOL> self . post_process_response = post_process_response <EOL> self . post_process_response_always = post_process_response_always <EOL> if isinstance ( only_get_keys , string_types ) : <EOL> only_get_keys = [ only_get_keys ] <EOL> self . only_get_keys = only_get_keys <EOL> if isinstance ( forget_get_keys , string_types ) : <EOL> forget_get_keys = [ forget_get_keys ] <EOL> self . forget_get_keys = forget_get_keys <EOL> self . remember_all_urls = remember_all_urls <EOL> self . remember_stats_all_urls = remember_stats_all_urls <EOL> try : <EOL> cache_alias = kwargs [ '<STR_LIT>' ] <EOL> if cache_alias is None : <EOL> cache_alias = DEFAULT_CACHE_ALIAS <EOL> except KeyError : <EOL> cache_alias = settings . CACHE_MIDDLEWARE_ALIAS <EOL> self . cache_alias = cache_alias </s>
