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

176 lines
7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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}`);
// Log di configurazione (utile per diagnosi)
console.log('[SCAN] Config:', {
WEB_ROOT,
SEND_PHOTOS,
BASE_URL,
WRITE_INDEX
});
// 1) Carico lindice precedente (fonte unica durante la run)
const previousIndexTree = await loadPreviousIndex(); // <— RAM source
// 2) Clono lindice per costruire il nuovo
const nextIndexTree = JSON.parse(JSON.stringify(previousIndexTree || {}));
// Funzioni di cleanup (solo thumbs + DB)
// NOTA: con Opzione A NON leggiamo più l'indice da file e NON aggiorniamo index.json "in itinere"
const {
// buildIdsListForFolder, // <— NON usato in Opzione A
removeIdFromList,
deleteThumbsById,
deleteFromDB
// deleteFromIndexById // <— NON usato in Opzione A
} = createCleanupFunctions(db); // [1](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/orphanCleanup.js.txt)
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("==============================================");
// Costruisci idsIndex dall'indice in RAM (previousIndexTree)
// Fonte unica di verità per questa run → evita drift con il file su disco.
let idsIndex = Object.keys(previousIndexTree?.[user]?.[cartella] || {})
.filter(k => k !== '_folderHash'); // <— niente metadati
console.log(`[ORPHAN] ID iniziali in RAM (${idsIndex.length}):`);
idsIndex.forEach(id => console.log(" -", id));
// File reali trovati nella cartella
const folderFiles = await scanCartella(
user,
cartella,
absCartella,
previousIndexTree
); // [2](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/scanCartella.js.txt)
for (const m of folderFiles) {
const prev = previousIndexTree?.[m.user]?.[m.cartella]?.[m.id];
// 🔥 FILE INVARIATO
if (prev && prev.hash === m._indexHash) {
console.log(`[SCAN] SKIP (unchanged) → ${m.path}`);
// Rimuovo SOLO dalla lista orfani (dalla RAM)
idsIndex = removeIdFromList(idsIndex, m.id); // [1](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/orphanCleanup.js.txt)
continue;
}
// 🔥 FILE NUOVO O MODIFICATO → aggiorno nextIndexTree
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
};
// Rimuovo dalla lista orfani (in RAM)
idsIndex = removeIdFromList(idsIndex, m.id); // [1](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/orphanCleanup.js.txt)
changes.push(m);
}
// ---------------------------------------------------------
// ORFANI → rimuovo SOLO da nextIndexTree + thumbs + DB
// ---------------------------------------------------------
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}`);
// 1) Cancello thumbs
const thumbsDeleted = await deleteThumbsById(orphanId); // [1](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/orphanCleanup.js.txt)
console.log(` → thumbsDeleted = ${thumbsDeleted}`);
// 2) Cancello dal DB
const dbDeleted = deleteFromDB(orphanId); // [1](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/orphanCleanup.js.txt)
console.log(` → dbDeleted = ${dbDeleted}`);
// 3) Cancello SOLO da nextIndexTree (in RAM)
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 SOLO SOTTOCARTELLE — niente _root
// ---------------------------------------------------------
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 SOLO nextIndexTree (scrittura unica a fine run)
// ---------------------------------------------------------
if (WRITE_INDEX) {
await saveIndex(nextIndexTree); // [1](https://electrolux-my.sharepoint.com/personal/fabio_micheluz_electrolux_com/Documents/File%20di%20Microsoft%20Copilot%20Chat/orphanCleanup.js.txt)
}
// ---------------------------------------------------------
// 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;