diff --git a/IPython/html/base/handlers.py b/IPython/html/base/handlers.py
index 76f9164..50551ee 100644
--- a/IPython/html/base/handlers.py
+++ b/IPython/html/base/handlers.py
@@ -27,7 +27,7 @@ except ImportError:
from IPython.config import Application
from IPython.utils.path import filefind
from IPython.utils.py3compat import string_types
-from IPython.html.utils import is_hidden
+from IPython.html.utils import is_hidden, url_path_join, url_escape
#-----------------------------------------------------------------------------
# Top-level handlers
@@ -409,6 +409,37 @@ class TrailingSlashHandler(web.RequestHandler):
def get(self):
self.redirect(self.request.uri.rstrip('/'))
+
+class FilesRedirectHandler(IPythonHandler):
+ """Handler for redirecting relative URLs to the /files/ handler"""
+ def get(self, path=''):
+ cm = self.contents_manager
+ if cm.path_exists(path):
+ # it's a *directory*, redirect to /tree
+ url = url_path_join(self.base_url, 'tree', path)
+ else:
+ orig_path = path
+ # otherwise, redirect to /files
+ parts = path.split('/')
+ path = '/'.join(parts[:-1])
+ name = parts[-1]
+
+ if not cm.file_exists(name=name, path=path) and 'files' in parts:
+ # redirect without files/ iff it would 404
+ # this preserves pre-2.0-style 'files/' links
+ self.log.warn("Deprecated files/ URL: %s", orig_path)
+ parts.remove('files')
+ path = '/'.join(parts[:-1])
+
+ if not cm.file_exists(name=name, path=path):
+ raise web.HTTPError(404)
+
+ url = url_path_join(self.base_url, 'files', path, name)
+ url = url_escape(url)
+ self.log.debug("Redirecting %s to %s", self.request.path, url)
+ self.redirect(url)
+
+
#-----------------------------------------------------------------------------
# URL pattern fragments for re-use
#-----------------------------------------------------------------------------
diff --git a/IPython/html/nbconvert/handlers.py b/IPython/html/nbconvert/handlers.py
index 93e6bf1..f6e1094 100644
--- a/IPython/html/nbconvert/handlers.py
+++ b/IPython/html/nbconvert/handlers.py
@@ -9,7 +9,10 @@ import zipfile
from tornado import web
-from ..base.handlers import IPythonHandler, notebook_path_regex
+from ..base.handlers import (
+ IPythonHandler, FilesRedirectHandler,
+ notebook_path_regex, path_regex,
+)
from IPython.nbformat.current import to_notebook_json
from IPython.utils.py3compat import cast_bytes
@@ -128,6 +131,7 @@ class NbconvertPostHandler(IPythonHandler):
self.finish(output)
+
#-----------------------------------------------------------------------------
# URL to handler mappings
#-----------------------------------------------------------------------------
@@ -139,4 +143,5 @@ default_handlers = [
(r"/nbconvert/%s%s" % (_format_regex, notebook_path_regex),
NbconvertFileHandler),
(r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
+ (r"/nbconvert/html%s" % path_regex, FilesRedirectHandler),
]
diff --git a/IPython/html/notebook/handlers.py b/IPython/html/notebook/handlers.py
index 78938a5..a7eae8a 100644
--- a/IPython/html/notebook/handlers.py
+++ b/IPython/html/notebook/handlers.py
@@ -1,31 +1,17 @@
-"""Tornado handlers for the live notebook view.
+"""Tornado handlers for the live notebook view."""
-Authors:
-
-* Brian Granger
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (C) 2011 The IPython Development Team
-#
-# Distributed under the terms of the BSD License. The full license is in
-# the file COPYING, distributed as part of this software.
-#-----------------------------------------------------------------------------
-
-#-----------------------------------------------------------------------------
-# Imports
-#-----------------------------------------------------------------------------
+# Copyright (c) IPython Development Team.
+# Distributed under the terms of the Modified BSD License.
import os
from tornado import web
HTTPError = web.HTTPError
-from ..base.handlers import IPythonHandler, notebook_path_regex, path_regex
-from ..utils import url_path_join, url_escape
-
-#-----------------------------------------------------------------------------
-# Handlers
-#-----------------------------------------------------------------------------
+from ..base.handlers import (
+ IPythonHandler, FilesRedirectHandler,
+ notebook_path_regex, path_regex,
+)
+from ..utils import url_escape
class NotebookHandler(IPythonHandler):
@@ -53,33 +39,6 @@ class NotebookHandler(IPythonHandler):
)
)
-class NotebookRedirectHandler(IPythonHandler):
- def get(self, path=''):
- cm = self.contents_manager
- if cm.path_exists(path):
- # it's a *directory*, redirect to /tree
- url = url_path_join(self.base_url, 'tree', path)
- else:
- orig_path = path
- # otherwise, redirect to /files
- parts = path.split('/')
- path = '/'.join(parts[:-1])
- name = parts[-1]
-
- if not cm.file_exists(name=name, path=path) and 'files' in parts:
- # redirect without files/ iff it would 404
- # this preserves pre-2.0-style 'files/' links
- self.log.warn("Deprecated files/ URL: %s", orig_path)
- parts.remove('files')
- path = '/'.join(parts[:-1])
-
- if not cm.file_exists(name=name, path=path):
- raise web.HTTPError(404)
-
- url = url_path_join(self.base_url, 'files', path, name)
- url = url_escape(url)
- self.log.debug("Redirecting %s to %s", self.request.path, url)
- self.redirect(url)
#-----------------------------------------------------------------------------
# URL to handler mappings
@@ -88,6 +47,6 @@ class NotebookRedirectHandler(IPythonHandler):
default_handlers = [
(r"/notebooks%s" % notebook_path_regex, NotebookHandler),
- (r"/notebooks%s" % path_regex, NotebookRedirectHandler),
+ (r"/notebooks%s" % path_regex, FilesRedirectHandler),
]