Skip to content

Commit bf05716

Browse files
committed
Processing directories, multiple files
1 parent 5a0c8d1 commit bf05716

File tree

5 files changed

+298
-88
lines changed

5 files changed

+298
-88
lines changed

.gitignore

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ node_modules
22
OLD/node_modules
33
out/*
44
output/*
5-
test/*
5+
test*/*
66
temp/*
7-
dev/*
7+
dev/*
8+
imageWorker1.js

btf.js

+86-13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const fsExtra = require('fs-extra');
33
const path = require('path');
44
const { Worker } = require('worker_threads');
55
const util = require('util');
6+
const { exec } = require('child_process');
67

78
const folderPath = './out';
89
const outputFolder = './output';
@@ -123,6 +124,23 @@ async function processWithLimitedWorkers(filePaths, maxWorkers) {
123124
return results;
124125
}
125126

127+
function playSound(times, delay = 500) {
128+
let count = 0;
129+
130+
const interval = setInterval(() => {
131+
exec('powershell -c [System.Media.SystemSounds]::Beep.Play()', (err, stdout, stderr) => {
132+
if (err) {
133+
console.error('Error playing sound:', err);
134+
}
135+
});
136+
137+
count++;
138+
if (count >= times) {
139+
clearInterval(interval);
140+
}
141+
}, delay);
142+
}
143+
126144
async function main() {
127145
try {
128146
const files = fs.readdirSync(folderPath).sort((a, b) =>
@@ -134,35 +152,90 @@ async function main() {
134152

135153
const streamFinished = util.promisify(require('stream').finished);
136154
const extractProgress = createIntermediateProgressOutput('Saving file ->', results.length);
137-
let dataFileStream;
155+
let dataFileStream = null;
156+
157+
for (let index = 0; index < resolvedResults.length; index++) {
158+
const tempFilePath = resolvedResults[index];
159+
let fileContent = fs.readFileSync(tempFilePath);
160+
const identifyFilePath = path.join(tempFolder, `${path.parse(tempFilePath).name}.identify`);
161+
162+
if (fs.existsSync(identifyFilePath)) {
163+
const identifyLines = fs.readFileSync(identifyFilePath, 'utf8').split('\n');
164+
let currentByteOffset = 0;
165+
166+
for (const line of identifyLines) {
167+
if (!line.trim()) continue;
168+
169+
const regex = /^(\d+)-(\d+)\s([A|D])$/;
170+
const match = line.match(regex);
171+
172+
if (!match) continue;
173+
174+
const start = parseInt(match[1], 10);
175+
const end = parseInt(match[2], 10);
176+
const identifier = match[3];
177+
178+
if (identifier === 'A') {
179+
const extractedBytes = fileContent.slice(start, end);
180+
const extractedName = extractedBytes.toString('utf-8').replace(/\0/g, '').trim();
181+
const outputFilePath = path.join(outputFolder, extractedName);
182+
183+
const outputDir = path.dirname(outputFilePath);
184+
fsExtra.ensureDirSync(outputDir);
185+
186+
if (dataFileStream) {
187+
dataFileStream.end();
188+
await streamFinished(dataFileStream);
189+
}
190+
191+
dataFileStream = fs.createWriteStream(outputFilePath);
192+
currentByteOffset = 0;
193+
194+
fileContent = Buffer.concat([
195+
fileContent.slice(0, start),
196+
fileContent.slice(end),
197+
]);
198+
}
138199

139-
resolvedResults.forEach((tempFilePath, index) => {
140-
const fileContent = fs.readFileSync(tempFilePath, 'utf-8');
141-
const nibbles = fileContent.split(' ');
200+
if (identifier === 'D') {
201+
const bytesToWrite = end - currentByteOffset;
202+
const contentToWrite = fileContent.slice(0, bytesToWrite);
142203

143-
const { dataNibbles, nameNibbles } = extractFileData(nibbles);
204+
if (dataFileStream) {
205+
dataFileStream.write(contentToWrite);
206+
currentByteOffset += contentToWrite.length;
207+
dataFileStream.end();
208+
await streamFinished(dataFileStream);
209+
dataFileStream = null;
210+
}
144211

145-
if (nameNibbles.length > 0) {
146-
const extractedName = Buffer.from(nibblesToBytes(nameNibbles)).toString('utf-8').trim();
147-
dataFileStream = fs.createWriteStream(path.join(outputFolder, extractedName));
212+
fileContent = fileContent.slice(bytesToWrite);
213+
}
214+
}
148215
}
149216

150-
dataFileStream.write(Buffer.from(nibblesToBytes(dataNibbles)));
217+
if (dataFileStream) {
218+
dataFileStream.write(fileContent);
219+
fileContent = null;
220+
}
151221

152222
const progressBar = extractProgress(index + 1);
153223
if (progressBar) {
154224
process.stdout.clearLine();
155225
process.stdout.cursorTo(0);
156226
process.stdout.write(progressBar);
157227
}
158-
});
159-
160-
dataFileStream.end();
161-
await streamFinished(dataFileStream);
228+
}
162229

230+
if (dataFileStream) {
231+
dataFileStream.end();
232+
await streamFinished(dataFileStream);
233+
}
163234
} catch (error) {
164235
console.error('Error processing files:', error);
236+
playSound(2, 500);
165237
}
238+
playSound(1);
166239
}
167240

168241
main();

ftb.js

+105-46
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const sharp = require('sharp');
44
const fsExtra = require('fs-extra');
55
const prompt = require('prompt-sync')();
66
const { Worker } = require('worker_threads');
7+
const { exec } = require('child_process');
78

89
const colorMap = {
910
'0000': { r: 255, g: 255, b: 255 },
@@ -95,77 +96,135 @@ function GenerateImagesFromRGBData(width, height, outputDir) {
9596
CreateImageFromArray(paddedChunk, width, height, outputFilePath);
9697
}
9798

98-
function ConvertFileToBinaryStream(filePath, callback) {
99-
if (!fs.existsSync(filePath)) {
100-
throw new Error('File does not exist.');
101-
}
99+
async function ConvertFileToBinaryStream(filePath) {
100+
return new Promise((resolve, reject) => {
101+
if (!fs.existsSync(filePath)) {
102+
reject(new Error('File does not exist.'));
103+
return;
104+
}
102105

103-
const stats = fs.statSync(filePath);
104-
const totalBytes = stats.size;
105-
let processedBytes = 0;
106+
const stats = fs.statSync(filePath);
107+
const totalBytes = stats.size;
108+
let processedBytes = 0;
106109

107-
const progressWorker = new Worker(path.join(__dirname, 'progressWorker.js'));
110+
const progressWorker = new Worker(path.join(__dirname, 'progressWorker.js'));
108111

109-
progressWorker.on('message', (progressBar) => {
110-
process.stdout.clearLine();
111-
process.stdout.cursorTo(0);
112-
process.stdout.write(`Processing: ${progressBar}`);
113-
});
112+
progressWorker.on('message', (progressBar) => {
113+
process.stdout.clearLine();
114+
process.stdout.cursorTo(0);
115+
process.stdout.write(`Processing: ${progressBar}`);
116+
});
114117

115-
const stream = fs.createReadStream(filePath);
118+
const stream = fs.createReadStream(filePath);
116119

117-
stream.on('data', (chunk) => {
118-
const chunkSize = chunk.length;
119-
processedBytes += chunkSize;
120+
stream.on('data', (chunk) => {
121+
const chunkSize = chunk.length;
122+
processedBytes += chunkSize;
120123

121-
const percentage = (processedBytes / totalBytes) * 100;
124+
const percentage = (processedBytes / totalBytes) * 100;
122125

123-
if (Math.round(percentage) % 1 === 0) {
124-
progressWorker.postMessage(Math.round(percentage));
125-
}
126+
if (Math.round(percentage) % 1 === 0) {
127+
progressWorker.postMessage(Math.round(percentage));
128+
}
129+
130+
const binaryData = Array.from(chunk).map(byte => byte.toString(2).padStart(8, '0'));
131+
binaryData.forEach(data => {
132+
const [part1, part2] = SplitByteTo2Nibbles(parseInt(data, 2));
133+
RGBDataArray.push(GetColorFromNibble(part1), GetColorFromNibble(part2));
126134

127-
const binaryData = Array.from(chunk).map(byte => byte.toString(2).padStart(8, '0'));
128-
binaryData.forEach(data => {
129-
const [part1, part2] = SplitByteTo2Nibbles(parseInt(data, 2));
130-
RGBDataArray.push(GetColorFromNibble(part1), GetColorFromNibble(part2));
135+
if (RGBDataArray.length >= imageWidth * imageHeight) {
136+
GenerateImagesFromRGBData(imageWidth, imageHeight, output);
137+
RGBDataArray = [];
138+
}
139+
});
140+
});
131141

132-
if (RGBDataArray.length >= imageWidth * imageHeight) {
142+
stream.on('end', () => {
143+
if (RGBDataArray.length > 0) {
144+
RGBDataArray.push({ r: 128, g: 0, b: 128 });
133145
GenerateImagesFromRGBData(imageWidth, imageHeight, output);
134-
RGBDataArray = [];
135146
}
147+
RGBDataArray = [];
148+
console.log('\nFile reading completed.');
149+
console.timeEnd("Processing Time");
150+
progressWorker.terminate();
151+
resolve(); // Resolve when processing is finished
152+
});
153+
154+
stream.on('error', (err) => {
155+
console.error('Error reading file:', err.message);
156+
reject(err); // Reject if there's an error
136157
});
137158
});
159+
}
138160

139-
stream.on('end', () => {
140-
if (RGBDataArray.length > 0) {
141-
RGBDataArray.push({ r: 128, g: 0, b: 128 });
142-
GenerateImagesFromRGBData(imageWidth, imageHeight, output);
161+
function getAllFiles(dirPath, filesArray = []) {
162+
const files = fs.readdirSync(dirPath);
163+
164+
files.forEach(file => {
165+
const fullPath = path.join(dirPath, file);
166+
if (fs.statSync(fullPath).isDirectory()) {
167+
getAllFiles(fullPath, filesArray); // Recursive call for subdirectories
168+
} else {
169+
filesArray.push(fullPath); // Add full file path to the array
143170
}
144-
console.log('\nFile reading completed.');
145-
console.timeEnd("Processing Time");
146-
progressWorker.terminate();
147171
});
148172

149-
stream.on('error', (err) => console.error('Error reading file:', err.message));
173+
return filesArray;
174+
}
175+
176+
function playSound(times, delay = 500) {
177+
let count = 0;
178+
179+
const interval = setInterval(() => {
180+
exec('powershell -c [System.Media.SystemSounds]::Beep.Play()', (err, stdout, stderr) => {
181+
if (err) {
182+
console.error('Error playing sound:', err);
183+
}
184+
});
185+
186+
count++;
187+
if (count >= times) {
188+
clearInterval(interval);
189+
}
190+
}, delay);
150191
}
151192

152193
// --------------------------------------------------------------
153194

154195
const imageWidth = 1920;
155196
const imageHeight = 1080;
156-
const inputFile = process.argv[2] || prompt("Define input file: ");
157-
const input = path.join(__dirname, inputFile);
197+
const input = process.argv[2] || prompt("Define input file: ");
158198
const output = path.join(__dirname, "out");
159-
const name = path.basename(input);
160-
fsExtra.emptyDirSync(output);
161199

200+
fsExtra.emptyDirSync(output);
162201
console.time("Processing Time");
163202

164-
PushFilename(name);
203+
async function processFiles(input) {
204+
if (fs.statSync(input).isDirectory()) {
205+
const allFiles = getAllFiles(input);
165206

166-
ConvertFileToBinaryStream(input, (binaryData) => {
167-
binaryData.forEach(data => {
168-
const [part1, part2] = SplitByteTo2Nibbles(parseInt(data, 2));
169-
RGBDataArray.push(GetColorFromNibble(part1), GetColorFromNibble(part2));
170-
});
171-
});
207+
for (const file of allFiles) {
208+
try {
209+
PushFilename(file);
210+
await ConvertFileToBinaryStream(file);
211+
} catch (error) {
212+
console.error('Error processing file:', error.message);
213+
}
214+
}
215+
} else {
216+
try {
217+
PushFilename(input);
218+
await ConvertFileToBinaryStream(input);
219+
} catch (error) {
220+
console.error('Error processing file:', error.message);
221+
}
222+
}
223+
}
224+
225+
processFiles(input).then(() => {
226+
playSound(1);
227+
console.log('All files processed.');
228+
}).catch(err => {
229+
console.error('Error during file processing:', err.message);
230+
});

0 commit comments

Comments
 (0)