Add support for directory listings in sky_server.
Unfortunate these aren't very useful since we can't actually click on links, nor do navigations work anyway... TBR=abarth@chromium.org Review URL: https://codereview.chromium.org/690133002
This commit is contained in:
parent
b0120fd284
commit
2c27800c53
@ -6,6 +6,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import cherrypy
|
import cherrypy
|
||||||
|
import staticdirindex
|
||||||
|
|
||||||
|
|
||||||
BUILD_DIRECTORY = 'out'
|
BUILD_DIRECTORY = 'out'
|
||||||
@ -16,6 +17,25 @@ SKY_ROOT = os.path.join(SRC_ROOT, 'sky')
|
|||||||
GEN_ROOT = os.path.join(SRC_ROOT, BUILD_DIRECTORY, CONFIG_DIRECTORY, 'gen')
|
GEN_ROOT = os.path.join(SRC_ROOT, BUILD_DIRECTORY, CONFIG_DIRECTORY, 'gen')
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: This should be replaced by just json and inflated into DOM client-side.
|
||||||
|
def skydir(section="", dir="", path="", **kwargs):
|
||||||
|
url = "%s%s" % (cherrypy.request.headers.get('Host', ''),
|
||||||
|
cherrypy.request.path_info)
|
||||||
|
sky = "<listing>"
|
||||||
|
sky += "<style>a { display: block; }"
|
||||||
|
sky += "header { border-bottom: 1px solid lightgrey }</style>"
|
||||||
|
sky += '<header>Listing for: <a href="' + url + '">' + url +'</a></header>'
|
||||||
|
for _, dir_names, file_names in os.walk(path.rstrip(r"\/")):
|
||||||
|
for dir_name in sorted(dir_names):
|
||||||
|
sky += "<a href=\"%s/\">%s/</a>\n" % (dir_name, dir_name)
|
||||||
|
|
||||||
|
del dir_names[:] # limit to one level
|
||||||
|
|
||||||
|
for file_name in sorted(file_names):
|
||||||
|
sky += "<a href=\"%s\">%s</a>\n" % (file_name, file_name)
|
||||||
|
return sky + "</listing>"
|
||||||
|
|
||||||
|
|
||||||
# FIXME: This doesn't yet support directory listings. We'll do something like:
|
# FIXME: This doesn't yet support directory listings. We'll do something like:
|
||||||
# http://tools.cherrypy.org/wiki/staticdirindex
|
# http://tools.cherrypy.org/wiki/staticdirindex
|
||||||
# but have it spit .sky instead of HTML
|
# but have it spit .sky instead of HTML
|
||||||
@ -43,6 +63,7 @@ def main():
|
|||||||
'/': {
|
'/': {
|
||||||
'tools.staticdir.on': True,
|
'tools.staticdir.on': True,
|
||||||
'tools.staticdir.dir': os.path.abspath(args.app_path),
|
'tools.staticdir.dir': os.path.abspath(args.app_path),
|
||||||
|
'tools.staticdir.indexlister': skydir,
|
||||||
},
|
},
|
||||||
'/mojo': {
|
'/mojo': {
|
||||||
'tools.staticdir.on': True,
|
'tools.staticdir.on': True,
|
||||||
|
120
engine/src/flutter/tools/staticdirindex.py
Normal file
120
engine/src/flutter/tools/staticdirindex.py
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
# From http://tools.cherrypy.org/wiki/staticdirindex
|
||||||
|
# CherryPy code is covered under a BSD License:
|
||||||
|
# https://bitbucket.org/cherrypy/cherrypy/src/697c7af588b8/cherrypy/LICENSE.txt
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import stat
|
||||||
|
import urllib
|
||||||
|
import cherrypy
|
||||||
|
from cherrypy.lib import cptools, http
|
||||||
|
|
||||||
|
# Undercover kludge to wrap staticdir
|
||||||
|
from cherrypy.lib.static import staticdir
|
||||||
|
|
||||||
|
def staticdirindex(section, dir, root="", match="", content_types=None,
|
||||||
|
index="", indexlistermatch="", indexlister=None, **kwargs):
|
||||||
|
"""Serve a directory index listing for a dir.
|
||||||
|
|
||||||
|
Compatibility alert: staticdirindex is built on and is dependent on
|
||||||
|
staticdir and its configurations. staticdirindex only works effectively
|
||||||
|
in locations where staticdir is also configured. staticdirindex is
|
||||||
|
coded to allow easy integration with staticdir, if demand warrants.
|
||||||
|
|
||||||
|
indexlister must be configured, or no function is performed.
|
||||||
|
indexlister should be a callable that accepts the following parameters:
|
||||||
|
section: same as for staticdir (and implicitly calculated for it)
|
||||||
|
dir: same as for staticdir, but already combined with root
|
||||||
|
path: combination of section and dir
|
||||||
|
|
||||||
|
Other parameters that are configured for staticdirindex will be passed
|
||||||
|
on to indexlister.
|
||||||
|
|
||||||
|
Should use priorty > than that of staticdir, so that only directories not
|
||||||
|
served by staticdir, call staticdirindex.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# first call old staticdir, and see if it does anything
|
||||||
|
sdret = staticdir( section, dir, root, match, content_types, index )
|
||||||
|
if sdret:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# if not, then see if we are configured to do anything
|
||||||
|
if indexlister is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
req = cherrypy.request
|
||||||
|
response = cherrypy.response
|
||||||
|
|
||||||
|
match = indexlistermatch
|
||||||
|
|
||||||
|
# N.B. filename ending in a slash or not does not imply a directory
|
||||||
|
# the following block of code directly copied from static.py staticdir
|
||||||
|
if match and not re.search(match, cherrypy.request.path_info):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Allow the use of '~' to refer to a user's home directory.
|
||||||
|
dir = os.path.expanduser(dir)
|
||||||
|
|
||||||
|
# If dir is relative, make absolute using "root".
|
||||||
|
if not os.path.isabs(dir):
|
||||||
|
if not root:
|
||||||
|
msg = "Static dir requires an absolute dir (or root)."
|
||||||
|
raise ValueError(msg)
|
||||||
|
dir = os.path.join(root, dir)
|
||||||
|
|
||||||
|
# Determine where we are in the object tree relative to 'section'
|
||||||
|
# (where the static tool was defined).
|
||||||
|
if section == 'global':
|
||||||
|
section = "/"
|
||||||
|
section = section.rstrip(r"\/")
|
||||||
|
branch = cherrypy.request.path_info[len(section) + 1:]
|
||||||
|
branch = urllib.unquote(branch.lstrip(r"\/"))
|
||||||
|
|
||||||
|
# If branch is "", filename will end in a slash
|
||||||
|
filename = os.path.join(dir, branch)
|
||||||
|
|
||||||
|
# There's a chance that the branch pulled from the URL might
|
||||||
|
# have ".." or similar uplevel attacks in it. Check that the final
|
||||||
|
# filename is a child of dir.
|
||||||
|
if not os.path.normpath(filename).startswith(os.path.normpath(dir)):
|
||||||
|
raise cherrypy.HTTPError(403) # Forbidden
|
||||||
|
# the above block of code directly copied from static.py staticdir
|
||||||
|
# N.B. filename ending in a slash or not does not imply a directory
|
||||||
|
|
||||||
|
# Check if path is a directory.
|
||||||
|
|
||||||
|
path = filename
|
||||||
|
# The following block of code copied from static.py serve_file
|
||||||
|
|
||||||
|
# If path is relative, users should fix it by making path absolute.
|
||||||
|
# That is, CherryPy should not guess where the application root is.
|
||||||
|
# It certainly should *not* use cwd (since CP may be invoked from a
|
||||||
|
# variety of paths). If using tools.static, you can make your relative
|
||||||
|
# paths become absolute by supplying a value for "tools.static.root".
|
||||||
|
if not os.path.isabs(path):
|
||||||
|
raise ValueError("'%s' is not an absolute path." % path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
st = os.stat(path)
|
||||||
|
except OSError:
|
||||||
|
# The above block of code copied from static.py serve_file
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
if stat.S_ISDIR(st.st_mode):
|
||||||
|
|
||||||
|
# Set the Last-Modified response header, so that
|
||||||
|
# modified-since validation code can work.
|
||||||
|
response.headers['Last-Modified'] = http.HTTPDate(st.st_mtime)
|
||||||
|
cptools.validate_since()
|
||||||
|
response.body = indexlister( section=section, dir=dir, path=path,
|
||||||
|
**kwargs )
|
||||||
|
response.headers['Content-Type'] = 'text/html'
|
||||||
|
req.is_index = True
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Replace the real staticdir with our version
|
||||||
|
cherrypy.tools.staticdir = cherrypy._cptools.HandlerTool( staticdirindex )
|
Loading…
x
Reference in New Issue
Block a user