pngtile.tile: split off BaseAppliation
authorTero Marttila <terom@paivola.fi>
Sun, 14 Sep 2014 18:04:11 +0300
changeset 138 59d61da2b64f
parent 137 79eedd96112d
child 139 8eff4a9fdd5e
pngtile.tile: split off BaseAppliation
bin/tile-server
bin/tile.wsgi
pngtile/application.py
pngtile/tile.py
--- a/bin/tile-server	Sun Sep 14 17:23:01 2014 +0300
+++ b/bin/tile-server	Sun Sep 14 18:04:11 2014 +0300
@@ -25,7 +25,7 @@
 
     args = parser.parse_args()
 
-    application = pngtile.tile.Application(
+    application = pngtile.tile.TileApplication(
         image_root  = args.image_root,
     )
 
--- a/bin/tile.wsgi	Sun Sep 14 17:23:01 2014 +0300
+++ b/bin/tile.wsgi	Sun Sep 14 18:04:11 2014 +0300
@@ -1,5 +1,5 @@
 import pngtile.tile
 
-application = pngtile.tile.Application(
+application = pngtile.tile.TileApplication(
     image_root  = './var',
 )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pngtile/application.py	Sun Sep 14 18:04:11 2014 +0300
@@ -0,0 +1,117 @@
+from werkzeug import Request, Response, exceptions
+from werkzeug.utils import html
+
+import pypngtile
+
+import os.path
+
+class BaseApplication (object):
+    def __init__ (self, image_root):
+        if not os.path.isdir(image_root) :
+            raise Exception("Given image_root does not exist: {image_root}".format(image_root=image_root))
+
+        self.image_root = os.path.abspath(image_root)
+
+        self.image_cache = { }
+
+    def lookup_image (self, url):
+        """
+            Lookup image by request path.
+
+            Returns image_name, image_path.
+        """
+
+        if not os.path.isdir(self.image_root):
+            raise exceptions.InternalServerError("Server image_root has gone missing")
+    
+        # path to image
+        name = url.lstrip('/')
+        
+        # build absolute path
+        path = os.path.abspath(os.path.join(self.image_root, name))
+
+        # ensure the path points inside the data root
+        if not path.startswith(self.image_root):
+            raise exceptions.NotFound(name)
+        
+        if not os.path.exists(path):
+            raise exceptions.NotFound(name)
+
+        if os.path.isdir(path):
+            raise exceptions.BadRequest("Is a directory: {name}".format(name=name))
+
+        if not path.endswith('.png'):
+            raise exceptions.BadRequest("Not a PNG image: {name}".format(name=name))
+
+        return name, path
+
+    def get_image (self, url):
+        """
+            Return Image object.
+        """
+
+        name, path = self.lookup_image(url)
+
+        # get Image object
+        image = self.image_cache.get(path)
+
+        if not image:
+            # open
+            image = pypngtile.Image(path)
+
+            # check
+            if image.status() not in (pypngtile.CACHE_FRESH, pypngtile.CACHE_STALE):
+                raise exceptions.InternalServerError("Image cache not available: {name}".format(name=name))
+
+            # load
+            image.open()
+
+            # cache
+            self.image_cache[path] = image
+        
+        return image, name
+
+    def handle (self, request):
+        """
+            Handle request for an image
+        """
+
+        raise NotImplementedError()
+
+    @Request.application
+    def __call__ (self, request):
+        """
+            WSGI entry point.
+        """
+
+        try:
+            return self.handle(request)
+
+        except exceptions.HTTPException as error:
+            return error
+
+    STYLESHEETS = ( )
+    SCRIPTS = ( )
+
+    def render_html (self, title, body, stylesheets=None, scripts=None):
+        if stylesheets is None:
+            stylesheets = self.STYLESHEETS
+
+        if scripts is None:
+            scripts = self.SCRIPTS
+
+        return html.html(lang='en', *[
+            html.head(
+                html.title(title),
+                *[
+                    html.link(rel='stylesheet', href=href) for href in stylesheets
+                ]
+            ),
+            html.body(
+                *(body + tuple(
+                    html.script(src=src) for src in scripts
+                ))
+            ),
+        ])
+
+
--- a/pngtile/tile.py	Sun Sep 14 17:23:01 2014 +0300
+++ b/pngtile/tile.py	Sun Sep 14 18:04:11 2014 +0300
@@ -2,8 +2,7 @@
     Raw tile handling.
 """
 
-import os.path
-
+from pngtile.application import BaseApplication
 from werkzeug import Request, Response, exceptions
 
 import pypngtile
@@ -40,63 +39,10 @@
 
     return scale(val - dim / 2, zoom)
 
-class Application (object):
-    def __init__ (self, image_root):
-        if not os.path.isdir(image_root) :
-            raise Exception("Given image_root does not exist: {image_root}".format(image_root=image_root))
-
-        self.image_root = os.path.abspath(image_root)
-
-        self.image_cache = { }
-
-    def lookup_image (self, url):
-        """
-            Lookup image by request path.
-
-            Returns image_name, image_path.
-        """
-
-        if not os.path.isdir(self.image_root):
-            raise exceptions.InternalServerError("Server image_root has gone missing")
-    
-        # path to image
-        name = url.lstrip('/')
+class TileApplication (BaseApplication):
+    def __init__ (self, **opts):
+        BaseApplication.__init__(self, **opts)
         
-        # build absolute path
-        path = os.path.abspath(os.path.join(self.image_root, name))
-
-        # ensure the path points inside the data root
-        if not path.startswith(self.image_root):
-            raise exceptions.NotFound(name)
-
-        return name, path
-
-    def get_image (self, url):
-        """
-            Return Image object.
-        """
-
-        name, path = self.lookup_image(url)
-
-        # get Image object
-        image = self.image_cache.get(path)
-
-        if not image:
-            # open
-            image = pypngtile.Image(path)
-
-            # check
-            if image.status() not in (pypngtile.CACHE_FRESH, pypngtile.CACHE_STALE):
-                raise exceptions.InternalServerError("Image cache not available: {name}".format(name=name))
-
-            # load
-            image.open()
-
-            # cache
-            self.image_cache[path] = image
-        
-        return image
-
     def render_region (self, request, image):
         """
             Handle request for an image region
@@ -147,7 +93,7 @@
         """
         
         try:
-            image = self.get_image(request.path)
+            image, name = self.get_image(request.path)
         except pypngtile.Error as error:
             raise exceptions.BadRequest(str(error))
 
@@ -161,16 +107,3 @@
             raise exceptions.BadRequest("Unknown args")
 
         return Response(png, content_type='image/png')
-
-    @Request.application
-    def __call__ (self, request):
-        """
-            WSGI entry point.
-        """
-
-        try:
-            return self.handle(request)
-
-        except exceptions.HTTPException as error:
-            return error
-