##// END OF EJS Templates
alternate notebook upload methods...
Matthias BUSSONNIER -
Show More
@@ -0,0 +1,23 b''
1 /* We need an invisible input field on top of the sentense*/
2 /* "Drag file onto the list ..." */
3
4 .alternate_upload
5 {
6 background-color:none;
7 display: inline;
8 }
9
10 .alternate_upload.form
11 {
12 padding: 0;
13 margin:0;
14 }
15
16 .alternate_upload input.fileinput
17 {
18 background-color:red;
19 position:relative;
20 opacity: 0;
21 z-index: 2;
22 width: 356px;
23 }
@@ -1,267 +1,279 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-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
14 14 var NotebookList = function (selector) {
15 15 this.selector = selector;
16 16 if (this.selector !== undefined) {
17 17 this.element = $(selector);
18 18 this.style();
19 19 this.bind_events();
20 20 }
21 21 };
22 22
23 23 NotebookList.prototype.style = function () {
24 24 $('#notebook_toolbar').addClass('list_toolbar');
25 25 $('#drag_info').addClass('toolbar_info');
26 26 $('#notebook_buttons').addClass('toolbar_buttons');
27 27 $('div#project_name').addClass('list_header ui-widget ui-widget-header');
28 28 $('#refresh_notebook_list').button({
29 29 icons : {primary: 'ui-icon-arrowrefresh-1-s'},
30 30 text : false
31 31 });
32 32 };
33 33
34 34
35 35 NotebookList.prototype.bind_events = function () {
36 36 if (IPython.read_only){
37 37 return;
38 38 }
39 39 var that = this;
40 40 $('#refresh_notebook_list').click(function () {
41 41 that.load_list();
42 42 });
43 43 this.element.bind('dragover', function () {
44 44 return false;
45 45 });
46 this.element.bind('drop', function (event) {
47 var files = event.originalEvent.dataTransfer.files;
48 for (var i = 0, f; f = files[i]; i++) {
49 var reader = new FileReader();
50 reader.readAsText(f);
51 var fname = f.name.split('.');
52 var nbname = fname.slice(0,-1).join('.');
53 var nbformat = fname.slice(-1)[0];
54 if (nbformat === 'ipynb') {nbformat = 'json';};
55 if (nbformat === 'py' || nbformat === 'json') {
56 var item = that.new_notebook_item(0);
57 that.add_name_input(nbname, item);
58 item.data('nbformat', nbformat);
59 // Store the notebook item in the reader so we can use it later
60 // to know which item it belongs to.
61 $(reader).data('item', item);
62 reader.onload = function (event) {
63 var nbitem = $(event.target).data('item');
64 that.add_notebook_data(event.target.result, nbitem);
65 that.add_upload_button(nbitem);
66 };
67 };
68 }
46 this.element.bind('drop', function(event){
47 console.log('bound to drop');
48 that.handelFilesUpload(event,'drop');
69 49 return false;
70 50 });
71 51 };
72 52
53 NotebookList.prototype.handelFilesUpload = function(event, dropOrForm) {
54 var that = this;
55 var files;
56 if(dropOrForm =='drop'){
57 files = event.originalEvent.dataTransfer.files;
58 } else
59 {
60 files = event.originalEvent.target.files
61 }
62 for (var i = 0, f; f = files[i]; i++) {
63 var reader = new FileReader();
64 reader.readAsText(f);
65 var fname = f.name.split('.');
66 var nbname = fname.slice(0,-1).join('.');
67 var nbformat = fname.slice(-1)[0];
68 if (nbformat === 'ipynb') {nbformat = 'json';};
69 if (nbformat === 'py' || nbformat === 'json') {
70 var item = that.new_notebook_item(0);
71 that.add_name_input(nbname, item);
72 item.data('nbformat', nbformat);
73 // Store the notebook item in the reader so we can use it later
74 // to know which item it belongs to.
75 $(reader).data('item', item);
76 reader.onload = function (event) {
77 var nbitem = $(event.target).data('item');
78 that.add_notebook_data(event.target.result, nbitem);
79 that.add_upload_button(nbitem);
80 };
81 };
82 }
83 return false;
84 };
73 85
74 86 NotebookList.prototype.clear_list = function () {
75 87 this.element.children('.list_item').remove();
76 88 }
77 89
78 90
79 91 NotebookList.prototype.load_list = function () {
80 92 this.clear_list();
81 93 var settings = {
82 94 processData : false,
83 95 cache : false,
84 96 type : "GET",
85 97 dataType : "json",
86 98 success : $.proxy(this.list_loaded, this)
87 99 };
88 100 var url = $('body').data('baseProjectUrl') + 'notebooks';
89 101 $.ajax(url, settings);
90 102 };
91 103
92 104
93 105 NotebookList.prototype.list_loaded = function (data, status, xhr) {
94 106 var len = data.length;
95 107 // Todo: remove old children
96 108 for (var i=0; i<len; i++) {
97 109 var notebook_id = data[i].notebook_id;
98 110 var nbname = data[i].name;
99 111 var item = this.new_notebook_item(i);
100 112 this.add_link(notebook_id, nbname, item);
101 113 if (!IPython.read_only){
102 114 // hide delete buttons when readonly
103 115 this.add_delete_button(item);
104 116 }
105 117 };
106 118 };
107 119
108 120
109 121 NotebookList.prototype.new_notebook_item = function (index) {
110 122 var item = $('<div/>');
111 123 item.addClass('list_item ui-widget ui-widget-content ui-helper-clearfix');
112 124 item.css('border-top-style','none');
113 125 var item_name = $('<span/>').addClass('item_name');
114 126
115 127 item.append(item_name);
116 128 if (index === -1) {
117 129 this.element.append(item);
118 130 } else {
119 131 this.element.children().eq(index).after(item);
120 132 }
121 133 return item;
122 134 };
123 135
124 136
125 137 NotebookList.prototype.add_link = function (notebook_id, nbname, item) {
126 138 item.data('nbname', nbname);
127 139 item.data('notebook_id', notebook_id);
128 140 var new_item_name = $('<span/>').addClass('item_name');
129 141 new_item_name.append(
130 142 $('<a/>').
131 143 attr('href', $('body').data('baseProjectUrl')+notebook_id).
132 144 attr('target','_blank').
133 145 text(nbname)
134 146 );
135 147 var e = item.find('.item_name');
136 148 if (e.length === 0) {
137 149 item.append(new_item_name);
138 150 } else {
139 151 e.replaceWith(new_item_name);
140 152 };
141 153 };
142 154
143 155
144 156 NotebookList.prototype.add_name_input = function (nbname, item) {
145 157 item.data('nbname', nbname);
146 158 var new_item_name = $('<span/>').addClass('item_name');
147 159 new_item_name.append(
148 160 $('<input/>').addClass('ui-widget ui-widget-content').
149 161 attr('value', nbname).
150 162 attr('size', '30').
151 163 attr('type', 'text')
152 164 );
153 165 var e = item.find('.item_name');
154 166 if (e.length === 0) {
155 167 item.append(new_item_name);
156 168 } else {
157 169 e.replaceWith(new_item_name);
158 170 };
159 171 };
160 172
161 173
162 174 NotebookList.prototype.add_notebook_data = function (data, item) {
163 175 item.data('nbdata',data);
164 176 };
165 177
166 178
167 179 NotebookList.prototype.add_delete_button = function (item) {
168 180 var new_buttons = $('<span/>').addClass('item_buttons');
169 181 var delete_button = $('<button>Delete</button>').button().
170 182 click(function (e) {
171 183 // $(this) is the button that was clicked.
172 184 var that = $(this);
173 185 // We use the nbname and notebook_id from the parent notebook_item element's
174 186 // data because the outer scopes values change as we iterate through the loop.
175 187 var parent_item = that.parents('div.list_item');
176 188 var nbname = parent_item.data('nbname');
177 189 var notebook_id = parent_item.data('notebook_id');
178 190 var dialog = $('<div/>');
179 191 dialog.html('Are you sure you want to permanently delete the notebook: ' + nbname + '?');
180 192 parent_item.append(dialog);
181 193 dialog.dialog({
182 194 resizable: false,
183 195 modal: true,
184 196 title: "Delete notebook",
185 197 buttons : {
186 198 "Delete": function () {
187 199 var settings = {
188 200 processData : false,
189 201 cache : false,
190 202 type : "DELETE",
191 203 dataType : "json",
192 204 success : function (data, status, xhr) {
193 205 parent_item.remove();
194 206 }
195 207 };
196 208 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
197 209 $.ajax(url, settings);
198 210 $(this).dialog('close');
199 211 },
200 212 "Cancel": function () {
201 213 $(this).dialog('close');
202 214 }
203 215 }
204 216 });
205 217 });
206 218 new_buttons.append(delete_button);
207 219 var e = item.find('.item_buttons');
208 220 if (e.length === 0) {
209 221 item.append(new_buttons);
210 222 } else {
211 223 e.replaceWith(new_buttons);
212 224 };
213 225 };
214 226
215 227
216 228 NotebookList.prototype.add_upload_button = function (item) {
217 229 var that = this;
218 230 var new_buttons = $('<span/>').addClass('item_buttons');
219 231 var upload_button = $('<button>Upload</button>').button().
220 232 click(function (e) {
221 233 var nbname = item.find('.item_name > input').attr('value');
222 234 var nbformat = item.data('nbformat');
223 235 var nbdata = item.data('nbdata');
224 236 var content_type = 'text/plain';
225 237 if (nbformat === 'json') {
226 238 content_type = 'application/json';
227 239 } else if (nbformat === 'py') {
228 240 content_type = 'application/x-python';
229 241 };
230 242 var settings = {
231 243 processData : false,
232 244 cache : false,
233 245 type : 'POST',
234 246 dataType : 'json',
235 247 data : nbdata,
236 248 headers : {'Content-Type': content_type},
237 249 success : function (data, status, xhr) {
238 250 that.add_link(data, nbname, item);
239 251 that.add_delete_button(item);
240 252 }
241 253 };
242 254
243 255 var qs = $.param({name:nbname, format:nbformat});
244 256 var url = $('body').data('baseProjectUrl') + 'notebooks?' + qs;
245 257 $.ajax(url, settings);
246 258 });
247 259 var cancel_button = $('<button>Cancel</button>').button().
248 260 click(function (e) {
249 261 item.remove();
250 262 });
251 263 upload_button.addClass('upload_button');
252 264 new_buttons.append(upload_button).append(cancel_button);
253 265 var e = item.find('.item_buttons');
254 266 if (e.length === 0) {
255 267 item.append(new_buttons);
256 268 } else {
257 269 e.replaceWith(new_buttons);
258 270 };
259 271 };
260 272
261 273
262 274 IPython.NotebookList = NotebookList;
263 275
264 276 return IPython;
265 277
266 278 }(IPython));
267 279
@@ -1,39 +1,42 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-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 // On document ready
10 10 //============================================================================
11 11
12 12
13 13 $(document).ready(function () {
14 14
15 15 IPython.page = new IPython.Page();
16 16
17 17 $('div#tabs').tabs();
18 18 $('div#tabs').on('tabsselect', function (event, ui) {
19 19 var new_url = $('body').data('baseProjectUrl') + '#' + ui.panel.id;
20 20 window.history.replaceState({}, '', new_url);
21 21 });
22 22 $('div#main_app').addClass('border-box-sizing ui-widget');
23 23 $('div#notebooks_toolbar').addClass('ui-widget ui-helper-clearfix');
24 24 $('#new_notebook').button().click(function (e) {
25 25 window.open($('body').data('baseProjectUrl')+'new');
26 26 });
27 27
28 28 IPython.read_only = $('body').data('readOnly') === 'True';
29 29 IPython.notebook_list = new IPython.NotebookList('div#notebook_list');
30 30 IPython.cluster_list = new IPython.ClusterList('div#cluster_list');
31 31 IPython.login_widget = new IPython.LoginWidget('span#login_widget');
32 32
33 33 IPython.notebook_list.load_list();
34 34 IPython.cluster_list.load_list();
35
36 35 IPython.page.show();
37
36
37 // bound the upload method to the on change of the file select list
38 $("#alternate_upload").change(function (event){
39 IPython.notebook_list.handelFilesUpload(event,'form');
40 });
38 41 });
39 42
@@ -1,77 +1,84 b''
1 1 {% extends page.html %}
2 2
3 3 {% block title %}IPython Dashboard{% end %}
4 4
5 5 {% block stylesheet %}
6 6 <link rel="stylesheet" href="{{static_url("css/projectdashboard.css") }}" type="text/css" />
7 <link rel="stylesheet" href="{{static_url("css/alternate_uploadform.css") }}" type="text/css" />
7 8 {% end %}
8 9
9 10
10 11 {% block params %}
11 12
12 13 data-project={{project}}
13 14 data-base-project-url={{base_project_url}}
14 15 data-base-kernel-url={{base_kernel_url}}
15 16 data-read-only={{read_only}}
16 17
17 18 {% end %}
18 19
19 20
20 21 {% block site %}
21 22
22 23 <div id="main_app">
23 24
24 25 <div id="tabs">
25 26 <ul>
26 27 <li><a href="#tab1">Notebooks</a></li>
27 28 <li><a href="#tab2">Clusters</a></li>
28 29 </ul>
29 30
30 31 <div id="tab1">
31 32 {% if logged_in or not read_only %}
32 33 <div id="notebook_toolbar">
33 <span id="drag_info">Drag files onto the list to import
34 notebooks.</span>
34
35 <form id='alternate_upload' action="notebooks" enctype="multipart/form-data" method="post" class='alternate_upload'>
36 <span id="drag_info" style="position:absolute" >Drag files
37 onto the list, or click here, to import
38 notebooks.</span>
39 <input type="file" name="datafile" class="fileinput">
40 </form>
41
35 42
36 43 <span id="notebook_buttons">
37 44 <button id="refresh_notebook_list" title="Refresh notebook list">Refresh</button>
38 45 <button id="new_notebook" title="Create new notebook">New Notebook</button>
39 46 </span>
40 47 </div>
41 48 {% end %}
42 49
43 50 <div id="notebook_list">
44 51 <div id="project_name"><h2>{{project}}</h2></div>
45 52 </div>
46 53 </div>
47 54 <div id="tab2">
48 55
49 56 <div id="cluster_toolbar">
50 57 <span id="cluster_list_info">IPython parallel computing clusters</span>
51 58
52 59 <span id="cluster_buttons">
53 60 <button id="refresh_cluster_list" title="Refresh cluster list">Refresh</button>
54 61 </span>
55 62 </div>
56 63
57 64 <div id="cluster_list">
58 65 <div id="cluster_header">
59 66 <span>profile</span>
60 67 <span>action</span>
61 68 <span title="Enter the number of engines to start or empty for default"># of engines</span>
62 69 <span>status</span>
63 70 </div>
64 71 </div>
65 72
66 73 </div>
67 74 </div>
68 75
69 76 </div>
70 77
71 78 {% end %}
72 79
73 80 {% block script %}
74 81 <script src="{{static_url("js/notebooklist.js") }}" type="text/javascript" charset="utf-8"></script>
75 82 <script src="{{static_url("js/clusterlist.js") }}" type="text/javascript" charset="utf-8"></script>
76 83 <script src="{{static_url("js/projectdashboardmain.js") }}" type="text/javascript" charset="utf-8"></script>
77 84 {% end %}
General Comments 0
You need to be logged in to leave comments. Login now