annotate pics2/pics_app.py @ 53:0482bffd7d7f

update pics2/pics_app.py with browse page
author paulo
date Sat, 01 Jun 2013 20:43:00 -0700
parents f5c2934a1e3f
children 496714f2fd8c
rev   line source
paulo@52 1 import os
paulo@52 2 import re
paulo@52 3 import glob
paulo@52 4 import traceback
paulo@52 5
paulo@52 6 import html
paulo@52 7
paulo@53 8 import logging
paulo@53 9 logging.basicConfig(
paulo@53 10 level=logging.DEBUG,
paulo@53 11 filename="_LOG",
paulo@53 12 format="%(asctime)s %(levelname)-8s %(message)s",
paulo@53 13 )
paulo@52 14
paulo@52 15
paulo@52 16
paulo@52 17 def _get_pics_url(environ, dirpath):
paulo@52 18 script_name = environ.get("SCRIPT_NAME", '')
paulo@52 19 return os.path.normpath(os.path.join(os.path.dirname(script_name), dirpath))
paulo@52 20
paulo@52 21
paulo@53 22 def _get_app_url(environ, dirpath):
paulo@53 23 script_name = environ.get("SCRIPT_NAME", '')
paulo@53 24 return os.path.normpath(os.path.join(script_name, dirpath))
paulo@53 25
paulo@53 26
paulo@53 27 def _parse_path_info(path_info):
paulo@53 28 ppi = path_info.split(os.sep)
paulo@53 29 if len(ppi) > 1 and ppi[-1] == '':
paulo@53 30 del ppi[-1]
paulo@53 31
paulo@53 32 return ppi
paulo@53 33
paulo@53 34
paulo@53 35 def _get_standard_html_doc(title):
paulo@53 36 root = html.HTML("html")
paulo@53 37
paulo@53 38 header = root.header
paulo@53 39 header.title(title)
paulo@53 40
paulo@53 41 body = root.body
paulo@53 42 body.h1(title)
paulo@53 43
paulo@53 44 return (root, header, body)
paulo@53 45
paulo@53 46
paulo@53 47 def _numeric_pad_basename(path, maxdigits=20):
paulo@53 48 return os.path.basename(path).zfill(maxdigits)
paulo@53 49
paulo@53 50
paulo@53 51 def _get_images(d):
paulo@53 52 thumb_fns = glob.glob(os.path.join(d, "thumbs", "*.jpg"))
paulo@53 53 thumb_fns = sorted(thumb_fns, key=_numeric_pad_basename)
paulo@53 54 logging.debug("thumb_fns = %s" % thumb_fns)
paulo@53 55
paulo@53 56 browse_fns = [os.path.join(d, "browse", os.path.basename(i)) for i in thumb_fns]
paulo@53 57 logging.debug("browse_fns = %s" % browse_fns)
paulo@53 58
paulo@53 59 return zip(thumb_fns, browse_fns)
paulo@53 60
paulo@53 61
paulo@53 62 def _go_thumbnail_links_to_browse_imgs_html_body(environ, body, t, b):
paulo@53 63 thumb_img_url = _get_pics_url(environ, t)
paulo@53 64 browse_url = _get_app_url(environ, b)
paulo@53 65 body.a(href=browse_url).img(src=thumb_img_url)
paulo@53 66
paulo@53 67
paulo@52 68 def main(environ):
paulo@53 69 page_func = None
paulo@52 70
paulo@53 71 logging.debug("environ['PATH_INFO'] = %s" % environ["PATH_INFO"])
paulo@53 72 logging.debug("environ['SCRIPT_NAME'] = %s" % environ["SCRIPT_NAME"])
paulo@52 73
paulo@53 74 pi = environ["PATH_INFO"]
paulo@53 75 ppi = _parse_path_info(pi)
paulo@53 76 logging.debug("ppi = %s" % ppi)
paulo@53 77
paulo@53 78 if len(ppi) < 1 or ppi[0] != '':
paulo@53 79 raise AssertionError("Parsed path length must start empty: " + pi)
paulo@53 80
paulo@53 81 if len(ppi) >= 2 and os.path.exists(os.path.join(ppi[1], "_picsroot")):
paulo@53 82 if len(ppi) == 2:
paulo@53 83 page_func = page_thumbs
paulo@53 84 elif len(ppi) >= 4 and ppi[2] == "browse" and os.path.exists(os.path.join(*ppi)):
paulo@53 85 page_func = page_browse
paulo@53 86 elif len(ppi) == 1:
paulo@53 87 page_func = page_index
paulo@53 88
paulo@53 89 if page_func is None:
paulo@53 90 raise RuntimeError("Cannot find path: " + pi)
paulo@52 91
paulo@53 92 return unicode(page_func(environ)).encode("utf-8")
paulo@53 93
paulo@52 94
paulo@53 95 def page_index(environ):
paulo@53 96 (html_root, html_header, html_body) = _get_standard_html_doc("pics index")
paulo@52 97
paulo@53 98 return html_root
paulo@52 99
paulo@52 100
paulo@53 101 def page_thumbs(environ):
paulo@53 102 ppi = _parse_path_info(environ["PATH_INFO"])
paulo@53 103 d = os.path.join(*ppi)
paulo@53 104 (html_root, html_header, html_body) = _get_standard_html_doc(d)
paulo@53 105
paulo@53 106 html_p = html_body.p
paulo@53 107 for (t, b) in _get_images(d):
paulo@53 108 _go_thumbnail_links_to_browse_imgs_html_body(environ, html_p, t, b)
paulo@53 109
paulo@53 110 return html_root
paulo@53 111
paulo@53 112
paulo@53 113 def page_browse(environ):
paulo@53 114 ppi = _parse_path_info(environ["PATH_INFO"])
paulo@53 115 d = os.path.join(*ppi[:2])
paulo@53 116 imgs = _get_images(d)
paulo@53 117 img = os.path.join(*ppi)
paulo@53 118
paulo@53 119 # thumbnail preview ribbon
paulo@53 120 w = 7 # must be odd
paulo@53 121 v = w/2
paulo@53 122 imgs_circ = [None] * w
paulo@53 123 x = None
paulo@53 124 n = len(imgs)
paulo@53 125 for (i, (t, b)) in enumerate(imgs):
paulo@53 126 if b == img:
paulo@53 127 x = i + 1
paulo@53 128 imgs_circ[v] = (t, b)
paulo@53 129 for j in range(1, v + 1):
paulo@53 130 if (i + j) < n: imgs_circ[v + j] = imgs[i + j]
paulo@53 131 if (i - j) >= 0: imgs_circ[v - j] = imgs[i - j]
paulo@53 132
paulo@53 133 break
paulo@53 134
paulo@53 135 if x is None:
paulo@53 136 raise AssertionError
paulo@53 137
paulo@53 138 (html_root, html_header, html_body) = _get_standard_html_doc(u"%s \u2014 %s of %s" % (d, x, len(imgs)))
paulo@53 139
paulo@53 140 browse_img_url = _get_pics_url(environ, img)
paulo@53 141 html_body.p.img(src=browse_img_url)
paulo@53 142
paulo@53 143 logging.debug("imgs_circ = %s" % imgs_circ)
paulo@53 144
paulo@53 145 html_p_ribbon = html_body.p
paulo@53 146 for i in imgs_circ:
paulo@53 147 if i is not None:
paulo@53 148 (t, b) = i
paulo@53 149 _go_thumbnail_links_to_browse_imgs_html_body(environ, html_p_ribbon, t, b)
paulo@53 150
paulo@53 151 return html_root
paulo@53 152
paulo@52 153
paulo@52 154 def app(environ, start_response):
paulo@52 155 response_code = "500 Internal Server Error"
paulo@52 156 response_type = "text/plain; charset=UTF-8"
paulo@52 157
paulo@52 158 try:
paulo@52 159 response_body = main(environ)
paulo@52 160 response_code = "200 OK"
paulo@52 161 response_type = "text/html; charset=UTF-8"
paulo@52 162 except:
paulo@52 163 response_body = traceback.format_exc()
paulo@52 164
paulo@52 165 response_headers = [
paulo@52 166 ("Content-Type", response_type),
paulo@52 167 ("Content-Length", str(len(response_body))),
paulo@52 168 ]
paulo@52 169
paulo@52 170 start_response(response_code, response_headers)
paulo@52 171
paulo@52 172 return [response_body]