photo_server_json_flutter_c.../api_v1/scanner/scanPhoto.js.ok
2026-03-18 09:34:41 +01:00

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;