"""This module contains a tile cache handler."""

__author__ = 'Aaron Steele'

# MOL imports
import cache

# Standard Python imports
import hashlib
import logging
import os
import urllib
import webapp2

# Google App Engine imports
from google.appengine.api import memcache
from google.appengine.api import urlfetch
from google.appengine.ext.webapp.util import run_wsgi_app

if 'SERVER_SOFTWARE' in os.environ:
    PROD = not os.environ['SERVER_SOFTWARE'].startswith('Development')
else:
    PROD = True

app_id = os.environ['CURRENT_VERSION_ID'].split('.')[0]
if PROD:
    host_prefix = 'http'
    if os.environ['SERVER_PORT'] == 443:
        host_prefix = 'https'
    app_host = host_prefix + '://' + os.environ['SERVER_NAME'] 
else:
    app_host = 'http://localhost:8080'

class TileHandler(webapp2.RequestHandler):
    """Request handler for cache requests."""

    def get(self):
        tile_url = self.request.url.replace(app_host, 'http://mol.cartodb.com')
        tile_key = 'tc-%s' % hashlib.sha224(tile_url).hexdigest() # tc means Tile Cache
        tile_png = memcache.get(tile_key)
        if not tile_png:
            tile_png = cache.get(tile_key, value_type='blob')
            if not tile_png:
                tile_png = urlfetch.fetch(tile_url, deadline=60).content
                cache.add(tile_key, tile_png, value_type='blob')
            memcache.add(tile_key, tile_png)
        self.response.headers["Content-Type"] = "image/png"
        self.response.headers["Cache-Control"] = "max-age=2629743" # Cache 1 month
        self.response.out.write(tile_png)

class GridHandler(webapp2.RequestHandler):
    """Request handler for cache requests."""

    def get(self):
        grid_url = self.request.url.replace(app_host, 'http://mol.cartodb.com')
        grid_key = 'gc-%s' % hashlib.sha224(grid_url).hexdigest() # gc means Grid Cache
        grid_json = memcache.get(grid_key)
        if not grid_json:
            grid_json = cache.get(grid_key)            
            if not grid_json:
                grid_json = urlfetch.fetch(grid_url, deadline=60).content
                cache.add(grid_key, grid_json)
        self.response.headers["Content-Type"] = "application/json"
        self.response.headers["Cache-Control"] = "max-age=2629743" # Cache 1 month
        self.response.out.write(grid_json)                    
                    
application = webapp2.WSGIApplication(
    [('/tiles/[a-zA-Z0-9_-]+/[\d]+/[\d]+/[\d]+.png?.*', TileHandler),
     ('/tiles/[a-zA-Z0-9_-]+/[\d]+/[\d]+/[\d]+.grid.json?.*', GridHandler),], 
    debug=True)
         
def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

@@ -978,17 +978,19 @@
 key = 't
-c
+ile
 -%25s' %25 h
@@ -1084,24 +1084,41 @@
 et(tile_key)
+ # Check memcache
 %0A        if 
@@ -1184,32 +1184,56 @@
 lue_type='blob')
+ # Check datastore cache
 %0A            if 
@@ -1262,24 +1262,22 @@
         
-tile_png
+result
  = urlfe
@@ -1300,32 +1300,161 @@
 rl, deadline=60)
+ # Check CartoDB%0A                if result.status_code == 200 or result.status_code == 304:%0A                    tile_png = result
 .content%0A       
@@ -1438,32 +1438,36 @@
  result.content%0A
+    
                 
@@ -1527,16 +1527,24 @@
         
+      
+  
 memcache
@@ -1568,16 +1568,158 @@
 le_png)%0A
+            else:%0A                    memcache.add(tile_key, tile_png)%0A        if not tile_png:%0A            self.error(404)%0A        else:%0A    
         
@@ -1770,16 +1770,20 @@
 ge/png%22%0A
+    
         
@@ -1849,32 +1849,36 @@
 # Cache 1 month%0A
+    
         self.res
@@ -2113,18 +2113,23 @@
 _key = '
-gc
+utfgrid
 -%25s' %25 h
@@ -2357,25 +2357,22 @@
         
-grid_json
+result
  = urlfe
@@ -2403,16 +2403,150 @@
 line=60)
+%0A                if result.status_code == 200 or result.status_code == 304:                    %0A                    grid_json = result
 .content
@@ -2538,32 +2538,36 @@
  result.content%0A
+    
                 
@@ -2597,16 +2597,210 @@
 d_json)%0A
+                    memcache.add(grid_key, grid_json)%0A            else:%0A                memcache.add(grid_key, grid_json)%0A        if not grid_json:%0A            self.error(404)%0A        else:%0A    
         
@@ -2858,16 +2858,20 @@
 n/json%22%0A
+    
         
@@ -2937,32 +2937,36 @@
 # Cache 1 month%0A
+    
         self.res

Add memcache proxy to tile responses, check CartoDB response code.