gallery_server_client_s190js/routes/scanStatus.js
2026-10-26 11:00:14 +01:00

90 lines
3.2 KiB
JavaScript

// routes/scanStatus.js
const express = require('express');
const router = express.Router();
const db = require('../db/knex');
const photoIngestQueue = require('../api_v1/scanner/photoIngestQueue');
const photoScanProgress = require('../api_v1/scanner/photoScanProgress');
const activityScanProgress = require('../api_v1/scanner/activityScanProgress');
const activityIngestQueue = require('../api_v1/scanner/activityIngestQueue');
router.get('/photos', async (req, res) => {
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
try {
const status = await photoScanProgress.getGlobalPhotoScanStatus(db);
res.json(status);
} catch (err) {
console.error('[scanStatus/photos] Errore:', err.message);
res.status(500).json({
ok: false,
error: 'Impossibile leggere lo stato della coda foto'
});
}
});
router.get('/activities', async (req, res) => {
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
try {
const status = await activityScanProgress.getGlobalActivityScanStatus(db);
res.json(status);
} catch (err) {
console.error('[scanStatus/activities] Errore:', err.message);
res.status(500).json({
ok: false,
error: 'Impossibile leggere lo stato della coda attività'
});
}
});
// Conteggio dei job ancora in attesa o in elaborazione.
// Questa route legge le code senza modificarle e non interferisce con i worker.
router.get('/worker-queues', async (req, res) => {
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
try {
const activityIngestQueue = require('../api_v1/scanner/activityIngestQueue');
const [faceCounts, geocodeCounts, photoCounts, activityCounts] = await Promise.all([
db('face_scan_jobs')
.select('status')
.count({ count: '*' })
.groupBy('status'),
db('geocode_jobs')
.select('status')
.count({ count: '*' })
.groupBy('status'),
photoIngestQueue.getPhotoIngestQueueCounts(db),
activityIngestQueue.getActivityIngestQueueCounts(db)
]);
const countStatus = (rows, statuses) =>
rows.reduce((total, row) =>
statuses.includes(row.status) ? total + Number(row.count || 0) : total,
0);
res.json({
ok: true,
photos: Number(photoCounts.pending || 0) +
Number(photoCounts.processing || 0),
photosErrors: Number(photoCounts.error || 0),
activities: Number(activityCounts.pending || 0) +
Number(activityCounts.processing || 0),
activitiesErrors: Number(activityCounts.error || 0),
faces: countStatus(faceCounts, ['pending', 'processing']),
facesErrors: countStatus(faceCounts, ['error']),
locations: countStatus(geocodeCounts, ['pending', 'processing']),
locationsErrors: countStatus(geocodeCounts, ['error'])
});
} catch (err) {
console.error('[worker-queues] Errore conteggio code:', err.message);
res.status(500).json({ ok: false, error: 'Impossibile leggere le code' });
}
});
module.exports = router;