|
32 | 32 | background: #f0f0f0;
|
33 | 33 | }
|
34 | 34 | */
|
| 35 | + |
| 36 | + .file-box { |
| 37 | + margin: 4px; |
| 38 | + padding: 4px; |
| 39 | + background: #888; |
| 40 | + } |
35 | 41 | </style>
|
36 | 42 | <script src="term.js"></script>
|
| 43 | +<script src="FileSaver.js"></script> |
37 | 44 | </head>
|
38 | 45 | <body>
|
| 46 | + |
| 47 | +<div style="display:inline-block; vertical-align:top;"> |
39 | 48 | <form>
|
40 | 49 | <input type="text" name="webrepl_url" id="url" value="ws://192.168.4.1:8266/" />
|
41 | 50 | <input type="submit" id="button" value="Connect" onclick="button_click(); return false;" />
|
42 |
| -<input type="button" value="Upload" onclick="put_file(); return false;" /> |
43 |
| -<input type="button" value="Download" onclick="get_file(); return false;" /> |
44 | 51 | </form>
|
45 | 52 | <div id="term">
|
46 | 53 | </div>
|
| 54 | +</div> |
| 55 | + |
| 56 | +<div id="file-boxes" style="display:inline-block; vertical-align:top; width:230px;"> |
| 57 | + |
| 58 | + <div class="file-box"> |
| 59 | + <strong>Send a file</strong> |
| 60 | + <input type="file" id="put-file-select" /> |
| 61 | + <div id="put-file-list"></div> |
| 62 | + <input type="button" value="Send to device" id="put-file-button" onclick="put_file(); return false;" /> |
| 63 | + </div> |
| 64 | + |
| 65 | + <div class="file-box"> |
| 66 | + <strong>Get a file</strong> |
| 67 | + <input type="text" name="get_filename" id="get_filename" value="" size="13" /> |
| 68 | + <input type="button" value="Get from device" onclick="get_file(); return false;" /> |
| 69 | + </div> |
| 70 | + |
| 71 | + <div class="file-box" id="file-status"></div> |
| 72 | + |
| 73 | +</div> |
| 74 | + |
47 | 75 | <br clear="both" />
|
48 | 76 | <i>Terminal widget should be focused (text cursor visible) to accept input. Click on it if not.</i><br/>
|
49 | 77 | <i>To paste, press Ctrl+A, then Ctrl+V</i>
|
|
56 | 84 | var ws;
|
57 | 85 | var connected = false;
|
58 | 86 | var binary_state = 0;
|
| 87 | +var put_file_name = null; |
| 88 | +var put_file_data = null; |
| 89 | +var get_file_name = null; |
| 90 | +var get_file_data = null; |
59 | 91 |
|
60 | 92 | function calculate_size(win) {
|
61 |
| - var cols = Math.max(80, Math.min(150, (win.innerWidth - 40) / 7)) | 0; |
| 93 | + var cols = Math.max(80, Math.min(150, (win.innerWidth - 280) / 7)) | 0; |
62 | 94 | var rows = Math.max(24, Math.min(80, (win.innerHeight - 180) / 12)) | 0;
|
63 | 95 | return [cols, rows];
|
64 | 96 | }
|
|
97 | 129 | document.getElementById('button').value = "Connect";
|
98 | 130 | }
|
99 | 131 |
|
| 132 | +function update_file_status(s) { |
| 133 | + document.getElementById('file-status').innerHTML = s; |
| 134 | +} |
| 135 | + |
100 | 136 | function connect(url) {
|
101 | 137 | ws = new WebSocket(url);
|
102 | 138 | ws.binaryType = 'arraybuffer';
|
|
120 | 156 | ws.onmessage = function(event) {
|
121 | 157 | if (event.data instanceof ArrayBuffer) {
|
122 | 158 | var data = new Uint8Array(event.data);
|
123 |
| - console.log('ws data:', data); |
124 | 159 | switch (binary_state) {
|
125 | 160 | case 11:
|
126 | 161 | // first response for put
|
127 | 162 | if (decode_resp(data) == 0) {
|
128 |
| - // send file data |
129 |
| - ws.send(new Uint8Array([64,64,64,64,64,64,64,64,64,10])); |
| 163 | + // send file data in chunks |
| 164 | + for (var offset = 0; offset < put_file_data.length; offset += 1024) { |
| 165 | + ws.send(put_file_data.slice(offset, offset + 1024)); |
| 166 | + } |
130 | 167 | binary_state = 12;
|
131 | 168 | }
|
132 | 169 | break;
|
133 | 170 | case 12:
|
134 | 171 | // final response for put
|
135 | 172 | if (decode_resp(data) == 0) {
|
136 |
| - console.log('success!'); |
| 173 | + update_file_status('Sent ' + put_file_name + ', ' + put_file_data.length + ' bytes'); |
137 | 174 | } else {
|
138 |
| - console.log('fail'); |
| 175 | + update_file_status('Failed sending ' + put_file_name); |
139 | 176 | }
|
140 | 177 | binary_state = 0;
|
141 | 178 | break;
|
|
155 | 192 | // end of file
|
156 | 193 | binary_state = 23;
|
157 | 194 | } else {
|
158 |
| - console.log('file data:', data); |
| 195 | + // accumulate incoming data to get_file_data |
| 196 | + var new_buf = new Uint8Array(get_file_data.length + sz); |
| 197 | + new_buf.set(get_file_data); |
| 198 | + new_buf.set(data.slice(2), get_file_data.length); |
| 199 | + get_file_data = new_buf; |
| 200 | + update_file_status('Getting ' + get_file_name + ', ' + get_file_data.length + ' bytes'); |
159 | 201 | }
|
160 | 202 | } else {
|
161 | 203 | binary_state = 0;
|
|
165 | 207 | case 23:
|
166 | 208 | // final response
|
167 | 209 | if (decode_resp(data) == 0) {
|
168 |
| - console.log('success!'); |
| 210 | + update_file_status('Got ' + get_file_name + ', ' + get_file_data.length + ' bytes'); |
| 211 | + saveAs(new Blob([get_file_data], {type: "application/octet-stream"}), get_file_name); |
169 | 212 | } else {
|
170 |
| - console.log('fail'); |
| 213 | + update_file_status('Failed getting ' + get_file_name); |
171 | 214 | }
|
172 | 215 | binary_state = 0;
|
173 | 216 | break;
|
|
196 | 239 | }
|
197 | 240 |
|
198 | 241 | function put_file() {
|
199 |
| - var dest_fname = 'test2.txt'; |
200 |
| - var dest_fsize = 10; |
| 242 | + var dest_fname = put_file_name; |
| 243 | + var dest_fsize = put_file_data.length; |
201 | 244 |
|
202 | 245 | // WEBREPL_FILE = "<2sBBQLH64s"
|
203 | 246 | var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64);
|
|
218 | 261 |
|
219 | 262 | // initiate put
|
220 | 263 | binary_state = 11;
|
| 264 | + update_file_status('Sending ' + put_file_name + '...'); |
221 | 265 | ws.send(rec);
|
222 | 266 | }
|
223 | 267 |
|
224 | 268 | function get_file() {
|
225 |
| - var src_fname = 'test.txt'; |
| 269 | + var src_fname = document.getElementById('get_filename').value; |
226 | 270 |
|
227 | 271 | // WEBREPL_FILE = "<2sBBQLH64s"
|
228 | 272 | var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64);
|
|
243 | 287 |
|
244 | 288 | // initiate get
|
245 | 289 | binary_state = 21;
|
| 290 | + get_file_name = src_fname; |
| 291 | + get_file_data = new Uint8Array(0); |
| 292 | + update_file_status('Getting ' + get_file_name + '...'); |
246 | 293 | ws.send(rec);
|
247 | 294 | }
|
248 | 295 |
|
| 296 | +function handle_put_file_select(evt) { |
| 297 | + // The event holds a FileList object which is a list of File objects, |
| 298 | + // but we only support single file selection at the moment. |
| 299 | + var files = evt.target.files; |
| 300 | + |
| 301 | + // Get the file info and load its data. |
| 302 | + var f = files[0]; |
| 303 | + put_file_name = f.name; |
| 304 | + var reader = new FileReader(); |
| 305 | + reader.onload = function(e) { |
| 306 | + put_file_data = new Uint8Array(e.target.result); |
| 307 | + document.getElementById('put-file-list').innerHTML = '' + escape(put_file_name) + ' - ' + put_file_data.length + ' bytes'; |
| 308 | + document.getElementById('put-file-button').disabled = false; |
| 309 | + }; |
| 310 | + reader.readAsArrayBuffer(f); |
| 311 | +} |
| 312 | + |
| 313 | +document.getElementById('put-file-select').addEventListener('change', handle_put_file_select, false); |
| 314 | +document.getElementById('put-file-button').disabled = true; |
| 315 | + |
249 | 316 | </script>
|
250 | 317 |
|
251 | 318 | </html>
|
0 commit comments