From ec191df8809c6da463fcc195966afb4fdf872263 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Sun, 10 Mar 2024 15:02:23 +0100 Subject: [PATCH 01/11] Implemented binary transfer to handle emoji and other non-ascii characters. Signed-off-by: ubi de feo --- examples/07_save_file.js | 1 + examples/big_file.py | 2 +- examples/test.py | 2 +- micropython.js | 35 +++++++++++++---------------------- 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/examples/07_save_file.js b/examples/07_save_file.js index c0f806e..5729b0a 100644 --- a/examples/07_save_file.js +++ b/examples/07_save_file.js @@ -4,6 +4,7 @@ let content = ` """ Test """ +# Emoji TEST πŸ’©πŸ€―πŸ«ΆπŸΌ from time import sleep from machine import Pin diff --git a/examples/big_file.py b/examples/big_file.py index f9affdf..8994a6c 100644 --- a/examples/big_file.py +++ b/examples/big_file.py @@ -36,7 +36,7 @@ # When the following number is sampled at four consecutive # even-numbered bits it will have two bits set, but sampling at four # consecutive odd-numbered bits will only yield one bit set. - +# 😌πŸ₯²πŸ™πŸΌπŸ’© _WAVE_MAGIC = 0b0000011100000111 class Stepper: diff --git a/examples/test.py b/examples/test.py index 62f1fe9..a110c7e 100644 --- a/examples/test.py +++ b/examples/test.py @@ -1,7 +1,7 @@ """ Test """ - +# πŸ™πŸΌ from time import sleep print("start OK \r\n") diff --git a/micropython.js b/micropython.js index 1317687..d8959da 100644 --- a/micropython.js +++ b/micropython.js @@ -266,22 +266,17 @@ class MicroPythonBoard { async fs_put(src, dest, data_consumer) { data_consumer = data_consumer || function() {} if (src && dest) { - const contentBuffer = fs.readFileSync(path.resolve(src)) - let contentString = contentBuffer.toString() - contentString = fixLineBreak(contentString) - const hexArray = contentString.split('').map( - c => c.charCodeAt(0).toString(16).padStart(2, '0') - ) + const fileContent = fs.readFileSync(path.resolve(src), 'binary') + const contentBuffer = Buffer.from(fileContent, 'binary') let out = '' out += await this.enter_raw_repl() - out += await this.exec_raw(`f=open('${dest}','w')\nw=f.write`) + out += await this.exec_raw(`f=open('${dest}','wb')\nw=f.write`) const chunkSize = 48 - for (let i = 0; i < hexArray.length; i+= chunkSize) { - let slice = hexArray.slice(i, i+chunkSize) - let bytes = slice.map(h => `0x${h}`) - let line = `w(bytes([${bytes.join(',')}]))` + for (let i = 0; i < contentBuffer.length; i+= chunkSize) { + let slice = Uint8Array.from(contentBuffer.subarray(i, i+chunkSize)) + let line = `w(bytes([${slice}]))` out += await this.exec_raw(line) - data_consumer( parseInt((i / hexArray.length) * 100) + '%') + data_consumer( parseInt((i / contentBuffer.length) * 100) + '%') } out += await this.exec_raw(`f.close()`) out += await this.exit_raw_repl() @@ -293,20 +288,16 @@ class MicroPythonBoard { async fs_save(content, dest, data_consumer) { data_consumer = data_consumer || function() {} if (content && dest) { - let contentString = fixLineBreak(content) - const hexArray = contentString.split('').map( - c => c.charCodeAt(0).toString(16).padStart(2, '0') - ) + const contentBuffer = Buffer.from(content, 'utf-8') let out = '' out += await this.enter_raw_repl() - out += await this.exec_raw(`f=open('${dest}','w')\nw=f.write`) + out += await this.exec_raw(`f=open('${dest}','wb')\nw=f.write`) const chunkSize = 48 - for (let i = 0; i < hexArray.length; i+= chunkSize) { - let slice = hexArray.slice(i, i+chunkSize) - let bytes = slice.map(h => `0x${h}`) - let line = `w(bytes([${bytes.join(',')}]))` + for (let i = 0; i < contentBuffer.length; i+= chunkSize) { + let slice = Uint8Array.from(contentBuffer.subarray(i, i+chunkSize)) + let line = `w(bytes([${slice}]))` out += await this.exec_raw(line) - data_consumer( parseInt((i / hexArray.length) * 100) + '%') + data_consumer( parseInt((i / contentBuffer.length) * 100) + '%') } out += await this.exec_raw(`f.close()`) out += await this.exit_raw_repl() From 1200053178d9be82ec47cbde26d7f1f7fece6f85 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Sun, 10 Mar 2024 15:24:28 +0100 Subject: [PATCH 02/11] Version update to 1.4.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 623bd6c..beab231 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "micropython.js", - "version": "1.4.3", + "version": "1.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "micropython.js", - "version": "1.4.3", + "version": "1.4.4", "dependencies": { "serialport": "^10.4.0" }, diff --git a/package.json b/package.json index b46b237..8f1e408 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "micropython.js", - "version": "1.4.3", + "version": "1.4.4", "description": "Interpretation of pyboard.py in javascript", "main": "micropython.js", "scripts": { From f3e2c58e2138b6fce8f7784f2e65791a8aca4c7b Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Thu, 14 Nov 2024 07:55:05 +0100 Subject: [PATCH 03/11] Tentative: Implemented binary output from fs_cat. Signed-off-by: ubi de feo --- micropython.js | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/micropython.js b/micropython.js index d8959da..bf4b0ca 100644 --- a/micropython.js +++ b/micropython.js @@ -25,6 +25,12 @@ function extract(out) { return out.slice(2, -3) } +function extractBytes(out, cut_before = 2, cut_after = 3) { + bytes = out.slice(cut_before, -cut_after) + bytes = bytes.split(',').map(Number) + return bytes +} + class MicroPythonBoard { constructor() { this.port = null @@ -254,15 +260,28 @@ class MicroPythonBoard { if (filePath) { await this.enter_raw_repl() let output = await this.exec_raw( - `with open('${filePath}','r') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(b,end='')` + `with open('${filePath}','rb') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(",".join(str(e) for e in b),end=',')` ) await this.exit_raw_repl() - output = extract(output) - return Promise.resolve(fixLineBreak(output)) + output = extractBytes(output, 2, 4) + return Promise.resolve((output)) } return Promise.reject(new Error(`Path to file was not specified`)) } + // async fs_cat(filePath) { + // if (filePath) { + // await this.enter_raw_repl() + // let output = await this.exec_raw( + // `with open('${filePath}','r') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(b,end='')` + // ) + // await this.exit_raw_repl() + // output = extract(output) + // return Promise.resolve(fixLineBreak(output)) + // } + // return Promise.reject(new Error(`Path to file was not specified`)) + // } + async fs_put(src, dest, data_consumer) { data_consumer = data_consumer || function() {} if (src && dest) { From ab3070fed89a86ea4fb8374f34bfa7698ef66ea9 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Thu, 14 Nov 2024 13:31:22 +0100 Subject: [PATCH 04/11] Restored the text-based fs_cat method and implemented fs_cat_binary. Signed-off-by: ubi de feo --- micropython.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/micropython.js b/micropython.js index bf4b0ca..173f67b 100644 --- a/micropython.js +++ b/micropython.js @@ -256,7 +256,7 @@ class MicroPythonBoard { return Promise.resolve(files) } - async fs_cat(filePath) { + async fs_cat_binary(filePath) { if (filePath) { await this.enter_raw_repl() let output = await this.exec_raw( @@ -269,18 +269,18 @@ class MicroPythonBoard { return Promise.reject(new Error(`Path to file was not specified`)) } - // async fs_cat(filePath) { - // if (filePath) { - // await this.enter_raw_repl() - // let output = await this.exec_raw( - // `with open('${filePath}','r') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(b,end='')` - // ) - // await this.exit_raw_repl() - // output = extract(output) - // return Promise.resolve(fixLineBreak(output)) - // } - // return Promise.reject(new Error(`Path to file was not specified`)) - // } + async fs_cat(filePath) { + if (filePath) { + await this.enter_raw_repl() + let output = await this.exec_raw( + `with open('${filePath}','r') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(b,end='')` + ) + await this.exit_raw_repl() + output = extract(output) + return Promise.resolve(fixLineBreak(output)) + } + return Promise.reject(new Error(`Path to file was not specified`)) + } async fs_put(src, dest, data_consumer) { data_consumer = data_consumer || function() {} From 3518a3dfde4a92369d7abc42a51894f20584ca63 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Thu, 14 Nov 2024 15:08:33 +0100 Subject: [PATCH 05/11] Bump version to 1.5.0 Signed-off-by: ubi de feo --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8f1e408..e554810 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "micropython.js", - "version": "1.4.4", + "version": "1.5.0", "description": "Interpretation of pyboard.py in javascript", "main": "micropython.js", "scripts": { From 1db1b60361a8505ab23d9e2694d5e0a0b7570005 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Fri, 15 Nov 2024 07:15:18 +0100 Subject: [PATCH 06/11] Updated cli.js getfile method to leverage binary transfer. Signed-off-by: ubi de feo --- cli.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli.js b/cli.js index 124d37a..e7c7c7a 100755 --- a/cli.js +++ b/cli.js @@ -140,7 +140,8 @@ const getFile = (args, port, dataConsumer) => { return board.open(port) .then(async () => { try { - let output = await board.fs_cat(boardFilename, consumer) + let output = await board.fs_cat_binary(boardFilename, consumer) + output = Buffer.from(output); fs.writeFileSync(diskFilename, output) log('output') log(output) From 63a140244f5f88438c92d0893f5aa2f660f3f2c9 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Sat, 7 Dec 2024 08:14:11 +0100 Subject: [PATCH 07/11] Refactored commands. Delete f,w,l leftover symbols. Signed-off-by: ubi de feo --- cli.js | 2 +- micropython.js | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cli.js b/cli.js index e7c7c7a..7a13be2 100755 --- a/cli.js +++ b/cli.js @@ -82,7 +82,7 @@ const executeString = (args, port, dataConsumer) => { const code = args[0] || '' return board.open(port) .then(() => board.enter_raw_repl()) - .then(() => board.exec_raw({ command: code, data_consumer: dataConsumer })) + .then(() => board.exec_raw(code, dataConsumer)) .then(async (out) => { await board.exit_raw_repl() await board.close() diff --git a/micropython.js b/micropython.js index 173f67b..a6418aa 100644 --- a/micropython.js +++ b/micropython.js @@ -210,6 +210,7 @@ class MicroPythonBoard { command += ` print(1)\n` command += `except OSError:\n` command += ` print(0)\n` + command += `del f\n` await this.enter_raw_repl() let output = await this.exec_raw(command) await this.exit_raw_repl() @@ -245,6 +246,7 @@ class MicroPythonBoard { command += ` print(l)\n` command += `except OSError:\n` command += ` print([])\n` + command += `del l\n` await this.enter_raw_repl() let output = await this.exec_raw(command) await this.exit_raw_repl() @@ -259,9 +261,16 @@ class MicroPythonBoard { async fs_cat_binary(filePath) { if (filePath) { await this.enter_raw_repl() - let output = await this.exec_raw( - `with open('${filePath}','rb') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(",".join(str(e) for e in b),end=',')` - ) + const chunkSize = 256 + let command = `with open('${filePath}','rb') as f:\n` + command += ` while 1:\n` + command += ` b=f.read(${chunkSize})\n` + command += ` if not b:break\n` + command += ` print(",".join(str(e) for e in b),end=',')\n` + command += `del f\n` + command += `del b\n` + let output = await this.exec_raw(command) + await this.exit_raw_repl() output = extractBytes(output, 2, 4) return Promise.resolve((output)) @@ -273,7 +282,7 @@ class MicroPythonBoard { if (filePath) { await this.enter_raw_repl() let output = await this.exec_raw( - `with open('${filePath}','r') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(b,end='')` + `with open('${filePath}','r') as f:\n while 1:\n b=f.read(256)\n if not b:break\n print(b,end='')\ndel f\ndel b\n` ) await this.exit_raw_repl() output = extract(output) @@ -297,7 +306,7 @@ class MicroPythonBoard { out += await this.exec_raw(line) data_consumer( parseInt((i / contentBuffer.length) * 100) + '%') } - out += await this.exec_raw(`f.close()`) + out += await this.exec_raw(`f.close()\ndel f\ndel w\n`) out += await this.exit_raw_repl() return Promise.resolve(out) } @@ -318,7 +327,7 @@ class MicroPythonBoard { out += await this.exec_raw(line) data_consumer( parseInt((i / contentBuffer.length) * 100) + '%') } - out += await this.exec_raw(`f.close()`) + out += await this.exec_raw(`f.close()\ndel f\ndel w\n`) out += await this.exit_raw_repl() return Promise.resolve(out) } else { From 2c26a586ec935f6b7f3406f87a21a45b4a4254b3 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Mon, 9 Dec 2024 12:13:17 +0100 Subject: [PATCH 08/11] Removed leftover 'file' and renamed variable to 'f'. Signed-off-by: ubi de feo --- micropython.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/micropython.js b/micropython.js index a6418aa..5bec72b 100644 --- a/micropython.js +++ b/micropython.js @@ -241,12 +241,13 @@ class MicroPythonBoard { let command = `import uos\n` command += `try:\n` command += ` l=[]\n` - command += ` for file in uos.ilistdir("${folderPath}"):\n` - command += ` l.append(list(file))\n` + command += ` for f in uos.ilistdir("${folderPath}"):\n` + command += ` l.append(list(f))\n` command += ` print(l)\n` command += `except OSError:\n` command += ` print([])\n` command += `del l\n` + command += `del f\n` await this.enter_raw_repl() let output = await this.exec_raw(command) await this.exit_raw_repl() From 050d300875153bc551dcfb16b6800cb3ca3a61a4 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Mon, 9 Dec 2024 12:23:01 +0100 Subject: [PATCH 09/11] Updated package version. Signed-off-by: ubi de feo --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index beab231..b5256b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "micropython.js", - "version": "1.4.4", + "version": "1.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "micropython.js", - "version": "1.4.4", + "version": "1.5.1", "dependencies": { "serialport": "^10.4.0" }, diff --git a/package.json b/package.json index e554810..62cae7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "micropython.js", - "version": "1.5.0", + "version": "1.5.1", "description": "Interpretation of pyboard.py in javascript", "main": "micropython.js", "scripts": { From bc4cc1c3a8e8d3a20f65b407e478804613f7d873 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Tue, 10 Dec 2024 07:53:51 +0100 Subject: [PATCH 10/11] Added contribution guidelines. Signed-off-by: ubi de feo --- CONTRIBUTING.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..70880ca --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing to [Project Name] + +This document provides guidelines and instructions for contributing to the project. + + +## Getting Started + +1. Fork the repository +2. Clone your fork: + ```bash + git clone https://github.com/your-username/project-name.git + cd project-name + ``` +3. Create a new branch, be descriptive: + ```bash + git checkout -b feature/your-feature-name + + # OR + + git checkout -b bugfix/bug-this-pr-fixes + + # OR + + git checkout -b docs/documenting-something + ``` + +## Development Workflow + +### Testing + +- Implement your feature/changes +- Test any code changes thoroughly +- Make sure your PR contains all the information for any developer to checkout your branch and validate it + + +### Commit Guidelines (not enforced but nice) + +- Your commit message should be under 72 characters +- Your commit message should start with a topic (e.g.: "Docs: ") +- Sign-off your commits with `git commit -sm "Feature: Commit subject under 72 characters."` + +## Submitting Changes + +1. Push your changes to your fork +2. Submit a pull request towards the `development` branch of this repository +3. Ensure the PR description clearly describes the problem and solution +4. Include the relevant issue number if applicable + +### Pull Request Process + +1. Update documentation if needed: anyone should be able to checkout your branch and validate the changes +2. Add tests for new features +3. Wait for review +4. Upon approval, if you have write access you can merge your PR + +### New version/release (maintainers only) + +The branch `main` is always assumed to be stable, and new versions are created from there. +To create a new version of this module: + +1. Create a new branch from `main` and name it as the new version (e.g.: `v1.5.5`) +1. Update the `"version"` field in `package.json` +1. Run `npm install` to update `package-lock.json` +1. Validate the above +1. Commit and push these changes +1. Open a PR from this new branch to `main` to align version numbers + + +## License + +By contributing, you agree that your contributions will be licensed under the project's license. From 0b44596434a52c0f188050e3ca8f7a6646aa997e Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Tue, 10 Dec 2024 08:09:39 +0100 Subject: [PATCH 11/11] Fixed executeString parameters. Signed-off-by: ubi de feo --- cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli.js b/cli.js index e7c7c7a..7a13be2 100755 --- a/cli.js +++ b/cli.js @@ -82,7 +82,7 @@ const executeString = (args, port, dataConsumer) => { const code = args[0] || '' return board.open(port) .then(() => board.enter_raw_repl()) - .then(() => board.exec_raw({ command: code, data_consumer: dataConsumer })) + .then(() => board.exec_raw(code, dataConsumer)) .then(async (out) => { await board.exit_raw_repl() await board.close()