var term; var webreplws; var connected = false; var binary_state = 0; var put_file_name = null; var put_file_data = null; var get_file_name = null; var get_file_data = null; var _filename; sendfile = function () { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } var _codetext = blockpy.components.editor.codeMirror.getValue(); var _arr = blockpy.components.editor.codeMirror.getValue().split("\n"); // _arr.unshift("import gc"); // for (var i = 0; i < _arr.length; i++) { // if (_arr[i].indexOf("import") == -1) { // _arr.splice(i, 0, "gc.enable()"); // _arr.splice(i + 1, 0, "gc.collect()"); // break; // } // } _codetext = _arr.join("\n"); // if (pythonnewcode || Blockly.Python.workspaceToCode(this.blockly)) { // _codetext = pythonnewcode || Blockly.Python.workspaceToCode(this.blockly); // } //web repl 上传 if ($(".select-connected")[0].selectedIndex) { _filename = "python" + Math.round(Math.random() * 100000); $('#runCode')[0].innerHTML = CCB.str_group.uploading; $('#runCode')[0].style.backgroundColor = "d9d9d9"; put_file_data = stringToUint8Array(_codetext); // stringToUint8Array($("#text")[0].innerHTML); put_file_name = _filename + ".py"; put_file(); } //有线上传 else { $('#runCode')[0].innerHTML = CCB.str_group.uploading;//CCB.str_group.uploading; $('#runCode')[0].style.backgroundColor = "d9d9d9"; //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonupload`, { method: 'POST', data: { comname: $("#ports")[0].value, code: _codetext, sid: CCB.socket.id, type: $("#mode")[0].selectedIndex == 1 }, complete: (data) => { //成功之后去除上传中的提示,改成上传成功 $('#runCode')[0].innerHTML = CCB.str_group.run_code; $('#runCode')[0].style.backgroundColor = "#508cf0"; }, error: function (error) { $('#runCode')[0].innerHTML = CCB.str_group.run_code; $('#runCode')[0].style.backgroundColor = "#508cf0"; } }); } } sendstring = function () { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } if ($(".select-connected")[0].selectedIndex) { webreplws.send(data + "/r"); } else { if($("#send_string")[0].className.indexOf("disabled") != -1){ return; } // $('#resetDevice')[0].innerHTML = CCB.str_group.reseting; // $('#resetDevice')[0].style.backgroundColor = "d9d9d9"; $("#refresh-press").css("display","block"); $("#refresh").css("display","none"); // $("#refresh-disabled").css("display","none"); //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonreset`, { method: 'POST', data: { comname: $("#ports")[0].value, sid: CCB.socket.id }, complete: (data) => { //成功之后去除上传中的提示,改成上传成功 // $('#resetDevice')[0].innerHTML = CCB.str_group.reset_device; // $('#resetDevice')[0].style.backgroundColor = "#508cf0"; $("#refresh").css("display","block"); $("#refresh-press").css("display","none"); // $("#refresh-disabled").css("display","none"); }, error: function (error) { // $('#resetDevice')[0].innerHTML = CCB.str_group.reset_device; // $('#resetDevice')[0].style.backgroundColor = "#508cf0"; $("#refresh").css("display","block"); $("#refresh-press").css("display","none"); // $("#refresh-disabled").css("display","none"); } }); } } sendcontent = function (data) { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } if ($(".select-connected")[0].selectedIndex) { webreplws.send(data); } else { //上传中的处理 $.ajax(`${CCB.socket.io.uri}/sendcontent`, { method: 'POST', data: { content: data, sid: CCB.socket.id }, complete: (data) => { }, error: function (error) { } }); } } uploadpyfile = function () { $('#error-btn').css('display', 'none'); var _codetext = blockpy.components.editor.codeMirror.getValue(); if ($(".select-connected")[0].selectedIndex) { } else { $('#uploadFiles')[0].innerHTML = CCB.str_group.uploading; $('#runCuploadFilesode')[0].style.backgroundColor = "d9d9d9"; var path = $("#mode")[0].selectedIndex == 1 ? "sd/user_latest_code.py" : "user_latest_code.py"; //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonuploadfile`, { method: 'POST', data: { comname: $("#ports")[0].value, code: _codetext, sid: CCB.socket.id, name: path }, complete: (data) => { //成功之后去除上传中的提示,改成上传成功 $('#uploadFiles')[0].innerHTML = Ardublockly.LOCALISED_TEXT.uploadFiles; $('#uploadFiles')[0].style.backgroundColor = "#508cf0"; }, error: function (error) { $('#uploadFiles')[0].innerHTML = Ardublockly.LOCALISED_TEXT.uploadFiles; $('#uploadFiles')[0].style.backgroundColor = "#508cf0"; } }); } } uploadfile = function (type) { $('#error-btn').css('display', 'none'); var name = $("#mode")[0].selectedIndex == 1 ? "AI" : "IoT"; var path = name + (type ? "模組_開機啓動可視化菜單界面" : "模組_開機運行上次的程式"); readTxt("/src/python/" + path + ".py", function (txt) { var _codetext = txt; //无限模式 if ($(".select-connected")[0].selectedIndex) { } else { path = $("#mode")[0].selectedIndex == 1 ? "sd/main.py" : "boot.py"; var _title = $('#runCuploadFilesode')[0].innerHTML; $('#runCuploadFilesode')[0].innerHTML = CCB.str_group.uploading; $('#runCuploadFilesode')[0].style.backgroundColor = "d9d9d9"; //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythonuploadfile`, { method: 'POST', data: { comname: $("#ports")[0].value, code: _codetext, sid: CCB.socket.id, name: path }, complete: (data) => { //成功之后去除上传中的提示,改成上传成功 $('#runCuploadFilesode')[0].innerHTML = _title; $('#runCuploadFilesode')[0].style.backgroundColor = "#508cf0"; }, error: function (error) { $('#runCuploadFilesode')[0].innerHTML = _title; $('#runCuploadFilesode')[0].style.backgroundColor = "#508cf0"; } }); } }); } function pythoncmdselect(path,cb){ pythoncmd(` import os for filename in os.listdir(${path}): print(filename)`,cb); } function pythoncmddel(path,cb){ pythoncmd(` import shutil shutil.rmtree(${path}) `,cb); } function pythoncmd(codetext, cb) { $('#error-btn').css('display', 'none'); if (!(CCB.socket && CCB.socket.id)) { return; } //上传中的处理 $.ajax(`${CCB.socket.io.uri}/pythoncmd`, { method: 'POST', data: { comname: $("#ports")[0].value, code: codetext, sid: CCB.socket.id }, complete: (data) => { cb(data); }, error: function (error) { cb(error); } }); } function stringToUint8Array(str) { var arr = []; for (var i = 0, j = str.length; i < j; ++i) { arr.push(str.charCodeAt(i)); } var tmpUint8Array = new Uint8Array(arr); return tmpUint8Array } function calculate_size(win) { var cols = Math.floor(win.offsetWidth / 12) - 1; var rows = Math.floor(win.offsetHeight / 14); //var cols = Math.max(30, Math.min(30, (win.innerWidth - 280) / 7)) | 0; ///var rows = Math.max(24, Math.min(80, (win.innerHeight - 180) / 12)) | 0; return [cols, rows]; } (function () { window.onload = function () { /* var url = window.location.hash.substring(1); if (url) { document.getElementById('ipAddress').value = 'ws://' + url; } var size = calculate_size($("#term")[0]); term = new Terminal({ cols: size[0], rows: size[1], useStyle: true, screenKeys: true, cursorBlink: false }); term.open(document.getElementById("term")); show_https_warning(); */ }; window.addEventListener('resize', function () { /* var size = calculate_size(self); term.resize(size[0], size[1]); */ }); }).call(this); function show_https_warning() { if (window.location.protocol == 'https:') { var warningDiv = document.createElement('div'); warningDiv.style.cssText = 'background:#f99;padding:5px;margin-bottom:10px;line-height:1.5em;text-align:center'; warningDiv.innerHTML = [ 'At this time, the WebREPL client cannot be accessed over HTTPS connections.', 'Use a HTTP connection, eg. http://micropython.org/webrepl/.', 'Alternatively, download the files from GitHub and run them locally.' ].join('
'); document.body.insertBefore(warningDiv, document.body.childNodes[0]); term.resize(term.cols, term.rows - 7); } } function button_click() { if (connected) { connected = false; prepare_for_connect(); webreplws.close(); } else if (document.getElementById('ipAddress').value) { document.getElementById('ConnectBtn').innerHTML = CCB.str_group.run_code; $('#ConnectBtn')[0].style.backgroundColor = "#508cf0"; document.getElementById('ConnectBtn').innerHTML = CCB.str_group.connection; connect("ws://" + document.getElementById('ipAddress').value + ":8266"); document.getElementById('ipAddress').disabled = true; connected = true; } } function prepare_for_connect() { document.getElementById('ipAddress').disabled = false; document.getElementById('ConnectBtn').style.backgroundColor = "#508cf0"; document.getElementById('ConnectBtn').innerHTML = CCB.str_group.connect; } function update_file_status(s) { console.log(s); //document.getElementById('file-status').innerHTML = s; } function is_news() { } /** * 创建对话框 */ function Alert(c, t) { !t ? t = 3000 : ""; var div = document.createElement("div") div.style.cssText = "padding: 12px 25px 12px 25px;font-size: 16px;max-width:300px;min-width:100px;color: rgba(255,255,255,1);background: rgba(0,0,0,0.75);border-radius: 10px;position: fixed;top:20%;left:0px;right:0px;margin:0px auto;text-align:center; word-break: break-word;z-index:999; "; div.innerHTML = c; document.body.appendChild(div); setTimeout(function () { div.parentNode.removeChild(div); }, t); } function connect(url) { window.location.hash = url.substring(5); webreplws = new WebSocket(url); webreplws.binaryType = 'arraybuffer'; webreplws.onopen = function () { term.removeAllListeners('data'); term.on('data', function (data) { // Pasted data from clipboard will likely contain // LF as EOL chars. data = data.replace(/\n/g, "\r"); webreplws.send(data); }); term.on('title', function (title) { document.title = title; }); term.focus(); term.element.focus(); term.write('\x1b[31mWelcome to MicroPython!\x1b[m\r\n'); webreplws.onmessage = function (event) { if (event.data instanceof ArrayBuffer) { var data = new Uint8Array(event.data); switch (binary_state) { case 11: // first response for put if (decode_resp(data) == 0) { // send file data in chunks for (var offset = 0; offset < put_file_data.length; offset += 1024) { webreplws.send(put_file_data.slice(offset, offset + 1024)); } binary_state = 12; } break; case 12: $('#runCode')[0].innerHTML = CCB.str_group.run_code; $('#runCode')[0].style.backgroundColor = "#508cf0"; // final response for put if (decode_resp(data) == 0) { webreplws.send("import " + _filename); webreplws.send("\r"); update_file_status('Sent ' + put_file_name + ', ' + put_file_data.length + ' bytes'); Alert("上传成功"); } else { update_file_status('Failed sending ' + put_file_name); } binary_state = 0; break; case 21: // first response for get if (decode_resp(data) == 0) { binary_state = 22; var rec = new Uint8Array(1); rec[0] = 0; webreplws.send(rec); } break; case 22: { // file data var sz = data[0] | (data[1] << 8); if (data.length == 2 + sz) { // we assume that the data comes in single chunks if (sz == 0) { // end of file binary_state = 23; } else { // accumulate incoming data to get_file_data var new_buf = new Uint8Array(get_file_data.length + sz); new_buf.set(get_file_data); new_buf.set(data.slice(2), get_file_data.length); get_file_data = new_buf; update_file_status('Getting ' + get_file_name + ', ' + get_file_data.length + ' bytes'); var rec = new Uint8Array(1); rec[0] = 0; webreplws.send(rec); } } else { binary_state = 0; } break; } case 23: // final response if (decode_resp(data) == 0) { update_file_status('Got ' + get_file_name + ', ' + get_file_data.length + ' bytes'); saveAs(new Blob([get_file_data], { type: "application/octet-stream" }), get_file_name); } else { update_file_status('Failed getting ' + get_file_name); } binary_state = 0; break; case 31: // first (and last) response for GET_VER console.log('GET_VER', data); binary_state = 0; break; } } term.write(event.data); if (event.data == "Password: ") { webreplws.send("cocorobo\r"); document.getElementById('ConnectBtn').style.backgroundColor = "#f0505f"; document.getElementById('ConnectBtn').innerHTML = CCB.str_group.disconnect; } }; }; webreplws.onclose = function () { connected = false; if (term) { term.write('\x1b[31mDisconnected\x1b[m\r\n'); } term.off('data'); prepare_for_connect(); } } function decode_resp(data) { if (data[0] == 'W'.charCodeAt(0) && data[1] == 'B'.charCodeAt(0)) { var code = data[2] | (data[3] << 8); return code; } else { return -1; } } function put_file() { var dest_fname = put_file_name; var dest_fsize = put_file_data.length; // WEBREPL_FILE = "<2sBBQLH64s" var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); rec[0] = 'W'.charCodeAt(0); rec[1] = 'A'.charCodeAt(0); rec[2] = 1; // put rec[3] = 0; rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; rec[12] = dest_fsize & 0xff; rec[13] = (dest_fsize >> 8) & 0xff; rec[14] = (dest_fsize >> 16) & 0xff; rec[15] = (dest_fsize >> 24) & 0xff; rec[16] = dest_fname.length & 0xff; rec[17] = (dest_fname.length >> 8) & 0xff; for (var i = 0; i < 64; ++i) { if (i < dest_fname.length) { rec[18 + i] = dest_fname.charCodeAt(i); } else { rec[18 + i] = 0; } } // initiate put binary_state = 11; update_file_status('Sending ' + put_file_name + '...'); webreplws.send(rec); } function get_file(name) { var src_fname = name; //document.getElementById('get_filename').value; // WEBREPL_FILE = "<2sBBQLH64s" var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); rec[0] = 'W'.charCodeAt(0); rec[1] = 'A'.charCodeAt(0); rec[2] = 2; // get rec[3] = 0; rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; rec[12] = 0; rec[13] = 0; rec[14] = 0; rec[15] = 0; rec[16] = src_fname.length & 0xff; rec[17] = (src_fname.length >> 8) & 0xff; for (var i = 0; i < 64; ++i) { if (i < src_fname.length) { rec[18 + i] = src_fname.charCodeAt(i); } else { rec[18 + i] = 0; } } // initiate get binary_state = 21; get_file_name = src_fname; get_file_data = new Uint8Array(0); update_file_status('Getting ' + get_file_name + '...'); webreplws.send(rec); } function get_ver() { // WEBREPL_REQ_S = "<2sBBQLH64s" var rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); rec[0] = 'W'.charCodeAt(0); rec[1] = 'A'.charCodeAt(0); rec[2] = 3; // GET_VER // rest of "rec" is zero // initiate GET_VER binary_state = 31; webreplws.send(rec); } function handle_put_file_select(evt) { // The event holds a FileList object which is a list of File objects, // but we only support single file selection at the moment. var files = evt.target.files; // Get the file info and load its data. var f = files[0]; put_file_name = f.name; var reader = new FileReader(); reader.onload = function (e) { put_file_data = new Uint8Array(e.target.result); document.getElementById('put-file-list').innerHTML = '' + escape(put_file_name) + ' - ' + put_file_data.length + ' bytes'; document.getElementById('put-file-button').disabled = false; }; reader.readAsArrayBuffer(f); } /* document.getElementById('put-file-select').addEventListener('click', function () { this.value = null; }, false); document.getElementById('put-file-select').addEventListener('change', handle_put_file_select, false); document.getElementById('put-file-button').disabled = true; */