Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions voila/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
from .configuration import VoilaConfiguration
from .execute import VoilaExecutor
from .exporter import VoilaExporter
from .handler import VoilaHandler
from .paths import ROOT, STATIC_ROOT, collect_static_paths, collect_template_paths
from .request_info_handler import RequestInfoSocketHandler
from .shutdown_kernel_handler import VoilaShutdownKernelHandler
Expand All @@ -76,7 +75,8 @@
TemplateStaticFileHandler,
WhiteListFileHandler,
)
from .treehandler import VoilaTreeHandler
from .tornado.handler import TornadoVoilaHandler
from .tornado.treehandler import TornadoVoilaTreeHandler
from .utils import create_include_assets_functions
from .voila_kernel_manager import voila_kernel_manager_factory

Expand Down Expand Up @@ -684,7 +684,7 @@ def init_handlers(self) -> List:
handlers.append(
(
url_path_join(self.server_url, r"/(.*)"),
VoilaHandler,
TornadoVoilaHandler,
{
"notebook_path": os.path.relpath(
self.notebook_path, self.root_dir
Expand All @@ -700,15 +700,15 @@ def init_handlers(self) -> List:
self.log.debug("serving directory: %r", self.root_dir)
handlers.extend(
[
(self.server_url, VoilaTreeHandler, tree_handler_conf),
(self.server_url, TornadoVoilaTreeHandler, tree_handler_conf),
(
url_path_join(self.server_url, r"/voila/tree" + path_regex),
VoilaTreeHandler,
TornadoVoilaTreeHandler,
tree_handler_conf,
),
(
url_path_join(self.server_url, r"/voila/render/(.*)"),
VoilaHandler,
TornadoVoilaHandler,
{
"template_paths": self.template_paths,
"config": self.config,
Expand Down
8 changes: 0 additions & 8 deletions voila/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from pathlib import Path
from typing import Dict

import tornado.web
from jupyter_server.base.handlers import JupyterHandler
from jupyter_server.utils import url_path_join
from nbclient.util import ensure_async
Expand Down Expand Up @@ -255,13 +254,6 @@ async def put_html():
break
yield html_snippet

@tornado.web.authenticated
async def get(self, path=None):
gen = self.get_generator(path=path)
async for html in gen:
self.write(html)
self.flush()

def redirect_to_file(self, path):
self.redirect(url_path_join(self.base_url, "voila", "files", path))

Expand Down
14 changes: 9 additions & 5 deletions voila/server_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
from jupyterlab_server.themes_handler import ThemesHandler

from .configuration import VoilaConfiguration
from .handler import VoilaHandler
from .tornado.handler import TornadoVoilaHandler
from .paths import ROOT, collect_static_paths, collect_template_paths, jupyter_path
from .shutdown_kernel_handler import VoilaShutdownKernelHandler
from .static_file_handler import (
MultiStaticFileHandler,
TemplateStaticFileHandler,
WhiteListFileHandler,
)
from .treehandler import VoilaTreeHandler
from .tornado.treehandler import TornadoVoilaTreeHandler
from .utils import get_server_root_dir


Expand Down Expand Up @@ -66,17 +66,21 @@ def _load_jupyter_server_extension(server_app):
[
(
url_path_join(base_url, "/voila/render/(.*)"),
VoilaHandler,
TornadoVoilaHandler,
{
"config": server_app.config,
"template_paths": template_paths,
"voila_configuration": voila_configuration,
},
),
(url_path_join(base_url, "/voila"), VoilaTreeHandler, tree_handler_conf),
(
url_path_join(base_url, "/voila"),
TornadoVoilaTreeHandler,
tree_handler_conf,
),
(
url_path_join(base_url, "/voila/tree" + path_regex),
VoilaTreeHandler,
TornadoVoilaTreeHandler,
tree_handler_conf,
),
(
Expand Down
20 changes: 20 additions & 0 deletions voila/tornado/handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#############################################################################
# Copyright (c) 2018, Voilà Contributors #
# Copyright (c) 2018, QuantStack #
# #
# Distributed under the terms of the BSD 3-Clause License. #
# #
# The full license is in the file LICENSE, distributed with this software. #
#############################################################################
import tornado.web

from ..handler import VoilaHandler


class TornadoVoilaHandler(VoilaHandler):
@tornado.web.authenticated
async def get(self, path=None):
gen = self.get_generator(path=path)
async for html in gen:
self.write(html)
self.flush()
70 changes: 70 additions & 0 deletions voila/tornado/treehandler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#############################################################################
# Copyright (c) 2018, Voilà Contributors #
# Copyright (c) 2018, QuantStack #
# #
# Distributed under the terms of the BSD 3-Clause License. #
# #
# The full license is in the file LICENSE, distributed with this software. #
#############################################################################
import os

from jupyter_server.utils import url_escape, url_path_join
from nbclient.util import ensure_async
from tornado import web

from ..treehandler import VoilaTreeHandler
from ..utils import get_server_root_dir


class TornadoVoilaTreeHandler(VoilaTreeHandler):
@web.authenticated
async def get(self, path=""):
cm = self.contents_manager
dir_exists = await ensure_async(cm.dir_exists(path=path))
file_exists = await ensure_async(cm.file_exists(path))
if dir_exists:
is_hidden = await ensure_async(cm.is_hidden(path))
if is_hidden and not cm.allow_hidden:
self.log.info("Refusing to serve hidden directory, via 404 Error")
raise web.HTTPError(404)
breadcrumbs = self.generate_breadcrumbs(path)
page_title = self.generate_page_title(path)
contents = await ensure_async(cm.get(path))

def allowed_content(content):
if content["type"] in ["directory", "notebook"]:
return True
__, ext = os.path.splitext(content.get("path"))
return ext in self.allowed_extensions

contents["content"] = sorted(contents["content"], key=lambda i: i["name"])
contents["content"] = filter(allowed_content, contents["content"])

self.write(
self.render_template(
"tree.html",
frontend="voila",
main_js="voila.js",
page_title=page_title,
notebook_path=path,
breadcrumbs=breadcrumbs,
contents=contents,
terminals_available=False,
server_root=get_server_root_dir(self.settings),
query=self.request.query,
)
)
elif file_exists:
# it's not a directory, we have redirecting to do
model = await ensure_async(cm.get(path, content=False))
# redirect to /api/notebooks if it's a notebook, otherwise /api/files
service = "notebooks" if model["type"] == "notebook" else "files"
url = url_path_join(
self.base_url,
service,
url_escape(path),
)
self.log.debug("Redirecting %s to %s", self.request.path, url)
self.redirect(url)
else:
raise web.HTTPError(404)
57 changes: 0 additions & 57 deletions voila/treehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@
# #
# The full license is in the file LICENSE, distributed with this software. #
#############################################################################
import os

from jupyter_server.utils import url_escape, url_path_join
from tornado import web

from .handler import BaseVoilaHandler
from .utils import get_server_root_dir
from nbclient.util import ensure_async


class VoilaTreeHandler(BaseVoilaHandler):
Expand Down Expand Up @@ -50,55 +45,3 @@ def generate_page_title(self, path):
return page_title + "/"
else:
return "Voilà Home"

@web.authenticated
async def get(self, path=""):
cm = self.contents_manager
dir_exists = await ensure_async(cm.dir_exists(path=path))
file_exists = await ensure_async(cm.file_exists(path))
if dir_exists:
is_hidden = await ensure_async(cm.is_hidden(path))
if is_hidden and not cm.allow_hidden:
self.log.info("Refusing to serve hidden directory, via 404 Error")
raise web.HTTPError(404)
breadcrumbs = self.generate_breadcrumbs(path)
page_title = self.generate_page_title(path)
contents = await ensure_async(cm.get(path))

def allowed_content(content):
if content["type"] in ["directory", "notebook"]:
return True
__, ext = os.path.splitext(content.get("path"))
return ext in self.allowed_extensions

contents["content"] = sorted(contents["content"], key=lambda i: i["name"])
contents["content"] = filter(allowed_content, contents["content"])

self.write(
self.render_template(
"tree.html",
frontend="voila",
main_js="voila.js",
page_title=page_title,
notebook_path=path,
breadcrumbs=breadcrumbs,
contents=contents,
terminals_available=False,
server_root=get_server_root_dir(self.settings),
query=self.request.query,
)
)
elif file_exists:
# it's not a directory, we have redirecting to do
model = await ensure_async(cm.get(path, content=False))
# redirect to /api/notebooks if it's a notebook, otherwise /api/files
service = "notebooks" if model["type"] == "notebook" else "files"
url = url_path_join(
self.base_url,
service,
url_escape(path),
)
self.log.debug("Redirecting %s to %s", self.request.path, url)
self.redirect(url)
else:
raise web.HTTPError(404)