Files
2026-06-18 10:53:32 +02:00

147 lines
5.4 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
const { loadConfig, loadSitesFromFile } = require('./src/config');
const { processSite } = require('./src/processor');
const { createCLI, parseCLI } = require('./src/cli');
async function main() {
const cliOptions = parseCLI();
if (cliOptions.help) {
createCLI().help();
return;
}
const config = loadConfig();
let sitesToProcess = config.sites || [];
if (cliOptions.file) {
console.log(`Loading sites from: ${cliOptions.file}`);
sitesToProcess = loadSitesFromFile(cliOptions.file);
console.log(`Loaded ${sitesToProcess.length} sites from file`);
}
const logFile = cliOptions.log ? path.join(__dirname, `run_${new Date().toISOString().replace(/[:.]/g, '-')}.log`) : null;
if (cliOptions.target) {
sitesToProcess = sitesToProcess.filter(site =>
site.name.toLowerCase().includes(cliOptions.target.toLowerCase()) ||
site.url.toLowerCase().includes(cliOptions.target.toLowerCase())
);
if (sitesToProcess.length === 0) {
console.error(`No site found matching "${cliOptions.target}"`);
return;
}
console.log(`Targeting ${sitesToProcess.length} site(s)`);
}
if (cliOptions.keepOpen) {
console.log('Keep-open mode: Tabs will stay open for verification');
}
const browserConfig = config.browser || {};
const globalCreds = config.global_credentials || {};
const userDataDir = browserConfig.userDataDir;
if (!userDataDir) {
console.error('userDataDir not set in config.toml');
return;
}
if (cliOptions.log && logFile) {
const originalLog = console.log;
const originalError = console.error;
const originalWarn = console.warn;
const writeToLog = (type, args) => {
const message = args.map(arg => typeof arg === 'string' ? arg : JSON.stringify(arg)).join(' ');
fs.appendFileSync(logFile, `[${new Date().toISOString()}] [${type}] ${message}\n`);
};
console.log = (...args) => { writeToLog('LOG', args); originalLog.apply(console, args); };
console.error = (...args) => { writeToLog('ERROR', args); originalError.apply(console, args); };
console.warn = (...args) => { writeToLog('WARN', args); originalWarn.apply(console, args); };
console.log(`Logging to: ${logFile}`);
}
const failedSites = [];
const processedCount = { success: 0, failed: 0 };
const browser = await puppeteer.launch({
headless: false,
userDataDir: userDataDir,
args: ['--start-maximized', '--no-sandbox', '--disable-setuid-sandbox']
});
try {
console.log(`\nProcessing ${sitesToProcess.length} sites...\n`);
const allResults = [];
for (let i = 0; i < sitesToProcess.length; i++) {
const site = sitesToProcess[i];
console.log(`[${i + 1}/${sitesToProcess.length}]`);
const result = await processSite(browser, site, globalCreds, browserConfig, cliOptions.keepOpen, cliOptions.dryRun);
const siteResult = {
name: site.name,
url: site.url,
success: !result.siteFailed,
reason: result.failureReason || 'Success',
timestamp: new Date().toISOString()
};
allResults.push(siteResult);
if (result.siteFailed) {
failedSites.push(siteResult);
processedCount.failed++;
} else {
processedCount.success++;
}
// Write results after each site
const reportPath = path.join(__dirname, 'site_results.txt');
const now = new Date();
const dateStr = now.toLocaleDateString('en-GB');
const timeStr = now.toLocaleTimeString('en-GB');
let reportContent = '';
if (!fs.existsSync(reportPath)) {
reportContent = 'DATE | TIME | STATUS | WEBSITE | RESULT\n';
reportContent += '-'.repeat(110) + '\n';
}
const website = `${site.name} (${site.url})`.substring(0, 32).padEnd(32);
const status = siteResult.success ? 'SUCCESS' : 'FAILED';
reportContent += `${dateStr} | ${timeStr} | ${status} | ${website} | ${siteResult.reason}\n`;
fs.appendFileSync(reportPath, reportContent);
console.log(` -> Result written to site_results.txt`);
await new Promise(r => setTimeout(r, 1000));
}
console.log(`\n${'='.repeat(70)}`);
console.log(`Done: ${processedCount.success} success, ${processedCount.failed} failed`);
console.log(`Full results: site_results.txt`);
} catch(error) {
console.error('Fatal error:', error.message);
} finally {
if (cliOptions.keepOpen) {
console.log(`\nBrowser kept open for verification`);
console.log(` Close browser manually when done`);
} else {
await browser.close();
}
}
}
main();