]> arthur.barton.de Git - bup.git/commitdiff
Convert 'bup web' directory listing to use tornado templates.
authorJoe Beda <joe@bedafamily.com>
Fri, 23 Jul 2010 07:10:36 +0000 (00:10 -0700)
committerAvery Pennarun <apenwarr@gmail.com>
Fri, 23 Jul 2010 07:19:03 +0000 (03:19 -0400)
This includes creating a new idea of a "resource path" that currently sits
under the lib dir. Getting resources is supported with a new helper
(resource_path).

Signed-off-by: Joe Beda <joe@bedafamily.com>
Makefile
cmd/web-cmd.py
lib/bup/helpers.py
lib/web/list-directory.html [new file with mode: 0644]
main.py

index dcc4bab5fd14d2eb49dd0c65f5678338977ffcf6..c9fb7c8a3c3315891b2fd1710d4092d87c9f2fed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,8 @@ BINDIR=$(DESTDIR)/usr/bin
 LIBDIR=$(DESTDIR)/usr/lib/bup
 install: all
        $(INSTALL) -d $(MANDIR)/man1 $(DOCDIR) $(BINDIR) \
-               $(LIBDIR)/bup $(LIBDIR)/cmd $(LIBDIR)/tornado
+               $(LIBDIR)/bup $(LIBDIR)/cmd $(LIBDIR)/tornado \
+               $(LIBDIR)/web
        [ ! -e Documentation/.docs-available ] || \
          $(INSTALL) -o 0 -g 0 -m 0644 \
                $(wildcard Documentation/*.1) \
@@ -52,7 +53,9 @@ install: all
        $(INSTALL) -o 0 -g 0 -m 0644 \
                $(wildcard lib/tornado/*.py) \
                $(LIBDIR)/tornado
-
+       $(INSTALL) -o 0 -g 0 -m 0644 \
+               $(wildcard lib/web/*) \
+               $(LIBDIR)/web
 %/all:
        $(MAKE) -C $* all
        
index e32fbb8a75f975102635554f58aee4c885a0438b..52f5468daccc42995af45e28356a3dc20edf6f50 100755 (executable)
@@ -2,12 +2,48 @@
 import sys, stat, cgi, shutil, urllib, mimetypes, posixpath, time
 import tornado.httpserver
 import tornado.ioloop
+import tornado.template
 import tornado.web
 from bup import options, git, vfs
 from bup.helpers import *
 
 handle_ctrl_c()
 
+
+def _compute_breadcrumbs(path):
+    """Returns a list of breadcrumb objects for a path."""
+    breadcrumbs = []
+    breadcrumbs.append(('[root]', '/'))
+    path_parts = path.split('/')[1:-1]
+    full_path = '/'
+    for part in path_parts:
+        full_path += part + '/'
+        breadcrumbs.append((part, full_path))
+    return breadcrumbs
+
+
+def _compute_dir_contents(n):
+    """Given a vfs node, returns an iterator for display info of all subs."""
+    contents = []
+    for sub in n:
+        display = link = sub.name
+
+        # link should be based on fully resolved type to avoid extra
+        # HTTP redirect.
+        if stat.S_ISDIR(sub.lresolve('').mode):
+            link = sub.name + "/"
+
+        size = None
+        if stat.S_ISDIR(sub.mode):
+            display = sub.name + '/'
+        elif stat.S_ISLNK(sub.mode):
+            display = sub.name + '@'
+        else:
+            size = sub.size()
+
+        yield (display, link, size)
+
+
 class BupRequestHandler(tornado.web.RequestHandler):
     def get(self, path):
         return self._process_request(path)
@@ -39,61 +75,13 @@ class BupRequestHandler(tornado.web.RequestHandler):
             print 'Redirecting from %s to %s' % (path, path + '/')
             return self.redirect(path + '/', permanent=True)
 
-        self.set_header("Content-Type", "text/html")
-
-        displaypath = cgi.escape(path)
-        self.write("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-    <title>Directory listing for %(displaypath)s</title>
-    <style type="text/css">
-      body, table { font-family: sans-serif }
-      #breadcrumb { margin: 10px 0; }
-      .dir-name { text-align: left }
-      .dir-size { text-align: right }
-    </style>
-  </head>
-  <body>
-    <div id="breadcrumb">
-""" % { 'displaypath': displaypath })
-        if path == "/":
-            self.write("""<strong>[root]</strong>""")
-        else:
-            self.write("""<a href="/">[root]</a> """)
-            path_parts = path.split("/")
-            path_parts_cleaned = path_parts[1:-1]
-            for index, value in enumerate(path_parts_cleaned[0:-1]):
-                self.write("""/ <a href="/%(path)s/">%(element)s</a> """ % { 'path' : "/".join(path_parts_cleaned[0:(index + 1)]) , 'element' : value})
-            self.write("""/ <strong>%s</strong>""" % path_parts_cleaned[-1])
-        self.write("""
-    </div>
-    <table>
-      <tr>
-        <th class="dir-name">Name</th>
-        <th class="dir-size">Size</th>
-      </tr>
-""")
-        for sub in n:
-            displayname = linkname = sub.name
-            # Append / for directories or @ for symbolic links
-            size = str(sub.size())
-            if stat.S_ISDIR(sub.mode):
-                displayname = sub.name + "/"
-                linkname = sub.name + "/"
-                size = '&nbsp;'
-            if stat.S_ISLNK(sub.mode):
-                displayname = sub.name + "@"
-                # Note: a link to a directory displays with @ and links with /
-                size = '&nbsp;'
-            self.write("""      <tr>
-        <td class="dir-name"><a href="%s">%s</a></td>
-        <td class="dir-size">%s</td>
-      </tr>""" % (urllib.quote(linkname), cgi.escape(displayname), size))
-        self.write("""
-    </table>
-  </body>
-</html>""")
+        self.render(
+            'list-directory.html',
+            path=path,
+            breadcrumbs=_compute_breadcrumbs(path),
+            dir_contents=_compute_dir_contents(n),
+            # We need the standard url_escape so we don't escape /
+            url_escape=urllib.quote)
 
     def _get_file(self, path, n):
         """Process a request on a file.
@@ -169,10 +157,9 @@ if len(extra) > 0:
 git.check_repo_or_die()
 top = vfs.RefList(None)
 
-(pwd,junk) = os.path.split(sys.argv[0])
-
 settings = dict(
     debug = 1,
+    template_path = resource_path('web'),
 )
 
 # Disable buffering on stdout, for debug messages
index 76d1a68f9afbab9c7d8b87ddcfbbdfc9ceae14d4..352485951a5684d1b2fbcde206ed27430d38cd4f 100644 (file)
@@ -126,6 +126,13 @@ def hostname():
     return _hostname
 
 
+_resource_path = None
+def resource_path(subdir=''):
+    global _resource_path
+    if not _resource_path:
+        _resource_path = os.environ.get('BUP_RESOURCE_PATH') or '.'
+    return os.path.join(_resource_path, subdir)
+
 class NotOk(Exception):
     pass
 
diff --git a/lib/web/list-directory.html b/lib/web/list-directory.html
new file mode 100644 (file)
index 0000000..49c1971
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Directory listing for {{ escape(path) }}</title>
+    <style type="text/css">
+      body, table { font-family: sans-serif }
+      #breadcrumb { margin: 10px 0; }
+      .dir-name { text-align: left }
+      .dir-size { text-align: right }
+    </style>
+  </head>
+  <body>
+    <div id="breadcrumb">
+      {% for (display, part_path) in breadcrumbs[:-1] %}
+        <a href="{{ url_escape(part_path) }}">{{ escape(display) }}</a> /
+      {% end %}
+      <strong>{{ escape(breadcrumbs[-1][0]) }}</strong>
+    </div>
+    <table>
+      <tr>
+        <th class="dir-name">Name</th>
+        <th class="dir-size">Size</th>
+      </tr>
+      {% for (display, link, size) in dir_contents %}
+        <tr>
+          <td class="dir-name"><a href="{{ url_escape(link) }}">{{ escape(display) }}</a></td>
+          <td class="dir-size">{% if size != None %}{{ size }}{% else %}&nbsp;{% end %}</td>
+        </tr>
+      {% end %}
+    </table>
+  </body>
+</html>
+
diff --git a/main.py b/main.py
index 90d0ec8760791477719d6937fd170951e18a8ed9..38a5b0ae5ec6bd56ed50f6459fe945484005bf8c 100755 (executable)
--- a/main.py
+++ b/main.py
@@ -12,13 +12,16 @@ if os.path.exists("%s/lib/bup/cmd/." % exeprefix):
     # eg. /usr/bin/bup means /usr/lib/bup/... is where our libraries are.
     cmdpath = "%s/lib/bup/cmd" % exeprefix
     libpath = "%s/lib/bup" % exeprefix
+    resourcepath = libpath
 else:
     # running from the src directory without being installed first
     cmdpath = os.path.join(exepath, 'cmd')
     libpath = os.path.join(exepath, 'lib')
+    resourcepath = libpath
 sys.path[:0] = [libpath]
 os.environ['PYTHONPATH'] = libpath + ':' + os.environ.get('PYTHONPATH', '')
 os.environ['BUP_MAIN_EXE'] = os.path.abspath(exe)
+os.environ['BUP_RESOURCE_PATH'] = resourcepath
 
 from bup.helpers import *