ok
|
|
@ -8,35 +8,63 @@ const { SUPPORTED_EXTS } = require('../config');
|
|||
/**
|
||||
* Scansiona ricorsivamente una cartella e ritorna SOLO i cambiamenti
|
||||
* (nuovi/modificati) rispetto a previousIndex (mappa { id: meta }).
|
||||
*
|
||||
* @param {string} userName - Nome utente (es. "Fabio" o "Common")
|
||||
* @param {string} cartella - Nome della cartella logica sotto "original" (es. "2017Irlanda19-29ago")
|
||||
* @param {string} absCartella - Percorso assoluto della cartella da scansionare (p.es. .../photos/<Utente>/original/<cartella>)
|
||||
* @param {Object} previousIndex- Mappa dell'indice precedente: { <id>: meta }
|
||||
* @returns {Promise<Array<Object>>} changes - Lista dei soli meta cambiati o nuovi
|
||||
*/
|
||||
async function scanCartella(userName, cartella, absCartella, previousIndex) {
|
||||
const changes = [];
|
||||
|
||||
async function walk(currentAbs, relPath = '') {
|
||||
const entries = await fsp.readdir(currentAbs, { withFileTypes: true });
|
||||
let entries = [];
|
||||
try {
|
||||
entries = await fsp.readdir(currentAbs, { withFileTypes: true });
|
||||
} catch (err) {
|
||||
// Cartella non leggibile: logga e prosegui (non bloccare la scansione globale)
|
||||
console.error(`[SCAN] Impossibile leggere: ${currentAbs} - ${err.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const e of entries) {
|
||||
const absPath = path.join(currentAbs, e.name);
|
||||
|
||||
if (e.isDirectory()) {
|
||||
await walk(absPath, path.join(relPath, e.name));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filtra estensioni non supportate
|
||||
const ext = path.extname(e.name).toLowerCase();
|
||||
if (!SUPPORTED_EXTS.has(ext)) continue;
|
||||
|
||||
// Percorso relativo POSIX (usato per mantenere slash '/')
|
||||
const fileRelPath = relPath ? `${relPath}/${e.name}` : e.name;
|
||||
|
||||
// ID deterministico: user/cartella/relPath
|
||||
const id = sha256(`${userName}/${cartella}/${fileRelPath}`);
|
||||
|
||||
const st = await fsp.stat(absPath);
|
||||
const prev = previousIndex[id];
|
||||
// Confronto con indice precedente per saltare "unchanged"
|
||||
let st;
|
||||
try {
|
||||
st = await fsp.stat(absPath);
|
||||
} catch (err) {
|
||||
// File sparito o non accessibile: salta
|
||||
console.warn(`[SCAN] stat fallita: ${absPath} - ${err.message}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const prev = previousIndex[id];
|
||||
const unchanged =
|
||||
prev &&
|
||||
prev.size_bytes === st.size &&
|
||||
prev.mtimeMs === st.mtimeMs;
|
||||
|
||||
if (unchanged) continue; // NOTE: skip "unchanged"
|
||||
if (unchanged) continue; // nulla da aggiornare
|
||||
|
||||
// Estrae metadati (EXIF, mime, dimensioni, thumbs, ecc.)
|
||||
const meta = await processFile(
|
||||
userName,
|
||||
cartella,
|
||||
|
|
@ -46,7 +74,20 @@ async function scanCartella(userName, cartella, absCartella, previousIndex) {
|
|||
st
|
||||
);
|
||||
|
||||
meta.id = id; // id sempre presente
|
||||
// ID sempre presente
|
||||
meta.id = id;
|
||||
|
||||
// 🔧 Canonicalizza SEMPRE il path pubblicato nell’index:
|
||||
// /photos/<Utente>/original/<cartella>/<fileRelPath>
|
||||
{
|
||||
// Normalizza separatori e rimuove eventuali leading-slash multipli
|
||||
const relPosix = String(fileRelPath).replace(/\\/g, '/').replace(/^\/+/, '');
|
||||
// Costruisci il path canonico e comprimi eventuali '//' in '/'
|
||||
const canonical = `/photos/${userName}/original/${cartella}/${relPosix}`.replace(/\/+/g, '/');
|
||||
meta.path = canonical;
|
||||
// NB: thub1/thub2 rimangono quelli prodotti da processFile (ok per immagini e video)
|
||||
}
|
||||
|
||||
changes.push(meta);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 4.3 MiB After Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
|
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 4.5 MiB |
|
Before Width: | Height: | Size: 4.6 MiB After Width: | Height: | Size: 4.6 MiB |
|
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 4.5 MiB |