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