diff options
author | Sascha Silbe <sascha-pgp@silbe.org> | 2012-04-03 14:29:50 (GMT) |
---|---|---|
committer | Sascha Silbe <sascha-pgp@silbe.org> | 2012-04-03 14:29:50 (GMT) |
commit | 44a6fdb8a695395e5e198126984298c0193b51e8 (patch) | |
tree | 5fee1711ecf596a3f9bc00a9518e6df4943aaeb8 | |
parent | 7171fc973bff00898ab72a16044ebb84e35366f2 (diff) |
Resurrect HTML output for directory listings
Output (rather minimal) HTML listings for directories if they're accessed via
GET. This allows regular web browsers to browse a journal2webdav server.
-rwxr-xr-x | journal2webdav | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/journal2webdav b/journal2webdav index 8529664..e54d9f7 100755 --- a/journal2webdav +++ b/journal2webdav @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from BaseHTTPServer import HTTPServer from SocketServer import ThreadingMixIn +import cgi import logging import optparse import os @@ -152,8 +153,8 @@ class JournalObjectResource(object): class ObjectListHtmlResource(object): - def __init__(self, data_store, query): - self._html = self._generate_html(data_store, query) + def __init__(self, directory): + self._html = self._generate_html(directory) self._position = 0 def __len__(self): @@ -169,21 +170,29 @@ class ObjectListHtmlResource(object): self._position += length or len(self._html) return self._html[old_position:self._position] - def _generate_html(self, data_store, query): - entries = data_store.find_entries(query) - + def _generate_html(self, directory): lines = ['<html>', '<head><title>Journal listing</title></head>', - '<body>','<table>', '<tr><th>Title</th></tr>'] + '<body>','<table>', '<tr><th>Name</th></tr>'] - if entries and isinstance(entries[0][0], tuple): - lines += [u'<tr><td><a href="/object/%s/%s">%s</a></td></tr>' % \ - object_id + (title, ) for object_id, title in entries] - else: - lines += [u'<tr><td><a href="/object/%s">%s</a></td></tr>' % \ - (object_id, title) for object_id, title in entries] + for name, fs_object in directory.readdir(): + if name == '.': + continue + + lines.append(self._generate_html_entry(name, fs_object)) lines += ['</table>', '</html>'] - return u'\n'.join(lines).encode('utf-8') + return '\n'.join(lines) + + def _generate_html_entry(self, name, fs_object): + url = urllib.quote(name.encode('utf-8')) + escaped_name = cgi.escape(name.encode('utf-8')) + if isinstance(fs_object, fsemulation.Directory): + return '<tr><td><a href="%s/">%s/</a></td></tr>' % (url, + escaped_name) + else: + return '<tr><td><a href="%s">%s</a></td></tr>' % (url, + escaped_name) + class JournalHandler(dav_interface): @@ -272,13 +281,10 @@ class JournalHandler(dav_interface): log.debug('get_data %r %r', uri, byte_range) fs_object = self._lookup_uri(uri) - if not isinstance(fs_object, fsemulation.DSObject): - # FIXME: directory listings - #~ return self._get_data_object_list(self._root_query, scheme, - #~ netloc, range) - raise DAV_NotFound - - return JournalObjectResource(fs_object) + if isinstance(fs_object, fsemulation.Directory): + return ObjectListHtmlResource(fs_object) + else: + return JournalObjectResource(fs_object) def _get_dav_resourcetype(self, uri): log.debug('_get_dav_resourcetype %r', uri) @@ -294,12 +300,16 @@ class JournalHandler(dav_interface): if isinstance(fs_object, fsemulation.DSObject): return str(fs_object.get_size()) else: + # In theory, we should return the size of the HTML block + # we return on a GET request on this directory. However, + # native WebDAV clients are usually not used to download + # the GET representation of a collection and non-WebDAV + # clients don't request a WebDAV listing containing this + # property. So as it's expensive to calculate (we need to + # construct the full HTML block to determine the length), + # we just claim its empty and hope nothing breaks. return '0' - #~ if not path: - #~ # FIXME: inefficient - #~ return str(len(ObjectListHtmlResource(self._ds, self._root_query))) - def _get_dav_getcontenttype(self, uri): log.debug('_get_dav_getcontenttype %r', uri) fs_object = self._lookup_uri(uri) |