##// END OF EJS Templates
Merge pull request #12 from minrk/ipynb...
Brian E. Granger -
r15098:c92a53d1 merge
parent child Browse files
Show More
@@ -1,436 +1,437 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2011 The IPython Development Team
2 // Copyright (C) 2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // NotebookList
9 // NotebookList
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13 "use strict";
13 "use strict";
14
14
15 var utils = IPython.utils;
15 var utils = IPython.utils;
16
16
17 var NotebookList = function (selector) {
17 var NotebookList = function (selector) {
18 this.selector = selector;
18 this.selector = selector;
19 if (this.selector !== undefined) {
19 if (this.selector !== undefined) {
20 this.element = $(selector);
20 this.element = $(selector);
21 this.style();
21 this.style();
22 this.bind_events();
22 this.bind_events();
23 }
23 }
24 this.notebooks_list = [];
24 this.notebooks_list = [];
25 this.sessions = {};
25 this.sessions = {};
26 };
26 };
27
27
28 NotebookList.prototype.baseProjectUrl = function () {
28 NotebookList.prototype.baseProjectUrl = function () {
29 return $('body').data('baseProjectUrl');
29 return $('body').data('baseProjectUrl');
30 };
30 };
31
31
32 NotebookList.prototype.notebookPath = function() {
32 NotebookList.prototype.notebookPath = function() {
33 return $('body').data('notebookPath');
33 return $('body').data('notebookPath');
34 };
34 };
35
35
36 NotebookList.prototype.style = function () {
36 NotebookList.prototype.style = function () {
37 $('#notebook_toolbar').addClass('list_toolbar');
37 $('#notebook_toolbar').addClass('list_toolbar');
38 $('#drag_info').addClass('toolbar_info');
38 $('#drag_info').addClass('toolbar_info');
39 $('#notebook_buttons').addClass('toolbar_buttons');
39 $('#notebook_buttons').addClass('toolbar_buttons');
40 $('#notebook_list_header').addClass('list_header');
40 $('#notebook_list_header').addClass('list_header');
41 this.element.addClass("list_container");
41 this.element.addClass("list_container");
42 };
42 };
43
43
44
44
45 NotebookList.prototype.bind_events = function () {
45 NotebookList.prototype.bind_events = function () {
46 var that = this;
46 var that = this;
47 $('#refresh_notebook_list').click(function () {
47 $('#refresh_notebook_list').click(function () {
48 that.load_list();
48 that.load_list();
49 });
49 });
50 this.element.bind('dragover', function () {
50 this.element.bind('dragover', function () {
51 return false;
51 return false;
52 });
52 });
53 this.element.bind('drop', function(event){
53 this.element.bind('drop', function(event){
54 that.handelFilesUpload(event,'drop');
54 that.handelFilesUpload(event,'drop');
55 return false;
55 return false;
56 });
56 });
57 };
57 };
58
58
59 NotebookList.prototype.handelFilesUpload = function(event, dropOrForm) {
59 NotebookList.prototype.handelFilesUpload = function(event, dropOrForm) {
60 var that = this;
60 var that = this;
61 var files;
61 var files;
62 if(dropOrForm =='drop'){
62 if(dropOrForm =='drop'){
63 files = event.originalEvent.dataTransfer.files;
63 files = event.originalEvent.dataTransfer.files;
64 } else
64 } else
65 {
65 {
66 files = event.originalEvent.target.files;
66 files = event.originalEvent.target.files;
67 }
67 }
68 for (var i = 0; i < files.length; i++) {
68 for (var i = 0; i < files.length; i++) {
69 var f = files[i];
69 var f = files[i];
70 var reader = new FileReader();
70 var reader = new FileReader();
71 reader.readAsText(f);
71 reader.readAsText(f);
72 var name_and_ext = utils.splitext(f.name);
72 var name_and_ext = utils.splitext(f.name);
73 var nbname = name_and_ext[0];
74 var file_ext = name_and_ext[1];
73 var file_ext = name_and_ext[1];
75 if (file_ext === '.ipynb') {
74 if (file_ext === '.ipynb') {
76 var item = that.new_notebook_item(0);
75 var item = that.new_notebook_item(0);
77 that.add_name_input(nbname, item);
76 that.add_name_input(f.name, item);
78 // Store the notebook item in the reader so we can use it later
77 // Store the notebook item in the reader so we can use it later
79 // to know which item it belongs to.
78 // to know which item it belongs to.
80 $(reader).data('item', item);
79 $(reader).data('item', item);
81 reader.onload = function (event) {
80 reader.onload = function (event) {
82 var nbitem = $(event.target).data('item');
81 var nbitem = $(event.target).data('item');
83 that.add_notebook_data(event.target.result, nbitem);
82 that.add_notebook_data(event.target.result, nbitem);
84 that.add_upload_button(nbitem);
83 that.add_upload_button(nbitem);
85 };
84 };
86 } else {
85 } else {
87 var dialog = 'Uploaded notebooks must be .ipynb files';
86 var dialog = 'Uploaded notebooks must be .ipynb files';
88 IPython.dialog.modal({
87 IPython.dialog.modal({
89 title : 'Invalid file type',
88 title : 'Invalid file type',
90 body : dialog,
89 body : dialog,
91 buttons : {'OK' : {'class' : 'btn-primary'}}
90 buttons : {'OK' : {'class' : 'btn-primary'}}
92 });
91 });
93 }
92 }
94 }
93 }
95 // Replace the file input form wth a clone of itself. This is required to
94 // Replace the file input form wth a clone of itself. This is required to
96 // reset the form. Otherwise, if you upload a file, delete it and try to
95 // reset the form. Otherwise, if you upload a file, delete it and try to
97 // upload it again, the changed event won't fire.
96 // upload it again, the changed event won't fire.
98 var form = $('input.fileinput');
97 var form = $('input.fileinput');
99 form.replaceWith(form.clone(true));
98 form.replaceWith(form.clone(true));
100 return false;
99 return false;
101 };
100 };
102
101
103 NotebookList.prototype.clear_list = function () {
102 NotebookList.prototype.clear_list = function () {
104 this.element.children('.list_item').remove();
103 this.element.children('.list_item').remove();
105 };
104 };
106
105
107 NotebookList.prototype.load_sessions = function(){
106 NotebookList.prototype.load_sessions = function(){
108 var that = this;
107 var that = this;
109 var settings = {
108 var settings = {
110 processData : false,
109 processData : false,
111 cache : false,
110 cache : false,
112 type : "GET",
111 type : "GET",
113 dataType : "json",
112 dataType : "json",
114 success : $.proxy(that.sessions_loaded, this)
113 success : $.proxy(that.sessions_loaded, this)
115 };
114 };
116 var url = this.baseProjectUrl() + 'api/sessions';
115 var url = this.baseProjectUrl() + 'api/sessions';
117 $.ajax(url,settings);
116 $.ajax(url,settings);
118 };
117 };
119
118
120
119
121 NotebookList.prototype.sessions_loaded = function(data){
120 NotebookList.prototype.sessions_loaded = function(data){
122 this.sessions = {};
121 this.sessions = {};
123 var len = data.length;
122 var len = data.length;
124 if (len > 0) {
123 if (len > 0) {
125 for (var i=0; i<len; i++) {
124 for (var i=0; i<len; i++) {
126 var nb_path;
125 var nb_path;
127 if (!data[i].notebook.path) {
126 if (!data[i].notebook.path) {
128 nb_path = data[i].notebook.name;
127 nb_path = data[i].notebook.name;
129 }
128 }
130 else {
129 else {
131 nb_path = utils.url_path_join(
130 nb_path = utils.url_path_join(
132 data[i].notebook.path,
131 data[i].notebook.path,
133 data[i].notebook.name
132 data[i].notebook.name
134 );
133 );
135 }
134 }
136 this.sessions[nb_path] = data[i].id;
135 this.sessions[nb_path] = data[i].id;
137 }
136 }
138 }
137 }
139 this.load_list();
138 this.load_list();
140 };
139 };
141
140
142 NotebookList.prototype.load_list = function () {
141 NotebookList.prototype.load_list = function () {
143 var that = this;
142 var that = this;
144 var settings = {
143 var settings = {
145 processData : false,
144 processData : false,
146 cache : false,
145 cache : false,
147 type : "GET",
146 type : "GET",
148 dataType : "json",
147 dataType : "json",
149 success : $.proxy(this.list_loaded, this),
148 success : $.proxy(this.list_loaded, this),
150 error : $.proxy( function(){
149 error : $.proxy( function(){
151 that.list_loaded([], null, null, {msg:"Error connecting to server."});
150 that.list_loaded([], null, null, {msg:"Error connecting to server."});
152 },this)
151 },this)
153 };
152 };
154
153
155 var url = utils.url_join_encode(
154 var url = utils.url_join_encode(
156 this.baseProjectUrl(),
155 this.baseProjectUrl(),
157 'api',
156 'api',
158 'notebooks',
157 'notebooks',
159 this.notebookPath()
158 this.notebookPath()
160 );
159 );
161 $.ajax(url, settings);
160 $.ajax(url, settings);
162 };
161 };
163
162
164
163
165 NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
164 NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
166 var message = 'Notebook list empty.';
165 var message = 'Notebook list empty.';
167 if (param !== undefined && param.msg) {
166 if (param !== undefined && param.msg) {
168 message = param.msg;
167 message = param.msg;
169 }
168 }
170 var item = null;
169 var item = null;
171 var len = data.length;
170 var len = data.length;
172 this.clear_list();
171 this.clear_list();
173 if (len === 0) {
172 if (len === 0) {
174 var item = this.new_notebook_item(0);
173 item = this.new_notebook_item(0);
175 var span12 = item.children().first();
174 var span12 = item.children().first();
176 span12.empty();
175 span12.empty();
177 span12.append($('<div style="margin:auto;text-align:center;color:grey"/>').text(message))
176 span12.append($('<div style="margin:auto;text-align:center;color:grey"/>').text(message));
178 }
177 }
179 var path = this.notebookPath();
178 var path = this.notebookPath();
180 var offset = 0;
179 var offset = 0;
181 if (path !== '') {
180 if (path !== '') {
182 item = this.new_notebook_item(0);
181 item = this.new_notebook_item(0);
183 this.add_dir(path, '..', item);
182 this.add_dir(path, '..', item);
184 offset = 1;
183 offset = 1;
185 }
184 }
186 for (var i=0; i<len; i++) {
185 for (var i=0; i<len; i++) {
187 if (data[i].type === 'directory') {
186 if (data[i].type === 'directory') {
188 var name = data[i].name;
187 var name = data[i].name;
189 item = this.new_notebook_item(i+offset);
188 item = this.new_notebook_item(i+offset);
190 this.add_dir(path, name, item);
189 this.add_dir(path, name, item);
191 } else {
190 } else {
192 var name = data[i].name;
191 var name = data[i].name;
193 var nbname = utils.splitext(name)[0];
194 item = this.new_notebook_item(i+offset);
192 item = this.new_notebook_item(i+offset);
195 this.add_link(path, nbname, item);
193 this.add_link(path, name, item);
196 name = utils.url_path_join(path, name);
194 name = utils.url_path_join(path, name);
197 if(this.sessions[name] === undefined){
195 if(this.sessions[name] === undefined){
198 this.add_delete_button(item);
196 this.add_delete_button(item);
199 } else {
197 } else {
200 this.add_shutdown_button(item,this.sessions[name]);
198 this.add_shutdown_button(item,this.sessions[name]);
201 }
199 }
202 }
200 }
203 }
201 }
204 };
202 };
205
203
206
204
207 NotebookList.prototype.new_notebook_item = function (index) {
205 NotebookList.prototype.new_notebook_item = function (index) {
208 var item = $('<div/>').addClass("list_item").addClass("row-fluid");
206 var item = $('<div/>').addClass("list_item").addClass("row-fluid");
209 // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
207 // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
210 // item.css('border-top-style','none');
208 // item.css('border-top-style','none');
211 item.append($("<div/>").addClass("span12").append(
209 item.append($("<div/>").addClass("span12").append(
212 $('<i/>').addClass('item_icon')
210 $('<i/>').addClass('item_icon')
213 ).append(
211 ).append(
214 $("<a/>").addClass("item_link").append(
212 $("<a/>").addClass("item_link").append(
215 $("<span/>").addClass("item_name")
213 $("<span/>").addClass("item_name")
216 )
214 )
217 ).append(
215 ).append(
218 $('<div/>').addClass("item_buttons btn-group pull-right")
216 $('<div/>').addClass("item_buttons btn-group pull-right")
219 ));
217 ));
220
218
221 if (index === -1) {
219 if (index === -1) {
222 this.element.append(item);
220 this.element.append(item);
223 } else {
221 } else {
224 this.element.children().eq(index).after(item);
222 this.element.children().eq(index).after(item);
225 }
223 }
226 return item;
224 return item;
227 };
225 };
228
226
229
227
230 NotebookList.prototype.add_dir = function (path, name, item) {
228 NotebookList.prototype.add_dir = function (path, name, item) {
231 item.data('name', name);
229 item.data('name', name);
232 item.data('path', path);
230 item.data('path', path);
233 item.find(".item_name").text(name);
231 item.find(".item_name").text(name);
234 item.find(".item_icon").addClass('icon-folder-open');
232 item.find(".item_icon").addClass('icon-folder-open');
235 item.find("a.item_link")
233 item.find("a.item_link")
236 .attr('href',
234 .attr('href',
237 utils.url_join_encode(
235 utils.url_join_encode(
238 this.baseProjectUrl(),
236 this.baseProjectUrl(),
239 "tree",
237 "tree",
240 path,
238 path,
241 name
239 name
242 )
240 )
243 );
241 );
244 };
242 };
245
243
246
244
247 NotebookList.prototype.add_link = function (path, nbname, item) {
245 NotebookList.prototype.add_link = function (path, nbname, item) {
248 item.data('nbname', nbname);
246 item.data('nbname', nbname);
249 item.data('path', path);
247 item.data('path', path);
250 item.find(".item_name").text(nbname + '.ipynb');
248 item.find(".item_name").text(nbname);
251 item.find(".item_icon").addClass('icon-book');
249 item.find(".item_icon").addClass('icon-book');
252 item.find("a.item_link")
250 item.find("a.item_link")
253 .attr('href',
251 .attr('href',
254 utils.url_join_encode(
252 utils.url_join_encode(
255 this.baseProjectUrl(),
253 this.baseProjectUrl(),
256 "notebooks",
254 "notebooks",
257 path,
255 path,
258 nbname + ".ipynb"
256 nbname
259 )
257 )
260 ).attr('target','_blank');
258 ).attr('target','_blank');
261 };
259 };
262
260
263
261
264 NotebookList.prototype.add_name_input = function (nbname, item) {
262 NotebookList.prototype.add_name_input = function (nbname, item) {
265 item.data('nbname', nbname);
263 item.data('nbname', nbname);
266 item.find(".item_icon").addClass('icon-book');
264 item.find(".item_icon").addClass('icon-book');
267 item.find(".item_name").empty().append(
265 item.find(".item_name").empty().append(
268 $('<input/>')
266 $('<input/>')
269 .addClass("nbname_input")
267 .addClass("nbname_input")
270 .attr('value', nbname)
268 .attr('value', utils.splitext(nbname)[0])
271 .attr('size', '30')
269 .attr('size', '30')
272 .attr('type', 'text')
270 .attr('type', 'text')
273 );
271 );
274 };
272 };
275
273
276
274
277 NotebookList.prototype.add_notebook_data = function (data, item) {
275 NotebookList.prototype.add_notebook_data = function (data, item) {
278 item.data('nbdata', data);
276 item.data('nbdata', data);
279 };
277 };
280
278
281
279
282 NotebookList.prototype.add_shutdown_button = function (item, session) {
280 NotebookList.prototype.add_shutdown_button = function (item, session) {
283 var that = this;
281 var that = this;
284 var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-mini btn-danger").
282 var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-mini btn-danger").
285 click(function (e) {
283 click(function (e) {
286 var settings = {
284 var settings = {
287 processData : false,
285 processData : false,
288 cache : false,
286 cache : false,
289 type : "DELETE",
287 type : "DELETE",
290 dataType : "json",
288 dataType : "json",
291 success : function () {
289 success : function () {
292 that.load_sessions();
290 that.load_sessions();
293 }
291 }
294 };
292 };
295 var url = utils.url_join_encode(
293 var url = utils.url_join_encode(
296 that.baseProjectUrl(),
294 that.baseProjectUrl(),
297 'api/sessions',
295 'api/sessions',
298 session
296 session
299 );
297 );
300 $.ajax(url, settings);
298 $.ajax(url, settings);
301 return false;
299 return false;
302 });
300 });
303 // var new_buttons = item.find('a'); // shutdown_button;
301 // var new_buttons = item.find('a'); // shutdown_button;
304 item.find(".item_buttons").text("").append(shutdown_button);
302 item.find(".item_buttons").text("").append(shutdown_button);
305 };
303 };
306
304
307 NotebookList.prototype.add_delete_button = function (item) {
305 NotebookList.prototype.add_delete_button = function (item) {
308 var new_buttons = $('<span/>').addClass("btn-group pull-right");
306 var new_buttons = $('<span/>').addClass("btn-group pull-right");
309 var notebooklist = this;
307 var notebooklist = this;
310 var delete_button = $("<button/>").text("Delete").addClass("btn btn-mini").
308 var delete_button = $("<button/>").text("Delete").addClass("btn btn-mini").
311 click(function (e) {
309 click(function (e) {
312 // $(this) is the button that was clicked.
310 // $(this) is the button that was clicked.
313 var that = $(this);
311 var that = $(this);
314 // We use the nbname and notebook_id from the parent notebook_item element's
312 // We use the nbname and notebook_id from the parent notebook_item element's
315 // data because the outer scopes values change as we iterate through the loop.
313 // data because the outer scopes values change as we iterate through the loop.
316 var parent_item = that.parents('div.list_item');
314 var parent_item = that.parents('div.list_item');
317 var nbname = parent_item.data('nbname');
315 var nbname = parent_item.data('nbname');
318 var message = 'Are you sure you want to permanently delete the notebook: ' + nbname + '?';
316 var message = 'Are you sure you want to permanently delete the notebook: ' + nbname + '?';
319 IPython.dialog.modal({
317 IPython.dialog.modal({
320 title : "Delete notebook",
318 title : "Delete notebook",
321 body : message,
319 body : message,
322 buttons : {
320 buttons : {
323 Delete : {
321 Delete : {
324 class: "btn-danger",
322 class: "btn-danger",
325 click: function() {
323 click: function() {
326 var settings = {
324 var settings = {
327 processData : false,
325 processData : false,
328 cache : false,
326 cache : false,
329 type : "DELETE",
327 type : "DELETE",
330 dataType : "json",
328 dataType : "json",
331 success : function (data, status, xhr) {
329 success : function (data, status, xhr) {
332 parent_item.remove();
330 parent_item.remove();
333 }
331 }
334 };
332 };
335 var url = utils.url_join_encode(
333 var url = utils.url_join_encode(
336 notebooklist.baseProjectUrl(),
334 notebooklist.baseProjectUrl(),
337 'api/notebooks',
335 'api/notebooks',
338 notebooklist.notebookPath(),
336 notebooklist.notebookPath(),
339 nbname + '.ipynb'
337 nbname
340 );
338 );
341 $.ajax(url, settings);
339 $.ajax(url, settings);
342 }
340 }
343 },
341 },
344 Cancel : {}
342 Cancel : {}
345 }
343 }
346 });
344 });
347 return false;
345 return false;
348 });
346 });
349 item.find(".item_buttons").text("").append(delete_button);
347 item.find(".item_buttons").text("").append(delete_button);
350 };
348 };
351
349
352
350
353 NotebookList.prototype.add_upload_button = function (item) {
351 NotebookList.prototype.add_upload_button = function (item) {
354 var that = this;
352 var that = this;
355 var upload_button = $('<button/>').text("Upload")
353 var upload_button = $('<button/>').text("Upload")
356 .addClass('btn btn-primary btn-mini upload_button')
354 .addClass('btn btn-primary btn-mini upload_button')
357 .click(function (e) {
355 .click(function (e) {
358 var nbname = item.find('.item_name > input').val();
356 var nbname = item.find('.item_name > input').val();
357 if (nbname.slice(nbname.length-6, nbname.length) != ".ipynb") {
358 nbname = nbname + ".ipynb";
359 }
359 var path = that.notebookPath();
360 var path = that.notebookPath();
360 var nbdata = item.data('nbdata');
361 var nbdata = item.data('nbdata');
361 var content_type = 'application/json';
362 var content_type = 'application/json';
362 var model = {
363 var model = {
363 content : JSON.parse(nbdata),
364 content : JSON.parse(nbdata),
364 };
365 };
365 var settings = {
366 var settings = {
366 processData : false,
367 processData : false,
367 cache : false,
368 cache : false,
368 type : 'PUT',
369 type : 'PUT',
369 dataType : 'json',
370 dataType : 'json',
370 data : JSON.stringify(model),
371 data : JSON.stringify(model),
371 headers : {'Content-Type': content_type},
372 headers : {'Content-Type': content_type},
372 success : function (data, status, xhr) {
373 success : function (data, status, xhr) {
373 that.add_link(path, nbname, item);
374 that.add_link(path, nbname, item);
374 that.add_delete_button(item);
375 that.add_delete_button(item);
375 },
376 },
376 error : function (data, status, xhr) {
377 error : function (data, status, xhr) {
377 console.log(data, status);
378 console.log(data, status);
378 }
379 }
379 };
380 };
380
381
381 var url = utils.url_join_encode(
382 var url = utils.url_join_encode(
382 that.baseProjectUrl(),
383 that.baseProjectUrl(),
383 'api/notebooks',
384 'api/notebooks',
384 that.notebookPath(),
385 that.notebookPath(),
385 nbname + '.ipynb'
386 nbname
386 );
387 );
387 $.ajax(url, settings);
388 $.ajax(url, settings);
388 return false;
389 return false;
389 });
390 });
390 var cancel_button = $('<button/>').text("Cancel")
391 var cancel_button = $('<button/>').text("Cancel")
391 .addClass("btn btn-mini")
392 .addClass("btn btn-mini")
392 .click(function (e) {
393 .click(function (e) {
393 console.log('cancel click');
394 console.log('cancel click');
394 item.remove();
395 item.remove();
395 return false;
396 return false;
396 });
397 });
397 item.find(".item_buttons").empty()
398 item.find(".item_buttons").empty()
398 .append(upload_button)
399 .append(upload_button)
399 .append(cancel_button);
400 .append(cancel_button);
400 };
401 };
401
402
402
403
403 NotebookList.prototype.new_notebook = function(){
404 NotebookList.prototype.new_notebook = function(){
404 var path = this.notebookPath();
405 var path = this.notebookPath();
405 var base_project_url = this.baseProjectUrl();
406 var base_project_url = this.baseProjectUrl();
406 var settings = {
407 var settings = {
407 processData : false,
408 processData : false,
408 cache : false,
409 cache : false,
409 type : "POST",
410 type : "POST",
410 dataType : "json",
411 dataType : "json",
411 async : false,
412 async : false,
412 success : function (data, status, xhr) {
413 success : function (data, status, xhr) {
413 var notebook_name = data.name;
414 var notebook_name = data.name;
414 window.open(
415 window.open(
415 utils.url_join_encode(
416 utils.url_join_encode(
416 base_project_url,
417 base_project_url,
417 'notebooks',
418 'notebooks',
418 path,
419 path,
419 notebook_name),
420 notebook_name),
420 '_blank'
421 '_blank'
421 );
422 );
422 }
423 }
423 };
424 };
424 var url = utils.url_join_encode(
425 var url = utils.url_join_encode(
425 base_project_url,
426 base_project_url,
426 'api/notebooks',
427 'api/notebooks',
427 path
428 path
428 );
429 );
429 $.ajax(url, settings);
430 $.ajax(url, settings);
430 };
431 };
431
432
432 IPython.NotebookList = NotebookList;
433 IPython.NotebookList = NotebookList;
433
434
434 return IPython;
435 return IPython;
435
436
436 }(IPython));
437 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now