Ver código fonte

Very basic execution of notebooks

Jason Grout 9 anos atrás
pai
commit
33f75e0b40
3 arquivos alterados com 91 adições e 11 exclusões
  1. 1 0
      package.json
  2. 4 0
      src/notebook/plugin.css
  3. 86 11
      src/notebook/plugin.ts

+ 1 - 0
package.json

@@ -6,6 +6,7 @@
   "typings": "lib/index.d.ts",
   "dependencies": {
     "codemirror": "^5.10.0",
+    "jupyter-js-cells": "^0.2.5",
     "jupyter-js-filebrowser": "^0.4.1",
     "jupyter-js-notebook": "^0.3.0",
     "jupyter-js-services": "^0.3.3",

+ 4 - 0
src/notebook/plugin.css

@@ -7,6 +7,10 @@
   min-height: 50px;
 }
 
+.jp-NotebookContainer {
+  overflow: auto;
+}
+
 .jp-NotebookWidget-body {
   padding: 0.5em;
   font-size: 11px;

+ 86 - 11
src/notebook/plugin.ts

@@ -3,7 +3,7 @@
 'use strict';
 
 import {
-  NotebookWidget, NotebookModel, NBData, populateNotebookModel
+  NotebookWidget, NotebookModel, NBData, populateNotebookModel, buildOutputModel, Output
 } from 'jupyter-js-notebook';
 
 import {
@@ -11,9 +11,15 @@ import {
 } from 'phosphor-di';
 
 import {
-  IContentsModel, IContentsManager
+  IContentsModel, IContentsManager,
+  NotebookSessionManager, INotebookSessionManager,
+  INotebookSession, IKernelMessage
 } from 'jupyter-js-services';
 
+import {
+  Panel
+} from 'phosphor-panel';
+
 import {
   IServicesProvider, IFileOpener
 } from '../index';
@@ -26,6 +32,11 @@ import {
   Widget
 } from 'phosphor-widget';
 
+
+import {
+  CodeCellModel, ICellModel, isCodeCell, BaseCellModel
+} from 'jupyter-js-cells';
+
 import './plugin.css';
 
 /**
@@ -40,20 +51,66 @@ export
 function resolve(container: Container): void {
   container.resolve({
     requires: [IServicesProvider, IFileOpener],
-    create: (services, opener) => {
-      let handler = new NotebookFileHandler(services.contentsManager);
+    create: (services: IServicesProvider, opener: IFileOpener) => {
+      let handler = new NotebookFileHandler(services.contentsManager, services.notebookSessionManager);
       opener.register(handler);
     }
   });
 }
 
+export
+class SessionStoreMapping {
+  constructor(services: IServicesProvider) {
+    this.services = services;
+  }
+  public services: IServicesProvider;
+}
+
+function messageToModel(msg: IKernelMessage) {  
+  let m: Output = msg.content;
+  let type = msg.header.msg_type;
+  if (type === 'execute_result') {
+    m.output_type = 'display_data';
+  } else {
+    m.output_type = type;
+  }
+  return buildOutputModel(m);
+}
+
+function executeSelectedCell(model: NotebookModel, session: INotebookSession)  {
+  let cell = model.cells.get(model.selectedCellIndex);
+  if (isCodeCell(cell)) {
+    let exRequest = {
+      code: cell.input.textEditor.text
+    };
+    let output = cell.output;
+    console.log(`executing`, exRequest)
+    let ex = session.kernel.execute(exRequest);
+    output.clear(false);
+    ex.onIOPub = (msg => {
+      // TODO: not getting an execute_result message
+      let model = messageToModel(msg);
+      console.log('iopub', msg);
+      if (model !== void 0) {
+        output.add(model)
+      }
+    });
+    ex.onReply = (msg => {console.log('a', msg)});
+    ex.onDone = (msg => {console.log('b', msg)});    
+  }
+}
 
 /**
  * An implementation of a file handler.
  */
 export
 class NotebookFileHandler extends AbstractFileHandler {
-
+  
+  constructor(contents: IContentsManager, session: INotebookSessionManager) {
+    super(contents);
+    this.session = session;
+  }
+  
   /**
    * Get the list of file extensions supported by the handler.
    */
@@ -73,17 +130,35 @@ class NotebookFileHandler extends AbstractFileHandler {
    */
   protected createWidget(path: string): Widget {
     let model = new NotebookModel();
-    let widget = new NotebookWidget(model);
-    widget.title.text = path.split('/').pop();
-    return widget;
+    let panel = new Panel()
+    let button = new Widget();
+    let b = document.createElement('button');
+    b.appendChild(document.createTextNode('Execute Current Cell'))
+    this.session.startNew({notebookPath: path}).then(s => {
+      b.addEventListener('click', ev=> {
+        executeSelectedCell(model, s);
+      })
+    })
+    button.node.appendChild(b);
+    panel.addChild(button);
+    panel.addChild(new NotebookWidget(model));
+    panel.title.text = path.split('/').pop();
+    panel.addClass('jp-NotebookContainer')
+    return panel;
   }
 
 
-  protected populateWidget(widget: NotebookWidget, model: IContentsModel): Promise<void> {
-    let nbdata: NBData = makedata(model);
-    populateNotebookModel(widget.model, nbdata);
+  /**
+   * Populate the notebook widget with the contents of the notebook.
+   */
+  protected populateWidget(widget: Widget, model: IContentsModel): Promise<void> {
+    let nbData: NBData = makedata(model);
+    let nbWidget: NotebookWidget = ((widget as Panel).childAt(1)) as NotebookWidget;
+    populateNotebookModel(nbWidget.model, nbData);
     return Promise.resolve();
   }
+  
+  session: INotebookSessionManager;
 }
 
 function makedata(a: IContentsModel): NBData {