##// END OF EJS Templates
File list refreshes no longer move the upload filename boxes....
Jeffrey Bush -
Show More
@@ -1,121 +1,115
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 require([
4 require([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/events',
7 'base/js/events',
8 'base/js/page',
8 'base/js/page',
9 'base/js/utils',
9 'base/js/utils',
10 'tree/js/notebooklist',
10 'tree/js/notebooklist',
11 'tree/js/clusterlist',
11 'tree/js/clusterlist',
12 'tree/js/sessionlist',
12 'tree/js/sessionlist',
13 'tree/js/kernellist',
13 'tree/js/kernellist',
14 'auth/js/loginwidget',
14 'auth/js/loginwidget',
15 // only loaded, not used:
15 // only loaded, not used:
16 'jqueryui',
16 'jqueryui',
17 'bootstrap',
17 'bootstrap',
18 'custom/custom',
18 'custom/custom',
19 ], function(
19 ], function(
20 IPython,
20 IPython,
21 $,
21 $,
22 events,
22 events,
23 page,
23 page,
24 utils,
24 utils,
25 notebooklist,
25 notebooklist,
26 clusterlist,
26 clusterlist,
27 sesssionlist,
27 sesssionlist,
28 kernellist,
28 kernellist,
29 loginwidget){
29 loginwidget){
30
30
31 page = new page.Page();
31 page = new page.Page();
32
32
33 var common_options = {
33 var common_options = {
34 base_url: utils.get_body_data("baseUrl"),
34 base_url: utils.get_body_data("baseUrl"),
35 notebook_path: utils.get_body_data("notebookPath"),
35 notebook_path: utils.get_body_data("notebookPath"),
36 };
36 };
37 session_list = new sesssionlist.SesssionList($.extend({
37 session_list = new sesssionlist.SesssionList($.extend({
38 events: events},
38 events: events},
39 common_options));
39 common_options));
40 notebook_list = new notebooklist.NotebookList('#notebook_list', $.extend({
40 notebook_list = new notebooklist.NotebookList('#notebook_list', $.extend({
41 session_list: session_list},
41 session_list: session_list},
42 common_options));
42 common_options));
43 cluster_list = new clusterlist.ClusterList('#cluster_list', common_options);
43 cluster_list = new clusterlist.ClusterList('#cluster_list', common_options);
44 kernel_list = new kernellist.KernelList('#running_list', $.extend({
44 kernel_list = new kernellist.KernelList('#running_list', $.extend({
45 session_list: session_list},
45 session_list: session_list},
46 common_options));
46 common_options));
47 login_widget = new loginwidget.LoginWidget('#login_widget', common_options);
47 login_widget = new loginwidget.LoginWidget('#login_widget', common_options);
48
48
49 $('#new_notebook').click(function (e) {
49 $('#new_notebook').click(function (e) {
50 notebook_list.new_notebook();
50 notebook_list.new_notebook();
51 });
51 });
52
52
53 var interval_id=0;
53 var interval_id=0;
54 // auto refresh every xx secondes, no need to be fast,
54 // auto refresh every xx secondes, no need to be fast,
55 // update is done at least when page get focus
55 // update is done at least when page get focus
56 var time_refresh = 60; // in sec
56 var time_refresh = 60; // in sec
57
57
58 var enable_autorefresh = function(){
58 var enable_autorefresh = function(){
59 //refresh immediately , then start interval
59 //refresh immediately , then start interval
60 if($('.upload_button').length === 0)
60 session_list.load_sessions();
61 {
61 cluster_list.load_list();
62 session_list.load_sessions();
63 cluster_list.load_list();
64 }
65 if (!interval_id){
62 if (!interval_id){
66 interval_id = setInterval(function(){
63 interval_id = setInterval(function(){
67 if($('.upload_button').length === 0)
64 session_list.load_sessions();
68 {
65 cluster_list.load_list();
69 session_list.load_sessions();
70 cluster_list.load_list();
71 }
72 }, time_refresh*1000);
66 }, time_refresh*1000);
73 }
67 }
74 };
68 };
75
69
76 var disable_autorefresh = function(){
70 var disable_autorefresh = function(){
77 clearInterval(interval_id);
71 clearInterval(interval_id);
78 interval_id = 0;
72 interval_id = 0;
79 };
73 };
80
74
81 // stop autorefresh when page lose focus
75 // stop autorefresh when page lose focus
82 $(window).blur(function() {
76 $(window).blur(function() {
83 disable_autorefresh();
77 disable_autorefresh();
84 });
78 });
85
79
86 //re-enable when page get focus back
80 //re-enable when page get focus back
87 $(window).focus(function() {
81 $(window).focus(function() {
88 enable_autorefresh();
82 enable_autorefresh();
89 });
83 });
90
84
91 // finally start it, it will refresh immediately
85 // finally start it, it will refresh immediately
92 enable_autorefresh();
86 enable_autorefresh();
93
87
94 page.show();
88 page.show();
95
89
96 // For backwards compatability.
90 // For backwards compatability.
97 IPython.page = page;
91 IPython.page = page;
98 IPython.notebook_list = notebook_list;
92 IPython.notebook_list = notebook_list;
99 IPython.cluster_list = cluster_list;
93 IPython.cluster_list = cluster_list;
100 IPython.session_list = session_list;
94 IPython.session_list = session_list;
101 IPython.kernel_list = kernel_list;
95 IPython.kernel_list = kernel_list;
102 IPython.login_widget = login_widget;
96 IPython.login_widget = login_widget;
103
97
104 events.trigger('app_initialized.DashboardApp');
98 events.trigger('app_initialized.DashboardApp');
105
99
106 // bound the upload method to the on change of the file select list
100 // bound the upload method to the on change of the file select list
107 $("#alternate_upload").change(function (event){
101 $("#alternate_upload").change(function (event){
108 notebook_list.handleFilesUpload(event,'form');
102 notebook_list.handleFilesUpload(event,'form');
109 });
103 });
110
104
111 // set hash on tab click
105 // set hash on tab click
112 $("#tabs").find("a").click(function() {
106 $("#tabs").find("a").click(function() {
113 window.location.hash = $(this).attr("href");
107 window.location.hash = $(this).attr("href");
114 });
108 });
115
109
116 // load tab if url hash
110 // load tab if url hash
117 if (window.location.hash) {
111 if (window.location.hash) {
118 $("#tabs").find("a[href=" + window.location.hash + "]").click();
112 $("#tabs").find("a[href=" + window.location.hash + "]").click();
119 }
113 }
120
114
121 });
115 });
@@ -1,539 +1,540
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 'base/js/dialog',
8 'base/js/dialog',
9 ], function(IPython, $, utils, dialog) {
9 ], function(IPython, $, utils, dialog) {
10 "use strict";
10 "use strict";
11
11
12 var NotebookList = function (selector, options) {
12 var NotebookList = function (selector, options) {
13 // Constructor
13 // Constructor
14 //
14 //
15 // Parameters:
15 // Parameters:
16 // selector: string
16 // selector: string
17 // options: dictionary
17 // options: dictionary
18 // Dictionary of keyword arguments.
18 // Dictionary of keyword arguments.
19 // session_list: SessionList instance
19 // session_list: SessionList instance
20 // element_name: string
20 // element_name: string
21 // base_url: string
21 // base_url: string
22 // notebook_path: string
22 // notebook_path: string
23 var that = this;
23 var that = this;
24 this.session_list = options.session_list;
24 this.session_list = options.session_list;
25 // allow code re-use by just changing element_name in kernellist.js
25 // allow code re-use by just changing element_name in kernellist.js
26 this.element_name = options.element_name || 'notebook';
26 this.element_name = options.element_name || 'notebook';
27 this.selector = selector;
27 this.selector = selector;
28 if (this.selector !== undefined) {
28 if (this.selector !== undefined) {
29 this.element = $(selector);
29 this.element = $(selector);
30 this.style();
30 this.style();
31 this.bind_events();
31 this.bind_events();
32 }
32 }
33 this.notebooks_list = [];
33 this.notebooks_list = [];
34 this.sessions = {};
34 this.sessions = {};
35 this.base_url = options.base_url || utils.get_body_data("baseUrl");
35 this.base_url = options.base_url || utils.get_body_data("baseUrl");
36 this.notebook_path = options.notebook_path || utils.get_body_data("notebookPath");
36 this.notebook_path = options.notebook_path || utils.get_body_data("notebookPath");
37 if (this.session_list && this.session_list.events) {
37 if (this.session_list && this.session_list.events) {
38 this.session_list.events.on('sessions_loaded.Dashboard',
38 this.session_list.events.on('sessions_loaded.Dashboard',
39 function(e, d) { that.sessions_loaded(d); });
39 function(e, d) { that.sessions_loaded(d); });
40 }
40 }
41 };
41 };
42
42
43 NotebookList.prototype.style = function () {
43 NotebookList.prototype.style = function () {
44 var prefix = '#' + this.element_name;
44 var prefix = '#' + this.element_name;
45 $(prefix + '_toolbar').addClass('list_toolbar');
45 $(prefix + '_toolbar').addClass('list_toolbar');
46 $(prefix + '_list_info').addClass('toolbar_info');
46 $(prefix + '_list_info').addClass('toolbar_info');
47 $(prefix + '_buttons').addClass('toolbar_buttons');
47 $(prefix + '_buttons').addClass('toolbar_buttons');
48 $(prefix + '_list_header').addClass('list_header');
48 $(prefix + '_list_header').addClass('list_header');
49 this.element.addClass("list_container");
49 this.element.addClass("list_container");
50 };
50 };
51
51
52
52
53 NotebookList.prototype.bind_events = function () {
53 NotebookList.prototype.bind_events = function () {
54 var that = this;
54 var that = this;
55 $('#refresh_' + this.element_name + '_list').click(function () {
55 $('#refresh_' + this.element_name + '_list').click(function () {
56 that.load_sessions();
56 that.load_sessions();
57 });
57 });
58 this.element.bind('dragover', function () {
58 this.element.bind('dragover', function () {
59 return false;
59 return false;
60 });
60 });
61 this.element.bind('drop', function(event){
61 this.element.bind('drop', function(event){
62 that.handleFilesUpload(event,'drop');
62 that.handleFilesUpload(event,'drop');
63 return false;
63 return false;
64 });
64 });
65 };
65 };
66
66
67 NotebookList.prototype.handleFilesUpload = function(event, dropOrForm) {
67 NotebookList.prototype.handleFilesUpload = function(event, dropOrForm) {
68 var that = this;
68 var that = this;
69 var files;
69 var files;
70 if(dropOrForm =='drop'){
70 if(dropOrForm =='drop'){
71 files = event.originalEvent.dataTransfer.files;
71 files = event.originalEvent.dataTransfer.files;
72 } else
72 } else
73 {
73 {
74 files = event.originalEvent.target.files;
74 files = event.originalEvent.target.files;
75 }
75 }
76 for (var i = 0; i < files.length; i++) {
76 for (var i = 0; i < files.length; i++) {
77 var f = files[i];
77 var f = files[i];
78 var name_and_ext = utils.splitext(f.name);
78 var name_and_ext = utils.splitext(f.name);
79 var file_ext = name_and_ext[1];
79 var file_ext = name_and_ext[1];
80
80
81 var reader = new FileReader();
81 var reader = new FileReader();
82 if (file_ext === '.ipynb') {
82 if (file_ext === '.ipynb') {
83 reader.readAsText(f);
83 reader.readAsText(f);
84 } else {
84 } else {
85 // read non-notebook files as binary
85 // read non-notebook files as binary
86 reader.readAsArrayBuffer(f);
86 reader.readAsArrayBuffer(f);
87 }
87 }
88 var item = that.new_item(0);
88 var item = that.new_item(0);
89 item.addClass('new-file');
89 item.addClass('new-file');
90 that.add_name_input(f.name, item, file_ext == '.ipynb' ? 'notebook' : 'file');
90 that.add_name_input(f.name, item, file_ext == '.ipynb' ? 'notebook' : 'file');
91 // Store the list item in the reader so we can use it later
91 // Store the list item in the reader so we can use it later
92 // to know which item it belongs to.
92 // to know which item it belongs to.
93 $(reader).data('item', item);
93 $(reader).data('item', item);
94 reader.onload = function (event) {
94 reader.onload = function (event) {
95 var item = $(event.target).data('item');
95 var item = $(event.target).data('item');
96 that.add_file_data(event.target.result, item);
96 that.add_file_data(event.target.result, item);
97 that.add_upload_button(item);
97 that.add_upload_button(item);
98 };
98 };
99 reader.onerror = function (event) {
99 reader.onerror = function (event) {
100 var item = $(event.target).data('item');
100 var item = $(event.target).data('item');
101 var name = item.data('name')
101 var name = item.data('name')
102 item.remove();
102 item.remove();
103 dialog.modal({
103 dialog.modal({
104 title : 'Failed to read file',
104 title : 'Failed to read file',
105 body : "Failed to read file '" + name + "'",
105 body : "Failed to read file '" + name + "'",
106 buttons : {'OK' : { 'class' : 'btn-primary' }}
106 buttons : {'OK' : { 'class' : 'btn-primary' }}
107 });
107 });
108 };
108 };
109 }
109 }
110 // Replace the file input form wth a clone of itself. This is required to
110 // Replace the file input form wth a clone of itself. This is required to
111 // reset the form. Otherwise, if you upload a file, delete it and try to
111 // reset the form. Otherwise, if you upload a file, delete it and try to
112 // upload it again, the changed event won't fire.
112 // upload it again, the changed event won't fire.
113 var form = $('input.fileinput');
113 var form = $('input.fileinput');
114 form.replaceWith(form.clone(true));
114 form.replaceWith(form.clone(true));
115 return false;
115 return false;
116 };
116 };
117
117
118 NotebookList.prototype.clear_list = function (remove_uploads) {
118 NotebookList.prototype.clear_list = function (remove_uploads) {
119 // Clears the navigation tree.
119 // Clears the navigation tree.
120 //
120 //
121 // Parameters
121 // Parameters
122 // remove_uploads: bool=False
122 // remove_uploads: bool=False
123 // Should upload prompts also be removed from the tree.
123 // Should upload prompts also be removed from the tree.
124 if (remove_uploads) {
124 if (remove_uploads) {
125 this.element.children('.list_item').remove();
125 this.element.children('.list_item').remove();
126 } else {
126 } else {
127 this.element.children('.list_item:not(.new-file)').remove();
127 this.element.children('.list_item:not(.new-file)').remove();
128 }
128 }
129 };
129 };
130
130
131 NotebookList.prototype.load_sessions = function(){
131 NotebookList.prototype.load_sessions = function(){
132 this.session_list.load_sessions();
132 this.session_list.load_sessions();
133 };
133 };
134
134
135
135
136 NotebookList.prototype.sessions_loaded = function(data){
136 NotebookList.prototype.sessions_loaded = function(data){
137 this.sessions = data;
137 this.sessions = data;
138 this.load_list();
138 this.load_list();
139 };
139 };
140
140
141 NotebookList.prototype.load_list = function () {
141 NotebookList.prototype.load_list = function () {
142 var that = this;
142 var that = this;
143 var settings = {
143 var settings = {
144 processData : false,
144 processData : false,
145 cache : false,
145 cache : false,
146 type : "GET",
146 type : "GET",
147 dataType : "json",
147 dataType : "json",
148 success : $.proxy(this.list_loaded, this),
148 success : $.proxy(this.list_loaded, this),
149 error : $.proxy( function(xhr, status, error){
149 error : $.proxy( function(xhr, status, error){
150 utils.log_ajax_error(xhr, status, error);
150 utils.log_ajax_error(xhr, status, error);
151 that.list_loaded([], null, null, {msg:"Error connecting to server."});
151 that.list_loaded([], null, null, {msg:"Error connecting to server."});
152 },this)
152 },this)
153 };
153 };
154
154
155 var url = utils.url_join_encode(
155 var url = utils.url_join_encode(
156 this.base_url,
156 this.base_url,
157 'api',
157 'api',
158 'contents',
158 'contents',
159 this.notebook_path
159 this.notebook_path
160 );
160 );
161 $.ajax(url, settings);
161 $.ajax(url, settings);
162 };
162 };
163
163
164
164
165 NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
165 NotebookList.prototype.list_loaded = function (data, status, xhr, param) {
166 var message = 'Notebook list empty.';
166 var message = 'Notebook list empty.';
167 if (param !== undefined && param.msg) {
167 if (param !== undefined && param.msg) {
168 message = param.msg;
168 message = param.msg;
169 }
169 }
170 var item = null;
170 var item = null;
171 var model = null;
171 var model = null;
172 var list = data.content;
172 var list = data.content;
173 var len = list.length;
173 var len = list.length;
174 this.clear_list();
174 this.clear_list();
175 var n_uploads = this.element.children('.list_item').length;
175 if (len === 0) {
176 if (len === 0) {
176 item = this.new_item(0);
177 item = this.new_item(0);
177 var span12 = item.children().first();
178 var span12 = item.children().first();
178 span12.empty();
179 span12.empty();
179 span12.append($('<div style="margin:auto;text-align:center;color:grey"/>').text(message));
180 span12.append($('<div style="margin:auto;text-align:center;color:grey"/>').text(message));
180 }
181 }
181 var path = this.notebook_path;
182 var path = this.notebook_path;
182 var offset = 0;
183 var offset = n_uploads;
183 if (path !== '') {
184 if (path !== '') {
184 item = this.new_item(0);
185 item = this.new_item(offset);
185 model = {
186 model = {
186 type: 'directory',
187 type: 'directory',
187 name: '..',
188 name: '..',
188 path: path,
189 path: path,
189 };
190 };
190 this.add_link(model, item);
191 this.add_link(model, item);
191 offset = 1;
192 offset += 1;
192 }
193 }
193 for (var i=0; i<len; i++) {
194 for (var i=0; i<len; i++) {
194 model = list[i];
195 model = list[i];
195 item = this.new_item(i+offset);
196 item = this.new_item(i+offset);
196 this.add_link(model, item);
197 this.add_link(model, item);
197 }
198 }
198 };
199 };
199
200
200
201
201 NotebookList.prototype.new_item = function (index) {
202 NotebookList.prototype.new_item = function (index) {
202 var item = $('<div/>').addClass("list_item").addClass("row");
203 var item = $('<div/>').addClass("list_item").addClass("row");
203 // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
204 // item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
204 // item.css('border-top-style','none');
205 // item.css('border-top-style','none');
205 item.append($("<div/>").addClass("col-md-12").append(
206 item.append($("<div/>").addClass("col-md-12").append(
206 $('<i/>').addClass('item_icon')
207 $('<i/>').addClass('item_icon')
207 ).append(
208 ).append(
208 $("<a/>").addClass("item_link").append(
209 $("<a/>").addClass("item_link").append(
209 $("<span/>").addClass("item_name")
210 $("<span/>").addClass("item_name")
210 )
211 )
211 ).append(
212 ).append(
212 $('<div/>').addClass("item_buttons btn-group pull-right")
213 $('<div/>').addClass("item_buttons btn-group pull-right")
213 ));
214 ));
214
215
215 if (index === -1) {
216 if (index === -1) {
216 this.element.append(item);
217 this.element.append(item);
217 } else {
218 } else {
218 this.element.children().eq(index).after(item);
219 this.element.children().eq(index).after(item);
219 }
220 }
220 return item;
221 return item;
221 };
222 };
222
223
223
224
224 NotebookList.icons = {
225 NotebookList.icons = {
225 directory: 'folder_icon',
226 directory: 'folder_icon',
226 notebook: 'notebook_icon',
227 notebook: 'notebook_icon',
227 file: 'file_icon',
228 file: 'file_icon',
228 };
229 };
229
230
230 NotebookList.uri_prefixes = {
231 NotebookList.uri_prefixes = {
231 directory: 'tree',
232 directory: 'tree',
232 notebook: 'notebooks',
233 notebook: 'notebooks',
233 file: 'files',
234 file: 'files',
234 };
235 };
235
236
236
237
237 NotebookList.prototype.add_link = function (model, item) {
238 NotebookList.prototype.add_link = function (model, item) {
238 var path = model.path,
239 var path = model.path,
239 name = model.name;
240 name = model.name;
240 item.data('name', name);
241 item.data('name', name);
241 item.data('path', path);
242 item.data('path', path);
242 item.find(".item_name").text(name);
243 item.find(".item_name").text(name);
243 var icon = NotebookList.icons[model.type];
244 var icon = NotebookList.icons[model.type];
244 var uri_prefix = NotebookList.uri_prefixes[model.type];
245 var uri_prefix = NotebookList.uri_prefixes[model.type];
245 item.find(".item_icon").addClass(icon).addClass('icon-fixed-width');
246 item.find(".item_icon").addClass(icon).addClass('icon-fixed-width');
246 var link = item.find("a.item_link")
247 var link = item.find("a.item_link")
247 .attr('href',
248 .attr('href',
248 utils.url_join_encode(
249 utils.url_join_encode(
249 this.base_url,
250 this.base_url,
250 uri_prefix,
251 uri_prefix,
251 path,
252 path,
252 name
253 name
253 )
254 )
254 );
255 );
255 // directory nav doesn't open new tabs
256 // directory nav doesn't open new tabs
256 // files, notebooks do
257 // files, notebooks do
257 if (model.type !== "directory") {
258 if (model.type !== "directory") {
258 link.attr('target','_blank');
259 link.attr('target','_blank');
259 }
260 }
260 var path_name = utils.url_path_join(path, name);
261 var path_name = utils.url_path_join(path, name);
261 if (model.type == 'file') {
262 if (model.type == 'file') {
262 this.add_delete_button(item);
263 this.add_delete_button(item);
263 } else if (model.type == 'notebook') {
264 } else if (model.type == 'notebook') {
264 if(this.sessions[path_name] === undefined){
265 if(this.sessions[path_name] === undefined){
265 this.add_delete_button(item);
266 this.add_delete_button(item);
266 } else {
267 } else {
267 this.add_shutdown_button(item, this.sessions[path_name]);
268 this.add_shutdown_button(item, this.sessions[path_name]);
268 }
269 }
269 }
270 }
270 };
271 };
271
272
272
273
273 NotebookList.prototype.add_name_input = function (name, item, icon_type) {
274 NotebookList.prototype.add_name_input = function (name, item, icon_type) {
274 item.data('name', name);
275 item.data('name', name);
275 item.find(".item_icon").addClass(NotebookList.icons[icon_type]).addClass('icon-fixed-width');
276 item.find(".item_icon").addClass(NotebookList.icons[icon_type]).addClass('icon-fixed-width');
276 item.find(".item_name").empty().append(
277 item.find(".item_name").empty().append(
277 $('<input/>')
278 $('<input/>')
278 .addClass("filename_input")
279 .addClass("filename_input")
279 .attr('value', name)
280 .attr('value', name)
280 .attr('size', '30')
281 .attr('size', '30')
281 .attr('type', 'text')
282 .attr('type', 'text')
282 .keyup(function(event){
283 .keyup(function(event){
283 if(event.keyCode == 13){item.find('.upload_button').click();}
284 if(event.keyCode == 13){item.find('.upload_button').click();}
284 else if(event.keyCode == 27){item.remove();}
285 else if(event.keyCode == 27){item.remove();}
285 })
286 })
286 );
287 );
287 };
288 };
288
289
289
290
290 NotebookList.prototype.add_file_data = function (data, item) {
291 NotebookList.prototype.add_file_data = function (data, item) {
291 item.data('filedata', data);
292 item.data('filedata', data);
292 };
293 };
293
294
294
295
295 NotebookList.prototype.add_shutdown_button = function (item, session) {
296 NotebookList.prototype.add_shutdown_button = function (item, session) {
296 var that = this;
297 var that = this;
297 var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-xs btn-danger").
298 var shutdown_button = $("<button/>").text("Shutdown").addClass("btn btn-xs btn-danger").
298 click(function (e) {
299 click(function (e) {
299 var settings = {
300 var settings = {
300 processData : false,
301 processData : false,
301 cache : false,
302 cache : false,
302 type : "DELETE",
303 type : "DELETE",
303 dataType : "json",
304 dataType : "json",
304 success : function () {
305 success : function () {
305 that.load_sessions();
306 that.load_sessions();
306 },
307 },
307 error : utils.log_ajax_error,
308 error : utils.log_ajax_error,
308 };
309 };
309 var url = utils.url_join_encode(
310 var url = utils.url_join_encode(
310 that.base_url,
311 that.base_url,
311 'api/sessions',
312 'api/sessions',
312 session
313 session
313 );
314 );
314 $.ajax(url, settings);
315 $.ajax(url, settings);
315 return false;
316 return false;
316 });
317 });
317 // var new_buttons = item.find('a'); // shutdown_button;
318 // var new_buttons = item.find('a'); // shutdown_button;
318 item.find(".item_buttons").text("").append(shutdown_button);
319 item.find(".item_buttons").text("").append(shutdown_button);
319 };
320 };
320
321
321 NotebookList.prototype.add_delete_button = function (item) {
322 NotebookList.prototype.add_delete_button = function (item) {
322 var new_buttons = $('<span/>').addClass("btn-group pull-right");
323 var new_buttons = $('<span/>').addClass("btn-group pull-right");
323 var notebooklist = this;
324 var notebooklist = this;
324 var delete_button = $("<button/>").text("Delete").addClass("btn btn-default btn-xs").
325 var delete_button = $("<button/>").text("Delete").addClass("btn btn-default btn-xs").
325 click(function (e) {
326 click(function (e) {
326 // $(this) is the button that was clicked.
327 // $(this) is the button that was clicked.
327 var that = $(this);
328 var that = $(this);
328 // We use the filename from the parent list_item element's
329 // We use the filename from the parent list_item element's
329 // data because the outer scope's values change as we iterate through the loop.
330 // data because the outer scope's values change as we iterate through the loop.
330 var parent_item = that.parents('div.list_item');
331 var parent_item = that.parents('div.list_item');
331 var name = parent_item.data('name');
332 var name = parent_item.data('name');
332 var message = 'Are you sure you want to permanently delete the file: ' + name + '?';
333 var message = 'Are you sure you want to permanently delete the file: ' + name + '?';
333 dialog.modal({
334 dialog.modal({
334 title : "Delete file",
335 title : "Delete file",
335 body : message,
336 body : message,
336 buttons : {
337 buttons : {
337 Delete : {
338 Delete : {
338 class: "btn-danger",
339 class: "btn-danger",
339 click: function() {
340 click: function() {
340 var settings = {
341 var settings = {
341 processData : false,
342 processData : false,
342 cache : false,
343 cache : false,
343 type : "DELETE",
344 type : "DELETE",
344 dataType : "json",
345 dataType : "json",
345 success : function (data, status, xhr) {
346 success : function (data, status, xhr) {
346 parent_item.remove();
347 parent_item.remove();
347 },
348 },
348 error : utils.log_ajax_error,
349 error : utils.log_ajax_error,
349 };
350 };
350 var url = utils.url_join_encode(
351 var url = utils.url_join_encode(
351 notebooklist.base_url,
352 notebooklist.base_url,
352 'api/contents',
353 'api/contents',
353 notebooklist.notebook_path,
354 notebooklist.notebook_path,
354 name
355 name
355 );
356 );
356 $.ajax(url, settings);
357 $.ajax(url, settings);
357 }
358 }
358 },
359 },
359 Cancel : {}
360 Cancel : {}
360 }
361 }
361 });
362 });
362 return false;
363 return false;
363 });
364 });
364 item.find(".item_buttons").text("").append(delete_button);
365 item.find(".item_buttons").text("").append(delete_button);
365 };
366 };
366
367
367
368
368 NotebookList.prototype.add_upload_button = function (item, type) {
369 NotebookList.prototype.add_upload_button = function (item, type) {
369 var that = this;
370 var that = this;
370 var upload_button = $('<button/>').text("Upload")
371 var upload_button = $('<button/>').text("Upload")
371 .addClass('btn btn-primary btn-xs upload_button')
372 .addClass('btn btn-primary btn-xs upload_button')
372 .click(function (e) {
373 .click(function (e) {
373 var path = that.notebook_path;
374 var path = that.notebook_path;
374 var filename = item.find('.item_name > input').val();
375 var filename = item.find('.item_name > input').val();
375 var filedata = item.data('filedata');
376 var filedata = item.data('filedata');
376 var format = 'text';
377 var format = 'text';
377 if (filename.length === 0 || filename[0] === '.') {
378 if (filename.length === 0 || filename[0] === '.') {
378 dialog.modal({
379 dialog.modal({
379 title : 'Invalid file name',
380 title : 'Invalid file name',
380 body : "File names must be at least one character and not start with a dot",
381 body : "File names must be at least one character and not start with a dot",
381 buttons : {'OK' : { 'class' : 'btn-primary' }}
382 buttons : {'OK' : { 'class' : 'btn-primary' }}
382 });
383 });
383 return false;
384 return false;
384 }
385 }
385 if (filedata instanceof ArrayBuffer) {
386 if (filedata instanceof ArrayBuffer) {
386 // base64-encode binary file data
387 // base64-encode binary file data
387 var bytes = '';
388 var bytes = '';
388 var buf = new Uint8Array(filedata);
389 var buf = new Uint8Array(filedata);
389 var nbytes = buf.byteLength;
390 var nbytes = buf.byteLength;
390 for (var i=0; i<nbytes; i++) {
391 for (var i=0; i<nbytes; i++) {
391 bytes += String.fromCharCode(buf[i]);
392 bytes += String.fromCharCode(buf[i]);
392 }
393 }
393 filedata = btoa(bytes);
394 filedata = btoa(bytes);
394 format = 'base64';
395 format = 'base64';
395 }
396 }
396 var model = {
397 var model = {
397 path: path,
398 path: path,
398 name: filename
399 name: filename
399 };
400 };
400
401
401 var name_and_ext = utils.splitext(filename);
402 var name_and_ext = utils.splitext(filename);
402 var file_ext = name_and_ext[1];
403 var file_ext = name_and_ext[1];
403 var content_type;
404 var content_type;
404 if (file_ext === '.ipynb') {
405 if (file_ext === '.ipynb') {
405 model.type = 'notebook';
406 model.type = 'notebook';
406 model.format = 'json';
407 model.format = 'json';
407 try {
408 try {
408 model.content = JSON.parse(filedata);
409 model.content = JSON.parse(filedata);
409 } catch (e) {
410 } catch (e) {
410 dialog.modal({
411 dialog.modal({
411 title : 'Cannot upload invalid Notebook',
412 title : 'Cannot upload invalid Notebook',
412 body : "The error was: " + e,
413 body : "The error was: " + e,
413 buttons : {'OK' : {
414 buttons : {'OK' : {
414 'class' : 'btn-primary',
415 'class' : 'btn-primary',
415 click: function () {
416 click: function () {
416 item.remove();
417 item.remove();
417 }
418 }
418 }}
419 }}
419 });
420 });
420 return false;
421 return false;
421 }
422 }
422 content_type = 'application/json';
423 content_type = 'application/json';
423 } else {
424 } else {
424 model.type = 'file';
425 model.type = 'file';
425 model.format = format;
426 model.format = format;
426 model.content = filedata;
427 model.content = filedata;
427 content_type = 'application/octet-stream';
428 content_type = 'application/octet-stream';
428 }
429 }
429 var filedata = item.data('filedata');
430 var filedata = item.data('filedata');
430
431
431 var settings = {
432 var settings = {
432 processData : false,
433 processData : false,
433 cache : false,
434 cache : false,
434 type : 'PUT',
435 type : 'PUT',
435 data : JSON.stringify(model),
436 data : JSON.stringify(model),
436 headers : {'Content-Type': content_type},
437 headers : {'Content-Type': content_type},
437 success : function (data, status, xhr) {
438 success : function (data, status, xhr) {
438 item.removeClass('new-file');
439 item.removeClass('new-file');
439 that.add_link(model, item);
440 that.add_link(model, item);
440 that.add_delete_button(item);
441 that.add_delete_button(item);
441 that.session_list.load_sessions();
442 that.session_list.load_sessions();
442 },
443 },
443 error : utils.log_ajax_error,
444 error : utils.log_ajax_error,
444 };
445 };
445
446
446 var url = utils.url_join_encode(
447 var url = utils.url_join_encode(
447 that.base_url,
448 that.base_url,
448 'api/contents',
449 'api/contents',
449 that.notebook_path,
450 that.notebook_path,
450 filename
451 filename
451 );
452 );
452
453
453 var exists = false;
454 var exists = false;
454 $.each(that.element.find('.list_item:not(.new-file)'), function(k,v){
455 $.each(that.element.find('.list_item:not(.new-file)'), function(k,v){
455 if ($(v).data('name') === filename) { exists = true; return false; }
456 if ($(v).data('name') === filename) { exists = true; return false; }
456 });
457 });
457 if (exists) {
458 if (exists) {
458 dialog.modal({
459 dialog.modal({
459 title : "Replace file",
460 title : "Replace file",
460 body : 'There is already a file named ' + filename + ', do you want to replace it?',
461 body : 'There is already a file named ' + filename + ', do you want to replace it?',
461 buttons : {
462 buttons : {
462 Overwrite : {
463 Overwrite : {
463 class: "btn-danger",
464 class: "btn-danger",
464 click: function() { $.ajax(url, settings); }
465 click: function() { $.ajax(url, settings); }
465 },
466 },
466 Cancel : {
467 Cancel : {
467 click: function() { item.remove(); }
468 click: function() { item.remove(); }
468 }
469 }
469 }
470 }
470 });
471 });
471 } else {
472 } else {
472 $.ajax(url, settings);
473 $.ajax(url, settings);
473 }
474 }
474
475
475 return false;
476 return false;
476 });
477 });
477 var cancel_button = $('<button/>').text("Cancel")
478 var cancel_button = $('<button/>').text("Cancel")
478 .addClass("btn btn-default btn-xs")
479 .addClass("btn btn-default btn-xs")
479 .click(function (e) {
480 .click(function (e) {
480 item.remove();
481 item.remove();
481 return false;
482 return false;
482 });
483 });
483 item.find(".item_buttons").empty()
484 item.find(".item_buttons").empty()
484 .append(upload_button)
485 .append(upload_button)
485 .append(cancel_button);
486 .append(cancel_button);
486 };
487 };
487
488
488
489
489 NotebookList.prototype.new_notebook = function(){
490 NotebookList.prototype.new_notebook = function(){
490 var path = this.notebook_path;
491 var path = this.notebook_path;
491 var base_url = this.base_url;
492 var base_url = this.base_url;
492 var settings = {
493 var settings = {
493 processData : false,
494 processData : false,
494 cache : false,
495 cache : false,
495 type : "POST",
496 type : "POST",
496 dataType : "json",
497 dataType : "json",
497 async : false,
498 async : false,
498 success : function (data, status, xhr) {
499 success : function (data, status, xhr) {
499 var notebook_name = data.name;
500 var notebook_name = data.name;
500 window.open(
501 window.open(
501 utils.url_join_encode(
502 utils.url_join_encode(
502 base_url,
503 base_url,
503 'notebooks',
504 'notebooks',
504 path,
505 path,
505 notebook_name),
506 notebook_name),
506 '_blank'
507 '_blank'
507 );
508 );
508 },
509 },
509 error : $.proxy(this.new_notebook_failed, this),
510 error : $.proxy(this.new_notebook_failed, this),
510 };
511 };
511 var url = utils.url_join_encode(
512 var url = utils.url_join_encode(
512 base_url,
513 base_url,
513 'api/contents',
514 'api/contents',
514 path
515 path
515 );
516 );
516 $.ajax(url, settings);
517 $.ajax(url, settings);
517 };
518 };
518
519
519
520
520 NotebookList.prototype.new_notebook_failed = function (xhr, status, error) {
521 NotebookList.prototype.new_notebook_failed = function (xhr, status, error) {
521 utils.log_ajax_error(xhr, status, error);
522 utils.log_ajax_error(xhr, status, error);
522 var msg;
523 var msg;
523 if (xhr.responseJSON && xhr.responseJSON.message) {
524 if (xhr.responseJSON && xhr.responseJSON.message) {
524 msg = xhr.responseJSON.message;
525 msg = xhr.responseJSON.message;
525 } else {
526 } else {
526 msg = xhr.statusText;
527 msg = xhr.statusText;
527 }
528 }
528 dialog.modal({
529 dialog.modal({
529 title : 'Creating Notebook Failed',
530 title : 'Creating Notebook Failed',
530 body : "The error was: " + msg,
531 body : "The error was: " + msg,
531 buttons : {'OK' : {'class' : 'btn-primary'}}
532 buttons : {'OK' : {'class' : 'btn-primary'}}
532 });
533 });
533 };
534 };
534
535
535 // Backwards compatability.
536 // Backwards compatability.
536 IPython.NotebookList = NotebookList;
537 IPython.NotebookList = NotebookList;
537
538
538 return {'NotebookList': NotebookList};
539 return {'NotebookList': NotebookList};
539 });
540 });
General Comments 0
You need to be logged in to leave comments. Login now