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" % |
|
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 |
|
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