Release 2.8.4
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
// Slide route registration and pagination wiring.
|
||||
|
||||
const { renderFragment } = require('../../../view');
|
||||
const fs = require('fs');
|
||||
const crypto = require('crypto');
|
||||
const path = require('path');
|
||||
const { verifyRequestAuth } = require('#src/request-auth');
|
||||
const { verifyRequestAuth, verifyPageAuthToken } = require('#src/request-auth');
|
||||
const { getFontStylesheetHref } = require('#src/web/lib/media/font-library');
|
||||
const { buildThumbnailPreviewPayload } = require('#src/web/lib/media/slide-thumbnail-preview');
|
||||
const { buildThumbnailPreviewPayload } = require('#src/web/lib/media/slide-thumbnails');
|
||||
|
||||
function safeJsonForScript(value) {
|
||||
return JSON.stringify(value === undefined ? null : value).replace(/</g, '\\u003c');
|
||||
@@ -27,6 +29,14 @@ module.exports = function registerSlidesRoutes(app, deps) {
|
||||
next();
|
||||
}
|
||||
|
||||
function requirePopupPreviewAccess(req, res, next) {
|
||||
if (verifyRequestAuth(req) || verifyPageAuthToken(req.headers && req.headers['x-pulse-page-auth'])) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return requirePermission('slides.read')(req, res, next);
|
||||
}
|
||||
|
||||
const LIST_PAGE_SIZE = 25;
|
||||
|
||||
app.get('/slides', requirePermission('slides.read'), async function (req, res, next) {
|
||||
@@ -45,7 +55,7 @@ module.exports = function registerSlidesRoutes(app, deps) {
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/slides/popup-preview', requirePermission('slides.read'), function (_req, res) {
|
||||
app.get('/slides/popup-preview', requirePopupPreviewAccess, function (_req, res) {
|
||||
res.send(renderFragment('slides/popup-preview', {
|
||||
title: 'Slide preview',
|
||||
framePopupCard: true,
|
||||
@@ -61,9 +71,52 @@ module.exports = function registerSlidesRoutes(app, deps) {
|
||||
return res.status(404).send('Slide not found');
|
||||
}
|
||||
|
||||
const rssData = typeof common.fetchRssFeedsData === 'function' ? await common.fetchRssFeedsData(pool) : { rssFeeds: [] };
|
||||
const rssFeeds = await Promise.all((rssData.rssFeeds || []).map(async function (feed) {
|
||||
const items = typeof common.fetchRssFeedItemsByFeedId === 'function' ? await common.fetchRssFeedItemsByFeedId(pool, feed.id) : [];
|
||||
return Object.assign({}, feed, { items: items });
|
||||
}));
|
||||
const apiData = typeof common.fetchApiSourcesData === 'function' ? await common.fetchApiSourcesData(pool) : { apiSources: [] };
|
||||
const apiSources = (apiData.apiSources || []).map(function (source) {
|
||||
return Object.assign({}, source, { responseJson: common.parseJsonSafe ? common.parseJsonSafe(source.last_response_json) : null });
|
||||
});
|
||||
const getApiItems = function (source) {
|
||||
const response = source && source.responseJson;
|
||||
const itemsPath = String(source && source.items_path || '').trim();
|
||||
if (itemsPath) {
|
||||
const selected = itemsPath.split('.').reduce(function (current, segment) { return current === undefined || current === null ? '' : current[segment]; }, response);
|
||||
return Array.isArray(selected) ? selected : [];
|
||||
}
|
||||
if (Array.isArray(response)) return response;
|
||||
if (response && Array.isArray(response.items)) return response.items;
|
||||
if (response && Array.isArray(response.results)) return response.results;
|
||||
if (response && Array.isArray(response.data)) return response.data;
|
||||
return response ? [response] : [];
|
||||
};
|
||||
const getItem = function (type, regionContent) {
|
||||
const index = Math.max(0, Math.max(1, Number(regionContent && regionContent.item_number || 1)) - 1);
|
||||
if (type === 'api') {
|
||||
const source = apiSources.find(function (entry) { return Number(entry.id) === Number(regionContent.source_id); });
|
||||
return getApiItems(source)[index] || null;
|
||||
}
|
||||
if (type === 'rss') {
|
||||
const feed = rssFeeds.find(function (entry) { return Number(entry.id) === Number(regionContent.feed_id); });
|
||||
return feed && Array.isArray(feed.items) ? feed.items[index] || null : null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const getCachedImagePath = function (remoteUrl) {
|
||||
const hash = crypto.createHash('sha256').update(String(remoteUrl || '')).digest('hex');
|
||||
const cacheDir = path.join(mediaDir, 'player-cache', 'remote-images');
|
||||
const extensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'];
|
||||
const file = extensions.map(function (extension) { return hash + extension; }).find(function (name) { return fs.existsSync(path.join(cacheDir, name)); });
|
||||
return file ? '/media/player-cache/remote-images/' + file : '';
|
||||
};
|
||||
const payload = buildThumbnailPreviewPayload(slide, {
|
||||
baseUrl: webBaseUrl || (String(req.headers.host || '').trim() ? `${req.protocol}://${String(req.headers.host).trim()}` : ''),
|
||||
fontStylesheetHref: getFontStylesheetHref(mediaDir)
|
||||
fontStylesheetHref: getFontStylesheetHref(mediaDir),
|
||||
getItem: getItem,
|
||||
getCachedImagePath: getCachedImagePath
|
||||
});
|
||||
|
||||
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
||||
|
||||
Reference in New Issue
Block a user