Simple, ready to use static file server script using CherryPy and python 3.
It allows you to navigate into subdirectories if the path specified has any.
"""Simple CherryPy Static Server.""" | |
import os | |
import os.path | |
import cherrypy | |
import cgi | |
FILES_DIR = "D:/Books" | |
ORDERED_LIST = False | |
def get_dir_entries(path): | |
"""Return directories and files found at path.""" | |
entries = os.scandir(path) | |
dirs = {} | |
files = {} | |
for entry in entries: | |
base_name = entry.name | |
abs_name = entry.path | |
if entry.is_file(): | |
files[base_name] = abs_name | |
elif not entry.name.startswith('.') and entry.is_dir(): | |
dirs[base_name] = abs_name | |
return ( | |
((k, dirs[k]) for k in sorted(dirs.keys())), | |
((k, files[k]) for k in sorted(files.keys())) | |
) | |
class FileServer(object): | |
"""Serve the files and allows navigation to subdirectories.""" | |
@cherrypy.expose | |
def index(self, path=None): | |
"""Create html page with a list of files from a path.""" | |
print("session_id: {}".format(cherrypy.session.id)) | |
list_type = 'ol' if ORDERED_LIST else 'ul' | |
# path = cherrypy.session.set("_cur_path", path) | |
base_str = os.path.split(FILES_DIR)[-1] | |
abs_path = FILES_DIR | |
if path is not None: | |
base_str = os.path.join(base_str, path).replace("\\", "/") | |
abs_path = os.path.join(abs_path, path).replace("\\", "/") | |
dirs, files = get_dir_entries(abs_path) | |
file_icon = chr(int("1F4C4", 16)) | |
folder_icon = chr(int("1F4C1", 16)) | |
html = [] | |
html.append('<html><body><%s>' % list_type) | |
html.append("<h2>%s</h2><hr>" % base_str) | |
if path is not None and path != "": | |
previous = os.path.split(path)[0] | |
print("previous \"{}\"".format(previous)) | |
if previous == "": | |
html.append("<li><a href=\"index\">{} ..</a></li>".format( | |
folder_icon) | |
) | |
else: | |
html.append( | |
"<li><a href=\"index?path={}\">{} ..</a></li>".format( | |
previous, | |
folder_icon)) | |
for tup in dirs: | |
dname, abs_dname = tup | |
# print("dirs tup", tup) | |
if path is not None and path != "": | |
continuos_dname = "/".join((path, dname)) | |
else: | |
continuos_dname = dname | |
html.append("<li><a href=\"index?path={}\">{} {}</a></li>".format( | |
continuos_dname, | |
folder_icon, | |
dname)) | |
html.append("<br>") | |
for tup in files: | |
fname, abs_fname = tup | |
html.append("<li><a href=\"{}\">{} {}</a></li>".format( | |
cgi.escape(fname, True), | |
file_icon, | |
cgi.escape(fname))) | |
html.append('</%s></body></html>' % list_type) | |
return "\n".join(html) | |
if __name__ == '__main__': | |
cherrypy.config.update({ | |
'server.socket_host': '0.0.0.0', | |
'server.socket_port': 8001, | |
}) | |
conf = { | |
'/': { | |
'tools.staticdir.on': True, | |
'tools.staticdir.dir': FILES_DIR, | |
'tools.sessions.on': True, | |
'tools.sessions.timeout': 60 # minutes | |
} | |
} | |
cherrypy.quickstart(FileServer(), config=conf) |
@LukeMS I tried with the above code, to list my sub-directories through the index page and it's not working. Could you help me and try to run on my local mac.