From c85292cf2e3d8250c237fbff032b9ef10b66069a Mon Sep 17 00:00:00 2001 From: MinRK Date: Wed, 25 Sep 2013 16:24:40 -0700 Subject: [PATCH 1/4] add js_extensions_path serves files in `IPYTHONDIR/js_extensions` at `/js_extensions`. This is a location for users / devs to drop-in frontend customization as js modules, css, etc. The model is very much like the extensions dir (hence the name) - it's a location made available, but not loaded by default. You can load things from there with require, etc. It's a configurable search path, just like static. This way we can define a system-wide location at a later point (/usr/share/ipython/js_extensions?) and still have user installs. --- IPython/html/notebookapp.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index 955f6df6b..f3216dafe 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -85,7 +85,7 @@ from IPython.utils.traitlets import ( DottedObjectName ) from IPython.utils import py3compat -from IPython.utils.path import filefind +from IPython.utils.path import filefind, get_ipython_dir from .utils import url_path_join @@ -170,6 +170,7 @@ class NotebookWebApplication(web.Application): cluster_manager=cluster_manager, # IPython stuff + js_extensions_path = ipython_app.js_extensions_path, mathjax_url=ipython_app.mathjax_url, config=ipython_app.config, use_less=ipython_app.use_less, @@ -193,6 +194,7 @@ class NotebookWebApplication(web.Application): handlers.extend(load_handlers('services.clusters.handlers')) handlers.extend([ (r"/files/(.*)", AuthenticatedFileHandler, {'path' : settings['notebook_manager'].notebook_dir}), + (r"/js_extensions/(.*)", FileFindHandler, {'path' : settings['js_extensions_path']}), ]) # prepend base_project_url onto the patterns that we match new_handlers = [] @@ -432,6 +434,12 @@ class NotebookApp(BaseIPythonApplication): def static_file_path(self): """return extra paths + the default location""" return self.extra_static_paths + [DEFAULT_STATIC_FILES_PATH] + + js_extensions_path = List(Unicode, config=True, + help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/js_extensions""" + ) + def _js_extensions_path_default(self): + return [os.path.join(get_ipython_dir(), 'js_extensions')] mathjax_url = Unicode("", config=True, help="""The url for MathJax.js.""" @@ -521,9 +529,9 @@ class NotebookApp(BaseIPythonApplication): def init_webapp(self): """initialize tornado webapp and httpserver""" self.web_app = NotebookWebApplication( - self, self.kernel_manager, self.notebook_manager, + self, self.kernel_manager, self.notebook_manager, self.cluster_manager, self.log, - self.base_project_url, self.webapp_settings + self.base_project_url, self.webapp_settings, ) if self.certfile: ssl_options = dict(certfile=self.certfile) From 84e2384acf3db3f1e5867eabad4d51a3020255ae Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 26 Sep 2013 15:05:10 -0700 Subject: [PATCH 2/4] s/js_extensions/nb_extensions --- IPython/html/notebookapp.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index f3216dafe..bbbe81a5f 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -170,7 +170,7 @@ class NotebookWebApplication(web.Application): cluster_manager=cluster_manager, # IPython stuff - js_extensions_path = ipython_app.js_extensions_path, + nb_extensions_path = ipython_app.nb_extensions_path, mathjax_url=ipython_app.mathjax_url, config=ipython_app.config, use_less=ipython_app.use_less, @@ -194,7 +194,7 @@ class NotebookWebApplication(web.Application): handlers.extend(load_handlers('services.clusters.handlers')) handlers.extend([ (r"/files/(.*)", AuthenticatedFileHandler, {'path' : settings['notebook_manager'].notebook_dir}), - (r"/js_extensions/(.*)", FileFindHandler, {'path' : settings['js_extensions_path']}), + (r"/nb_extensions/(.*)", FileFindHandler, {'path' : settings['nb_extensions_path']}), ]) # prepend base_project_url onto the patterns that we match new_handlers = [] @@ -435,11 +435,11 @@ class NotebookApp(BaseIPythonApplication): """return extra paths + the default location""" return self.extra_static_paths + [DEFAULT_STATIC_FILES_PATH] - js_extensions_path = List(Unicode, config=True, - help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/js_extensions""" + nb_extensions_path = List(Unicode, config=True, + help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/nb_extensions""" ) - def _js_extensions_path_default(self): - return [os.path.join(get_ipython_dir(), 'js_extensions')] + def _nb_extensions_path_default(self): + return [os.path.join(get_ipython_dir(), 'nb_extensions')] mathjax_url = Unicode("", config=True, help="""The url for MathJax.js.""" From 06b2fdc076b04cd2a236db76b3091f27b83c1b36 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 26 Sep 2013 15:24:47 -0700 Subject: [PATCH 3/4] serve local mathjax from nb_extensions --- IPython/html/notebookapp.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index bbbe81a5f..af2d026df 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -450,21 +450,32 @@ class NotebookApp(BaseIPythonApplication): static_url_prefix = self.webapp_settings.get("static_url_prefix", url_path_join(self.base_project_url, "static") ) - try: - mathjax = filefind(os.path.join('mathjax', 'MathJax.js'), self.static_file_path) - except IOError: - if self.certfile: - # HTTPS: load from Rackspace CDN, because SSL certificate requires it - base = u"https://c328740.ssl.cf1.rackcdn.com" + + # try local mathjax, either in nb_extensions/mathjax or static/mathjax + for (url_prefix, search_path) in [ + (url_path_join(self.base_project_url, "extensions"), self.nb_extensions_path), + (static_url_prefix, self.static_file_path), + ]: + self.log.debug("searching for local mathjax in %s", search_path) + try: + mathjax = filefind(os.path.join('mathjax', 'MathJax.js'), search_path) + except IOError: + continue else: - base = u"http://cdn.mathjax.org" - - url = base + u"/mathjax/latest/MathJax.js" - self.log.info("Using MathJax from CDN: %s", url) - return url + url = url_path_join(url_prefix, u"mathjax/MathJax.js") + self.log.info("Serving local MathJax from %s at %s", mathjax, url) + return url + + # no local mathjax, serve from CDN + if self.certfile: + # HTTPS: load from Rackspace CDN, because SSL certificate requires it + host = u"https://c328740.ssl.cf1.rackcdn.com" else: - self.log.info("Using local MathJax from %s" % mathjax) - return url_path_join(static_url_prefix, u"mathjax/MathJax.js") + host = u"http://cdn.mathjax.org" + + url = host + u"/mathjax/latest/MathJax.js" + self.log.info("Using MathJax from CDN: %s", url) + return url def _mathjax_url_changed(self, name, old, new): if new and not self.enable_mathjax: From eae0cc7e770327cedc47c5b7c57c21ac07272ad8 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 26 Sep 2013 15:25:30 -0700 Subject: [PATCH 4/4] s/nb_extensions/nbextensions --- IPython/html/notebookapp.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index af2d026df..e5d2298bf 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -170,7 +170,7 @@ class NotebookWebApplication(web.Application): cluster_manager=cluster_manager, # IPython stuff - nb_extensions_path = ipython_app.nb_extensions_path, + nbextensions_path = ipython_app.nbextensions_path, mathjax_url=ipython_app.mathjax_url, config=ipython_app.config, use_less=ipython_app.use_less, @@ -194,7 +194,7 @@ class NotebookWebApplication(web.Application): handlers.extend(load_handlers('services.clusters.handlers')) handlers.extend([ (r"/files/(.*)", AuthenticatedFileHandler, {'path' : settings['notebook_manager'].notebook_dir}), - (r"/nb_extensions/(.*)", FileFindHandler, {'path' : settings['nb_extensions_path']}), + (r"/nbextensions/(.*)", FileFindHandler, {'path' : settings['nbextensions_path']}), ]) # prepend base_project_url onto the patterns that we match new_handlers = [] @@ -435,11 +435,11 @@ class NotebookApp(BaseIPythonApplication): """return extra paths + the default location""" return self.extra_static_paths + [DEFAULT_STATIC_FILES_PATH] - nb_extensions_path = List(Unicode, config=True, - help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/nb_extensions""" + nbextensions_path = List(Unicode, config=True, + help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/nbextensions""" ) - def _nb_extensions_path_default(self): - return [os.path.join(get_ipython_dir(), 'nb_extensions')] + def _nbextensions_path_default(self): + return [os.path.join(get_ipython_dir(), 'nbextensions')] mathjax_url = Unicode("", config=True, help="""The url for MathJax.js.""" @@ -451,9 +451,9 @@ class NotebookApp(BaseIPythonApplication): url_path_join(self.base_project_url, "static") ) - # try local mathjax, either in nb_extensions/mathjax or static/mathjax + # try local mathjax, either in nbextensions/mathjax or static/mathjax for (url_prefix, search_path) in [ - (url_path_join(self.base_project_url, "extensions"), self.nb_extensions_path), + (url_path_join(self.base_project_url, "nbextensions"), self.nbextensions_path), (static_url_prefix, self.static_file_path), ]: self.log.debug("searching for local mathjax in %s", search_path)