Files
ai-bayarea/batch_runner.ts
2026-07-12 12:30:20 -05:00

101 lines
3.5 KiB
TypeScript

import * as fs from 'fs';
import * as path from 'path';
import { DeterministicParser } from './BuyerSheetParser';
async function main() {
// 1. Argument-Check
const args = process.argv.slice(2);
// Verzeichnis Parameter
const dirArgIndex = args.indexOf('--dir');
if (dirArgIndex === -1 || !args[dirArgIndex + 1]) {
console.error("Fehler: Bitte ein Verzeichnis angeben!");
console.error("Nutzung: npx tsx batch_runner.ts --dir \"/Pfad/zum/Ordner\" [--limit 10]");
process.exit(1);
}
const dirPath = args[dirArgIndex + 1];
// Limit Parameter
const limitArgIndex = args.indexOf('--limit');
let limit = -1; // -1 bedeutet: Kein Limit, alle verarbeiten
if (limitArgIndex !== -1 && args[limitArgIndex + 1]) {
limit = parseInt(args[limitArgIndex + 1], 10);
}
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
console.error(`Fehler: Der Pfad "${dirPath}" existiert nicht oder ist kein Verzeichnis.`);
process.exit(1);
}
// 2. PDFs finden und Metadaten (für die Sortierung) auslesen
const filesWithStats = fs.readdirSync(dirPath)
.filter(f => f.toLowerCase().endsWith('.pdf'))
.map(file => {
const fullPath = path.join(dirPath, file);
return {
file,
fullPath,
// Änderungsdatum der Datei auslesen (in Millisekunden)
mtime: fs.statSync(fullPath).mtimeMs
};
});
if (filesWithStats.length === 0) {
console.log("Keine PDFs in diesem Verzeichnis gefunden.");
process.exit(0);
}
// 3. Absteigend sortieren (Neueste zuerst)
filesWithStats.sort((a, b) => b.mtime - a.mtime);
// 4. Limit anwenden (falls gesetzt)
const filesToProcess = limit > 0 ? filesWithStats.slice(0, limit) : filesWithStats;
console.log(`Starte Verarbeitung: ${filesToProcess.length} von ${filesWithStats.length} PDFs ausgewählt (Sortierung: Neueste zuerst)...\n`);
const parser = new DeterministicParser();
const finalResults = [];
let skippedCounter = 0;
// 5. PDFs iterieren
for (const fileObj of filesToProcess) {
const { file, fullPath } = fileObj;
process.stdout.write(`-> Verarbeite: ${file} ... `);
try {
const data = await parser.parsePdf(fullPath, file);
if (data === null) {
console.log("ÜBERSPRUNGEN (> 10 Seiten)");
skippedCounter++;
} else if (data.is_buyer_sheet === false) {
console.log("IMAGE SCAN (Zuweisung an Vision AI)");
finalResults.push(data);
} else {
console.log("ERFOLGREICH");
finalResults.push(data);
}
} catch (error) {
console.log("FEHLER BEIM PARSEN");
console.error(error);
}
}
// 6. JSON Export unter ./out/buyers.json
const outDir = path.join(process.cwd(), 'out');
if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir);
}
const outPath = path.join(outDir, 'buyers.json');
fs.writeFileSync(outPath, JSON.stringify(finalResults, null, 2), 'utf-8');
console.log(`\n=================================================`);
console.log(`Zusammenfassung:`);
console.log(` Verarbeitet: ${finalResults.length}`);
console.log(` Verworfen (>10 Seiten): ${skippedCounter}`);
console.log(` Export gespeichert in: ${outPath}`);
console.log(`=================================================`);
}
main();