From 7d4424a8444254daecd6e44aadb77257a215b3a1 Mon Sep 17 00:00:00 2001 From: dave Date: Sun, 2 Jun 2019 00:34:59 -0700 Subject: [PATCH] proper 404s --- dirview/__init__.py | 58 ++++++++++++++++++++++++++------------------- dirview/dirtools.py | 9 +++++++ setup.py | 3 ++- templates/page.html | 4 ++-- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/dirview/__init__.py b/dirview/__init__.py index 2ee9a10..53c5dcd 100644 --- a/dirview/__init__.py +++ b/dirview/__init__.py @@ -4,7 +4,7 @@ import logging import cherrypy from threading import Thread from jinja2 import Environment, FileSystemLoader, select_autoescape -from dirview.dirtools import gen_db, gen_node_index, NodeType, NodeGroup +from dirview.dirtools import gen_db, gen_node_index, node_by_path, NodeType, NodeGroup from dirview.utils import jinja_filters from time import time import json @@ -37,7 +37,7 @@ class AppWeb(object): def __init__(self, database, template_dir): self.db = database self.tpl = Environment(loader=FileSystemLoader(template_dir), - autoescape=select_autoescape(['html', 'xml'])) + autoescape=select_autoescape(["html", "xml"])) self.tpl.filters.update(**jinja_filters) def render(self, template, **kwargs): @@ -49,22 +49,32 @@ class AppWeb(object): NodeType=NodeType, NodeGroup=NodeGroup) #, **self.get_default_vars()) + def _cp_dispatch(self, vpath): + return self.index + @cherrypy.expose - def index(self, n=None): + def index(self, *args, n=None): start = time() if self.db.root is None: return "I'm still scanning your files, check back soon." - if n is None: - node = self.db.root - else: + if n: try: node = self.db.index[int(n)] - except (ValueError, KeyError): + except KeyError: + raise cherrypy.HTTPError(404) + raise cherrypy.HTTPRedirect("/".join(node.path[1:])) + else: + path = cherrypy.request.path_info[1:].split("/") + if path and path[0] == "": + path = [] # :/ + node = node_by_path(self.db.root, path) + if not node: raise cherrypy.HTTPError(404) page = self.render("page.html", node=node, root=self.db.root) dur = time() - start + return page + f"\n" @cherrypy.expose @@ -147,10 +157,10 @@ def main(): import signal parser = argparse.ArgumentParser(description="NAS storage visualizer") - parser.add_argument('-d', '--dir', required=True, help="directory to scan") - parser.add_argument('--cache', help="cache dir") - parser.add_argument('-p', '--port', default=8080, type=int, help="http port to listen on") - parser.add_argument('--debug', action="store_true", help="enable development options") + parser.add_argument("-d", "--dir", required=True, help="directory to scan") + parser.add_argument("--cache", help="cache dir") + parser.add_argument("-p", "--port", default=8080, type=int, help="http port to listen on") + parser.add_argument("--debug", action="store_true", help="enable development options") args = parser.parse_args() logging.basicConfig(level=logging.INFO if args.debug else logging.WARNING, @@ -162,25 +172,25 @@ def main(): web = AppWeb(db, tpl_dir) - cherrypy.tree.mount(web, '/', - {'/': {}, - '/static': {"tools.staticdir.on": True, + cherrypy.tree.mount(web, "/", + {"/": {}, + "/static": {"tools.staticdir.on": True, "tools.staticdir.dir": os.path.join(APPROOT, "static")}, # TODO non --debug path - # '/login': {'tools.auth_basic.on': True, - # 'tools.auth_basic.realm': 'webapp', - # 'tools.auth_basic.checkpassword': validate_password}}) + # "/login": {"tools.auth_basic.on": True, + # "tools.auth_basic.realm": "webapp", + # "tools.auth_basic.checkpassword": validate_password}}) }) cherrypy.config.update({ - 'tools.sessions.on': False, - 'server.socket_host': '0.0.0.0', - 'server.socket_port': args.port, - 'server.thread_pool': 5, - 'engine.autoreload.on': args.debug + "tools.sessions.on": False, + "server.socket_host": "0.0.0.0", + "server.socket_port": args.port, + "server.thread_pool": 5, + "engine.autoreload.on": args.debug }) def signal_handler(signum, stack): - logging.critical('Got sig {}, exiting...'.format(signum)) + logging.critical("Got sig {}, exiting...".format(signum)) cherrypy.engine.exit() signal.signal(signal.SIGINT, signal_handler) @@ -196,5 +206,5 @@ def main(): cherrypy.engine.exit() -if __name__ == '__main__': +if __name__ == "__main__": main() \ No newline at end of file diff --git a/dirview/dirtools.py b/dirview/dirtools.py index 17bace2..28d88b7 100644 --- a/dirview/dirtools.py +++ b/dirview/dirtools.py @@ -230,6 +230,15 @@ def load_db(fpath): return root +def node_by_path(db, path): + if not path: + return db + + for node in db.children: + if node.name == path[0]: + return node_by_path(node, path[1:]) + + def test_gen_write_db(path): path = os.path.normpath(os.path.abspath(path)) diff --git a/setup.py b/setup.py index f86ff16..58f2e0a 100644 --- a/setup.py +++ b/setup.py @@ -16,5 +16,6 @@ setup(name='dirview', ] }, package_data={'dirview': ['../templates/*.html', - '../static/scripts.js']}, + '../static/scripts.js', + '../static/style.css']}, zip_safe=False) diff --git a/templates/page.html b/templates/page.html index de2cd2a..b56b082 100644 --- a/templates/page.html +++ b/templates/page.html @@ -49,14 +49,14 @@

Subdirs:

{% for child in node.children|sort(attribute='total_children', reverse=True) %}{% if child.typ in NodeGroup.DIRLIKE %}
- {{ child.name }}: {{ child.total_size|data }} - {{ child.total_children|commafy }} children + {{ child.name }}: {{ child.total_size|data }} - {{ child.total_children|commafy }} children {% endif %}{% endfor %}

Files:

{% for child in node.children|sort(attribute='name') %}{% if child.typ in NodeGroup.FILELIKE %}
- {{ child.name }}: {{ child.total_size|data }} + {{ child.name }}: {{ child.total_size|data }} {% endif %}{% endfor %}