feat: HA-Entitaeten mit Bereichs-Praefixen, Media-Anfragen quittierbar per Button, umfangreiche 3D-Statistik

This commit is contained in:
2026-07-10 19:57:10 +02:00
parent 12094901a4
commit bbf937c671
3 changed files with 329 additions and 106 deletions

View File

@@ -881,15 +881,34 @@ router.get('/favorites/unacked', authenticate, (req, res) => {
// POST /favorites/acknowledge-all Admin: alle quittieren
router.post('/favorites/acknowledge-all', authenticate, requireAdmin, (req, res) => {
// Betroffene Favoriten vor dem Update holen (für Pushover-Benachrichtigungen)
// ── Quittier-Logik (wiederverwendbar: HTTP-Routen + MQTT-Buttons) ───────────
function ackFavorite(id) {
const fav = db.prepare('SELECT * FROM movie_favorites WHERE id=?').get(id);
if (!fav) return null;
db.prepare('UPDATE movie_favorites SET acknowledged=1, acknowledged_at=CURRENT_TIMESTAMP, user_notified=0 WHERE id=?').run(fav.id);
try {
const poCfg = db.prepare('SELECT user_key, app_token FROM pushover_settings WHERE user_id=?').get(fav.user_id);
if (poCfg?.app_token && poCfg?.user_key) {
fetch('https://api.pushover.net/1/messages.json', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: poCfg.app_token,
user: poCfg.user_key,
title: '✅ Favorit bestätigt',
message: `"${fav.title}" wurde von einem Admin bestätigt.`,
priority: 0,
}),
}).catch(() => {});
}
} catch {}
return fav;
}
function ackAllFavorites() {
const toAck = db.prepare('SELECT id, user_id, title FROM movie_favorites WHERE acknowledged=0').all();
db.prepare('UPDATE movie_favorites SET acknowledged=1, acknowledged_at=CURRENT_TIMESTAMP, user_notified=0 WHERE acknowledged=0').run();
res.json({ ok: true });
// Pushover an jeden betroffenen User (fire & forget, pro User gruppiert)
try {
// User mit Pushover-Konfiguration ermitteln
const userIds = [...new Set(toAck.map(f => f.user_id))];
for (const userId of userIds) {
const poCfg = db.prepare('SELECT user_key, app_token FROM pushover_settings WHERE user_id=?').get(userId);
@@ -911,6 +930,13 @@ router.post('/favorites/acknowledge-all', authenticate, requireAdmin, (req, res)
}).catch(() => {});
}
} catch {}
return toAck.length;
}
// POST /favorites/acknowledge-all Admin: alle quittieren
router.post('/favorites/acknowledge-all', authenticate, requireAdmin, (req, res) => {
ackAllFavorites();
res.json({ ok: true });
});
// POST /favorites Favorit hinzufügen (alle User inkl. Admin bekommen Pushover)
@@ -958,27 +984,9 @@ router.delete('/favorites/:tmdb_id', authenticate, (req, res) => {
// POST /favorites/:id/acknowledge Admin: einzelnen quittieren
router.post('/favorites/:id/acknowledge', authenticate, requireAdmin, (req, res) => {
const fav = db.prepare('SELECT * FROM movie_favorites WHERE id=?').get(req.params.id);
const fav = ackFavorite(req.params.id);
if (!fav) return res.status(404).json({ error: 'Nicht gefunden' });
db.prepare('UPDATE movie_favorites SET acknowledged=1, acknowledged_at=CURRENT_TIMESTAMP, user_notified=0 WHERE id=?').run(fav.id);
res.json({ ok: true });
// Pushover an den User schicken falls eingerichtet (fire & forget)
try {
const poCfg = db.prepare('SELECT user_key, app_token FROM pushover_settings WHERE user_id=?').get(fav.user_id);
if (poCfg?.app_token && poCfg?.user_key) {
fetch('https://api.pushover.net/1/messages.json', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: poCfg.app_token,
user: poCfg.user_key,
title: '✅ Favorit bestätigt',
message: `"${fav.title}" wurde von einem Admin bestätigt.`,
priority: 0,
}),
}).catch(() => {});
}
} catch {}
});
// POST /favorites/:id/unacknowledge Admin: Quittierung rückgängig machen
@@ -1238,3 +1246,5 @@ router.get('/debug-xrel-tv', authenticate, async (req, res) => {
});
module.exports = router;
module.exports.ackFavorite = ackFavorite;
module.exports.ackAllFavorites = ackAllFavorites;