plugin.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. 'use strict';
  4. import {
  5. NotebookWidget, NotebookModel, NBData, populateNotebookModel, buildOutputModel, Output
  6. } from 'jupyter-js-notebook';
  7. import {
  8. Container
  9. } from 'phosphor-di';
  10. import {
  11. IContentsModel, IContentsManager,
  12. NotebookSessionManager, INotebookSessionManager,
  13. INotebookSession, IKernelMessage
  14. } from 'jupyter-js-services';
  15. import {
  16. Panel
  17. } from 'phosphor-panel';
  18. import {
  19. IServicesProvider, IFileOpener, IFileHandler
  20. } from '../index';
  21. import {
  22. AbstractFileHandler
  23. } from 'jupyter-js-filebrowser';
  24. import {
  25. Widget
  26. } from 'phosphor-widget';
  27. import {
  28. CodeCellModel, ICellModel, isCodeCell, BaseCellModel
  29. } from 'jupyter-js-cells';
  30. import {
  31. WidgetManager
  32. } from './widgetmanager';
  33. import './plugin.css';
  34. /**
  35. * Register the plugin contributions.
  36. *
  37. * @param container - The di container for type registration.
  38. *
  39. * #### Notes
  40. * This is called automatically when the plugin is loaded.
  41. */
  42. export
  43. function resolve(container: Container): Promise<IFileHandler> {
  44. return container.resolve({
  45. requires: [IServicesProvider, IFileOpener],
  46. create: (services: IServicesProvider, opener: IFileOpener) => {
  47. let handler = new NotebookFileHandler(services.contentsManager, services.notebookSessionManager);
  48. opener.register(handler);
  49. return handler;
  50. }
  51. });
  52. }
  53. export
  54. class SessionStoreMapping {
  55. constructor(services: IServicesProvider) {
  56. this.services = services;
  57. }
  58. public services: IServicesProvider;
  59. }
  60. function messageToModel(msg: IKernelMessage) {
  61. let m: Output = msg.content;
  62. let type = msg.header.msg_type;
  63. if (type === 'execute_result') {
  64. m.output_type = 'display_data';
  65. } else {
  66. m.output_type = type;
  67. }
  68. return buildOutputModel(m);
  69. }
  70. function executeSelectedCell(model: NotebookModel, session: INotebookSession) {
  71. let cell = model.cells.get(model.selectedCellIndex);
  72. if (isCodeCell(cell)) {
  73. let exRequest = {
  74. code: cell.input.textEditor.text,
  75. silent: false,
  76. store_history: true,
  77. stop_on_error: true,
  78. allow_stdin: true
  79. };
  80. let output = cell.output;
  81. console.log(`executing`, exRequest)
  82. let ex = session.kernel.execute(exRequest);
  83. output.clear(false);
  84. ex.onIOPub = (msg => {
  85. // TODO: not getting an execute_result message
  86. let model = messageToModel(msg);
  87. console.log('iopub', msg);
  88. if (model !== void 0) {
  89. output.add(model)
  90. }
  91. });
  92. ex.onReply = (msg => {console.log('a', msg)});
  93. ex.onDone = (msg => {console.log('b', msg)});
  94. }
  95. }
  96. /**
  97. * An implementation of a file handler.
  98. */
  99. export
  100. class NotebookFileHandler extends AbstractFileHandler {
  101. constructor(contents: IContentsManager, session: INotebookSessionManager) {
  102. super(contents);
  103. this.session = session;
  104. }
  105. /**
  106. * Get the list of file extensions supported by the handler.
  107. */
  108. get fileExtensions(): string[] {
  109. return ['.ipynb']
  110. }
  111. /**
  112. * Get file contents given a path.
  113. */
  114. protected getContents(path: string): Promise<IContentsModel> {
  115. return this.manager.get(path, { type: 'notebook' });
  116. }
  117. /**
  118. * Create the widget from an `IContentsModel`.
  119. */
  120. protected createWidget(path: string): Widget {
  121. let model = new NotebookModel();
  122. let panel = new Panel();
  123. let button = new Widget();
  124. let b = document.createElement('button');
  125. b.appendChild(document.createTextNode('Execute Current Cell'))
  126. this.session.startNew({notebookPath: path}).then(s => {
  127. b.addEventListener('click', ev=> {
  128. executeSelectedCell(model, s);
  129. })
  130. s.kernel.commOpened.connect((kernel, msg) => {
  131. // TODO: cast msg to be a comm open message.
  132. let content = msg.content;
  133. if (content.target_name !== 'jupyter.widget') {
  134. return;
  135. }
  136. let comm = kernel.connectToComm('jupyter.widget', content.comm_id);
  137. console.log('comm message', msg);
  138. comm.onMsg = (msg) => {
  139. // TODO: create a widget and hand it the comm
  140. // render the widget to the widget display area
  141. console.log('comm widget message', msg);
  142. }
  143. comm.onClose = (msg) => {
  144. console.log('comm widget close', msg);
  145. }
  146. })
  147. })
  148. button.node.appendChild(b);
  149. let widgetarea = new Widget();
  150. var manager = new WidgetManager(widgetarea.node);
  151. panel.addChild(button);
  152. panel.addChild(widgetarea)
  153. panel.addChild(new NotebookWidget(model));
  154. panel.title.text = path.split('/').pop();
  155. panel.addClass('jp-NotebookContainer')
  156. return panel;
  157. }
  158. /**
  159. * Populate the notebook widget with the contents of the notebook.
  160. */
  161. protected setState(widget: Widget, model: IContentsModel): Promise<void> {
  162. let nbData: NBData = makedata(model);
  163. let nbWidget: NotebookWidget = ((widget as Panel).childAt(2)) as NotebookWidget;
  164. populateNotebookModel(nbWidget.model, nbData);
  165. return Promise.resolve();
  166. }
  167. protected getState(widget: Widget): Promise<IContentsModel> {
  168. return Promise.resolve(void 0);
  169. }
  170. session: INotebookSessionManager;
  171. }
  172. function makedata(a: IContentsModel): NBData {
  173. return {
  174. content: a.content,
  175. name: a.name,
  176. path: a.path
  177. }
  178. }
  179. /**
  180. * Widgets:
  181. * - write my own manager that inserts the widget element in a widget in the output area
  182. * - maybe have a single widget panel at the top of the notebook for starters.
  183. * - register with the comm manager of the kernel
  184. * -
  185. */