forked from circuitpython/web-editor
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrepl-file-transfer.js
121 lines (99 loc) · 3.58 KB
/
repl-file-transfer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import {FileOps} from '@adafruit/circuitpython-repl-js';
class FileTransferClient {
constructor(connectionStatusCB, repl) {
this.connectionStatus = connectionStatusCB;
this._dirHandle = null;
this._fileops = new FileOps(repl, false);
this._isReadOnly = null;
}
async readOnly() {
await this._checkConnection();
return this._isReadOnly;
}
async _checkConnection() {
if (!this.connectionStatus(true)) {
throw new Error("Unable to perform file operation. Not Connected.");
}
if (this._isReadOnly === null) {
this._isReadOnly = await this._fileops.isReadOnly();
}
}
async _checkWritable() {
if (await this.readOnly()) {
throw new Error("File System is Read Only.");
}
}
async readFile(path, raw = false) {
await this._checkConnection();
let contents = await this._fileops.readFile(path, raw);
if (contents === null) {
return raw ? null : "";
}
return contents;
}
async writeFile(path, offset, contents, modificationTime, raw = false) {
await this._checkConnection();
await this._checkWritable();
if (!raw) {
let encoder = new TextEncoder();
let same = contents.slice(0, offset);
let different = contents.slice(offset);
offset = encoder.encode(same).byteLength;
contents = encoder.encode(different);
} else if (offset > 0) {
contents = contents.slice(offset);
}
return await this._fileops.writeFile(path, contents, offset, modificationTime, raw);
}
async makeDir(path, modificationTime = Date.now()) {
await this._checkConnection();
await this._checkWritable();
return await this._fileops.makeDir(path, modificationTime);
}
// Returns an array of objects, one object for each file or directory in the given path
async listDir(path) {
await this._checkConnection();
return await this._fileops.listDir(path);
}
// Deletes the file or directory at the given path. Directories must be empty.
async delete(path) {
await this._checkConnection();
await this._checkWritable();
return await this._fileops.delete(path);
}
// Moves the file or directory from oldPath to newPath.
async move(oldPath, newPath) {
await this._checkConnection();
await this._checkWritable();
return await this._fileops.move(oldPath, newPath);
}
async versionInfo() {
// Possibly open /boot_out.txt and read the version info
let versionInfo = {};
console.log("Reading version info");
let bootout = await this.readFile('/boot_out.txt', false);
console.log(bootout);
if (!bootout) {
console.error("Unable to read boot_out.txt");
return null;
}
bootout += "\n";
// Add these items as they are found
const searchItems = {
version: /Adafruit CircuitPython (.*?) on/,
build_date: /on ([0-9]{4}-[0-9]{2}-[0-9]{2});/,
board_name: /; (.*?) with/,
mcu_name: /with (.*?)\r?\n/,
board_id: /Board ID:(.*?)\r?\n/,
uid: /UID:([0-9A-F]{12,16})\r?\n/,
}
for (const [key, regex] of Object.entries(searchItems)) {
const match = bootout.match(regex);
if (match) {
versionInfo[key] = match[1];
}
}
return versionInfo;
}
}
export {FileTransferClient};