mirror of
https://github.com/onionshare/onionshare.git
synced 2025-06-07 06:13:03 -04:00
Starting to refactor website sharing so set_file_info builds a dict of all files, and path_logic will display any arbitrary file, or directory listing if no index.html is present
This commit is contained in:
parent
c378a32c51
commit
65a7a1790c
2 changed files with 102 additions and 90 deletions
|
@ -19,10 +19,8 @@ class WebsiteModeWeb(object):
|
||||||
self.web = web
|
self.web = web
|
||||||
self.auth = HTTPBasicAuth()
|
self.auth = HTTPBasicAuth()
|
||||||
|
|
||||||
# Information about the file to be shared
|
# Dictionary mapping file paths to filenames on disk
|
||||||
self.file_info = []
|
self.files = {}
|
||||||
self.website_folder = ''
|
|
||||||
self.download_filesize = 0
|
|
||||||
self.visit_count = 0
|
self.visit_count = 0
|
||||||
|
|
||||||
# Reset assets path
|
# Reset assets path
|
||||||
|
@ -55,10 +53,6 @@ class WebsiteModeWeb(object):
|
||||||
|
|
||||||
return _check_login()
|
return _check_login()
|
||||||
|
|
||||||
@self.web.app.route('/download/<path:page_path>')
|
|
||||||
def path_download(page_path):
|
|
||||||
return path_download(page_path)
|
|
||||||
|
|
||||||
@self.web.app.route('/<path:page_path>')
|
@self.web.app.route('/<path:page_path>')
|
||||||
def path_public(page_path):
|
def path_public(page_path):
|
||||||
return path_logic(page_path)
|
return path_logic(page_path)
|
||||||
|
@ -67,17 +61,7 @@ class WebsiteModeWeb(object):
|
||||||
def index_public():
|
def index_public():
|
||||||
return path_logic('')
|
return path_logic('')
|
||||||
|
|
||||||
def path_download(file_path=''):
|
def path_logic(path=''):
|
||||||
"""
|
|
||||||
Render the download links.
|
|
||||||
"""
|
|
||||||
self.web.add_request(self.web.REQUEST_LOAD, request.path)
|
|
||||||
if not os.path.isfile(os.path.join(self.website_folder, file_path)):
|
|
||||||
return self.web.error404()
|
|
||||||
|
|
||||||
return send_from_directory(self.website_folder, file_path)
|
|
||||||
|
|
||||||
def path_logic(page_path=''):
|
|
||||||
"""
|
"""
|
||||||
Render the onionshare website.
|
Render the onionshare website.
|
||||||
"""
|
"""
|
||||||
|
@ -87,85 +71,106 @@ class WebsiteModeWeb(object):
|
||||||
self.visit_count += 1
|
self.visit_count += 1
|
||||||
|
|
||||||
# Tell GUI the page has been visited
|
# Tell GUI the page has been visited
|
||||||
self.web.add_request(self.web.REQUEST_STARTED, page_path, {
|
self.web.add_request(self.web.REQUEST_STARTED, path, {
|
||||||
'id': visit_id,
|
'id': visit_id,
|
||||||
'action': 'visit'
|
'action': 'visit'
|
||||||
})
|
})
|
||||||
|
|
||||||
filelist = []
|
# Removing trailing slashes, because self.files doesn't have them
|
||||||
if self.file_info['files']:
|
path = path.rstrip('/')
|
||||||
self.website_folder = os.path.dirname(self.file_info['files'][0]['filename'])
|
|
||||||
filelist = [v['basename'] for v in self.file_info['files']]
|
if path in self.files:
|
||||||
elif self.file_info['dirs']:
|
filesystem_path = self.files[path]
|
||||||
self.website_folder = self.file_info['dirs'][0]['filename']
|
|
||||||
filelist = os.listdir(self.website_folder)
|
# If it's a directory
|
||||||
else:
|
if os.path.isdir(filesystem_path):
|
||||||
return self.web.error404()
|
# Is there an index.html?
|
||||||
|
index_path = os.path.join(path, 'index.html')
|
||||||
if any((fname == 'index.html') for fname in filelist):
|
if index_path in self.files:
|
||||||
self.web.app.static_url_path = self.website_folder
|
# Render it
|
||||||
self.web.app.static_folder = self.website_folder
|
dirname = os.path.dirname(self.files[index_path])
|
||||||
if not os.path.isfile(os.path.join(self.website_folder, page_path)):
|
basename = os.path.basename(self.files[index_path])
|
||||||
page_path = os.path.join(page_path, 'index.html')
|
return send_from_directory(dirname, basename)
|
||||||
return send_from_directory(self.website_folder, page_path)
|
|
||||||
elif any(os.path.isfile(os.path.join(self.website_folder, i)) for i in filelist):
|
else:
|
||||||
filenames = []
|
# Otherwise, render directory listing
|
||||||
for i in filelist:
|
filenames = os.listdir(filesystem_path)
|
||||||
filenames.append(os.path.join(self.website_folder, i))
|
filenames.sort()
|
||||||
|
|
||||||
self.web.app.static_folder=self.common.get_resource_path('static')
|
files = []
|
||||||
self.set_file_info(filenames)
|
dirs = []
|
||||||
|
|
||||||
r = make_response(render_template(
|
for filename in filenames:
|
||||||
'listing.html',
|
this_filesystem_path = os.path.join(filesystem_path, filename)
|
||||||
file_info=self.file_info,
|
is_dir = os.path.isdir(this_filesystem_path)
|
||||||
filesize=self.download_filesize,
|
|
||||||
filesize_human=self.common.human_readable_filesize(self.download_filesize)))
|
if is_dir:
|
||||||
|
dirs.append({
|
||||||
return self.web.add_security_headers(r)
|
'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
|
||||||
|
elif os.path.isfile(filesystem_path):
|
||||||
|
dirname = os.path.dirname(filesystem_path)
|
||||||
|
basename = os.path.basename(filesystem_path)
|
||||||
|
return send_from_directory(dirname, basename)
|
||||||
|
|
||||||
|
# If it's not a directory or file, throw a 404
|
||||||
|
else:
|
||||||
|
return self.web.error404()
|
||||||
else:
|
else:
|
||||||
|
# If the path isn't found, throw a 404
|
||||||
return self.web.error404()
|
return self.web.error404()
|
||||||
|
|
||||||
|
|
||||||
def set_file_info(self, filenames, processed_size_callback=None):
|
def set_file_info(self, filenames):
|
||||||
"""
|
"""
|
||||||
Using the list of filenames being shared, fill in details that the web
|
Build a data structure that describes the list of files that make up
|
||||||
page will need to display. This includes zipping up the file in order to
|
the static website.
|
||||||
get the zip file's name and size.
|
|
||||||
"""
|
"""
|
||||||
self.common.log("WebsiteModeWeb", "set_file_info")
|
self.common.log("WebsiteModeWeb", "set_file_info")
|
||||||
self.web.cancel_compression = True
|
|
||||||
|
|
||||||
self.cleanup_filenames = []
|
# This is a dictionary that maps HTTP routes to filenames on disk
|
||||||
|
self.files = {}
|
||||||
|
|
||||||
# build file info list
|
# If there's just one folder, replace filenames with a list of files inside that folder
|
||||||
self.file_info = {'files': [], 'dirs': []}
|
if len(filenames) == 1 and os.path.isdir(filenames[0]):
|
||||||
|
filenames = [os.path.join(filenames[0], x) for x in os.listdir(filenames[0])]
|
||||||
|
|
||||||
|
# Loop through the files
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
info = {
|
basename = os.path.basename(filename.rstrip('/'))
|
||||||
'filename': filename,
|
|
||||||
'basename': os.path.basename(filename.rstrip('/'))
|
# If it's a filename, add it
|
||||||
}
|
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
info['size'] = os.path.getsize(filename)
|
self.files[basename] = filename
|
||||||
info['size_human'] = self.common.human_readable_filesize(info['size'])
|
|
||||||
self.file_info['files'].append(info)
|
|
||||||
if os.path.isdir(filename):
|
|
||||||
info['size'] = self.common.dir_size(filename)
|
|
||||||
info['size_human'] = self.common.human_readable_filesize(info['size'])
|
|
||||||
self.file_info['dirs'].append(info)
|
|
||||||
|
|
||||||
self.download_filesize += info['size']
|
# If it's a directory, add it recursively
|
||||||
|
elif os.path.isdir(filename):
|
||||||
|
for root, _, nested_filenames in os.walk(filename):
|
||||||
|
# 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".
|
||||||
|
# The normalized_root should be "some_folder/foobar"
|
||||||
|
normalized_root = os.path.join(basename, root.lstrip(filename)).rstrip('/')
|
||||||
|
|
||||||
self.file_info['files'] = sorted(self.file_info['files'], key=lambda k: k['basename'])
|
# Add the dir itself
|
||||||
self.file_info['dirs'] = sorted(self.file_info['dirs'], key=lambda k: k['basename'])
|
self.files[normalized_root] = filename
|
||||||
|
|
||||||
# Check if there's only 1 file and no folders
|
|
||||||
if len(self.file_info['files']) == 1 and len(self.file_info['dirs']) == 0:
|
|
||||||
self.download_filename = self.file_info['files'][0]['filename']
|
|
||||||
self.download_filesize = self.file_info['files'][0]['size']
|
|
||||||
|
|
||||||
self.download_filesize = os.path.getsize(self.download_filename)
|
|
||||||
|
|
||||||
|
# Add the files in this dir
|
||||||
|
for nested_filename in nested_filenames:
|
||||||
|
self.files[os.path.join(normalized_root, nested_filename)] = os.path.join(root, nested_filename)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -8,11 +8,6 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<header class="clearfix">
|
<header class="clearfix">
|
||||||
<div class="right">
|
|
||||||
<ul>
|
|
||||||
<li>Total size: <strong>{{ filesize_human }}</strong></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<img class="logo" src="/static/img/logo.png" title="OnionShare">
|
<img class="logo" src="/static/img/logo.png" title="OnionShare">
|
||||||
<h1>OnionShare</h1>
|
<h1>OnionShare</h1>
|
||||||
</header>
|
</header>
|
||||||
|
@ -24,17 +19,29 @@
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{% for info in file_info.files %}
|
{% for info in dirs %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img width="30" height="30" title="" alt="" src="/static/img/web_folder.png" />
|
||||||
|
<a href="/{{ path }}/{{ info.basename }}">
|
||||||
|
{{ info.basename }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for info in files %}
|
||||||
<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" />
|
||||||
{{ info.basename }}
|
<a href="/{{ path }}/{{ info.basename }}">
|
||||||
|
{{ info.basename }}
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ info.size_human }}</td>
|
<td>{{ info.size_human }}</td>
|
||||||
<td><a href="/download/{{ info.basename }}">download</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<script src="/static/js/send.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue