def raw_exercise_contents(exercise_file): if templatetags.use_compressed_packages(): exercises_dir = "../khan-exercises/exercises-packed" safe_to_cache = True else: exercises_dir = "../khan-exercises/exercises" safe_to_cache = False path = os.path.join(os.path.dirname(__file__), "%s/%s" % (exercises_dir, exercise_file)) f = None contents = "" try: f = open(path) contents = f.read() except: raise MissingExerciseException( "Missing exercise file for exid '%s'" % exercise_file) finally: if f: f.close() if not len(contents): raise MissingExerciseException( "Missing exercise content for exid '%s'" % exercise_file) if safe_to_cache: return contents else: # we are displaying an unpacked exercise, either locally or in prod # with a querystring override. It's unsafe to cache this. return layer_cache.UncachedResult(contents)
def get_profile_from_cookie_key_value(cookie_key, cookie_value): """ Communicate with Facebook to get a FB profile associated with the specific cookie value. Because this talks to Facebook via an HTTP request, this is cached in memcache to avoid constant communication while a FB user is browsing the site. If we encounter an error or fail to load a Facebook profile, the results are not cached in memcache. However, we also cache in request_cache because if we fail to load a Facebook profile, we only want to do that once per request. """ fb_auth_dict = facebook.get_user_from_cookie_patched( {cookie_key: cookie_value}, App.facebook_app_id, App.facebook_app_secret) if fb_auth_dict: profile = _get_profile_from_fb_token(fb_auth_dict["access_token"]) if profile: return profile # Don't cache any missing results in memcache return layer_cache.UncachedResult(None)
class ImageCache(blobstore_handlers.BlobstoreDownloadHandler): """ ImageCache is a little utility used to cache images at other URLs in our blobstore with our own aggressive caching headers for client-side perf. Example: youtube_url = ImageCache.url_for("http://youtube.com/some/thumbnail") """ @staticmethod def url_for(source_url, fallback_url = None): if fallback_url: return "/image_cache/%s?fallback=%s" % (urllib.quote(source_url), urllib.quote(fallback_url)) else: return "/image_cache/%s" % urllib.quote(source_url) def get(self, source_url): blob_key = self.image_cache_blob_key(source_url) fallback_url = self.request.get("fallback") if fallback_url and not blob_key: blob_key = self.image_cache_blob_key(fallback_url) if not blob_key: # If we failed to grab something outta the blob store, just try a redirect. # ...but log the error, cuz we don't like this. logging.error("Failed to load image cache for source url, redirecting: %s" % source_url) self.redirect(source_url) return self.response.cache_control.max_age = CACHE_EXPIRATION self.response.cache_control.no_cache = None self.response.cache_control.public = True self.send_blob(blob_key) @layer_cache.cache_with_key_fxn( lambda self, source_url: "image_cache:%s" % source_url, layer=layer_cache.Layers.Datastore, persist_across_app_versions=True) def image_cache_blob_key(self, source_url): tries = 0 max_tries = 3 while tries < max_tries: response = None try: response = urlfetch.fetch(url = source_url, headers = self.request.headers, deadline=10) except Exception, e: logging.info("Failed to load image cache source url %s due to %s" % (source_url, e)) if response and response.status_code == 200: return blob_key_for_data(response.headers.get("Content-Type"), response.content) else: tries += 1 return layer_cache.UncachedResult(None)
def exercise_sha1(exercise): sha1 = None try: contents = raw_exercise_contents("%s.html" % exercise.name) sha1 = hashlib.sha1(contents).hexdigest() except MissingExerciseException: pass if templatetags.use_compressed_packages(): return sha1 else: return layer_cache.UncachedResult(sha1)
def get_facebook_nickname(user_id): id = user_id.replace(FACEBOOK_ID_PREFIX, "") graph = facebook.GraphAPI() try: profile = graph.get_object(id) # Workaround http://code.google.com/p/googleappengine/issues/detail?id=573 # Bug fixed, utf-8 and nonascii is okay return unicodedata.normalize('NFKD', profile["name"]).encode('utf-8', 'ignore') except (facebook.GraphAPIError, urlfetch.DownloadError, AttributeError, httplib.HTTPException): # In the event of an FB error, don't cache the result. return layer_cache.UncachedResult(user_id)
def get_profile_from_cookie_key_value(cookie_key, cookie_value): fb_auth_dict = facebook.get_user_from_cookie_patched( {cookie_key: cookie_value}, App.facebook_app_id, App.facebook_app_secret) if fb_auth_dict: profile = get_profile_from_fb_token(fb_auth_dict["access_token"]) if profile: return profile # Don't cache any missing results return layer_cache.UncachedResult(None)
def exercise_sha1(exercise): sha1 = None try: file_name = exercise.file_name # TODO(eater): remove this after adding the filename to all existing # exercise entities if not file_name or file_name == "": file_name = exercise.name + ".html" contents = raw_exercise_contents(file_name) sha1 = hashlib.sha1(contents).hexdigest() except MissingExerciseException: pass if templatetags.use_compressed_packages(): return sha1 else: return layer_cache.UncachedResult(sha1)