pngtile/image.py
changeset 147 77330e43c855
parent 145 51908b0cc3a1
child 153 55f3d3bc95d3
equal deleted inserted replaced
146:0f2a918eb90a 147:77330e43c855
     9 import pngtile.tile
     9 import pngtile.tile
    10 from pngtile.application import BaseApplication
    10 from pngtile.application import BaseApplication
    11 import pypngtile
    11 import pypngtile
    12 
    12 
    13 import json
    13 import json
       
    14 import os, os.path
       
    15 
       
    16 def dir_url (prefix, name, item):
       
    17     """
       
    18         Join together an absolute URL prefix, an optional directory name, and a directory item
       
    19     """
       
    20 
       
    21     url = prefix
       
    22 
       
    23     if name:
       
    24         url += '/' + name
       
    25     
       
    26     url += '/' + item
       
    27 
       
    28     return url
       
    29 
       
    30 def dir_list (root):
       
    31     """
       
    32         Yield a series of directory items to show for the given dir
       
    33     """
       
    34 
       
    35     for name in os.listdir(root):
       
    36         path = os.path.join(root, name)
       
    37 
       
    38         # skip dotfiles
       
    39         if name.startswith('.'):
       
    40             continue
       
    41         
       
    42         # show dirs
       
    43         if os.path.isdir(path):
       
    44             yield name
       
    45 
       
    46         # examine ext
       
    47         if '.' in name:
       
    48             name_base, name_type = name.rsplit('.', 1)
       
    49         else:
       
    50             name_base = name
       
    51             name_type = None
       
    52 
       
    53         # show .png files with a .cache file
       
    54         if name_type in ImageApplication.IMAGE_TYPES and os.path.exists(os.path.join(root, name_base + '.cache')):
       
    55             yield name
    14 
    56 
    15 class ImageApplication (BaseApplication):
    57 class ImageApplication (BaseApplication):
    16 
    58 
    17     STYLESHEETS = (
    59     STYLESHEETS = (
    18         'https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css',
    60         'https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css',
    28         '/static/pngtile/map.js',
    70         '/static/pngtile/map.js',
    29     )
    71     )
    30 
    72 
    31     def __init__ (self, **opts):
    73     def __init__ (self, **opts):
    32         BaseApplication.__init__(self, **opts)
    74         BaseApplication.__init__(self, **opts)
       
    75 
       
    76     def render_dir_breadcrumb (self, name):
       
    77         path = []
       
    78 
       
    79         yield html.li(html.a(href='/', *[u"Index"]))
       
    80         
       
    81         if name:
       
    82             for part in name.split('/'):
       
    83                 path.append(part)
       
    84 
       
    85                 yield html.li(html.a(href='/'.join(path), *[part]))
       
    86 
       
    87     def render_dir (self, request, name, items):
       
    88         """
       
    89             request:    werkzeug.Request
       
    90             name:       /.../... url to dir
       
    91             items:      [...] items in dir
       
    92         """
       
    93         
       
    94         if name:
       
    95             title = name
       
    96         else:
       
    97             title = "Index"
       
    98 
       
    99         return self.render_html(
       
   100             title       = name,
       
   101             body        = (
       
   102                 html.div(class_='container', *[
       
   103                     html.h1(title),
       
   104                     html.div(*[
       
   105                         html.ol(class_='breadcrumb', *self.render_dir_breadcrumb(name)),
       
   106                     ]),
       
   107                     html.div(class_='list', *[
       
   108                         html.ul(class_='list-group', *[html.li(class_='list-group-item', *[
       
   109                                 html.a(href=dir_url('', name, item), *[item])
       
   110                             ]) for item in items]
       
   111                         ),
       
   112                     ]),
       
   113                 ]),
       
   114             ),
       
   115         )
    33 
   116 
    34     def render_image (self, request, image, name):
   117     def render_image (self, request, image, name):
    35         """
   118         """
    36             request:    werkzeug.Request
   119             request:    werkzeug.Request
    37             image:      pypngtile.Image
   120             image:      pypngtile.Image
    63             end         = (
   146             end         = (
    64                 html.script("""$(function() {{ map_init({map_config}); }});""".format(map_config=json.dumps(map_config))),
   147                 html.script("""$(function() {{ map_init({map_config}); }});""".format(map_config=json.dumps(map_config))),
    65             ),
   148             ),
    66         )
   149         )
    67 
   150 
    68     def handle (self, request):
   151     def handle_dir (self, request, name, path):
    69         """
   152         """
    70             Handle request for an image
   153             Generate response for directory listing.
    71         """
   154         """
    72          
   155 
       
   156         items = sorted(dir_list(path))
       
   157 
       
   158         html = self.render_dir(request, name, items)
       
   159 
       
   160         return Response(html, content_type="text/html")
       
   161 
       
   162     def handle_image (self, request, name, path):
       
   163         """
       
   164             Generate Response for image request.
       
   165         """
       
   166         
    73         try:
   167         try:
    74             image, name = self.get_image(request.path)
   168             image, name = self.get_image(request.path)
    75         except pypngtile.Error as error:
   169         except pypngtile.Error as error:
    76             raise exceptions.BadRequest(str(error))
   170             raise exceptions.BadRequest(str(error))
    77 
   171 
    78         html = self.render_image(request, image, name)
   172         html = self.render_image(request, image, name)
    79 
   173 
    80         return Response(html, content_type="text/html")
   174         return Response(html, content_type="text/html")
    81 
   175 
    82 
   176     def handle (self, request):
       
   177         """
       
   178             Handle request for an image
       
   179         """
       
   180 
       
   181         name, path = self.lookup_path(request.path)
       
   182         
       
   183         # determine type
       
   184         if '/' in name:
       
   185             _, name_base = name.rsplit('/', 1)
       
   186         else:
       
   187             name_base = name
       
   188 
       
   189         if '.' in name_base:
       
   190             name_base, name_type = name_base.rsplit('.', 1)
       
   191         else:
       
   192             name_type = None
       
   193 
       
   194         # determine handler
       
   195         if os.path.isdir(path):
       
   196             return self.handle_dir(request, name, path)
       
   197         
       
   198         elif name_type and name_type in self.IMAGE_TYPES:
       
   199             return self.handle_image(request, name, path)
       
   200 
       
   201         else:
       
   202             raise exceptions.NotFound(path)
       
   203