##// END OF EJS Templates
don't enforce .ipynb extension in URLs...
Min RK -
Show More
@@ -496,7 +496,6 class FilesRedirectHandler(IPythonHandler):
496
496
497 # path matches any number of `/foo[/bar...]` or just `/` or ''
497 # path matches any number of `/foo[/bar...]` or just `/` or ''
498 path_regex = r"(?P<path>(?:(?:/[^/]+)+|/?))"
498 path_regex = r"(?P<path>(?:(?:/[^/]+)+|/?))"
499 notebook_path_regex = r"(?P<path>(?:/[^/]+)+\.ipynb)"
500
499
501 #-----------------------------------------------------------------------------
500 #-----------------------------------------------------------------------------
502 # URL to handler mappings
501 # URL to handler mappings
@@ -11,7 +11,7 from tornado import web
11
11
12 from ..base.handlers import (
12 from ..base.handlers import (
13 IPythonHandler, FilesRedirectHandler,
13 IPythonHandler, FilesRedirectHandler,
14 notebook_path_regex, path_regex,
14 path_regex,
15 )
15 )
16 from IPython.nbformat import from_dict
16 from IPython.nbformat import from_dict
17
17
@@ -83,6 +83,8 class NbconvertFileHandler(IPythonHandler):
83 path = path.strip('/')
83 path = path.strip('/')
84 model = self.contents_manager.get(path=path)
84 model = self.contents_manager.get(path=path)
85 name = model['name']
85 name = model['name']
86 if model['type'] != 'notebook':
87 raise web.HTTPError(400, "Not a notebook: %s" % path)
86
88
87 self.set_header('Last-Modified', model['last_modified'])
89 self.set_header('Last-Modified', model['last_modified'])
88
90
@@ -142,8 +144,8 _format_regex = r"(?P<format>\w+)"
142
144
143
145
144 default_handlers = [
146 default_handlers = [
145 (r"/nbconvert/%s%s" % (_format_regex, notebook_path_regex),
146 NbconvertFileHandler),
147 (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
147 (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
148 (r"/nbconvert/%s%s" % (_format_regex, path_regex),
149 NbconvertFileHandler),
148 (r"/nbconvert/html%s" % path_regex, FilesRedirectHandler),
150 (r"/nbconvert/html%s" % path_regex, FilesRedirectHandler),
149 ]
151 ]
@@ -8,8 +8,7 from tornado import web
8 HTTPError = web.HTTPError
8 HTTPError = web.HTTPError
9
9
10 from ..base.handlers import (
10 from ..base.handlers import (
11 IPythonHandler, FilesRedirectHandler,
11 IPythonHandler, FilesRedirectHandler, path_regex,
12 notebook_path_regex, path_regex,
13 )
12 )
14 from ..utils import url_escape
13 from ..utils import url_escape
15
14
@@ -23,9 +22,11 class NotebookHandler(IPythonHandler):
23 path = path.strip('/')
22 path = path.strip('/')
24 cm = self.contents_manager
23 cm = self.contents_manager
25
24
26 # a .ipynb filename was given
25 # will raise 404 on not found
27 if not cm.file_exists(path):
26 model = cm.get(path, content=False)
28 raise web.HTTPError(404, u'Notebook does not exist: %s' % path)
27 if model['type'] != 'notebook':
28 # not a notebook, redirect to files
29 return FilesRedirectHandler.get(self, path)
29 name = url_escape(path.rsplit('/', 1)[-1])
30 name = url_escape(path.rsplit('/', 1)[-1])
30 path = url_escape(path)
31 path = url_escape(path)
31 self.write(self.render_template('notebook.html',
32 self.write(self.render_template('notebook.html',
@@ -43,7 +44,6 class NotebookHandler(IPythonHandler):
43
44
44
45
45 default_handlers = [
46 default_handlers = [
46 (r"/notebooks%s" % notebook_path_regex, NotebookHandler),
47 (r"/notebooks%s" % path_regex, NotebookHandler),
47 (r"/notebooks%s" % path_regex, FilesRedirectHandler),
48 ]
48 ]
49
49
@@ -2,7 +2,7
2 import re
2 import re
3 import nose.tools as nt
3 import nose.tools as nt
4
4
5 from IPython.html.base.handlers import path_regex, notebook_path_regex
5 from IPython.html.base.handlers import path_regex
6
6
7 try: # py3
7 try: # py3
8 assert_regex = nt.assert_regex
8 assert_regex = nt.assert_regex
@@ -14,7 +14,6 except AttributeError: # py2
14
14
15 # build regexps that tornado uses:
15 # build regexps that tornado uses:
16 path_pat = re.compile('^' + '/x%s' % path_regex + '$')
16 path_pat = re.compile('^' + '/x%s' % path_regex + '$')
17 nb_path_pat = re.compile('^' + '/y%s' % notebook_path_regex + '$')
18
17
19 def test_path_regex():
18 def test_path_regex():
20 for path in (
19 for path in (
@@ -39,23 +38,3 def test_path_regex_bad():
39 '/y/x/foo',
38 '/y/x/foo',
40 ):
39 ):
41 assert_not_regex(path, path_pat)
40 assert_not_regex(path, path_pat)
42
43 def test_notebook_path_regex():
44 for path in (
45 '/y/asdf.ipynb',
46 '/y/foo/bar.ipynb',
47 '/y/a/b/c/d/e.ipynb',
48 ):
49 assert_regex(path, nb_path_pat)
50
51 def test_notebook_path_regex_bad():
52 for path in (
53 '/y',
54 '/y/',
55 '/y/.ipynb',
56 '/y/foo/.ipynb',
57 '/y/foo/bar',
58 '/yfoo.ipynb',
59 '/yfoo/bar.ipynb',
60 ):
61 assert_not_regex(path, nb_path_pat)
General Comments 0
You need to be logged in to leave comments. Login now