dirbrowser: fix navigation on windows

Issue #1334

The problem was that there were too few slashes. On Linux, absolute
paths start with /, so

    file:// + /home

gives file:///home, which is a valid path. On windows however, absolute
paths start with a drive letter, so

    file:// + C:/Users

gives file://C:/Users, which is parsed as "host C, path Users", which is
why it could be written as file://c/Users (strip out the empty "port"),
giving us an invalid path.

The solution is to add the third slash in the template, and strip the
redundant slash on unix systems.

Additionally, this fixes a bug where navigating from '/home/' to the
parent directory would give '/home' instead of '/'
This commit is contained in:
Daniel Schadt 2016-03-23 23:31:38 +01:00
parent c0f9ab9b2b
commit a77e085952
2 changed files with 17 additions and 7 deletions

View File

@ -44,7 +44,9 @@ def get_file_list(basedir, all_files, filterfunc):
for filename in all_files:
absname = os.path.join(basedir, filename)
if filterfunc(absname):
items.append({'name': filename, 'absname': absname})
# Absolute paths in Unix start with a slash ('/'), but we already
# have enough slashes in the template, so we don't need it here
items.append({'name': filename, 'absname': absname.lstrip('/')})
return sorted(items, key=lambda v: v['name'].lower())
@ -57,6 +59,14 @@ def is_root(directory):
Return:
Whether the directory is a root directory or not.
"""
# If you're curious as why this works:
# dirname('/') = '/'
# dirname('/home') = '/'
# dirname('/home/') = '/home'
# dirname('/home/foo') = '/home'
# basically, for files (no trailing slash) it removes the file part, and for
# directories, it removes the trailing slash, so the only way for this to be
# equal is if the directory is the root directory.
return os.path.dirname(directory) == directory
@ -74,14 +84,14 @@ def dirbrowser_html(path):
if is_root(path):
parent = None
else:
parent = os.path.dirname(path)
parent = os.path.normpath(os.path.join(path, '..')).lstrip('/')
try:
all_files = os.listdir(path)
except OSError as e:
html = jinja.render('error.html',
title="Error while reading directory",
url='file://{}'.format(path), error=str(e),
url='file:///{}'.format(path), error=str(e),
icon='')
return html.encode('UTF-8', errors='xmlcharrefreplace')

View File

@ -46,21 +46,21 @@ ul.files > li {
<p id="dirbrowserTitleText">Browse directory: {{url}}</p>
</div>
{% if parent %}
{% if parent is not none %}
<ul class="parent">
<li><a href="{{parent}}">..</a></li>
<li><a href="file:///{{parent}}">..</a></li>
</ul>
{% endif %}
<ul class="folders">
{% for item in directories %}
<li><a href="file://{{item.absname}}">{{item.name}}</a></li>
<li><a href="file:///{{item.absname}}">{{item.name}}</a></li>
{% endfor %}
</ul>
<ul class="files">
{% for item in files %}
<li><a href="file://{{item.absname}}">{{item.name}}</a></li>
<li><a href="file:///{{item.absname}}">{{item.name}}</a></li>
{% endfor %}
</ul>
</div>