pngtile/wsgi.py
changeset 92 e50ec4217fe6
parent 90 1c317e0628a7
child 93 581cdb831b32
--- a/pngtile/wsgi.py	Mon Jan 25 05:14:00 2010 +0200
+++ b/pngtile/wsgi.py	Mon Jan 25 18:46:59 2010 +0200
@@ -4,200 +4,18 @@
 
 from werkzeug import Request, Response, responder
 from werkzeug import exceptions
+
 import os.path, os
-
 import pypngtile as pt
 
-## Settings
+from pngtile import render
+
 # path to images
 DATA_ROOT = os.environ.get("PNGTILE_DATA_PATH") or os.path.abspath('data/')
 
 # only open each image once
 IMAGE_CACHE = {}
 
-# width of a tile
-TILE_WIDTH = 256
-TILE_HEIGHT = 256
-
-# max. output resolution to allow
-MAX_PIXELS = 1920 * 1200
-
-def dir_url (prefix, name, item) :
-    """
-        Join together an absolute URL prefix, an optional directory name, and a directory item
-    """
-
-    url = prefix
-
-    if name :
-        url = os.path.join(url, name)
-
-    url = os.path.join(url, item)
-
-    return url
-
-def dir_list (dir_path) :
-    """
-        Yield a series of directory items to show for the given dir
-    """
-
-    # link to parent
-    yield '..'
-
-    for item in os.listdir(dir_path) :
-        path = os.path.join(dir_path, item)
-
-        # skip dotfiles
-        if item.startswith('.') :
-            continue
-        
-        # show dirs
-        if os.path.isdir(path) :
-            yield item
-
-        # examine ext
-        base, ext = os.path.splitext(path)
-
-        # show .png files with a .cache file
-        if ext == '.png' and os.path.exists(base + '.cache') :
-            yield item
-
-### Render HTML data
-def render_dir (req, name, path) :
-    """
-        Directory index
-    """
-
-    prefix = os.path.dirname(req.script_root).rstrip('/')
-    script_prefix = req.script_root
-    name = name.rstrip('/')
-
-    return """\
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-    <head>
-        <title>Index of %(dir)s</title>
-        <link rel="Stylesheet" type="text/css" href="%(prefix)s/static/style.css">
-    </head>
-    <body>
-        <h1>Index of %(dir)s</h1>
-
-        <ul>
-%(listing)s
-        </ul>
-    </body>
-</html>""" % dict(
-        prefix          = prefix,
-        dir             = '/' + name,
-        
-        listing         = "\n".join(
-            # <li> link
-            """<li><a href="%(url)s">%(name)s</a></li>""" % dict(
-                # URL to dir
-                url         = dir_url(script_prefix, name, item),
-
-                # item name
-                name        = item,
-            ) for item in dir_list(path)
-        ),
-    )
-
-def render_img_viewport (req, name, image) :
-    """
-        HTML for image
-    """
-    
-    # a little slow, but not so bad - two stats(), heh
-    info = image.info()
-    img_width, img_height = info['img_width'], info['img_height']
-
-    return """\
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-    <head>
-        <title>%(title)s</title>
-        <script src="%(prefix)s/static/prototype.js" type="text/javascript"></script>
-        <script src="%(prefix)s/static/dragdrop.js" type="text/javascript"></script>
-        <script src="%(prefix)s/static/builder.js" type="text/javascript"></script>
-        <script src="%(prefix)s/static/tiles2.js" type="text/javascript"></script>
-        <link rel="Stylesheet" type="text/css" href="%(prefix)s/static/style.css">
-    </head>
-    <body>
-        <div id="wrapper">
-            <div id="viewport" style="width: 100%%; height: 100%%">
-                <div class="overlay">
-                    <input type="button" id="btn-zoom-in" value="Zoom In" />
-                    <input type="button" id="btn-zoom-out" value="Zoom Out" />
-                    <a class="link" id="lnk-image" href="#"></a>
-                </div>
-
-                <div class="substrate"></div>
-
-                <div class="background">
-                    Loading...
-                </div>
-            </div>
-        </div>
-
-        <script type="text/javascript">
-            var tile_source = new Source("%(tile_url)s", %(tile_width)d, %(tile_height)d, -4, 0, %(img_width)d, %(img_height)d);
-            var main = new Viewport(tile_source, "viewport");
-        </script>
-    </body>
-</html>""" % dict(
-        title           = name,
-        prefix          = os.path.dirname(req.script_root).rstrip('/'),
-        tile_url        = req.url,
-
-        tile_width      = TILE_WIDTH,
-        tile_height     = TILE_HEIGHT,
-
-        img_width       = img_width,
-        img_height      = img_height,
-    )
-
-def scale_by_zoom (val, zoom) :
-    """
-        Scale coordinates by zoom factor
-    """
-
-    if zoom > 0 :
-        return val << zoom
-
-    elif zoom > 0 :
-        return val >> -zoom
-
-    else :
-        return val
-
-### Render PNG Data
-def render_img_tile (image, x, y, zoom, width=TILE_WIDTH, height=TILE_HEIGHT) :
-    """
-        Render given tile, returning PNG data
-    """
-
-    return image.tile_mem(
-        width, height, 
-        scale_by_zoom(x, -zoom), scale_by_zoom(y, -zoom), 
-        zoom
-    )
-
-def render_img_region (image, cx, cy, zoom, width, height) :
-    """
-        Render arbitrary tile, returning PNG data
-    """
-
-    x = scale_by_zoom(cx - width / 2, -zoom)
-    y = scale_by_zoom(cy - height / 2, -zoom)
-
-    # safely limit
-    if width * height > MAX_PIXELS :
-        raise exceptions.Forbidden("Image too large: %d * %d > %d" % (width, height, MAX_PIXELS))
-
-    return image.tile_mem(
-        width, height,
-        x, y,
-        zoom
-    )
-
 
 ### Manipulate request data
 def get_req_path (req) :
@@ -254,8 +72,10 @@
     """
         Handle request for a directory
     """
+    
+    prefix = os.path.dirname(req.script_root).rstrip('/')
 
-    return Response(render_dir(req, name, path), content_type="text/html")
+    return Response(render.dir_html(prefix, name, path), content_type="text/html")
 
 
 
@@ -263,9 +83,11 @@
     """
         Handle request for image viewport
     """
+    
+    prefix = os.path.dirname(req.script_root).rstrip('/')
 
     # viewport
-    return Response(render_img_viewport(req, name, image), content_type="text/html")
+    return Response(render.img_html(prefix, name, image), content_type="text/html")
 
 
 def handle_img_region (req, image) :
@@ -279,9 +101,14 @@
     cx = int(req.args['cx'])
     cy = int(req.args['cy'])
     zoom = int(req.args.get('zl', "0"))
+    
+    try :
+        # yay full render
+        return Response(render.img_png_region(image, cx, cy, zoom, width, height), content_type="image/png")
 
-    # yay full render
-    return Response(render_img_region(image, cx, cy, zoom, width, height), content_type="image/png")
+    except ValueError, ex :
+        # too large
+        raise exceptions.Forbidden(str(ex))
 
 
 def handle_img_tile (req, image) :
@@ -295,7 +122,7 @@
     zoom = int(req.args.get('zl', "0"))
         
     # yay render
-    return Response(render_img_tile(image, x, y, zoom), content_type="image/png")
+    return Response(render.img_png_tile(image, x, y, zoom), content_type="image/png")
 
 ## Dispatch req to handle_img_*
 def handle_img (req, name, path) :