Make it so directory listings work, including root directory listing

This commit is contained in:
Micah Lee 2019-05-10 14:04:13 -07:00
parent 2299059304
commit ae54ef076e
2 changed files with 58 additions and 34 deletions

View File

@ -76,9 +76,6 @@ class WebsiteModeWeb(object):
'action': 'visit' 'action': 'visit'
}) })
# Removing trailing slashes, because self.files doesn't have them
path = path.rstrip('/')
if path in self.files: if path in self.files:
filesystem_path = self.files[path] filesystem_path = self.files[path]
@ -96,31 +93,7 @@ class WebsiteModeWeb(object):
# Otherwise, render directory listing # Otherwise, render directory listing
filenames = os.listdir(filesystem_path) filenames = os.listdir(filesystem_path)
filenames.sort() filenames.sort()
return self.directory_listing(path, filenames, filesystem_path)
files = []
dirs = []
for filename in filenames:
this_filesystem_path = os.path.join(filesystem_path, filename)
is_dir = os.path.isdir(this_filesystem_path)
if is_dir:
dirs.append({
'basename': filename
})
else:
size = os.path.getsize(this_filesystem_path)
size_human = self.common.human_readable_filesize(size)
files.append({
'basename': filename,
'size_human': size_human
})
r = make_response(render_template('listing.html',
path=path,
files=files,
dirs=dirs))
return self.web.add_security_headers(r)
# If it's a file # If it's a file
elif os.path.isfile(filesystem_path): elif os.path.isfile(filesystem_path):
@ -132,9 +105,54 @@ class WebsiteModeWeb(object):
else: else:
return self.web.error404() return self.web.error404()
else: else:
# If the path isn't found, throw a 404 # Special case loading /
return self.web.error404() if path == '':
index_path = 'index.html'
if index_path in self.files:
# Render it
dirname = os.path.dirname(self.files[index_path])
basename = os.path.basename(self.files[index_path])
return send_from_directory(dirname, basename)
else:
# Root directory listing
filenames = list(self.root_files)
filenames.sort()
return self.directory_listing(path, filenames)
else:
# If the path isn't found, throw a 404
return self.web.error404()
def directory_listing(self, path, filenames, filesystem_path=None):
# If filesystem_path is None, this is the root directory listing
files = []
dirs = []
for filename in filenames:
if filesystem_path:
this_filesystem_path = os.path.join(filesystem_path, filename)
else:
this_filesystem_path = self.files[filename]
is_dir = os.path.isdir(this_filesystem_path)
if is_dir:
dirs.append({
'basename': filename
})
else:
size = os.path.getsize(this_filesystem_path)
size_human = self.common.human_readable_filesize(size)
files.append({
'basename': filename,
'size_human': size_human
})
r = make_response(render_template('listing.html',
path=path,
files=files,
dirs=dirs))
return self.web.add_security_headers(r)
def set_file_info(self, filenames): def set_file_info(self, filenames):
""" """
@ -146,6 +164,9 @@ class WebsiteModeWeb(object):
# This is a dictionary that maps HTTP routes to filenames on disk # This is a dictionary that maps HTTP routes to filenames on disk
self.files = {} self.files = {}
# This is only the root files and dirs, as opposed to all of them
self.root_files = {}
# If there's just one folder, replace filenames with a list of files inside that folder # If there's just one folder, replace filenames with a list of files inside that folder
if len(filenames) == 1 and os.path.isdir(filenames[0]): if len(filenames) == 1 and os.path.isdir(filenames[0]):
filenames = [os.path.join(filenames[0], x) for x in os.listdir(filenames[0])] filenames = [os.path.join(filenames[0], x) for x in os.listdir(filenames[0])]
@ -157,9 +178,12 @@ class WebsiteModeWeb(object):
# If it's a filename, add it # If it's a filename, add it
if os.path.isfile(filename): if os.path.isfile(filename):
self.files[basename] = filename self.files[basename] = filename
self.root_files[basename] = filename
# If it's a directory, add it recursively # If it's a directory, add it recursively
elif os.path.isdir(filename): elif os.path.isdir(filename):
self.root_files[basename + '/'] = filename
for root, _, nested_filenames in os.walk(filename): for root, _, nested_filenames in os.walk(filename):
# Normalize the root path. So if the directory name is "/home/user/Documents/some_folder", # Normalize the root path. So if the directory name is "/home/user/Documents/some_folder",
# and it has a nested folder foobar, the root is "/home/user/Documents/some_folder/foobar". # and it has a nested folder foobar, the root is "/home/user/Documents/some_folder/foobar".
@ -167,7 +191,7 @@ class WebsiteModeWeb(object):
normalized_root = os.path.join(basename, root.lstrip(filename)).rstrip('/') normalized_root = os.path.join(basename, root.lstrip(filename)).rstrip('/')
# Add the dir itself # Add the dir itself
self.files[normalized_root] = filename self.files[normalized_root + '/'] = filename
# Add the files in this dir # Add the files in this dir
for nested_filename in nested_filenames: for nested_filename in nested_filenames:

View File

@ -23,11 +23,11 @@
<tr> <tr>
<td> <td>
<img width="30" height="30" title="" alt="" src="/static/img/web_folder.png" /> <img width="30" height="30" title="" alt="" src="/static/img/web_folder.png" />
<a href="/{{ path }}/{{ info.basename }}"> <a href="{{ info.basename }}">
{{ info.basename }} {{ info.basename }}
</a> </a>
</td> </td>
<td></td> <td>&mdash;</td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -35,7 +35,7 @@
<tr> <tr>
<td> <td>
<img width="30" height="30" title="" alt="" src="/static/img/web_file.png" /> <img width="30" height="30" title="" alt="" src="/static/img/web_file.png" />
<a href="/{{ path }}/{{ info.basename }}"> <a href="{{ info.basename }}">
{{ info.basename }} {{ info.basename }}
</a> </a>
</td> </td>