# HG changeset patch # User Tero Marttila # Date 1264441550 -7200 # Node ID 581cdb831b327252d8b7855e84e67b3c98193c53 # Parent e50ec4217fe63633c7895c59c910dbff66cd0f83 split off werkzeug code to separate handlers module.. diff -r e50ec4217fe6 -r 581cdb831b32 pngtile/handlers.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pngtile/handlers.py Mon Jan 25 19:45:50 2010 +0200 @@ -0,0 +1,171 @@ +import os, os.path +import pypngtile as pt + +from werkzeug import Response, exceptions + +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 = {} + + +### Parse request data +def get_path (req_path) : + """ + Returns the name and path requested + """ + + # check DATA_ROOT exists.. + if not os.path.isdir(DATA_ROOT) : + raise exceptions.InternalServerError("Missing DATA_ROOT") + + # path to image + image_name = req_path.lstrip('/') + + # build absolute path + image_path = os.path.abspath(os.path.join(DATA_ROOT, image_name)) + + # ensure the path points inside the data root + if not image_path.startswith(DATA_ROOT) : + raise exceptions.NotFound(image_name) + + return image_name, image_path + +def get_image (name, path) : + """ + Gets an Image object from the cache, ensuring that the cached is available + """ + + # get Image object + if path in IMAGE_CACHE : + # get from cache + image = IMAGE_CACHE[path] + + else : + # open + image = pt.Image(path) + + # check + if image.status() not in (pt.CACHE_FRESH, pt.CACHE_STALE) : + raise exceptions.InternalServerError("Image cache not available: %s" % name) + + # load + image.open() + + # cache + IMAGE_CACHE[path] = image + + return image + + +### Handle werkzeug.Request objects -> werkzeug.Response +def handle_dir (req, name, path) : + """ + Handle request for a directory + """ + + prefix = os.path.dirname(req.script_root).rstrip('/') + + return Response(render.dir_html(prefix, name, path), content_type="text/html") + + + +def handle_img_viewport (req, image, name) : + """ + Handle request for image viewport + """ + + prefix = os.path.dirname(req.script_root).rstrip('/') + + # viewport + return Response(render.img_html(prefix, name, image), content_type="text/html") + + +def handle_img_region (req, image) : + """ + Handle request for an image region + """ + + # specific image + width = int(req.args['w']) + height = int(req.args['h']) + 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") + + except ValueError, ex : + # too large + raise exceptions.Forbidden(str(ex)) + + +def handle_img_tile (req, image) : + """ + Handle request for image tile + """ + + # tile + x = int(req.args['x']) + y = int(req.args['y']) + zoom = int(req.args.get('zl', "0")) + + # yay render + 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) : + """ + Handle request for an image + """ + + # get image object + image = get_image(name, path) + + # what view? + if not req.args : + return handle_img_viewport(req, image, name) + + elif 'w' in req.args and 'h' in req.args and 'cx' in req.args and 'cy' in req.args : + return handle_img_region(req, image) + + elif 'x' in req.args and 'y' in req.args : + return handle_img_tile(req, image) + + else : + raise exceptions.BadRequest("Unknown args") + + + +## Dispatch request to handle_* +def handle_req (req) : + """ + Main request handler + """ + + # decode req + name, path = get_path(req.path) + + # determine dir/image + if os.path.isdir(path) : + # directory + return handle_dir(req, name, path) + + elif not os.path.exists(path) : + # no such file + raise exceptions.NotFound(name) + + elif not name or not name.endswith('.png') : + # invalid file + raise exceptions.BadRequest("Not a PNG file") + + else : + # image + return handle_img(req, name, path) + + diff -r e50ec4217fe6 -r 581cdb831b32 pngtile/wsgi.py --- a/pngtile/wsgi.py Mon Jan 25 18:46:59 2010 +0200 +++ b/pngtile/wsgi.py Mon Jan 25 19:45:50 2010 +0200 @@ -2,191 +2,24 @@ Our WSGI web interface, which can serve the JS UI and any .png tiles via HTTP. """ -from werkzeug import Request, Response, responder +from werkzeug import Request, responder from werkzeug import exceptions -import os.path, os -import pypngtile as pt - -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 = {} - - -### Manipulate request data -def get_req_path (req) : - """ - Returns the name and path requested - """ - - # check DATA_ROOT exists.. - if not os.path.isdir(DATA_ROOT) : - raise exceptions.InternalServerError("Missing DATA_ROOT") - - # path to image - image_name = req.path.lstrip('/') - - # build absolute path - image_path = os.path.abspath(os.path.join(DATA_ROOT, image_name)) - - # ensure the path points inside the data root - if not image_path.startswith(DATA_ROOT) : - raise exceptions.NotFound(image_name) - - return image_name, image_path - -def get_image (name, path) : - """ - Gets an Image object from the cache, ensuring that it is cached - """ - - # get Image object - if path in IMAGE_CACHE : - # get from cache - image = IMAGE_CACHE[path] - - else : - # open - image = pt.Image(path) - - # check - if image.status() not in (pt.CACHE_FRESH, pt.CACHE_STALE) : - raise exceptions.InternalServerError("Image cache not available: %s" % name) - - # load - image.open() - - # cache - IMAGE_CACHE[path] = image - - return image - - - -### Handle request -def handle_dir (req, name, path) : - """ - Handle request for a directory - """ - - prefix = os.path.dirname(req.script_root).rstrip('/') - - return Response(render.dir_html(prefix, name, path), content_type="text/html") - - - -def handle_img_viewport (req, image, name) : - """ - Handle request for image viewport - """ - - prefix = os.path.dirname(req.script_root).rstrip('/') - - # viewport - return Response(render.img_html(prefix, name, image), content_type="text/html") - - -def handle_img_region (req, image) : - """ - Handle request for an image region - """ - - # specific image - width = int(req.args['w']) - height = int(req.args['h']) - 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") - - except ValueError, ex : - # too large - raise exceptions.Forbidden(str(ex)) - - -def handle_img_tile (req, image) : - """ - Handle request for image tile - """ - - # tile - x = int(req.args['x']) - y = int(req.args['y']) - zoom = int(req.args.get('zl', "0")) - - # yay render - 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) : - """ - Handle request for an image - """ - - # get image object - image = get_image(name, path) - - # what view? - if not req.args : - return handle_img_viewport(req, image, name) - - elif 'w' in req.args and 'h' in req.args and 'cx' in req.args and 'cy' in req.args : - return handle_img_region(req, image) - - elif 'x' in req.args and 'y' in req.args : - return handle_img_tile(req, image) - - else : - raise exceptions.BadRequest("Unknown args") - - - -## Dispatch request to handle_* -def handle_req (req) : - """ - Main request handler - """ - - # decode req - name, path = get_req_path(req) - - # determine dir/image - if os.path.isdir(path) : - # directory - return handle_dir(req, name, path) - - elif not os.path.exists(path) : - # no such file - raise exceptions.NotFound(name) - - elif not name or not name.endswith('.png') : - # invalid file - raise exceptions.BadRequest("Not a PNG file") - - else : - # image - return handle_img(req, name, path) - - +from pngtile import handlers @responder def application (env, start_response) : """ - Main WSGI entry point + Main WSGI entry point. + + This is wrapped with werkzeug, so we can return a Response object """ req = Request(env, start_response) try : - return handle_req(req) + return handlers.handle_req(req) except exceptions.HTTPException, e : return e