189 lines
5.7 KiB
JavaScript
189 lines
5.7 KiB
JavaScript
// scanner/scanPhoto.js
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
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) {
|
|
console.log(`[SCAN] Avvio scanPhoto 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 changes = [];
|
|
|
|
// ---------------------------------------------------------
|
|
// SCAN DI UNA SINGOLA CARTELLA
|
|
// ---------------------------------------------------------
|
|
async function scanSingleFolder(user, cartella, absCartella) {
|
|
console.log(`\n==============================================`);
|
|
console.log(`[SCAN] CARTELLA → ${user}/${cartella}`);
|
|
console.log(`[DEBUG] SCANSIONE CARTELLA PATH: ${absCartella}`);
|
|
console.log("==============================================");
|
|
|
|
let idsIndex = await buildIdsListForFolder(user, cartella);
|
|
|
|
const folderFiles = await scanCartella(
|
|
user,
|
|
cartella,
|
|
absCartella,
|
|
previousIndexTree
|
|
);
|
|
|
|
for (const m of folderFiles) {
|
|
const prev = previousIndexTree?.[m.user]?.[m.cartella]?.[m.id];
|
|
|
|
// 🔥 FILE INVARIATO
|
|
if (prev && prev.hash === m._indexHash) {
|
|
|
|
console.log("\n================ FILE INVARIATO ================");
|
|
console.log("[FILE]:", m.path);
|
|
|
|
console.log("[ID OGGI]:", JSON.stringify(m.id));
|
|
console.log("[ID INDEX]:", JSON.stringify(prev.id));
|
|
console.log("[UGUALI?]:", m.id === prev.id);
|
|
|
|
console.log("[LEN OGGI]:", m.id.length);
|
|
console.log("[LEN INDEX]:", prev.id.length);
|
|
|
|
console.log("----- BYTE PER BYTE -----");
|
|
const max = Math.min(m.id.length, prev.id.length, 64);
|
|
for (let i = 0; i < max; i++) {
|
|
const a = m.id[i];
|
|
const b = prev.id[i];
|
|
console.log(
|
|
i.toString().padStart(2, "0"),
|
|
a,
|
|
b,
|
|
a === b ? "==" : "!="
|
|
);
|
|
}
|
|
|
|
console.log("----- idsIndex PRIMA -----");
|
|
console.log(idsIndex.map(x => JSON.stringify(x)));
|
|
|
|
const found = idsIndex.includes(m.id);
|
|
console.log("[ID PRESENTE IN idsIndex?]:", found);
|
|
|
|
const newList = idsIndex.filter(x => x !== m.id);
|
|
|
|
console.log("----- idsIndex DOPO -----");
|
|
console.log(newList.map(x => JSON.stringify(x)));
|
|
|
|
idsIndex = newList;
|
|
|
|
console.log("=================================================\n");
|
|
continue;
|
|
}
|
|
|
|
// 🔥 FILE NUOVO O MODIFICATO
|
|
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);
|
|
changes.push(m);
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// ORFANI
|
|
// ---------------------------------------------------------
|
|
if (idsIndex.length > 0) {
|
|
console.log(`[ORPHAN] ID orfani trovati nella cartella ${cartella}:`);
|
|
idsIndex.forEach(id => console.log(" -", id));
|
|
} else {
|
|
console.log(`[ORPHAN] Nessun ID orfano nella cartella ${cartella}`);
|
|
}
|
|
|
|
for (const orphanId of idsIndex) {
|
|
console.log(`\n[ORPHAN] Eliminazione ID → ${orphanId}`);
|
|
|
|
const thumbsDeleted = await deleteThumbsById(orphanId);
|
|
console.log(` → thumbsDeleted = ${thumbsDeleted}`);
|
|
|
|
const dbDeleted = deleteFromDB(orphanId);
|
|
console.log(` → dbDeleted = ${dbDeleted}`);
|
|
|
|
const userTree = nextIndexTree[user];
|
|
if (userTree && userTree[cartella] && userTree[cartella][orphanId]) {
|
|
delete userTree[cartella][orphanId];
|
|
console.log(` → nextIndexTree updated (removed ${orphanId})`);
|
|
}
|
|
|
|
console.log(`[ORPHAN] COMPLETATO → ${orphanId}`);
|
|
}
|
|
|
|
console.log(`==============================================\n`);
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// SCAN SOTTOCARTELLE
|
|
// ---------------------------------------------------------
|
|
let entries = [];
|
|
try {
|
|
entries = await fsp.readdir(userDir, { withFileTypes: true });
|
|
} catch {
|
|
console.log(`[SCAN] 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
|
|
// ---------------------------------------------------------
|
|
if (SEND_PHOTOS && BASE_URL && changes.length) {
|
|
for (const p of changes) {
|
|
try {
|
|
await postWithAuth(`${BASE_URL}/photos`, p);
|
|
} catch (err) {
|
|
console.error('Errore invio:', err.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(`SCAN COMPLETATA: ${changes.length} file aggiornati`);
|
|
return changes;
|
|
}
|
|
|
|
module.exports = scanPhoto;
|