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), ]