mirror of
https://github.com/jupyter/notebook.git
synced 2025-02-23 12:49:41 +08:00
Merge pull request #899 from minrk/nbwork
Internal notebook refactoring and cleanup, plus fixing a bug that prevented Tornado from authenticating users with password.
This commit is contained in:
commit
38af53d027
@ -18,6 +18,7 @@ Authors:
|
||||
|
||||
import logging
|
||||
import Cookie
|
||||
import uuid
|
||||
|
||||
from tornado import web
|
||||
from tornado import websocket
|
||||
@ -40,51 +41,74 @@ except ImportError:
|
||||
|
||||
class AuthenticatedHandler(web.RequestHandler):
|
||||
"""A RequestHandler with an authenticated user."""
|
||||
|
||||
def get_current_user(self):
|
||||
user_id = self.get_secure_cookie("user")
|
||||
user_id = self.get_secure_cookie("username")
|
||||
# For now the user_id should not return empty, but it could eventually
|
||||
if user_id == '':
|
||||
user_id = 'anonymous'
|
||||
if user_id is None:
|
||||
# prevent extra Invalid cookie sig warnings:
|
||||
self.clear_cookie('user')
|
||||
self.clear_cookie('username')
|
||||
if not self.application.password:
|
||||
user_id = 'anonymous'
|
||||
return user_id
|
||||
|
||||
|
||||
class NBBrowserHandler(AuthenticatedHandler):
|
||||
class ProjectDashboardHandler(AuthenticatedHandler):
|
||||
|
||||
@web.authenticated
|
||||
def get(self):
|
||||
nbm = self.application.notebook_manager
|
||||
project = nbm.notebook_dir
|
||||
self.render('nbbrowser.html', project=project)
|
||||
self.render(
|
||||
'projectdashboard.html', project=project,
|
||||
base_project_url=u'/', base_kernel_url=u'/'
|
||||
)
|
||||
|
||||
|
||||
class LoginHandler(AuthenticatedHandler):
|
||||
|
||||
def get(self):
|
||||
user_id = self.get_secure_cookie("user") or ''
|
||||
self.render('login.html', user_id=user_id)
|
||||
self.render('login.html', next='/')
|
||||
|
||||
def post(self):
|
||||
pwd = self.get_argument("password", default=u'')
|
||||
pwd = self.get_argument('password', default=u'')
|
||||
if self.application.password and pwd == self.application.password:
|
||||
self.set_secure_cookie("user", self.get_argument("name", default=u''))
|
||||
url = self.get_argument("next", default="/")
|
||||
self.set_secure_cookie('username', str(uuid.uuid4()))
|
||||
url = self.get_argument('next', default='/')
|
||||
self.redirect(url)
|
||||
|
||||
|
||||
class NewHandler(AuthenticatedHandler):
|
||||
|
||||
@web.authenticated
|
||||
def get(self):
|
||||
notebook_id = self.application.notebook_manager.new_notebook()
|
||||
self.render('notebook.html', notebook_id=notebook_id)
|
||||
nbm = self.application.notebook_manager
|
||||
project = nbm.notebook_dir
|
||||
notebook_id = nbm.new_notebook()
|
||||
self.render(
|
||||
'notebook.html', project=project,
|
||||
notebook_id=notebook_id,
|
||||
base_project_url=u'/', base_kernel_url=u'/',
|
||||
kill_kernel=False
|
||||
)
|
||||
|
||||
|
||||
class NamedNotebookHandler(AuthenticatedHandler):
|
||||
|
||||
@web.authenticated
|
||||
def get(self, notebook_id):
|
||||
nbm = self.application.notebook_manager
|
||||
project = nbm.notebook_dir
|
||||
if not nbm.notebook_exists(notebook_id):
|
||||
raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
|
||||
self.render('notebook.html', notebook_id=notebook_id)
|
||||
self.render(
|
||||
'notebook.html', project=project,
|
||||
notebook_id=notebook_id,
|
||||
base_project_url=u'/', base_kernel_url=u'/',
|
||||
kill_kernel=False
|
||||
)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -166,11 +190,13 @@ class ZMQStreamHandler(websocket.WebSocketHandler):
|
||||
try:
|
||||
msg = self._reserialize_reply(msg_list)
|
||||
except:
|
||||
self.application.kernel_manager.log.critical("Malformed message: %r" % msg_list)
|
||||
self.application.log.critical("Malformed message: %r" % msg_list)
|
||||
else:
|
||||
self.write_message(msg)
|
||||
|
||||
|
||||
class AuthenticatedZMQStreamHandler(ZMQStreamHandler):
|
||||
|
||||
def open(self, kernel_id):
|
||||
self.kernel_id = kernel_id.decode('ascii')
|
||||
try:
|
||||
@ -184,7 +210,7 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler):
|
||||
self.on_message = self.on_first_message
|
||||
|
||||
def get_current_user(self):
|
||||
user_id = self.get_secure_cookie("user")
|
||||
user_id = self.get_secure_cookie("username")
|
||||
if user_id == '' or (user_id is None and not self.application.password):
|
||||
user_id = 'anonymous'
|
||||
return user_id
|
||||
@ -196,7 +222,7 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler):
|
||||
# Cookie can't constructor doesn't accept unicode strings for some reason
|
||||
msg = msg.encode('utf8', 'replace')
|
||||
try:
|
||||
self._cookies = Cookie.SimpleCookie(msg)
|
||||
self.request._cookies = Cookie.SimpleCookie(msg)
|
||||
except:
|
||||
logging.warn("couldn't parse cookie string: %s",msg, exc_info=True)
|
||||
|
||||
|
@ -37,7 +37,7 @@ from tornado import web
|
||||
|
||||
from .kernelmanager import MappingKernelManager
|
||||
from .handlers import (LoginHandler,
|
||||
NBBrowserHandler, NewHandler, NamedNotebookHandler,
|
||||
ProjectDashboardHandler, NewHandler, NamedNotebookHandler,
|
||||
MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
|
||||
ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler
|
||||
)
|
||||
@ -80,7 +80,7 @@ class NotebookWebApplication(web.Application):
|
||||
|
||||
def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
|
||||
handlers = [
|
||||
(r"/", NBBrowserHandler),
|
||||
(r"/", ProjectDashboardHandler),
|
||||
(r"/login", LoginHandler),
|
||||
(r"/new", NewHandler),
|
||||
(r"/%s" % _notebook_id_regex, NamedNotebookHandler),
|
||||
@ -125,11 +125,11 @@ notebook_flags = ['no-browser']
|
||||
aliases = dict(ipkernel_aliases)
|
||||
|
||||
aliases.update({
|
||||
'ip': 'IPythonNotebookApp.ip',
|
||||
'port': 'IPythonNotebookApp.port',
|
||||
'keyfile': 'IPythonNotebookApp.keyfile',
|
||||
'certfile': 'IPythonNotebookApp.certfile',
|
||||
'ws-hostname': 'IPythonNotebookApp.ws_hostname',
|
||||
'ip': 'NotebookApp.ip',
|
||||
'port': 'NotebookApp.port',
|
||||
'keyfile': 'NotebookApp.keyfile',
|
||||
'certfile': 'NotebookApp.certfile',
|
||||
'ws-hostname': 'NotebookApp.ws_hostname',
|
||||
'notebook-dir': 'NotebookManager.notebook_dir',
|
||||
})
|
||||
|
||||
@ -141,10 +141,10 @@ notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile', u'ws-hostname',
|
||||
u'notebook-dir']
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# IPythonNotebookApp
|
||||
# NotebookApp
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class IPythonNotebookApp(BaseIPythonApplication):
|
||||
class NotebookApp(BaseIPythonApplication):
|
||||
|
||||
name = 'ipython-notebook'
|
||||
default_config_file_name='ipython_notebook_config.py'
|
||||
@ -213,7 +213,7 @@ class IPythonNotebookApp(BaseIPythonApplication):
|
||||
return prefix + self.ws_hostname + u':' + unicode(self.port)
|
||||
|
||||
def parse_command_line(self, argv=None):
|
||||
super(IPythonNotebookApp, self).parse_command_line(argv)
|
||||
super(NotebookApp, self).parse_command_line(argv)
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
@ -254,14 +254,14 @@ class IPythonNotebookApp(BaseIPythonApplication):
|
||||
self.notebook_manager.list_notebooks()
|
||||
|
||||
def init_logging(self):
|
||||
super(IPythonNotebookApp, self).init_logging()
|
||||
super(NotebookApp, self).init_logging()
|
||||
# This prevents double log messages because tornado use a root logger that
|
||||
# self.log is a child of. The logging module dipatches log messages to a log
|
||||
# and all of its ancenstors until propagate is set to False.
|
||||
self.log.propagate = False
|
||||
|
||||
def initialize(self, argv=None):
|
||||
super(IPythonNotebookApp, self).initialize(argv)
|
||||
super(NotebookApp, self).initialize(argv)
|
||||
self.init_configurables()
|
||||
self.web_app = NotebookWebApplication(
|
||||
self, self.kernel_manager, self.notebook_manager, self.log
|
||||
@ -309,7 +309,7 @@ class IPythonNotebookApp(BaseIPythonApplication):
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def launch_new_instance():
|
||||
app = IPythonNotebookApp()
|
||||
app = NotebookApp()
|
||||
app.initialize()
|
||||
app.start()
|
||||
|
||||
|
@ -37,9 +37,8 @@ input#notebook_name {
|
||||
}
|
||||
|
||||
span#kernel_status {
|
||||
position: absolute;
|
||||
padding: 8px 5px 5px 5px;
|
||||
right: 10px;
|
||||
float: right;
|
||||
padding: 0px 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -65,10 +64,14 @@ div#left_panel {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
h3.section_header {
|
||||
div.section_header {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.section_header h3 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.section_content {
|
||||
padding: 5px;
|
||||
}
|
||||
|
@ -15,12 +15,10 @@ var IPython = (function (IPython) {
|
||||
|
||||
var Kernel = function () {
|
||||
this.kernel_id = null;
|
||||
this.base_url = "/kernels";
|
||||
this.kernel_url = null;
|
||||
this.shell_channel = null;
|
||||
this.iopub_channel = null;
|
||||
this.base_url = $('body').data('baseKernelUrl') + "kernels";
|
||||
this.running = false;
|
||||
|
||||
this.username = "username";
|
||||
this.session_id = utils.uuid();
|
||||
|
||||
@ -52,7 +50,8 @@ var IPython = (function (IPython) {
|
||||
var that = this;
|
||||
if (!this.running) {
|
||||
var qs = $.param({notebook:notebook_id});
|
||||
$.post(this.base_url + '?' + qs,
|
||||
var url = this.base_url + '?' + qs
|
||||
$.post(url,
|
||||
function (kernel_id) {
|
||||
that._handle_start_kernel(kernel_id, callback);
|
||||
},
|
||||
@ -97,7 +96,6 @@ var IPython = (function (IPython) {
|
||||
this.iopub_channel = new this.WebSocket(ws_url + "/iopub");
|
||||
send_cookie = function(){
|
||||
this.send(document.cookie);
|
||||
console.log(this);
|
||||
}
|
||||
this.shell_channel.onopen = send_cookie;
|
||||
this.iopub_channel.onopen = send_cookie;
|
||||
|
30
IPython/frontend/html/notebook/static/js/loginmain.js
Normal file
30
IPython/frontend/html/notebook/static/js/loginmain.js
Normal file
@ -0,0 +1,30 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2008-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.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//============================================================================
|
||||
// On document ready
|
||||
//============================================================================
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
$('div#header').addClass('border-box-sizing');
|
||||
$('div#header_border').addClass('border-box-sizing ui-widget ui-widget-content');
|
||||
|
||||
$('div#main_app').addClass('border-box-sizing ui-widget');
|
||||
$('div#app_hbox').addClass('hbox');
|
||||
|
||||
$('div#left_panel').addClass('box-flex');
|
||||
$('div#right_panel').addClass('box-flex');
|
||||
$('input#signin').button();
|
||||
|
||||
// These have display: none in the css file and are made visible here to prevent FLOUC.
|
||||
$('div#header').css('display','block');
|
||||
$('div#main_app').css('display','block');
|
||||
|
||||
});
|
||||
|
@ -931,7 +931,8 @@ var IPython = (function (IPython) {
|
||||
error : $.proxy(this.notebook_save_failed,this)
|
||||
};
|
||||
IPython.save_widget.status_saving();
|
||||
$.ajax("/notebooks/" + notebook_id, settings);
|
||||
var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
|
||||
$.ajax(url, settings);
|
||||
};
|
||||
};
|
||||
|
||||
@ -939,7 +940,7 @@ var IPython = (function (IPython) {
|
||||
Notebook.prototype.notebook_saved = function (data, status, xhr) {
|
||||
this.dirty = false;
|
||||
IPython.save_widget.notebook_saved();
|
||||
setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
|
||||
IPython.save_widget.status_save();
|
||||
}
|
||||
|
||||
|
||||
@ -947,7 +948,7 @@ var IPython = (function (IPython) {
|
||||
// Notify the user and reset the save button
|
||||
// TODO: Handle different types of errors (timeout etc.)
|
||||
alert('An unexpected error occured while saving the notebook.');
|
||||
setTimeout($.proxy(IPython.save_widget.reset_status,IPython.save_widget),500);
|
||||
IPython.save_widget.reset_status();
|
||||
}
|
||||
|
||||
|
||||
@ -968,7 +969,8 @@ var IPython = (function (IPython) {
|
||||
}
|
||||
};
|
||||
IPython.save_widget.status_loading();
|
||||
$.ajax("/notebooks/" + notebook_id, settings);
|
||||
var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
|
||||
$.ajax(url, settings);
|
||||
}
|
||||
|
||||
|
||||
@ -989,8 +991,10 @@ var IPython = (function (IPython) {
|
||||
}, 50);
|
||||
};
|
||||
|
||||
|
||||
IPython.Notebook = Notebook;
|
||||
|
||||
|
||||
return IPython;
|
||||
|
||||
}(IPython));
|
||||
|
@ -67,7 +67,8 @@ var IPython = (function (IPython) {
|
||||
dataType : "json",
|
||||
success : $.proxy(this.list_loaded, this)
|
||||
};
|
||||
$.ajax("/notebooks", settings);
|
||||
var url = $('body').data('baseProjectUrl') + 'notebooks'
|
||||
$.ajax(url, settings);
|
||||
};
|
||||
|
||||
|
||||
@ -105,7 +106,7 @@ var IPython = (function (IPython) {
|
||||
var new_item_name = $('<span/>').addClass('item_name');
|
||||
new_item_name.append(
|
||||
$('<a/>').
|
||||
attr('href','/'+notebook_id).
|
||||
attr('href', $('body').data('baseProjectURL')+notebook_id).
|
||||
attr('target','_blank').
|
||||
text(nbname)
|
||||
);
|
||||
@ -170,7 +171,8 @@ var IPython = (function (IPython) {
|
||||
parent_item.remove();
|
||||
}
|
||||
};
|
||||
$.ajax("/notebooks/" + notebook_id, settings);
|
||||
var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
|
||||
$.ajax(url, settings);
|
||||
$(this).dialog('close');
|
||||
},
|
||||
"Cancel": function () {
|
||||
@ -217,7 +219,8 @@ var IPython = (function (IPython) {
|
||||
};
|
||||
|
||||
var qs = $.param({name:nbname, format:nbformat});
|
||||
$.ajax('/notebooks?' + qs, settings);
|
||||
var url = $('body').data('baseProjectUrl') + 'notebooks?' + qs
|
||||
$.ajax(url, settings);
|
||||
});
|
||||
var cancel_button = $('<button>Cancel</button>').button().
|
||||
click(function (e) {
|
||||
|
@ -21,7 +21,7 @@ $(document).ready(function () {
|
||||
$('div#content_toolbar').addClass('ui-widget ui-helper-clearfix');
|
||||
|
||||
$('#new_notebook').button().click(function (e) {
|
||||
window.open('/new');
|
||||
window.open($('body').data('baseProjectUrl')+'new');
|
||||
});
|
||||
|
||||
$('div#left_panel').addClass('box-flex');
|
@ -82,12 +82,12 @@ var IPython = (function (IPython) {
|
||||
|
||||
SaveWidget.prototype.set_document_title = function () {
|
||||
nbname = this.get_notebook_name();
|
||||
document.title = 'IPy: ' + nbname;
|
||||
document.title = nbname;
|
||||
};
|
||||
|
||||
|
||||
SaveWidget.prototype.get_notebook_id = function () {
|
||||
return this.element.find('span#notebook_id').text()
|
||||
return $('body').data('notebookId');
|
||||
};
|
||||
|
||||
|
||||
|
@ -7,24 +7,13 @@
|
||||
<title>IPython Notebook</title>
|
||||
|
||||
<link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
|
||||
<!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
|
||||
<!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
|
||||
|
||||
<link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/css/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/css/base.css" type="text/css" />
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
function add_next_to_action(){
|
||||
// add 'next' argument to action url, to preserve redirect
|
||||
var query = location.search.substring(1);
|
||||
var form = document.forms[0];
|
||||
var action = form.getAttribute("action");
|
||||
form.setAttribute("action", action + '?' + query);
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="add_next_to_action()">
|
||||
<body>
|
||||
|
||||
<div id="header">
|
||||
<span id="ipython_notebook"><h1>IPython Notebook</h1></span>
|
||||
@ -40,10 +29,9 @@ function add_next_to_action(){
|
||||
</div>
|
||||
|
||||
<div id="content_panel">
|
||||
<form action="/login" method="post">
|
||||
Name: <input type="text" name="name" value="{{user_id}}">
|
||||
<form action="/login?next={{url_escape(next)}}" method="post">
|
||||
Password: <input type="password" name="password">
|
||||
<input type="submit" value="Sign in">
|
||||
<input type="submit" value="Sign in" id="signin">
|
||||
</form>
|
||||
</div>
|
||||
<div id="right_panel">
|
||||
@ -56,8 +44,7 @@ function add_next_to_action(){
|
||||
<script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/loginmain.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -6,10 +6,6 @@
|
||||
|
||||
<title>IPython Notebook</title>
|
||||
|
||||
<link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
|
||||
<!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
|
||||
<!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
|
||||
|
||||
<!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
|
||||
<script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
|
||||
<script type="text/javascript">
|
||||
@ -30,6 +26,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
|
||||
<link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
|
||||
<link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
|
||||
@ -47,19 +44,20 @@
|
||||
|
||||
</head>
|
||||
|
||||
<body onload='CheckMathJax();'>
|
||||
<body onload='CheckMathJax();'
|
||||
data-project={{project}} data-notebook-id={{notebook_id}}
|
||||
data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
|
||||
>
|
||||
|
||||
<div id="header">
|
||||
<span id="ipython_notebook"><h1>IPython Notebook</h1></span>
|
||||
<span id="save_widget">
|
||||
<input type="text" id="notebook_name" size="20"></textarea>
|
||||
<span id="notebook_id" style="display:none">{{notebook_id}}</span>
|
||||
<button id="save_notebook"><u>S</u>ave</button>
|
||||
</span>
|
||||
<span id="quick_help_area">
|
||||
<button id="quick_help">Quick<u>H</u>elp</button>
|
||||
</span>
|
||||
<span id="kernel_status">Idle</span>
|
||||
</div>
|
||||
|
||||
<div id="MathJaxFetchingWarning"
|
||||
@ -90,7 +88,9 @@
|
||||
<div id="left_panel">
|
||||
|
||||
<div id="notebook_section">
|
||||
<h3 class="section_header">Notebook</h3>
|
||||
<div class="section_header">
|
||||
<h3>Notebook</h3>
|
||||
</div>
|
||||
<div class="section_content">
|
||||
<div class="section_row">
|
||||
<span id="new_open" class="section_row_buttons">
|
||||
@ -121,7 +121,9 @@
|
||||
</div>
|
||||
|
||||
<div id="cell_section">
|
||||
<h3 class="section_header">Cell</h3>
|
||||
<div class="section_header">
|
||||
<h3>Cell</h3>
|
||||
</div>
|
||||
<div class="section_content">
|
||||
<div class="section_row">
|
||||
<span class="section_row_buttons">
|
||||
@ -175,7 +177,10 @@
|
||||
</div>
|
||||
|
||||
<div id="kernel_section">
|
||||
<h3 class="section_header">Kernel</h3>
|
||||
<div class="section_header">
|
||||
<h3>Kernel</h3>
|
||||
<span id="kernel_status">Idle</span>
|
||||
</div>
|
||||
<div class="section_content">
|
||||
<div class="section_row">
|
||||
<span id="int_restart" class="section_row_buttons">
|
||||
@ -186,7 +191,11 @@
|
||||
</div>
|
||||
<div class="section_row">
|
||||
<span id="kernel_persist">
|
||||
<input type="checkbox" id="kill_kernel"></input>
|
||||
{% if kill_kernel %}
|
||||
<input type="checkbox" id="kill_kernel" checked="true"></input>
|
||||
{% else %}
|
||||
<input type="checkbox" id="kill_kernel"></input>
|
||||
{% end %}
|
||||
</span>
|
||||
<span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
|
||||
</div>
|
||||
@ -194,7 +203,9 @@
|
||||
</div>
|
||||
|
||||
<div id="help_section">
|
||||
<h3 class="section_header">Help</h3>
|
||||
<div class="section_header">
|
||||
<h3>Cell</h3>
|
||||
</div>
|
||||
<div class="section_content">
|
||||
<div class="section_row">
|
||||
<span id="help_buttons0" class="section_row_buttons">
|
||||
@ -272,8 +283,7 @@
|
||||
<script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<script src="static/js/notebookmain.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -7,17 +7,15 @@
|
||||
<title>IPython Notebook</title>
|
||||
|
||||
<link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
|
||||
<!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
|
||||
<!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
|
||||
|
||||
<link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/css/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/css/base.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/css/nbbrowser.css" type="text/css" />
|
||||
<link rel="stylesheet" href="static/css/projectdashboard.css" type="text/css" />
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body data-project={{project}} data-base-project-url={{base_project_url}}
|
||||
data-base-kernel-url={{base_kernel_url}}>
|
||||
|
||||
<div id="header">
|
||||
<span id="ipython_notebook"><h1>IPython Notebook</h1></span>
|
||||
@ -56,7 +54,7 @@
|
||||
<script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="static/js/projectdashboardmain.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user