Release v2.10.3
This commit is contained in:
+41
-45
@@ -1,3 +1,5 @@
|
||||
// Thin-client bridge for player registration, snapshots, commands, and heartbeats.
|
||||
|
||||
const express = require('express');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
@@ -8,7 +10,6 @@ const common = require('../common');
|
||||
const { verifyRequestAuth, createRequestAuthHeaders } = require('#src/request-auth');
|
||||
const { normalizeDeviceId, upsertPlayerRegistration, recordPlayerHeartbeat } = require('#src/data/player-registry');
|
||||
const { createPlayerPlaylistService } = require('../player/playlist');
|
||||
const { buildThumbnailPreviewData } = require('../player/thumbnail-preview');
|
||||
const { commitDeviceBinding, bindPlayerToScreen, getOnboardingStatus, getPlayerPublicBaseUrl } = require('../player/onboarding');
|
||||
const { createStyledQrCodeSvg } = require('../data/qr-code');
|
||||
const { verifyPageAuthToken } = require('#src/request-auth');
|
||||
@@ -458,7 +459,21 @@ async function start() {
|
||||
|
||||
function storeScreenSnapshot(slug, connections, deviceIds) {
|
||||
const key = String(slug || '').trim();
|
||||
const normalizedConnections = Array.isArray(connections) ? connections : [];
|
||||
const normalizedConnections = [];
|
||||
const connectionIndexes = new Map();
|
||||
(Array.isArray(connections) ? connections : []).forEach(function (connection) {
|
||||
const identity = connection && typeof connection === 'object'
|
||||
? [String(connection.deviceId || '').trim(), String(connection.clientId || '').trim()].join('|')
|
||||
: '';
|
||||
if (!identity || !connectionIndexes.has(identity)) {
|
||||
if (identity) {
|
||||
connectionIndexes.set(identity, normalizedConnections.length);
|
||||
}
|
||||
normalizedConnections.push(connection);
|
||||
return;
|
||||
}
|
||||
normalizedConnections[connectionIndexes.get(identity)] = connection;
|
||||
});
|
||||
const normalizedDeviceIds = Array.isArray(deviceIds) ? deviceIds.map(function (value) {
|
||||
return normalizeDeviceId(value);
|
||||
}).filter(Boolean) : [];
|
||||
@@ -654,6 +669,16 @@ async function start() {
|
||||
}, response && typeof response === 'object' ? response : {});
|
||||
}));
|
||||
|
||||
logBridge('Screen command result', {
|
||||
screenSlug: slug,
|
||||
command: command,
|
||||
connectionId: connectionId || null,
|
||||
targets: targetPlayers.map(function (target) { return target.deviceId; }),
|
||||
results: results.map(function (result) {
|
||||
return { playerIdentifier: result.playerIdentifier, ok: result.ok, status: result.status, error: result.error || null };
|
||||
})
|
||||
});
|
||||
|
||||
res.json({
|
||||
ok: true,
|
||||
screenSlug: slug,
|
||||
@@ -882,48 +907,6 @@ async function start() {
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/internal/slide-thumbnails/:id/preview', requireRequestAuth, async function (req, res, next) {
|
||||
try {
|
||||
const slide = await common.fetchSlideById(pool, Number(req.params.id));
|
||||
if (!slide) {
|
||||
return res.status(404).send('Slide not found');
|
||||
}
|
||||
|
||||
const data = buildThumbnailPreviewData(slide);
|
||||
|
||||
if (typeof common.fetchRssFeedsData === 'function' && typeof common.fetchRssFeedItemsByFeedId === 'function') {
|
||||
const rssData = await common.fetchRssFeedsData(pool);
|
||||
data.rssFeeds = await Promise.all((rssData.rssFeeds || []).map(async function (feed) {
|
||||
const items = await common.fetchRssFeedItemsByFeedId(pool, feed.id);
|
||||
return Object.assign({}, feed, {
|
||||
items: items.map(function (item) {
|
||||
return typeof common.normalizeRssFeedItem === 'function' ? common.normalizeRssFeedItem(item) : item;
|
||||
})
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if (typeof common.fetchApiSourcesData === 'function') {
|
||||
const apiData = await common.fetchApiSourcesData(pool);
|
||||
data.apiSources = (apiData.apiSources || []).map(function (source) {
|
||||
return Object.assign({}, source, {
|
||||
responseJson: typeof common.parseJsonSafe === 'function' ? common.parseJsonSafe(source.last_response_json) : null
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof common.fetchTimetablesData === 'function') {
|
||||
const timetableData = await common.fetchTimetablesData(pool);
|
||||
data.timetableGroups = Array.isArray(timetableData && timetableData.timetableGroups) ? timetableData.timetableGroups : [];
|
||||
}
|
||||
|
||||
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
||||
res.send(common.renderPlayerPage('slide-thumbnail-preview-' + slide.id, data));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/players/:deviceId/commands', requireRequestAuth, async function (req, res, next) {
|
||||
try {
|
||||
const deviceId = normalizeDeviceId(req.params.deviceId);
|
||||
@@ -989,7 +972,14 @@ async function start() {
|
||||
return;
|
||||
}
|
||||
|
||||
setScreenSnapshotSource(slug, deviceId, Array.isArray(payload.connections) ? payload.connections : []);
|
||||
const snapshotPlayerPublicBaseUrl = String(payload.playerPublicBaseUrl || socket.publicBaseUrl || '').trim().replace(/\/$/, '');
|
||||
const connections = Array.isArray(payload.connections) ? payload.connections.map(function (connection) {
|
||||
if (!connection || typeof connection !== 'object' || !snapshotPlayerPublicBaseUrl) {
|
||||
return connection;
|
||||
}
|
||||
return Object.assign({}, connection, { playerPublicBaseUrl: snapshotPlayerPublicBaseUrl });
|
||||
}) : [];
|
||||
setScreenSnapshotSource(slug, deviceId, connections);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1021,6 +1011,12 @@ async function start() {
|
||||
publicBaseUrl: payload.publicBaseUrl,
|
||||
internalBaseUrl: payload.internalBaseUrl
|
||||
});
|
||||
if (typeof common.touchOnboardingDeviceLastSeen === 'function') {
|
||||
const onboardingClientIds = (Array.isArray(payload.connections) ? payload.connections : []).map(function (connection) {
|
||||
return connection && connection.clientId;
|
||||
});
|
||||
await common.touchOnboardingDeviceLastSeen(pool, onboardingClientIds);
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify({ type: 'heartbeat-ack', ok: true, player: player }));
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user