165 lines
4.8 KiB
Text
165 lines
4.8 KiB
Text
// 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;
|