263 lines
9.5 KiB
JavaScript
263 lines
9.5 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const { SatLocLogParser } = require('../../helpers/satloc_log_parser');
|
||
|
||
async function extractIds(filePath) {
|
||
const relativePath = path.relative('./test-logs', filePath);
|
||
console.log(`\n=== Processing: ${relativePath} ===`);
|
||
|
||
try {
|
||
const parser = new SatLocLogParser({
|
||
debugRecordTypes: [],
|
||
outputAllRecords: false,
|
||
verbose: false
|
||
});
|
||
|
||
const result = await parser.parseFile(filePath);
|
||
|
||
if (!result.success) {
|
||
console.log(`ERROR: ${result.error}`);
|
||
return;
|
||
}
|
||
|
||
let jobId = null;
|
||
let aircraftId = null;
|
||
let fileName = path.basename(filePath);
|
||
|
||
// Extract jobId from record 120 (SWATHING_SETUP)
|
||
const record120 = result.records.find(r => r.recordType === 120);
|
||
if (record120) {
|
||
jobId = record120.jobId || 'N/A';
|
||
}
|
||
|
||
// Extract aircraftId from record 100 (SYSTEM_SETUP)
|
||
const record100 = result.records.find(r => r.recordType === 100);
|
||
if (record100) {
|
||
aircraftId = record100.aircraftId || 'N/A';
|
||
}
|
||
|
||
console.log(`File Name: ${fileName}`);
|
||
console.log(`Job ID (from record 120): ${jobId || 'Not found'}`);
|
||
console.log(`Aircraft ID (from record 100): ${aircraftId || 'Not found'}`);
|
||
console.log(`Total records: ${result.records.length}`);
|
||
|
||
} catch (error) {
|
||
console.log(`ERROR processing ${filePath}: ${error.message}`);
|
||
}
|
||
}
|
||
|
||
async function extractIdsQuiet(filePath) {
|
||
try {
|
||
const parser = new SatLocLogParser({
|
||
debugRecordTypes: [],
|
||
outputAllRecords: false,
|
||
verbose: false
|
||
});
|
||
|
||
const result = await parser.parseFile(filePath);
|
||
|
||
if (!result.success) {
|
||
return null;
|
||
}
|
||
|
||
let jobId = null;
|
||
let aircraftId = null;
|
||
let fileName = path.basename(filePath);
|
||
let relativePath = path.relative('./test-logs', filePath);
|
||
|
||
// Extract jobId from record 120 (SWATHING_SETUP)
|
||
const record120 = result.records.find(r => r.recordType === 120);
|
||
if (record120) {
|
||
jobId = record120.jobId || null;
|
||
}
|
||
|
||
// Extract aircraftId from record 100 (SYSTEM_SETUP)
|
||
const record100 = result.records.find(r => r.recordType === 100);
|
||
if (record100) {
|
||
aircraftId = record100.aircraftId || null;
|
||
}
|
||
|
||
return {
|
||
fileName,
|
||
relativePath,
|
||
jobId,
|
||
aircraftId,
|
||
totalRecords: result.records.length,
|
||
filePath
|
||
};
|
||
|
||
} catch (error) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function findSatLocFiles(dir, fileList = []) {
|
||
const items = fs.readdirSync(dir);
|
||
|
||
for (const item of items) {
|
||
const fullPath = path.join(dir, item);
|
||
const stat = fs.statSync(fullPath);
|
||
|
||
if (stat.isDirectory()) {
|
||
// Recursively search subdirectories
|
||
findSatLocFiles(fullPath, fileList);
|
||
} else if (stat.isFile()) {
|
||
// Check if it's a potential SatLoc file
|
||
const fileName = item.toLowerCase();
|
||
if (fileName.endsWith('.log') ||
|
||
fileName.endsWith('.txt') ||
|
||
(fileName.includes('satloc') && !fileName.endsWith('.csv'))) {
|
||
fileList.push(fullPath);
|
||
}
|
||
}
|
||
}
|
||
|
||
return fileList;
|
||
}
|
||
|
||
async function processTestLogsFolder() {
|
||
const testLogsDir = './test-logs';
|
||
|
||
if (!fs.existsSync(testLogsDir)) {
|
||
console.log('ERROR: ./test-logs directory not found');
|
||
return;
|
||
}
|
||
|
||
console.log('=== SatLoc ID Extractor ===');
|
||
console.log('Extracting jobId (record 120) and aircraftId (record 100) from SatLoc files...');
|
||
console.log('Searching recursively through subfolders...\n');
|
||
|
||
const logFiles = findSatLocFiles(testLogsDir);
|
||
|
||
if (logFiles.length === 0) {
|
||
console.log('No SatLoc log files found in ./test-logs directory or its subdirectories');
|
||
return;
|
||
}
|
||
|
||
console.log(`Found ${logFiles.length} potential SatLoc files:`);
|
||
logFiles.forEach(file => {
|
||
const relativePath = path.relative(testLogsDir, file);
|
||
console.log(` - ${relativePath}`);
|
||
});
|
||
|
||
// Store results for summary table
|
||
const results = [];
|
||
|
||
for (const filePath of logFiles) {
|
||
const result = await extractIdsQuiet(filePath);
|
||
if (result) {
|
||
results.push(result);
|
||
}
|
||
}
|
||
|
||
// Generate formatted summary tables
|
||
console.log('\n' + '='.repeat(80));
|
||
console.log('📊 COMPLETE RESULTS SUMMARY');
|
||
console.log('='.repeat(80));
|
||
|
||
// Separate root and subfolder files
|
||
const rootFiles = results.filter(r => !r.relativePath.includes('/'));
|
||
const subfolderFiles = results.filter(r => r.relativePath.includes('/'));
|
||
|
||
if (rootFiles.length > 0) {
|
||
console.log('\n🗂️ ROOT FOLDER FILES:');
|
||
|
||
// Calculate the maximum width needed for each column
|
||
const maxFileNameWidth = Math.max(45, ...rootFiles.map(r => r.fileName.length));
|
||
const maxJobIdWidth = Math.max(15, ...rootFiles.map(r => (r.jobId || 'Not found').length));
|
||
const maxAircraftIdWidth = Math.max(15, ...rootFiles.map(r => (r.aircraftId || 'Not found').length));
|
||
|
||
// Create headers with proper spacing
|
||
const fileNameHeader = 'File Name'.padEnd(maxFileNameWidth);
|
||
const jobIdHeader = 'Job ID'.padEnd(maxJobIdWidth);
|
||
const aircraftIdHeader = 'Aircraft ID'.padEnd(maxAircraftIdWidth);
|
||
const recordsHeader = 'Total Records';
|
||
|
||
console.log(`\n${fileNameHeader} ${jobIdHeader} ${aircraftIdHeader} ${recordsHeader}`);
|
||
console.log('='.repeat(maxFileNameWidth + maxJobIdWidth + maxAircraftIdWidth + 15 + 3)); // +3 for spaces between columns
|
||
|
||
rootFiles.forEach(result => {
|
||
const fileName = result.fileName.padEnd(maxFileNameWidth);
|
||
const jobId = (result.jobId || 'Not found').padEnd(maxJobIdWidth);
|
||
const aircraftId = (result.aircraftId || 'Not found').padEnd(maxAircraftIdWidth);
|
||
const records = result.totalRecords.toLocaleString().padStart(12);
|
||
console.log(`${fileName} ${jobId} ${aircraftId} ${records}`);
|
||
});
|
||
}
|
||
|
||
if (subfolderFiles.length > 0) {
|
||
console.log('\n📁 SUBFOLDER FILES:');
|
||
|
||
// Calculate the maximum width needed for each column
|
||
const maxFilePathWidth = Math.max(45, ...subfolderFiles.map(r => r.relativePath.length));
|
||
const maxJobIdWidth = Math.max(15, ...subfolderFiles.map(r => (r.jobId || 'Not found').length));
|
||
const maxAircraftIdWidth = Math.max(15, ...subfolderFiles.map(r => (r.aircraftId || 'Not found').length));
|
||
|
||
// Create headers with proper spacing
|
||
const filePathHeader = 'File Path'.padEnd(maxFilePathWidth);
|
||
const jobIdHeader = 'Job ID'.padEnd(maxJobIdWidth);
|
||
const aircraftIdHeader = 'Aircraft ID'.padEnd(maxAircraftIdWidth);
|
||
const recordsHeader = 'Total Records';
|
||
|
||
console.log(`\n${filePathHeader} ${jobIdHeader} ${aircraftIdHeader} ${recordsHeader}`);
|
||
console.log('='.repeat(maxFilePathWidth + maxJobIdWidth + maxAircraftIdWidth + 15 + 3)); // +3 for spaces between columns
|
||
|
||
subfolderFiles.forEach(result => {
|
||
const filePath = result.relativePath.padEnd(maxFilePathWidth);
|
||
const jobId = (result.jobId || 'Not found').padEnd(maxJobIdWidth);
|
||
const aircraftId = (result.aircraftId || 'Not found').padEnd(maxAircraftIdWidth);
|
||
const records = result.totalRecords.toLocaleString().padStart(12);
|
||
console.log(`${filePath} ${jobId} ${aircraftId} ${records}`);
|
||
});
|
||
}
|
||
|
||
// Statistics summary
|
||
const totalRecords = results.reduce((sum, r) => sum + r.totalRecords, 0);
|
||
const uniqueJobIds = new Set(results.map(r => r.jobId).filter(id => id && id !== 'Not found'));
|
||
const uniqueAircraftIds = new Set(results.map(r => r.aircraftId).filter(id => id && id !== 'Not found'));
|
||
const largestFile = results.reduce((max, r) => r.totalRecords > max.totalRecords ? r : max, results[0]);
|
||
|
||
console.log('\n🎯 KEY STATISTICS:');
|
||
console.log('├─ Total files processed: ' + results.length);
|
||
console.log('├─ Total records across all files: ' + totalRecords.toLocaleString());
|
||
console.log('├─ Unique Job IDs found: ' + uniqueJobIds.size);
|
||
console.log('├─ Unique Aircraft IDs found: ' + uniqueAircraftIds.size);
|
||
console.log('└─ Largest file: ' + (largestFile.fileName || largestFile.relativePath) + ' (' + largestFile.totalRecords.toLocaleString() + ' records)');
|
||
|
||
console.log('\n✅ UNIQUE JOB IDS:');
|
||
Array.from(uniqueJobIds).sort().forEach((id, index) => {
|
||
console.log(' ' + (index + 1) + '. "' + id + '"');
|
||
});
|
||
|
||
console.log('\n✈️ UNIQUE AIRCRAFT IDS:');
|
||
Array.from(uniqueAircraftIds).sort().forEach((id, index) => {
|
||
console.log(' ' + (index + 1) + '. "' + id + '"');
|
||
});
|
||
|
||
console.log('\n================================================================================');
|
||
console.log('🚀 Processing complete! Analyzed ' + results.length + ' SatLoc files with null termination fix applied.');
|
||
console.log('================================================================================');
|
||
|
||
// Create CSV format for easy copy-paste into spreadsheets
|
||
console.log('\n📊 CSV FORMAT (Copy this into Excel/Google Sheets):');
|
||
console.log('File Name/Path,Job ID,Aircraft ID,Total Records,Location');
|
||
results.forEach(result => {
|
||
const location = result.relativePath.includes('/') ? 'Subfolder' : 'Root';
|
||
const filePath = result.fileName || result.relativePath;
|
||
const jobId = result.jobId || 'Not found';
|
||
const aircraftId = result.aircraftId || 'Not found';
|
||
console.log('"' + filePath + '","' + jobId + '","' + aircraftId + '",' + result.totalRecords + ',"' + location + '"');
|
||
});
|
||
}
|
||
|
||
// Run if called directly
|
||
if (require.main === module) {
|
||
processTestLogsFolder().catch(error => {
|
||
console.error('Fatal error:', error.message);
|
||
process.exit(1);
|
||
});
|
||
}
|
||
|
||
module.exports = { extractIds, extractIdsQuiet, processTestLogsFolder, findSatLocFiles }; |