diff --git a/IPython/html/base/handlers.py b/IPython/html/base/handlers.py index 6c3dcdde0..eb2a7a71c 100644 --- a/IPython/html/base/handlers.py +++ b/IPython/html/base/handlers.py @@ -496,7 +496,6 @@ class FilesRedirectHandler(IPythonHandler): # path matches any number of `/foo[/bar...]` or just `/` or '' path_regex = r"(?P(?:(?:/[^/]+)+|/?))" -notebook_path_regex = r"(?P(?:/[^/]+)+\.ipynb)" #----------------------------------------------------------------------------- # URL to handler mappings diff --git a/IPython/html/nbconvert/handlers.py b/IPython/html/nbconvert/handlers.py index 63ba2668e..40cca7f70 100644 --- a/IPython/html/nbconvert/handlers.py +++ b/IPython/html/nbconvert/handlers.py @@ -11,7 +11,7 @@ from tornado import web from ..base.handlers import ( IPythonHandler, FilesRedirectHandler, - notebook_path_regex, path_regex, + path_regex, ) from IPython.nbformat import from_dict @@ -83,6 +83,8 @@ class NbconvertFileHandler(IPythonHandler): path = path.strip('/') model = self.contents_manager.get(path=path) name = model['name'] + if model['type'] != 'notebook': + raise web.HTTPError(400, "Not a notebook: %s" % path) self.set_header('Last-Modified', model['last_modified']) @@ -142,8 +144,8 @@ _format_regex = r"(?P\w+)" default_handlers = [ - (r"/nbconvert/%s%s" % (_format_regex, notebook_path_regex), - NbconvertFileHandler), (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler), + (r"/nbconvert/%s%s" % (_format_regex, path_regex), + NbconvertFileHandler), (r"/nbconvert/html%s" % path_regex, FilesRedirectHandler), ] diff --git a/IPython/html/notebook/handlers.py b/IPython/html/notebook/handlers.py index f6e101209..65c171e0c 100644 --- a/IPython/html/notebook/handlers.py +++ b/IPython/html/notebook/handlers.py @@ -8,8 +8,7 @@ from tornado import web HTTPError = web.HTTPError from ..base.handlers import ( - IPythonHandler, FilesRedirectHandler, - notebook_path_regex, path_regex, + IPythonHandler, FilesRedirectHandler, path_regex, ) from ..utils import url_escape @@ -23,9 +22,11 @@ class NotebookHandler(IPythonHandler): path = path.strip('/') cm = self.contents_manager - # a .ipynb filename was given - if not cm.file_exists(path): - raise web.HTTPError(404, u'Notebook does not exist: %s' % path) + # will raise 404 on not found + model = cm.get(path, content=False) + if model['type'] != 'notebook': + # not a notebook, redirect to files + return FilesRedirectHandler.get(self, path) name = url_escape(path.rsplit('/', 1)[-1]) path = url_escape(path) self.write(self.render_template('notebook.html', @@ -43,7 +44,6 @@ class NotebookHandler(IPythonHandler): default_handlers = [ - (r"/notebooks%s" % notebook_path_regex, NotebookHandler), - (r"/notebooks%s" % path_regex, FilesRedirectHandler), + (r"/notebooks%s" % path_regex, NotebookHandler), ] diff --git a/IPython/html/tests/test_paths.py b/IPython/html/tests/test_paths.py index 18dc4ad7a..01b24fe02 100644 --- a/IPython/html/tests/test_paths.py +++ b/IPython/html/tests/test_paths.py @@ -2,7 +2,7 @@ import re import nose.tools as nt -from IPython.html.base.handlers import path_regex, notebook_path_regex +from IPython.html.base.handlers import path_regex try: # py3 assert_regex = nt.assert_regex @@ -14,7 +14,6 @@ except AttributeError: # py2 # build regexps that tornado uses: path_pat = re.compile('^' + '/x%s' % path_regex + '$') -nb_path_pat = re.compile('^' + '/y%s' % notebook_path_regex + '$') def test_path_regex(): for path in ( @@ -39,23 +38,3 @@ def test_path_regex_bad(): '/y/x/foo', ): assert_not_regex(path, path_pat) - -def test_notebook_path_regex(): - for path in ( - '/y/asdf.ipynb', - '/y/foo/bar.ipynb', - '/y/a/b/c/d/e.ipynb', - ): - assert_regex(path, nb_path_pat) - -def test_notebook_path_regex_bad(): - for path in ( - '/y', - '/y/', - '/y/.ipynb', - '/y/foo/.ipynb', - '/y/foo/bar', - '/yfoo.ipynb', - '/yfoo/bar.ipynb', - ): - assert_not_regex(path, nb_path_pat)