def on_load(self, g): from r2.lib.cache import CMemcache, MemcacheChain, LocalCache # TODO: use SelfEmptyingCache for localcache if we use this in jobs f2p_memcaches = CMemcache( 'f2p', g.f2pcaches, num_clients=g.num_mc_clients, ) g.f2pcache = MemcacheChain(( LocalCache(), f2p_memcaches, )) g.cache_chains.update(f2p=g.f2pcache) compendium = pkg_resources.resource_stream(__name__, "data/compendium.json") g.f2pitems = json.load(compendium) for kind, data in g.f2pitems.iteritems(): data["kind"] = kind
def pre(self): g.cache.caches = (LocalCache(), ) + g.cache.caches[1:] #check if user-agent needs a dose of rate-limiting if not c.error_page: ratelimit_agents() # the domain has to be set before Cookies get initialized set_subreddit() set_cnameframe() # populate c.cookies c.cookies = Cookies() try: for k, v in request.cookies.iteritems(): # we can unquote even if it's not quoted c.cookies[k] = Cookie(value=unquote(v), dirty=False) except CookieError: #pylons or one of the associated retarded libraries can't #handle broken cookies request.environ['HTTP_COOKIE'] = '' c.response_wrappers = [] c.errors = ErrorSet() c.firsttime = firsttime() (c.user, maybe_admin) = \ valid_cookie(c.cookies[g.login_cookie].value if g.login_cookie in c.cookies else '') if c.user: c.user_is_loggedin = True else: c.user = UnloggedUser(get_browser_langs()) c.user._load() if c.user_is_loggedin: if not c.user._loaded: c.user._load() c.modhash = c.user.modhash() if request.method.lower() == 'get': read_click_cookie() read_mod_cookie() if hasattr(c.user, 'msgtime') and c.user.msgtime: c.have_messages = c.user.msgtime c.user_is_admin = maybe_admin and c.user.name in g.admins c.user_is_sponsor = c.user_is_admin or c.user.name in g.sponsors c.over18 = over18() #set_browser_langs() set_host_lang() set_content_type() set_iface_lang() set_content_lang() set_colors() set_recent_reddits() # set some environmental variables in case we hit an abort if not isinstance(c.site, FakeSubreddit): request.environ['REDDIT_NAME'] = c.site.name # check if the user has access to this subreddit if not c.site.can_view(c.user) and not c.error_page: abort(403, "forbidden") #check over 18 if (c.site.over_18 and not c.over18 and request.path not in ("/frame", "/over18") and c.render_style == 'html'): return self.intermediate_redirect("/over18") #check whether to allow custom styles c.allow_styles = True if g.css_killswitch: c.allow_styles = False #if the preference is set and we're not at a cname elif not c.user.pref_show_stylesheets and not c.cname: c.allow_styles = False #if the site has a cname, but we're not using it elif c.site.domain and not c.cname: c.allow_styles = False #check content cache if not c.user_is_loggedin: r = cache.get(self.request_key()) if r and request.method == 'GET': response = c.response response.headers = r.headers response.content = r.content for x in r.cookies.keys(): if x in cache_affecting_cookies: cookie = r.cookies[x] response.set_cookie(key=x, value=cookie.value, domain=cookie.get('domain', None), expires=cookie.get( 'expires', None), path=cookie.get('path', None)) response.status_code = r.status_code request.environ['pylons.routes_dict'][ 'action'] = 'cached_response' # make sure to carry over the content type c.response_content_type = r.headers['content-type'] if r.headers.has_key('access-control'): c.response_access_control = r.headers['access-control'] c.used_cache = True # response wrappers have already been applied before cache write c.response_wrappers = []
def __init__(self, global_conf, app_conf, paths, **extra): """ Globals acts as a container for objects available throughout the life of the application. One instance of Globals is created by Pylons during application initialization and is available during requests via the 'g' variable. ``global_conf`` The same variable used throughout ``config/middleware.py`` namely, the variables from the ``[DEFAULT]`` section of the configuration file. ``app_conf`` The same ``kw`` dictionary used throughout ``config/middleware.py`` namely, the variables from the section in the config file for your application. ``extra`` The configuration returned from ``load_config`` in ``config/middleware.py`` which may be of use in the setup of your global variables. """ def to_bool(x): return (x.lower() == 'true') if x else None def to_iter(name, delim = ','): return (x.strip() for x in global_conf.get(name, '').split(delim)) # slop over all variables to start with for k, v in global_conf.iteritems(): if not k.startswith("_") and not hasattr(self, k): if k in self.int_props: v = int(v) elif k in self.bool_props: v = to_bool(v) elif k in self.tuple_props: v = tuple(to_iter(k)) setattr(self, k, v) # initialize caches mc = Memcache(self.memcaches, debug=True) self.cache = CacheChain((LocalCache(), mc)) self.permacache = Memcache(self.permacaches, debug=True) self.rendercache = Memcache(self.rendercaches, debug=True) self.make_lock = make_lock_factory(mc) self.rec_cache = Memcache(self.rec_cache, debug=True) # set default time zone if one is not set self.tz = pytz.timezone(global_conf.get('timezone')) #make a query cache self.stats_collector = QueryStats() # set the modwindow self.MODWINDOW = timedelta(self.MODWINDOW) self.REDDIT_MAIN = bool(os.environ.get('REDDIT_MAIN')) # turn on for language support self.languages, self.lang_name = _get_languages() all_languages = self.lang_name.keys() all_languages.sort() self.all_languages = all_languages # load the md5 hashes of files under static static_files = os.path.join(paths.get('static_files'), 'static') self.static_md5 = {} if os.path.exists(static_files): for f in os.listdir(static_files): if f.endswith('.md5'): key = f[0:-4] f = os.path.join(static_files, f) with open(f, 'r') as handle: md5 = handle.read().strip('\n') self.static_md5[key] = md5 #set up the logging directory log_path = self.log_path process_iden = global_conf.get('scgi_port', 'default') if log_path: if not os.path.exists(log_path): os.makedirs(log_path) for fname in os.listdir(log_path): if fname.startswith(process_iden): full_name = os.path.join(log_path, fname) os.remove(full_name) #setup the logger self.log = logging.getLogger('reddit') self.log.addHandler(logging.StreamHandler()) if self.debug: self.log.setLevel(logging.DEBUG) #read in our CSS so that it can become a default for subreddit #stylesheets stylesheet_path = os.path.join(paths.get('static_files'), self.static_path.lstrip('/'), self.stylesheet) with open(stylesheet_path) as s: self.default_stylesheet = s.read() self.reddit_host = socket.gethostname() self.reddit_pid = os.getpid()
def setUp(self): self.patch('ratelimit.time.time', lambda: self.now) self.cache = LocalCache() self.patch('ratelimit.g.ratelimitcache', self.cache)