server_photo_s35js/api_v1/scanner/scanPhotoSingle.js
2026-07-18 13:51:20 +02:00

206 lines
5.1 KiB
JavaScript

// api_v1/scanner/scanPhotoSingle.js
const processFile = require('./processFile');
const { sha256 } = require('./utils');
const { log } = require('./logger');
function normCountryCode(value) {
if (!value) return undefined;
const s = String(value).trim().toUpperCase();
return s.length ? s : undefined;
}
function normalizeLocation(location) {
if (!location) return null;
const countryCode = normCountryCode(
location.country_code ||
location.countryCode ||
location.isoCountryCode
);
const countyCode =
location.county_code ||
location.countyCode ||
undefined;
return {
...location,
// Paese
country: location.country || undefined,
country_code: countryCode,
// County / contea
county: location.county || undefined,
county_code: countyCode,
// Campi già esistenti
region: location.region || undefined,
city: location.city || undefined,
postcode: location.postcode || undefined,
address: location.address || undefined,
timezone: location.timezone || undefined,
time: location.time || undefined,
};
}
async function scanPhotoSingle(db, user, cartella, f, newFiles, prefix = '') {
const fileName = f.name;
const id = f.id;
const st = f.stat;
// Recupero precedente SENZA contentHash
let prev = await db('photos')
.select('id', 'size_bytes', 'mtimeMs', 'fast_hash', 'path')
.where({ id })
.first();
// Hash veloce basato su size + mtime
const fastHash = sha256(`${st.size}-${st.mtimeMs}`);
// ---------------------------------------------------------
// PATH CAMBIATO = NUOVO FILE
// ---------------------------------------------------------
if (prev && prev.path !== f.path) {
log(`${prefix} 🟢 Nuovo/Modificato (path changed): ${fileName}`);
prev = null;
}
// ---------------------------------------------------------
// NUOVO FILE
// ---------------------------------------------------------
if (!prev) {
log(`${prefix} 🟢 Nuovo: ${fileName}`);
const meta = await processFile(
user,
cartella,
f.relPath,
f.absPath,
f.ext,
st
);
meta.id = id;
meta.path = f.path;
// Normalizza location prima di salvarla e inviarla
meta.location = normalizeLocation(meta.location);
log(
`🌍 [LOCATION NEW] ${fileName} ` +
`location=${JSON.stringify(meta.location)}`
);
await db('photos').insert({
id: meta.id,
user,
cartella,
name: meta.name,
path: meta.path,
thub1: meta.thub1,
thub2: meta.thub2,
mime_type: meta.mime_type,
width: meta.width,
height: meta.height,
rotation: meta.rotation,
size_bytes: meta.size_bytes,
mtimeMs: meta.mtimeMs,
duration_ms: meta.duration_ms,
taken_at: meta.taken_at,
data: meta.data,
lat: meta.gps?.lat ?? null,
lon: meta.gps?.lng ?? null,
alt: meta.gps?.alt ?? null,
// Qui ora il JSON può contenere:
// country, country_code, county, county_code, region, city, ecc.
location: meta.location ? JSON.stringify(meta.location) : null,
fast_hash: fastHash,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
});
newFiles.push(meta);
return meta;
}
// ---------------------------------------------------------
// IDENTICO (fastHash uguale)
// ---------------------------------------------------------
if (prev.fast_hash === fastHash) {
await db('photos')
.where({ id })
.update({
path: f.path,
size_bytes: st.size,
mtimeMs: st.mtimeMs,
fast_hash: fastHash,
// Anche un file identico aggiorna updated_at
updated_at: new Date().toISOString(),
});
return null;
}
// ---------------------------------------------------------
// MODIFICATO (fastHash diverso)
// ---------------------------------------------------------
log(`${prefix} 🟠 Modificato: ${fileName}`);
const meta = await processFile(
user,
cartella,
f.relPath,
f.absPath,
f.ext,
st
);
meta.id = id;
meta.path = f.path;
// Normalizza location prima di salvarla e inviarla
meta.location = normalizeLocation(meta.location);
log(
`🌍 [LOCATION UPDATED] ${fileName} ` +
`location=${JSON.stringify(meta.location)}`
);
await db('photos')
.where({ id })
.update({
name: meta.name,
path: meta.path,
thub1: meta.thub1,
thub2: meta.thub2,
mime_type: meta.mime_type,
width: meta.width,
height: meta.height,
rotation: meta.rotation,
size_bytes: meta.size_bytes,
mtimeMs: meta.mtimeMs,
duration_ms: meta.duration_ms,
taken_at: meta.taken_at,
data: meta.data,
lat: meta.gps?.lat ?? null,
lon: meta.gps?.lng ?? null,
alt: meta.gps?.alt ?? null,
// Qui ora il JSON può contenere:
// country, country_code, county, county_code, region, city, ecc.
location: meta.location ? JSON.stringify(meta.location) : null,
fast_hash: fastHash,
updated_at: new Date().toISOString(),
});
newFiles.push(meta);
return meta;
}
module.exports = scanPhotoSingle;