Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Brian's Notebook work #899

Merged
merged 23 commits into from

3 participants

@minrk
Owner

This is a rebase of Brian's recent notebook work. It is principally a bit of housekeeping on some files and namespaces, but also fixes a bug preventing the password authentication from working in some environments.

@fperez
Owner

Everything looks great, except that I'd put the todo.rst file in the docs, not in the code directories. Otherwise good to go.

@minrk
Owner

Arg - I should have noted that it would be easier to rebase #897 on top of this one, rather than vice versa, since it's only one commit. Shouldn't be a big deal, though.

@fperez
Owner

Sorry! Just trying to keep up with you and push that open PR count down to 0 :)

@minrk
Owner

the conflict was tiny. Rebased again, with todo moved to dev docs.

@fperez fperez merged commit 284cfec into ipython:master
@fperez fperez referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 19, 2011
  1. @ellisonbg @minrk

    Adding base_project_url and base_kernel_url as HTML data attribs.

    ellisonbg authored minrk committed
    * Also saving the notebook_id using that as well.
  2. @minrk

    don't present meaningless username option in notebook

    minrk authored
    username isn't used for anything other than hash input
    for authentication, so remove the field in the login form
    and just use a uuid.
  3. @ellisonbg @minrk

    Minor changes to handlers.

    ellisonbg authored minrk committed
  4. @ellisonbg @minrk

    Removing focus.html.

    ellisonbg authored minrk committed
  5. @ellisonbg @minrk

    Misc changes to the notebook.

    ellisonbg authored minrk committed
    * IPythonNotebookApp->NotebookApp.
    * Cleaned up html templates of unused stylesheets.
  6. @ellisonbg @minrk

    Adding data-project to the body data attribs.

    ellisonbg authored minrk committed
  7. @ellisonbg @minrk

    Updating JS URL scheme to use embedded data.

    ellisonbg authored minrk committed
    All ajax requests from JS now use the data-base-project-url
    and data-base-kernel-url data attributes set on the body.
  8. @ellisonbg @minrk

    Updating notebook list to use data-base-project-url.

    ellisonbg authored minrk committed
  9. @ellisonbg @minrk
  10. @ellisonbg @minrk

    Simplifying logic on login page.

    ellisonbg authored minrk committed
  11. @ellisonbg @minrk

    Renaming things in the notebook.

    ellisonbg authored minrk committed
    * nbbrowser -> projectdashboard.
    * Getting rid of underscores on .js filenames.
  12. @ellisonbg @minrk

    Further cleanup and renaming of notebook.

    ellisonbg authored minrk committed
  13. @ellisonbg @minrk

    Renaming NBBrowserHandler->ProjectDashboardHandler.

    ellisonbg authored minrk committed
  14. @ellisonbg @minrk

    Removed save widget delay.

    ellisonbg authored minrk committed
  15. @ellisonbg @minrk

    Minor changes to the notebook handlers.

    ellisonbg authored minrk committed
  16. @minrk
  17. @minrk
  18. @ellisonbg @minrk

    Added kill_kernel to notebook template.

    ellisonbg authored minrk committed
  19. @ellisonbg @minrk

    Adding todo.rst for notebook.

    ellisonbg authored minrk committed
  20. @ellisonbg @minrk

    Using self.request._cookies in WS handlers.

    ellisonbg authored minrk committed
  21. @minrk

    update notebook todo

    minrk authored
  22. @minrk

    move notebook todo into dev docs

    minrk authored
  23. @minrk

    style Sign In button with jQuery

    minrk authored
This page is out of date. Refresh to see the latest.
Showing with 211 additions and 182 deletions.
  1. +3 −3 IPython/core/profileapp.py
  2. +41 −15 IPython/frontend/html/notebook/handlers.py
  3. +13 −13 IPython/frontend/html/notebook/notebookapp.py
  4. +7 −4 IPython/frontend/html/notebook/static/css/notebook.css
  5. 0  IPython/frontend/html/notebook/static/css/{nbbrowser.css → projectdashboard.css}
  6. +3 −5 IPython/frontend/html/notebook/static/js/kernel.js
  7. +30 −0 IPython/frontend/html/notebook/static/js/loginmain.js
  8. +8 −4 IPython/frontend/html/notebook/static/js/notebook.js
  9. +7 −4 IPython/frontend/html/notebook/static/js/notebooklist.js
  10. 0  IPython/frontend/html/notebook/static/js/{notebook_main.js → notebookmain.js}
  11. +5 −5 IPython/frontend/html/notebook/static/js/panelsection.js
  12. +1 −1  IPython/frontend/html/notebook/static/js/{nbbrowser_main.js → projectdashboardmain.js}
  13. +2 −2 IPython/frontend/html/notebook/static/js/savewidget.js
  14. +0 −87 IPython/frontend/html/notebook/templates/focus.html
  15. +5 −18 IPython/frontend/html/notebook/templates/login.html
  16. +24 −14 IPython/frontend/html/notebook/templates/notebook.html
  17. +4 −6 IPython/frontend/html/notebook/templates/{nbbrowser.html → projectdashboard.html}
  18. +1 −1  IPython/frontend/terminal/ipapp.py
  19. +1 −0  docs/source/development/index.txt
  20. +56 −0 docs/source/development/notebook_todo.txt
