// scanner/scanPhoto.js const path = require('path'); const fsp = require('fs/promises'); const { loadPreviousIndex, saveIndex } = require('./indexStore'); const scanCartella = require('./scanCartella'); const postWithAuth = require('./postWithAuth'); const { WEB_ROOT, SEND_PHOTOS, BASE_URL, WRITE_INDEX } = require('../config'); const createCleanupFunctions = require('./orphanCleanup'); async function scanPhoto(dir, userName, db) { const start = Date.now(); console.log(`\nšŸ”µ Inizio scan globale per user=${userName}`); const previousIndexTree = await loadPreviousIndex(); const nextIndexTree = JSON.parse(JSON.stringify(previousIndexTree || {})); const { buildIdsListForFolder, removeIdFromList, deleteThumbsById, deleteFromDB } = createCleanupFunctions(db); const photosRoot = path.resolve(__dirname, '..', '..', WEB_ROOT, 'photos'); const userDir = path.join(photosRoot, userName, 'original'); let totalNew = 0; let totalDeleted = 0; let totalUnchanged = 0; // šŸ”„ Array dei file nuovi/modificati (per DB e server) let newFiles = []; // --------------------------------------------------------- // SCAN DI UNA SINGOLA CARTELLA // --------------------------------------------------------- async function scanSingleFolder(user, cartella, absCartella) { console.log(`\nšŸ“ Inizio cartella: ${cartella}`); let idsIndex = await buildIdsListForFolder(user, cartella); let newCount = 0; let unchangedCount = 0; let deletedCount = 0; // STREAMING DEI FILE for await (const m of scanCartella(user, cartella, absCartella, previousIndexTree)) { const fileName = m.path.split('/').pop(); // ⚪ FILE INVARIATO if (m.unchanged) { console.log(` ⚪ Invariato: ${fileName}`); idsIndex = removeIdFromList(idsIndex, m.id); unchangedCount++; continue; } // 🟢 FILE NUOVO O MODIFICATO console.log(` 🟢 Nuovo/Modificato: ${fileName}`); nextIndexTree[m.user] ??= {}; nextIndexTree[m.user][m.cartella] ??= {}; nextIndexTree[m.user][m.cartella][m.id] = { id: m.id, user: m.user, cartella: m.cartella, path: m.path, hash: m._indexHash }; idsIndex = removeIdFromList(idsIndex, m.id); newCount++; // Aggiungiamo alla lista dei file nuovi newFiles.push(m); } // šŸ”“ ORFANI (FILE CANCELLATI) for (const orphanId of idsIndex) { const old = previousIndexTree?.[user]?.[cartella]?.[orphanId]; const fileName = old?.path?.split('/').pop() || orphanId; console.log(` šŸ”“ Eliminato: ${fileName}`); await deleteThumbsById(orphanId); deleteFromDB(orphanId); const userTree = nextIndexTree[user]; if (userTree?.[cartella]?.[orphanId]) { delete userTree[cartella][orphanId]; } deletedCount++; } console.log( `šŸ“Š Fine cartella ${cartella}: invariati=${unchangedCount}, nuovi=${newCount}, cancellati=${deletedCount}` ); totalNew += newCount; totalDeleted += deletedCount; totalUnchanged += unchangedCount; } // --------------------------------------------------------- // SCAN SOTTOCARTELLE // --------------------------------------------------------- let entries = []; try { entries = await fsp.readdir(userDir, { withFileTypes: true }); } catch { console.log(`Nessuna directory per utente ${userName}`); return []; } for (const e of entries) { if (!e.isDirectory()) continue; const cartella = e.name; const absCartella = path.join(userDir, cartella); await scanSingleFolder(userName, cartella, absCartella); } // --------------------------------------------------------- // SALVO INDEX // --------------------------------------------------------- if (WRITE_INDEX) { await saveIndex(nextIndexTree); } // --------------------------------------------------------- // INVIO AL SERVER / POPOLAZIONE DB // --------------------------------------------------------- if (SEND_PHOTOS && BASE_URL && newFiles.length > 0) { for (const p of newFiles) { const fileName = p.path.split('/').pop(); try { await postWithAuth(`${BASE_URL}/photos`, p); console.log(`šŸ“¤ Inviato al server: ${fileName}`); } catch (err) { console.error(`Errore invio ${fileName}:`, err.message); } } } // --------------------------------------------------------- // FINE SCAN // --------------------------------------------------------- const elapsed = ((Date.now() - start) / 1000).toFixed(2); console.log(`\n🟣 Scan COMPLETATO: nuovi=${totalNew}, cancellati=${totalDeleted}, invariati=${totalUnchanged}`); console.log(`ā± Tempo totale: ${elapsed}s\n`); return newFiles; } module.exports = scanPhoto;