photo_server_json_flutter_c.../api_v1/scanner/scanPhoto.js
2026-03-11 11:31:52 +01:00

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;