Aggiungi api_v1/scanphoto.js
This commit is contained in:
parent
5c3dc82778
commit
f4f2387739
1 changed files with 144 additions and 0 deletions
144
api_v1/scanphoto.js
Normal file
144
api_v1/scanphoto.js
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const ExifReader = require('exifreader');
|
||||||
|
const sharp = require('sharp');
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
const BASE_URL = process.env.BASE_URL;
|
||||||
|
const EMAIL = process.env.EMAIL;
|
||||||
|
const PASSWORD = process.env.PASSWORD;
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// LOGIN → ottiene token JWT
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function getToken() {
|
||||||
|
try {
|
||||||
|
const res = await axios.post(`${BASE_URL}/auth/login`, {
|
||||||
|
email: EMAIL,
|
||||||
|
password: PASSWORD
|
||||||
|
});
|
||||||
|
return res.data.token;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("ERRORE LOGIN:", err.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// INVIA FOTO AL SERVER
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function sendPhoto(json) {
|
||||||
|
const token = await getToken();
|
||||||
|
if (!token) {
|
||||||
|
console.error("Token non ottenuto, impossibile inviare foto");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.post(`${BASE_URL}/photos`, json, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Errore invio foto:", err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// CREA THUMBNAILS
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function createThumbnails(filePath, thumbMinPath, thumbAvgPath) {
|
||||||
|
try {
|
||||||
|
await sharp(filePath)
|
||||||
|
.resize(100, 100, { fit: "inside" })
|
||||||
|
.withMetadata()
|
||||||
|
.toFile(thumbMinPath);
|
||||||
|
|
||||||
|
await sharp(filePath)
|
||||||
|
.resize(400)
|
||||||
|
.withMetadata()
|
||||||
|
.toFile(thumbAvgPath);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Errore creazione thumbnails:", err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// SCANSIONE RICORSIVA
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function scanDir(dir, ext, results = []) {
|
||||||
|
const files = fs.readdirSync(dir);
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const filePath = path.join(dir, file);
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
await scanDir(filePath, ext, results);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.extname(file).toLowerCase() !== ext) continue;
|
||||||
|
|
||||||
|
console.log("Trovato:", file);
|
||||||
|
|
||||||
|
const relDir = dir.replace("public/", "");
|
||||||
|
const thumbDir = path.join("public", relDir.replace("original", "thumbs"));
|
||||||
|
|
||||||
|
if (!fs.existsSync(thumbDir)) {
|
||||||
|
fs.mkdirSync(thumbDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseName = path.parse(file).name;
|
||||||
|
const extName = path.parse(file).ext;
|
||||||
|
|
||||||
|
const thumbMin = path.join(thumbDir, `${baseName}_min${extName}`);
|
||||||
|
const thumbAvg = path.join(thumbDir, `${baseName}_avg${extName}`);
|
||||||
|
|
||||||
|
await createThumbnails(filePath, thumbMin, thumbAvg);
|
||||||
|
|
||||||
|
// EXIF
|
||||||
|
let tags = {};
|
||||||
|
try {
|
||||||
|
tags = await ExifReader.load(filePath, { expanded: true });
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
const time = tags?.exif?.DateTimeOriginal?.value?.[0] || null;
|
||||||
|
const gps = tags?.gps || null;
|
||||||
|
|
||||||
|
results.push({
|
||||||
|
name: file,
|
||||||
|
path: relDir + "/" + file,
|
||||||
|
thub1: thumbMin.replace("public/", ""),
|
||||||
|
thub2: thumbAvg.replace("public/", ""),
|
||||||
|
gps,
|
||||||
|
data: time,
|
||||||
|
location: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// FUNZIONE PRINCIPALE
|
||||||
|
// -----------------------------------------------------
|
||||||
|
async function scanPhoto(dir) {
|
||||||
|
console.log("Inizio scansione:", dir);
|
||||||
|
|
||||||
|
const photos = await scanDir(dir, ".jpg");
|
||||||
|
|
||||||
|
console.log("Trovate", photos.length, "foto");
|
||||||
|
|
||||||
|
for (const p of photos) {
|
||||||
|
await sendPhoto(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Scansione completata");
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = scanPhoto;
|
||||||
Loading…
Reference in a new issue