# HG changeset patch # User Tero Marttila # Date 1264438019 -7200 # Node ID e50ec4217fe63633c7895c59c910dbff66cd0f83 # Parent 0bf7878bdf5c4862574cd1b8d50921d3cc18030e separate non-wsgi render layer to render.png diff -r 0bf7878bdf5c -r e50ec4217fe6 pngtile/render.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pngtile/render.py Mon Jan 25 18:46:59 2010 +0200 @@ -0,0 +1,189 @@ +""" + Rendering output +""" + +import os, os.path + +## Settings +# 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 += '/' + name + + 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 + +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 HTML data +def dir_html (prefix, name, path) : + """ + Directory index + """ + + name = name.rstrip('/') + + return """\ + + + Index of %(dir)s + + + +

Index of %(dir)s

+ + + +""" % dict( + prefix = prefix, + dir = '/' + name, + + listing = "\n".join( + #
  • link + """
  • %(name)s
  • """ % dict( + # URL to dir + url = dir_url(prefix, name, item), + + # item name + name = item, + ) for item in dir_list(path) + ), + ) + +def img_html (prefix, 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 """\ + + + %(title)s + + + + + + + +
    +
    +
    + + + +
    + +
    + +
    + Loading... +
    +
    +
    + + + +""" % dict( + title = name, + prefix = prefix, + tile_url = prefix + '/' + name, + + tile_width = TILE_WIDTH, + tile_height = TILE_HEIGHT, + + img_width = img_width, + img_height = img_height, + ) + +### Render PNG Data +def img_png_tile (image, x, y, zoom) : + """ + Render given tile, returning PNG data + """ + + return image.tile_mem( + TILE_WIDTH, TILE_HEIGHT, + scale_by_zoom(x, -zoom), scale_by_zoom(y, -zoom), + zoom + ) + +def img_png_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 ValueError("Image size: %d * %d > %d" % (width, height, MAX_PIXELS)) + + return image.tile_mem( + width, height, + x, y, + zoom + ) + diff -r 0bf7878bdf5c -r e50ec4217fe6 pngtile/wsgi.py --- 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 """\ - - - Index of %(dir)s - - - -

    Index of %(dir)s

    - - - -""" % dict( - prefix = prefix, - dir = '/' + name, - - listing = "\n".join( - #
  • link - """
  • %(name)s
  • """ % 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 """\ - - - %(title)s - - - - - - - -
    -
    -
    - - - -
    - -
    - -
    - Loading... -
    -
    -
    - - - -""" % 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) :