View
6 IPython/core/profileapp.py
@@ -194,15 +194,15 @@ def init_config_files(self):
else:
apps.append(IPythonQtConsoleApp)
try:
- from IPython.frontend.html.notebook.notebookapp import IPythonNotebookApp
+ from IPython.frontend.html.notebook.notebookapp import NotebookApp
except ImportError:
pass
except Exception:
- self.log.debug('Unexpected error when importing IPythonNotebookApp',
+ self.log.debug('Unexpected error when importing NotebookApp',
exc_info=True
)
else:
- apps.append(IPythonNotebookApp)
+ apps.append(NotebookApp)
if self.parallel:
from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
from IPython.parallel.apps.ipengineapp import IPEngineApp
View
56 IPython/frontend/html/notebook/handlers.py
@@ -18,6 +18,7 @@
import logging
import Cookie
+import uuid
from tornado import web
from tornado import websocket
@@ -40,51 +41,74 @@
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 @@ def _on_zmq_reply(self, msg_list):
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 @@ def open(self, kernel_id):
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 @@ def _inject_cookie_message(self, msg):
# 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)
View
26 IPython/frontend/html/notebook/notebookapp.py
@@ -37,7 +37,7 @@
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 @@ def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
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 @@ def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
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 @@ def get_ws_url(self):
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 @@ def init_configurables(self):
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 @@ def start(self):
#-----------------------------------------------------------------------------
def launch_new_instance():
- app = IPythonNotebookApp()
+ app = NotebookApp()
app.initialize()
app.start()
View
11 IPython/frontend/html/notebook/static/css/notebook.css
@@ -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;
}
View
0  ...nd/html/notebook/static/css/nbbrowser.css → .../notebook/static/css/projectdashboard.css
File renamed without changes
View
8 IPython/frontend/html/notebook/static/js/kernel.js
@@ -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;
View
30 IPython/frontend/html/notebook/static/js/loginmain.js
@@ -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');
+
+});
+
View
12 IPython/frontend/html/notebook/static/js/notebook.js
@@ -929,7 +929,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);
};
};
@@ -937,7 +938,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();
}
@@ -945,7 +946,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();
}
@@ -966,7 +967,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);
}
@@ -987,8 +989,10 @@ var IPython = (function (IPython) {
}, 50);
};
+
IPython.Notebook = Notebook;
+
return IPython;
}(IPython));
View
11 IPython/frontend/html/notebook/static/js/notebooklist.js
@@ -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) {
View
0  .../html/notebook/static/js/notebook_main.js → ...d/html/notebook/static/js/notebookmain.js
File renamed without changes
View
10 IPython/frontend/html/notebook/static/js/panelsection.js
@@ -19,7 +19,7 @@ var IPython = (function (IPython) {
this.selector = selector;
if (this.selector !== undefined) {
this.element = $(selector);
- this.header = this.element.find('h3.section_header');
+ this.header = this.element.find('div.section_header');
this.content = this.element.find('div.section_content');
this.style();
this.bind_events();
@@ -29,7 +29,7 @@ var IPython = (function (IPython) {
PanelSection.prototype.style = function () {
- this.header.addClass('ui-widget ui-state-default');
+ this.header.addClass('ui-widget ui-state-default ui-helper-clearfix');
this.header.attr('title', "Click to Show/Hide Section");
this.content.addClass('ui-widget section_content');
};
@@ -106,15 +106,15 @@ var IPython = (function (IPython) {
PanelSection.prototype.bind_events.apply(this);
var that = this;
this.content.find('#new_notebook').click(function () {
- window.open('/new');
+ window.open($('body').data('baseProjectUrl')+'new');
});
this.content.find('#open_notebook').click(function () {
- window.open('/');
+ window.open($('body').data('baseProjectUrl'));
});
this.content.find('#download_notebook').click(function () {
var format = that.content.find('#download_format').val();
var notebook_id = IPython.save_widget.get_notebook_id();
- var url = '/notebooks/' + notebook_id + '?format=' + format;
+ var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id + '?format=' + format;
window.open(url,'_newtab');
});
};
View
2  ...html/notebook/static/js/nbbrowser_main.js → ...otebook/static/js/projectdashboardmain.js
@@ -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');
View
4 IPython/frontend/html/notebook/static/js/savewidget.js
@@ -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');
};
View
87 IPython/frontend/html/notebook/templates/focus.html
@@ -1,87 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-
-<head>
-
- <title>Event ordering</title>
-
- <style>
- div#outer {
- width: 400px;
- height: 300px;
- border: solid 2px black;
- }
-
- div#inner {
- width: 80%;
- height: 80%;
- border: solid 2px black;
- }
-
- div#innerinner {
- width: 80%;
- height: 80%;
- border: solid 2px black;
- }
-
- </style>
-</head>
-
-<body>
-
-<div id="outer" tabindex="-1">
- This is the outer div.
-
- <div id="inner" tabindex="-1">
- This is the inner div.
- <div id="innerinner" tabindex="-1">
- This is the innerinner div
- </div>
- </div>
-
-</div>
-
-<script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
-
-<script>
- $(document).ready(function () {
- $('div#outer').click(function (e) {
- console.log("outer.click");
- });
- $('div#outer').focus(function (e) {
- console.log("outer.focus");
- });
- $('div#outer').focusin(function (e) {
- console.log("outer.focusin");
- });
-
- $('div#inner').click(function (e) {
- console.log("--inner.click");
- });
- $('div#inner').focus(function (e) {
- console.log("--inner.focus");
- });
- $('div#inner').focusin(function (e) {
- console.log("--inner.focusin");
- e.stopPropagation();
- });
-
- $('div#innerinner').click(function (e) {
- console.log("----innerinner.click");
- });
- $('div#innerinner').focus(function (e) {
- console.log("----innerinner.focus");
- });
- $('div#innerinner').focusin(function (e) {
- console.log("----innerinner.focusin");
- });
-
- });
-</script>
-
-</body>
-
-</html>
-
-
-
View
23 IPython/frontend/html/notebook/templates/login.html
@@ -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 @@
</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 @@
<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>
View
38 IPython/frontend/html/notebook/templates/notebook.html
@@ -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 @@ <h3 class="section_header">Notebook</h3>
</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 @@ <h3 class="section_header">Cell</h3>
</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 @@ <h3 class="section_header">Kernel</h3>
</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 @@ <h3 class="section_header">Kernel</h3>
</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 @@ <h3 class="section_header">Help</h3>
<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>
View
10 ...nd/html/notebook/templates/nbbrowser.html → .../notebook/templates/projectdashboard.html
@@ -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>
View
2  IPython/frontend/terminal/ipapp.py
@@ -206,7 +206,7 @@ def _classes_default(self):
qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
"""Launch the IPython Qt Console."""
),
- notebook=('IPython.frontend.html.notebook.notebookapp.IPythonNotebookApp',
+ notebook=('IPython.frontend.html.notebook.notebookapp.NotebookApp',
"""Launch the IPython HTML Notebook Server"""
),
profile = ("IPython.core.profileapp.ProfileApp",
View
1  docs/source/development/index.txt
@@ -22,3 +22,4 @@ IPython developer's guide
ipgraph.txt
ipython_qt.txt
ipythonzmq.txt
+ notebook_todo.txt
View
56 docs/source/development/notebook_todo.txt
@@ -0,0 +1,56 @@
+Notebook todo
+=============
+
+* Style the login page consistently with the rest of the site.
+* Style the "Log Out" and username links in the header.
+* Do a review of the header design and decide what to do about save widget moving
+ to the Notebook section of the L panel.
+* Show last saved time next to save widget.
+* Make the header logo a link to "/".
+* Add a better divider line between the header and the content area.
+ - Fix spacing on notebook page.
+* Organize templates to use inheritance and includes.
+
+* Implement better restart logic.
+ - Have LocalKernel monitor the hb port and always to restarts.
+ - Have the WebSocket still monitor the hb and notify the user of restarts.
+
+* Create unrendered rst cells.
+* Users should be able to edit the contents of any cell in a global ACE editor.
+* Add JSON'd metadata to the .py format notebooks.
+* Implement white space between cells for insert.
+* Implement a notebook reload button.
+* Indicate visual difference between html and markdown cell.
+* Export should save first.
+* Add ability to merge and split cells.
+* Add Ctrl-Z for undo delete cell.
+* Fix horizontal overflow and scrolling of output_area.
+* Add per cells controls on the R side of each cell.
+* Users should be able to drag a .py file to a cell and have it imported into that cell.
+
+* Add reconnect logic in the javascript kernel.
+* Add logic for failed ajax requests. With this, investigate returning JSON data to more
+ completely describe the HTTP error codes.
+* Test web services against hostile attacks.
+* Add optional html sanitizing.
+* Add timestamp to cells. ISO8601. IPython.utils.jsonutil.ISO8601. Save as
+ submitted/started/completed/received. See http://webcloud.se/log/JavaScript-and-ISO-8601/
+* Try to figure out the issue with jQuery and <script> tags. See
+ http://stackoverflow.com/questions/610995/jquery-cant-append-script-element
+
+CodeMirror related
+------------------
+
+* Focus should only be called when the editor is on the page and visible.
+* Refresh needs to be called when the editor is shown after hiding.
+* Right now focus, then setValue causes the arrow keys to lock up. If that bug is
+ not fixed, we need to possible move to passing the input to the CodeCell
+ constructor.
+* Implement a top-level refresh methods on Cells and the Notebook that can be called
+ after page/notebook load.
+* Make insert_code_cell_* methods not call select always. Probably move to a model
+ where those methods take an options object.
+* Notebook loading should be done without calls to select/focus/refresh. A single
+ refresh pass should be done after everything has been made visible.
+* Remove \u0000 from placeholders after the relevant CM bug is fixed.
+
Something went wrong with that request. Please try again.