Support adding OTAs from directory

This commit is contained in:
Koen Kanters
2023-03-21 21:14:25 +01:00
parent 7412eadd46
commit aaab7d0560
+71 -59
View File
@@ -42,7 +42,7 @@ const main = async () => {
} }
const isURL = filenameOrURL.toLowerCase().startsWith("http"); const isURL = filenameOrURL.toLowerCase().startsWith("http");
let file = null; const files = [];
if (isURL) { if (isURL) {
const downloadFile = async (url, path) => { const downloadFile = async (url, path) => {
@@ -67,84 +67,96 @@ const main = async () => {
}); });
} }
file = path.resolve("temp"); const file = path.resolve("temp");
await downloadFile(filenameOrURL, file); await downloadFile(filenameOrURL, file);
files.push(file);
} else { } else {
file = path.resolve(filenameOrURL); const file = path.resolve(filenameOrURL);
if (!fs.existsSync(file)) { if (fs.lstatSync(file).isFile()) {
throw new Error(`${file} does not exist`); if (!fs.existsSync(file)) {
throw new Error(`${file} does not exist`);
}
files.push(file);
} else {
const otaExtension = ['.ota', '.zigbee'];
const otasInDirectory = fs.readdirSync(file)
.filter((f) => otaExtension.includes(path.extname(f).toLowerCase()))
.map((f) => path.join(file, f));
files.push(...otasInDirectory);
} }
} }
const buffer = fs.readFileSync(file); for (const file of files) {
const parsed = ota.parseImage(buffer); const buffer = fs.readFileSync(file);
const parsed = ota.parseImage(buffer);
if (!manufacturerNameLookup[parsed.header.manufacturerCode]) { if (!manufacturerNameLookup[parsed.header.manufacturerCode]) {
throw new Error(`${parsed.header.manufacturerCode} not in manufacturerNameLookup (please add it)`); throw new Error(`${parsed.header.manufacturerCode} not in manufacturerNameLookup (please add it)`);
} }
const manufacturerName = manufacturerNameLookup[parsed.header.manufacturerCode]; const manufacturerName = manufacturerNameLookup[parsed.header.manufacturerCode];
const indexJSON = JSON.parse(fs.readFileSync('index.json')); const indexJSON = JSON.parse(fs.readFileSync('index.json'));
const destination = path.join('images', manufacturerName, path.basename(file)); const destination = path.join('images', manufacturerName, path.basename(file));
const hash = crypto.createHash('sha512'); const hash = crypto.createHash('sha512');
hash.update(buffer); hash.update(buffer);
const entry = { const entry = {
fileVersion: parsed.header.fileVersion, fileVersion: parsed.header.fileVersion,
fileSize: parsed.header.totalImageSize, fileSize: parsed.header.totalImageSize,
manufacturerCode: parsed.header.manufacturerCode, manufacturerCode: parsed.header.manufacturerCode,
imageType: parsed.header.imageType, imageType: parsed.header.imageType,
sha512: hash.digest('hex'), sha512: hash.digest('hex'),
}; };
if (modelId) { if (modelId) {
entry.modelId = modelId; entry.modelId = modelId;
} }
if (isURL) { if (isURL) {
entry.url = filenameOrURL; entry.url = filenameOrURL;
} else { } else {
const destinationPosix = destination.replace(/\\/g, '/'); const destinationPosix = destination.replace(/\\/g, '/');
entry.url = `${baseURL}/${escape(destinationPosix)}`; entry.url = `${baseURL}/${escape(destinationPosix)}`;
entry.path = destinationPosix; entry.path = destinationPosix;
} }
const index = indexJSON.findIndex((i) => { const index = indexJSON.findIndex((i) => {
return i.manufacturerCode === entry.manufacturerCode && i.imageType === entry.imageType && (!i.modelId || i.modelId === entry.modelId) return i.manufacturerCode === entry.manufacturerCode && i.imageType === entry.imageType && (!i.modelId || i.modelId === entry.modelId)
}); });
if (index !== -1) { if (index !== -1) {
console.log(`Updated existing entry (${JSON.stringify(entry)})`); console.log(`Updated existing entry (${JSON.stringify(entry)})`);
indexJSON[index] = {...indexJSON[index], ...entry}; indexJSON[index] = {...indexJSON[index], ...entry};
if (entry.path && entry.path !== destination) { if (entry.path && entry.path !== destination) {
try { try {
fs.unlinkSync(path.resolve(entry.path)); fs.unlinkSync(path.resolve(entry.path));
} catch (err) { } catch (err) {
if (err && err.code != 'ENOENT') { if (err && err.code != 'ENOENT') {
console.error("Error in call to fs.unlink", err); console.error("Error in call to fs.unlink", err);
throw err; throw err;
}
} }
} }
} } else {
} else { console.log(`Added new entry (${JSON.stringify(entry)})`);
console.log(`Added new entry (${JSON.stringify(entry)})`); indexJSON.push(entry);
indexJSON.push(entry);
}
if (!isURL && file !== path.resolve(destination)) {
if (!fs.existsSync(path.dirname(destination))) {
fs.mkdirSync(path.dirname(destination));
} }
fs.copyFileSync(file, destination); if (!isURL && file !== path.resolve(destination)) {
} if (!fs.existsSync(path.dirname(destination))) {
fs.mkdirSync(path.dirname(destination));
}
fs.writeFileSync('index.json', JSON.stringify(indexJSON, null, ' ')); fs.copyFileSync(file, destination);
}
if (isURL) { fs.writeFileSync('index.json', JSON.stringify(indexJSON, null, ' '));
fs.unlinkSync(file);
if (isURL) {
fs.unlinkSync(file);
}
} }
} }