diff --git a/IPython/frontend/html/notebook/handlers/base.py b/IPython/frontend/html/notebook/handlers/base.py index 5d42ea2..adf1e3c 100644 --- a/IPython/frontend/html/notebook/handlers/base.py +++ b/IPython/frontend/html/notebook/handlers/base.py @@ -274,3 +274,11 @@ class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler): @authenticate_unless_readonly def get(self, path): return web.StaticFileHandler.get(self, path) + + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +default_handlers = [] diff --git a/IPython/frontend/html/notebook/handlers/clustersapi.py b/IPython/frontend/html/notebook/handlers/clustersapi.py index 25b35d7..486ada3 100644 --- a/IPython/frontend/html/notebook/handlers/clustersapi.py +++ b/IPython/frontend/html/notebook/handlers/clustersapi.py @@ -55,3 +55,18 @@ class ClusterActionHandler(IPythonHandler): if action == 'stop': data = cm.stop_cluster(profile) self.finish(jsonapi.dumps(data)) + + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +_cluster_action_regex = r"(?Pstart|stop)" +_profile_regex = r"(?P[^\/]+)" # there is almost no text that is invalid + +default_handlers = [ + (r"/clusters", MainClusterHandler), + (r"/clusters/%s/%s" % (_profile_regex, _cluster_action_regex), ClusterActionHandler), + (r"/clusters/%s" % _profile_regex, ClusterProfileHandler), +] diff --git a/IPython/frontend/html/notebook/handlers/kernelsapi.py b/IPython/frontend/html/notebook/handlers/kernelsapi.py index c1519d3..5c59015 100644 --- a/IPython/frontend/html/notebook/handlers/kernelsapi.py +++ b/IPython/frontend/html/notebook/handlers/kernelsapi.py @@ -244,8 +244,28 @@ class IOPubHandler(ZMQChannelHandler): """IOPub messages make no sense""" pass + class ShellHandler(ZMQChannelHandler): channel = 'shell' + class StdinHandler(ZMQChannelHandler): channel = 'stdin' + + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +_kernel_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" +_kernel_action_regex = r"(?Prestart|interrupt)" + +default_handlers = [ + (r"/kernels", MainKernelHandler), + (r"/kernels/%s" % _kernel_id_regex, KernelHandler), + (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler), + (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler), + (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler), + (r"/kernels/%s/stdin" % _kernel_id_regex, StdinHandler) +] diff --git a/IPython/frontend/html/notebook/handlers/login.py b/IPython/frontend/html/notebook/handlers/login.py index 27d953c..f63cc8b 100644 --- a/IPython/frontend/html/notebook/handlers/login.py +++ b/IPython/frontend/html/notebook/handlers/login.py @@ -28,7 +28,6 @@ from .base import IPythonHandler # Handler #----------------------------------------------------------------------------- - class LoginHandler(IPythonHandler): def _render(self, message=None): @@ -55,3 +54,9 @@ class LoginHandler(IPythonHandler): self.redirect(self.get_argument('next', default=self.base_project_url)) +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +default_handlers = [(r"/login", LoginHandler)] diff --git a/IPython/frontend/html/notebook/handlers/logout.py b/IPython/frontend/html/notebook/handlers/logout.py index 7474eba..43cefc3 100644 --- a/IPython/frontend/html/notebook/handlers/logout.py +++ b/IPython/frontend/html/notebook/handlers/logout.py @@ -34,3 +34,11 @@ class LogoutHandler(IPythonHandler): 'is disabled.'} self.write(self.render_template('logout.html', message=message)) + + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +default_handlers = [(r"/logout", LogoutHandler)] \ No newline at end of file diff --git a/IPython/frontend/html/notebook/handlers/notebooks.py b/IPython/frontend/html/notebook/handlers/notebooks.py index 3d14799..1a51843 100644 --- a/IPython/frontend/html/notebook/handlers/notebooks.py +++ b/IPython/frontend/html/notebook/handlers/notebooks.py @@ -73,3 +73,19 @@ class NotebookCopyHandler(IPythonHandler): notebook_id = self.notebook_manager.copy_notebook(notebook_id) self.redirect(url_path_join(self.base_project_url, notebook_id)) + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +_notebook_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" +_notebook_name_regex = r"(?P.+\.ipynb)" + +default_handlers = [ + (r"/new", NewHandler), + (r"/%s" % _notebook_id_regex, NamedNotebookHandler), + (r"/%s" % _notebook_name_regex, NotebookRedirectHandler), + (r"/%s/copy" % _notebook_id_regex, NotebookCopyHandler), + +] diff --git a/IPython/frontend/html/notebook/handlers/notebooksapi.py b/IPython/frontend/html/notebook/handlers/notebooksapi.py index c0f4db7..a0aa477 100644 --- a/IPython/frontend/html/notebook/handlers/notebooksapi.py +++ b/IPython/frontend/html/notebook/handlers/notebooksapi.py @@ -134,5 +134,23 @@ class ModifyNotebookCheckpointsHandler(IPythonHandler): self.finish() +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +_notebook_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" +_checkpoint_id_regex = r"(?P[\w-]+)" + +default_handlers = [ + (r"/notebooks", NotebookRootHandler), + (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler), + (r"/notebooks/%s/checkpoints" % _notebook_id_regex, NotebookCheckpointsHandler), + (r"/notebooks/%s/checkpoints/%s" % (_notebook_id_regex, _checkpoint_id_regex), + ModifyNotebookCheckpointsHandler + ), +] + + diff --git a/IPython/frontend/html/notebook/handlers/tree.py b/IPython/frontend/html/notebook/handlers/tree.py index ffcfce6..3133f95 100644 --- a/IPython/frontend/html/notebook/handlers/tree.py +++ b/IPython/frontend/html/notebook/handlers/tree.py @@ -31,3 +31,11 @@ class ProjectDashboardHandler(IPythonHandler): project=self.project, project_component=self.project.split('/'), )) + + +#----------------------------------------------------------------------------- +# URL to handler mappings +#----------------------------------------------------------------------------- + + +default_handlers = [(r"/", ProjectDashboardHandler)] \ No newline at end of file diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py index cf6b7e2..75ae14b 100644 --- a/IPython/frontend/html/notebook/notebookapp.py +++ b/IPython/frontend/html/notebook/notebookapp.py @@ -115,14 +115,6 @@ from .utils import url_path_join # Module globals #----------------------------------------------------------------------------- -_kernel_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" -_kernel_action_regex = r"(?Prestart|interrupt)" -_notebook_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" -_notebook_name_regex = r"(?P.+\.ipynb)" -_checkpoint_id_regex = r"(?P[\w-]+)" -_profile_regex = r"(?P[^\/]+)" # there is almost no text that is invalid -_cluster_action_regex = r"(?Pstart|stop)" - _examples = """ ipython notebook # start the notebook ipython notebook --profile=sympy # use the sympy profile @@ -146,6 +138,12 @@ def random_ports(port, n): for i in range(n-5): yield port + random.randint(-2*n, 2*n) +def load_handlers(name): + """Load the (URL pattern, handler) tuples for each component.""" + name = 'IPython.frontend.html.notebook.handlers.' + name + mod = __import__(name, fromlist=['default_handlers']) + return mod.default_handlers + #----------------------------------------------------------------------------- # The Tornado web application #----------------------------------------------------------------------------- @@ -155,31 +153,20 @@ class NotebookWebApplication(web.Application): def __init__(self, ipython_app, kernel_manager, notebook_manager, cluster_manager, log, base_project_url, settings_overrides): - handlers = [ - (r"/", ProjectDashboardHandler), - (r"/login", LoginHandler), - (r"/logout", LogoutHandler), - (r"/new", NewHandler), - (r"/%s" % _notebook_id_regex, NamedNotebookHandler), - (r"/%s" % _notebook_name_regex, NotebookRedirectHandler), - (r"/%s/copy" % _notebook_id_regex, NotebookCopyHandler), - (r"/kernels", MainKernelHandler), - (r"/kernels/%s" % _kernel_id_regex, KernelHandler), - (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler), - (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler), - (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler), - (r"/kernels/%s/stdin" % _kernel_id_regex, StdinHandler), - (r"/notebooks", NotebookRootHandler), - (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler), - (r"/notebooks/%s/checkpoints" % _notebook_id_regex, NotebookCheckpointsHandler), - (r"/notebooks/%s/checkpoints/%s" % (_notebook_id_regex, _checkpoint_id_regex), - ModifyNotebookCheckpointsHandler - ), + + # Load the (URL pattern, handler) tuples for each component. + handlers = [] + handlers.extend(load_handlers('base')) + handlers.extend(load_handlers('tree')) + handlers.extend(load_handlers('login')) + handlers.extend(load_handlers('logout')) + handlers.extend(load_handlers('notebooks')) + handlers.extend(load_handlers('kernelsapi')) + handlers.extend(load_handlers('notebooksapi')) + handlers.extend(load_handlers('clustersapi')) + handlers.extend([ (r"/files/(.*)", AuthenticatedFileHandler, {'path' : notebook_manager.notebook_dir}), - (r"/clusters", MainClusterHandler), - (r"/clusters/%s/%s" % (_profile_regex, _cluster_action_regex), ClusterActionHandler), - (r"/clusters/%s" % _profile_regex, ClusterProfileHandler), - ] + ]) # Python < 2.6.5 doesn't accept unicode keys in f(**kwargs), and # base_project_url will always be unicode, which will in turn