photo_server_json_flutter_c.../routes/photos.js
2026-03-23 12:31:01 +01:00

192 lines
No EOL
5.5 KiB
JavaScript
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.

// routes/photos.js
const express = require('express');
const router = express.Router();
const db = require('../db/knex');
// 🔥 IMPORTANTE: aggiungi questa riga
const wss = require('../ws-server');
// -----------------------------------------------------
// Normalizzazione record DB → formato identico al vecchio index.json
// -----------------------------------------------------
function normalizePhoto(p) {
return {
...p,
gps: (p.lat != null && p.lon != null)
? {
lat: p.lat,
lng: p.lon,
alt: p.alt ?? null
}
: null,
location: p.location ? JSON.parse(p.location) : null,
_indexHash: p._indexHash || null,
// Rimuovo campi DB non necessari
lat: undefined,
lon: undefined,
alt: undefined,
location_json: undefined
};
}
// -----------------------------------------------------
// POST /photos → salva una foto inviata dallo scanner locale
// -----------------------------------------------------
router.post('/', async (req, res) => {
console.log("📥 [POST /photos] Richiesta ricevuta");
console.log("📥 Body:", req.body);
try {
const p = req.body;
// 1) Inserisci la foto nel DB remoto
console.log(`📸 [DB INSERT] Salvo foto id=${p.id} user=${p.user}`);
await db('photos').insert({
id: p.id,
user: p.user,
cartella: p.cartella,
name: p.name,
path: p.path,
thub1: p.thub1,
thub2: p.thub2,
mime_type: p.mime_type,
width: p.width,
height: p.height,
rotation: p.rotation,
size_bytes: p.size_bytes,
mtimeMs: p.mtimeMs,
duration_ms: p.duration_ms,
taken_at: p.taken_at,
data: p.data,
lat: p.gps?.lat ?? null,
lon: p.gps?.lng ?? null,
alt: p.gps?.alt ?? null,
location: p.location ? JSON.stringify(p.location) : null,
_indexHash: p._indexHash,
fast_hash: p.fast_hash
});
// 2) Registra levento ADDED
console.log(`🟢 [DB CHANGE] Inserisco evento ADDED per id=${p.id}`);
await db('photo_changes').insert({
photo_id: p.id,
user: p.user,
change_type: 'added',
timestamp: new Date().toISOString()
});
// 🔥 3) INVIO EVENTO WEBSOCKET IN TEMPO REALE
console.log(`📡 [WS] Invio evento real-time a user=${p.user}`);
wss.broadcastToUser(p.user, {
type: "photo_added",
photo_id: p.id
});
console.log(`✅ [POST /photos] Foto id=${p.id} salvata con successo`);
res.json({ ok: true });
} catch (err) {
console.error("❌ Errore POST /photos:", err);
res.status(500).json({ error: err.message });
}
});
// -----------------------------------------------------
// GET /photos → restituisce TUTTE le foto dellutente + Common
// -----------------------------------------------------
router.get('/', async (req, res) => {
console.log("📤 [GET /photos] Richiesta ricevuta");
try {
const rows = await db('photos')
.select('*')
.orderBy('mtimeMs', 'desc');
console.log(`📤 [GET /photos] Restituisco ${rows.length} foto`);
const normalized = rows.map(normalizePhoto);
res.json(normalized);
} catch (err) {
console.error("❌ Errore GET /photos:", err);
res.status(500).json({ error: err.message });
}
});
// -----------------------------------------------------
// GET /photos/changes
// -----------------------------------------------------
router.get('/changes', async (req, res) => {
const since = req.query.since;
const users = Array.isArray(req.query.user) ? req.query.user : [req.query.user];
console.log(`📤 [GET /photos/changes] since=${since} users=${users}`);
if (!since || !users.length) {
console.log("❌ Parametri mancanti");
return res.status(400).json({ error: "Parametri richiesti: since, user" });
}
try {
const rows = await db('photo_changes')
.where('timestamp', '>', since)
.whereIn('user', users)
.orderBy('timestamp', 'asc');
console.log(`📤 [GET /photos/changes] Restituisco ${rows.length} cambiamenti`);
res.json({ changes: rows });
} catch (err) {
console.error("❌ Errore /photos/changes:", err);
res.status(500).json({ error: err.message });
}
});
// -----------------------------------------------------
// GET /photos/byIds
// -----------------------------------------------------
router.get('/byIds', async (req, res) => {
const ids = req.query.id;
const users = Array.isArray(req.query.user) ? req.query.user : [req.query.user];
console.log("📤 [GET /photos/byIds] ids:", ids);
console.log("📤 [GET /photos/byIds] users (raw):", req.query.user);
console.log("📤 [GET /photos/byIds] users (array):", users);
if (!ids) {
console.log("⚠️ Nessun id richiesto → []");
return res.json([]);
}
if (!users || users.length === 0 || users[0] === undefined) {
console.log("❌ [GET /photos/byIds] ERRORE: 'user' NON passato dal frontend!");
}
const list = Array.isArray(ids) ? ids : [ids];
console.log("📤 [GET /photos/byIds] lista finale id:", list);
try {
console.log("📤 [GET /photos/byIds] Eseguo query con:");
console.log(" → id IN", list);
console.log(" → user IN", users);
const rows = await db('photos')
.whereIn('id', list)
.whereIn('user', users);
console.log(`📤 [GET /photos/byIds] Query completata → trovate ${rows.length} foto`);
const normalized = rows.map(normalizePhoto);
res.json(normalized);
} catch (err) {
console.error("❌ Errore /photos/byIds:", err);
res.status(500).json({ error: err.message });
}
});
module.exports = router;