Permalink
Browse files

Rewrote backend js for new message tracking, works vastly better now

  • Loading branch information...
1 parent ad87ff3 commit a1ed6cdfc3291e7c1d8f6a35088168a70bfed835 @jamesgao committed Oct 28, 2010
@@ -113,6 +113,7 @@
.message .output {
float:left;
width:90%;
+ height:0px;
}
@@ -7,6 +7,7 @@
# Local imports
import os
+import threading
from IPython.external.argparse import ArgumentParser
from IPython.frontend.html.kernelmanager import HttpKernelManager, \
IPyHttpServer, IPyHttpHandler
@@ -59,30 +60,38 @@ def main():
help='use a GUI widget for tab completion')
args = parser.parse_args()
-
+
+ def defer():
+ import time
+ time.sleep(2)
+ import webbrowser
+ webbrowser.open("http://localhost:8080/notebook")
+ threading.Thread(target=defer).start()
+
+
# Don't let Qt or ZMQ swallow KeyboardInterupts.
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
-
- # Create a KernelManager and start a kernel.
- kernel_manager = HttpKernelManager(xreq_address=(args.ip, args.xreq),
- sub_address=(args.ip, args.sub),
- rep_address=(args.ip, args.rep),
- hb_address=(args.ip, args.hb))
- if args.ip == LOCALHOST and not args.existing:
- if args.pure:
- kernel_manager.start_kernel(ipython=False)
- elif args.pylab:
- kernel_manager.start_kernel(pylab=args.pylab)
- else:
- kernel_manager.start_kernel()
- kernel_manager.start_channels()
-
- #Start the web server
- import webbrowser
- webbrowser.open("http://localhost:8080/notebook")
- server = IPyHttpServer(("", 8080), IPyHttpHandler)
- server.serve_forever()
+ try:
+ # Create a KernelManager and start a kernel.
+ kernel_manager = HttpKernelManager(xreq_address=(args.ip, args.xreq),
+ sub_address=(args.ip, args.sub),
+ rep_address=(args.ip, args.rep),
+ hb_address=(args.ip, args.hb))
+ if args.ip == LOCALHOST and not args.existing:
+ if args.pure:
+ kernel_manager.start_kernel(ipython=False)
+ elif args.pylab:
+ kernel_manager.start_kernel(pylab=args.pylab)
+ else:
+ kernel_manager.start_kernel()
+ kernel_manager.start_channels()
+
+ #Start the web server
+ server = IPyHttpServer(("", 8080), IPyHttpHandler)
+ server.serve_forever()
+ except KeyboardInterrupt:
+ pass
if __name__ == '__main__':
main()
@@ -21,8 +21,11 @@ CometGetter.prototype.complete = function(json, status, request) {
statusbar.set(json.content.execution_state)
} else if (this.pause) {
this.queue.push(json)
- } else
- manager.process(json, false, !this.pause)
+ } else {
+ if (typeof(exec_count) != "undefined" ||
+ json.msg_type == "execute_reply")
+ manager.process(json, false, !this.pause)
+ }
}
CometGetter.prototype.start = function () {
this.pause = false
@@ -52,20 +55,20 @@ function execute(code, msg) {
$.ajax({
type: "POST",
data: {type:"execute", code:code},
- success: function(json, status, request) {
- if (json != null)
- manager.process(json, msg)
+ success: function(msg_id, status, request) {
+ if (msg != null)
+ manager.set(msg, msg_id)
comet.start()
}
})
}
-function tabcomplete(code, pos, func) {
+function tabcomplete(code, pos, callback) {
$.ajax({
type:"POST",
data: {type:"complete", code:code, pos:pos},
success: function(json, status, request) {
- func(json.content.matches)
+ callback(json.content.matches)
}
})
}
@@ -0,0 +1,135 @@
+/***********************************************************************
+ * Process any payload objects into html
+ ***********************************************************************/
+function procPayload(payload) {
+ var data = null
+ if (typeof(payload['format']) != "undefined") {
+ var format = payload['format']
+ if (format == "svg") {
+ //Remove the doctype from the top, otherwise no way to embed
+ data = payload['data'].split("\n").slice(4).join("\n")
+ } else if (format == "png") {
+ data = $(document.createElement("img"))
+ data.attr("src", "data:image/png;"+payload['data'])
+ }
+ } else if (typeof(payload["text"]) != "undefined") {
+ data = fixConsole(payload["text"])
+ }
+
+ return data
+}
+
+/***********************************************************************
+ * Manages the messages and their ordering
+ ***********************************************************************/
+function Manager(obj) {
+ this.messages = {}
+ this.ordering = []
+ this.obj = "#"+obj
+ this.ondeck = null
+ this.cursor = 0
+ var thisObj = this
+ $(document).click(function() {
+ thisObj.deactivate(thisObj.ondeck)
+ })
+
+ this.buf_out = null
+}
+Manager.prototype.set = function (msg, msg_id) {
+ msg.msg_id = msg_id
+ if (this.ondeck == msg) {
+ manager.messages[msg_id] = msg
+ manager.ordering.push(msg)
+ manager.ondeck = null
+ } else {
+ manager.messages[msg_id] = msg
+ }
+}
+Manager.prototype.get = function (msg_id) {
+ if (typeof(msg_id) == "undefined") {
+ //Handle manager.get(), to return a new message on deck
+ if (this.ondeck == null) {
+ this.ondeck = new Message(-1, this.obj)
+ this.cursor = this.ordering.length
+ }
+ return this.ondeck
+ } else if (msg_id[0] == "+" || msg_id[0] == "-") {
+ //Handle the manager.get("+1") case, to advance the cursor
+ var idx = parseInt(msg_id)
+ if (this.cursor + idx <= this.ordering.length &&
+ this.cursor + idx >= 0)
+ this.cursor += idx
+ if (this.cursor >= this.ordering.length ||
+ this.ordering.length == 0)
+ return this.get()
+
+ return this.ordering[this.cursor]
+ } else if (typeof(this.messages[msg_id]) == "undefined") {
+ //Handle the manager.get(unknown) case, for messages from other clients
+ if (this.ondeck != null)
+ this.ondeck.remove()
+ this.messages[msg_id] = new Message(msg_id, this.obj)
+ this.ordering.push(this.messages[msg_id])
+ if (this.ondeck != null) {
+ this.ondeck = null
+ this.get().activate()
+ }
+ }
+ return this.messages[msg_id]
+}
+Manager.prototype.deactivate = function (current) {
+ for (var i in this.messages)
+ this.messages[i].deactivate()
+ if (this.ondeck != null) {
+ this.ondeck.deactivate()
+ if (this.ondeck != current) {
+ this.ondeck.remove()
+ this.ondeck = null
+ }
+ }
+}
+Manager.prototype.process = function (json, origin, immediate) {
+ if (json.content.execution_count)
+ exec_count = json.content.execution_count
+
+ var id = json.parent_header.msg_id
+ var type = json.msg_type
+ var msg = this.get(id)
+ var output = $(document.createElement("div"))
+ var head = false
+
+ if (type == "execute_reply") {
+ if (json.content.payload.length > 0) {
+ for (var i in json.content.payload)
+ output.append(procPayload(json.content.payload[i]))
+ }
+ this.get().activate()
+ } else if (type == "pyin") {
+ if (json.content.code != "") {
+ msg.setInput(json.content.code, true)
+ kernhistory.append(json.content.code)
+ }
+ } else if (type == "stream") {
+ output.append(fixConsole(json.content.data))
+ } else if (type == "pyout") {
+ exec_count = json.content.execution_count
+ msg.num = json.content.execution_count
+ output.append(fixConsole(json.content.data))
+ head = true
+ } else if (type == "pyerr") {
+ output.append(fixConsole(json.content.traceback.join("\n")))
+ }
+ if (output.html() != "")
+ msg.setOutput(output, head )
+}
+Manager.prototype.length = function () {
+ return this.ordering.length
+}
+Manager.prototype.getOrder = function(msg) {
+ for (var i = 0; i < this.ordering.length; i++)
+ if (this.ordering[i] == msg)
+ return i
+ //If it's not found, it's probably ondeck, return the last element
+ return this.ordering.length
+}
+
@@ -8,17 +8,9 @@ $(document).ready(function() {
manager = new Manager("messages")
statusbar = new StatusBar("statusbar")
kernhistory = new History("history .inside")
- //Startup POST, set some globals
- $.ajax({
- type: "POST",
- data: {type:"connect"},
- success: function(json, status, request) {
- username = json.parent_header.username
- session = json.header.session
- exec_count = json.content.execution_count
- manager.get().activate()
- }
- })
+ //Startup connection, set some globals
+ //Currently a hack that looks like a messed up execute statement
+ execute(" ")
})
function xmlencode(string) {
Oops, something went wrong.

0 comments on commit a1ed6cd

Please sign in to comment.