diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index f2d1c53..bf7f4f8 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -173,6 +173,7 @@ class NotebookWebApplication(web.Application): mathjax_url=ipython_app.mathjax_url, config=ipython_app.config, jinja2_env=env, + terminals_available=False, # Set later if terminals are available ) # allow custom overrides for the tornado web app. @@ -765,10 +766,9 @@ class NotebookApp(BaseIPythonApplication): try: from .terminal import initialize initialize(self.web_app) - self.web_app.terminals_available = True + self.web_app.settings['terminals_available'] = True except ImportError as e: self.log.info("Terminals not available (error was %s)", e) - self.web_app.terminals_available = False def init_signal(self): if not sys.platform.startswith('win'): diff --git a/IPython/html/static/tree/js/main.js b/IPython/html/static/tree/js/main.js index ab0e08c..1f19758 100644 --- a/IPython/html/static/tree/js/main.js +++ b/IPython/html/static/tree/js/main.js @@ -11,6 +11,7 @@ require([ 'tree/js/clusterlist', 'tree/js/sessionlist', 'tree/js/kernellist', + 'tree/js/terminallist', 'auth/js/loginwidget', // only loaded, not used: 'jqueryui', @@ -25,7 +26,8 @@ require([ notebooklist, clusterlist, sesssionlist, - kernellist, + kernellist, + terminallist, loginwidget){ page = new page.Page(); @@ -44,6 +46,11 @@ require([ kernel_list = new kernellist.KernelList('#running_list', $.extend({ session_list: session_list}, common_options)); + + if (utils.get_body_data("terminalsAvailable") === "True") { + terminal_list = new terminallist.TerminalList('#terminal_list', common_options); + } + login_widget = new loginwidget.LoginWidget('#login_widget', common_options); $('#new_notebook').click(function (e) { diff --git a/IPython/html/static/tree/js/terminallist.js b/IPython/html/static/tree/js/terminallist.js new file mode 100644 index 0000000..c7ef391 --- /dev/null +++ b/IPython/html/static/tree/js/terminallist.js @@ -0,0 +1,103 @@ +// Copyright (c) IPython Development Team. +// Distributed under the terms of the Modified BSD License. + +define([ + 'base/js/namespace', + 'base/js/utils', + 'jquery', + 'tree/js/notebooklist', +], function(IPython, utils, $, notebooklist) { + "use strict"; + + var TerminalList = function (selector, options) { + // Constructor + // + // Parameters: + // selector: string + // options: dictionary + // Dictionary of keyword arguments. + // base_url: string + this.base_url = options.base_url || utils.get_body_data("baseUrl"); + this.element_name = options.element_name || 'terminal'; + this.selector = selector; + this.terminals = []; + if (this.selector !== undefined) { + this.element = $(selector); + this.style(); + this.bind_events(); + this.load_terminals(); + } + }; + + TerminalList.prototype = Object.create(notebooklist.NotebookList.prototype); + + TerminalList.prototype.bind_events = function () { + var that = this; + $('#refresh_' + this.element_name + '_list').click(function () { + that.load_terminals(); + }); + $('#new_terminal').click($.proxy(this.new_terminal, this)); + }; + + TerminalList.prototype.new_terminal = function() { + var url = utils.url_join_encode(this.base_url, 'terminals/new'); + window.open(url, '_blank'); + }; + + TerminalList.prototype.load_terminals = function() { + var that = this; + var url = utils.url_join_encode(this.base_url, 'api/terminals'); + $.ajax(url, { + type: "GET", + cache: false, + dataType: "json", + success: $.proxy(this.terminals_loaded, this), + error : utils.log_ajax_error + }); + }; + + TerminalList.prototype.terminals_loaded = function (data) { + this.terminals = data; + this.clear_list(); + var item, path_name, term; + for (var i=0; i < this.terminals.length; i++) { + term = this.terminals[i]; + item = this.new_item(-1); + this.add_link(term.name, item); + this.add_shutdown_button(term.name, item); + } + $('#terminal_list_header').toggle(data.length === 0); + }; + + TerminalList.prototype.add_link = function(name, item) { + item.data('term-name', name); + item.find(".item_name").text("terminals/" + name); + item.find(".item_icon").addClass("fa fa-terminal"); + var link = item.find("a.item_link") + .attr('href', utils.url_join_encode(this.base_url, "terminals", name)); + link.attr('target', '_blank'); + this.add_shutdown_button(name, item); + }; + + TerminalList.prototype.add_shutdown_button = function(name, item) { + var that = this; + var shutdown_button = $(" + + + + + +
+
+
There are no terminals running.
+
+
+ + {% endif %}
diff --git a/IPython/html/tree/handlers.py b/IPython/html/tree/handlers.py index 4c1fdf9..a57c993 100644 --- a/IPython/html/tree/handlers.py +++ b/IPython/html/tree/handlers.py @@ -55,7 +55,8 @@ class TreeHandler(IPythonHandler): self.write(self.render_template('tree.html', page_title=page_title, notebook_path=path, - breadcrumbs=breadcrumbs + breadcrumbs=breadcrumbs, + terminals_available=self.settings['terminals_available'], ))