openvibers/openvibe.mediahub Commits
Video: /updates — what shipped on openvibe.video (the shared update log) (#52)
Changes
@@@ -83,7 +83,7 @@ ${render(o.body)}logoutUrl: '/auth/logout?next={path}',silentLogin: `${String(o.baseUrl).replace(/\/+$/, '')}/auth/login?silent=1&next={url}`,},-- footer: { service: 'media-hub', variant: 'compact', brandName: SITE_NAME },++ footer: { service: 'media-hub', variant: 'compact', brandName: SITE_NAME, updates: '/updates' },head,body,});@@@ -23,7 +23,8 @@ const seo = require('openvibe-shared/seo');const ovServe = require('openvibe-shared/serve');const { asyncRouter } = require('../http/router');const { sameOrigin } = require('../http/principal');--const { html, notice } = require('../render/html');++const { html, raw, notice } = require('../render/html');++const frame = require('openvibe-shared/frame');const { send, asset, assetVersion, SITE_NAME } = require('./layout');const { createLiveClient, LiveRefusedError } = require('./live-client');const { createChatClient } = require('./chat-client');@@@ -643,6 +644,14 @@ ${kind === 'vod' ? html`<label class="ovv-field"><span>Description</span><textar});});++ // ── What shipped: the shared update log, as on every OpenVibe site (MediaHub's log: Video and Download ship together) ──++ r.get('/updates', (req, res) => page(req, res, {++ index: true,++ title: 'What shipped on OpenVibe.Video',++ description: 'Every change deployed to OpenVibe.Video, newest first.',++ body: raw(frame.updatesBody({ service: 'media-hub', siteName: 'OpenVibe.Video' }) + `<script src="${ovServe.url('shipped.js')}" defer></script>`),++ }));++// ── WebVTT tracks ───────────────────────────────────────r.get('/v/:id/captions.vtt', async (req, res) => {const id = String(req.params.id || '');@@@ -1140,6 +1149,7 @@ ${isOwner ? html`<p class="ovv-fine">You can reorder items with the up and down}const urls = [{ loc: `${base}/`, lastmod: newest(items.map((it) => it.created_at)) },++ { loc: `${base}/updates` },...items.map((it) => ({ loc: `${base}${it.kind === 'clip' ? '/c/' : '/v/'}${Number(it.id)}`, lastmod: day(it.created_at) })),...[...channels].map(([u, d]) => ({ loc: `${base}/@${u}`, lastmod: d })),].map((u) => (u.lastmod ? u : { loc: u.loc }));@@@ -330,6 +330,15 @@ function countOccurrences(haystack, needle) {assert.strictEqual(r.text, 'WEBVTT\n\n00:00:10.000 --> 00:00:30.000\nIntro & setup\n\n00:00:30.000 --> 00:00:45.000\nThe <main> part\n');});++ await check('/updates: the shared update log on the video host, one heading, in the sitemap', async () => {++ const r = await getVideo('/updates');++ assert.strictEqual(r.status, 200);++ assert.ok(r.text.includes('<h1>What shipped on OpenVibe.Video</h1>') && r.text.includes('data-ov-shipped="log" data-service="media-hub"'));++ assert.strictEqual((r.text.match(/<h1[\s>]/g) || []).length, 1);++ assert.match(r.text, /<script src="\/shared\/shipped\.js\?v=[0-9a-f]+" defer><\/script>/);++ assert.match((await getVideo('/sitemap.xml')).text, /<loc>[^<]+\/updates<\/loc>/);++ });++await check('the sitemap lists public items and leaves the unlisted VOD out', async () => {const r = await getVideo('/sitemap.xml');assert.match(r.text, /<loc>https:\/\/openvibe\.video\/<\/loc><lastmod>\d{4}-\d{2}-\d{2}<\/lastmod>/, 'the home, dated by the newest item');
@@ -83,7 +83,7 @@ ${render(o.body)}
@@ -83,7 +83,7 @@ ${render(o.body)}
logoutUrl: '/auth/logout?next={path}',
logoutUrl: '/auth/logout?next={path}',
silentLogin: `${String(o.baseUrl).replace(/\/+$/, '')}/auth/login?silent=1&next={url}`,
silentLogin: `${String(o.baseUrl).replace(/\/+$/, '')}/auth/login?silent=1&next={url}`,
},
},
- footer: { service: 'media-hub', variant: 'compact', brandName: SITE_NAME },
+ footer: { service: 'media-hub', variant: 'compact', brandName: SITE_NAME, updates: '/updates' },
head,
head,
body,
body,
});
});
@@ -23,7 +23,8 @@ const seo = require('openvibe-shared/seo');
@@ -23,7 +23,8 @@ const seo = require('openvibe-shared/seo');
const ovServe = require('openvibe-shared/serve');
const ovServe = require('openvibe-shared/serve');
const { asyncRouter } = require('../http/router');
const { asyncRouter } = require('../http/router');
const { sameOrigin } = require('../http/principal');
const { sameOrigin } = require('../http/principal');
-const { html, notice } = require('../render/html');
+const { html, raw, notice } = require('../render/html');
+const frame = require('openvibe-shared/frame');
const { send, asset, assetVersion, SITE_NAME } = require('./layout');
const { send, asset, assetVersion, SITE_NAME } = require('./layout');
const { createLiveClient, LiveRefusedError } = require('./live-client');
const { createLiveClient, LiveRefusedError } = require('./live-client');
const { createChatClient } = require('./chat-client');
const { createChatClient } = require('./chat-client');
@@ -643,6 +644,14 @@ ${kind === 'vod' ? html`<label class="ovv-field"><span>Description</span><textar
@@ -643,6 +644,14 @@ ${kind === 'vod' ? html`<label class="ovv-field"><span>Description</span><textar
});
});
});
});
+ // ── What shipped: the shared update log, as on every OpenVibe site (MediaHub's log: Video and Download ship together) ──
+ r.get('/updates', (req, res) => page(req, res, {
+ index: true,
+ title: 'What shipped on OpenVibe.Video',
+ description: 'Every change deployed to OpenVibe.Video, newest first.',
+ body: raw(frame.updatesBody({ service: 'media-hub', siteName: 'OpenVibe.Video' }) + `<script src="${ovServe.url('shipped.js')}" defer></script>`),
+ }));
+
// ── WebVTT tracks ───────────────────────────────────────
// ── WebVTT tracks ───────────────────────────────────────
r.get('/v/:id/captions.vtt', async (req, res) => {
r.get('/v/:id/captions.vtt', async (req, res) => {
const id = String(req.params.id || '');
const id = String(req.params.id || '');
@@ -1140,6 +1149,7 @@ ${isOwner ? html`<p class="ovv-fine">You can reorder items with the up and down
@@ -1140,6 +1149,7 @@ ${isOwner ? html`<p class="ovv-fine">You can reorder items with the up and down
}
}
const urls = [
const urls = [
{ loc: `${base}/`, lastmod: newest(items.map((it) => it.created_at)) },
{ loc: `${base}/`, lastmod: newest(items.map((it) => it.created_at)) },
+ { loc: `${base}/updates` },
...items.map((it) => ({ loc: `${base}${it.kind === 'clip' ? '/c/' : '/v/'}${Number(it.id)}`, lastmod: day(it.created_at) })),
...items.map((it) => ({ loc: `${base}${it.kind === 'clip' ? '/c/' : '/v/'}${Number(it.id)}`, lastmod: day(it.created_at) })),
...[...channels].map(([u, d]) => ({ loc: `${base}/@${u}`, lastmod: d })),
...[...channels].map(([u, d]) => ({ loc: `${base}/@${u}`, lastmod: d })),
].map((u) => (u.lastmod ? u : { loc: u.loc }));
].map((u) => (u.lastmod ? u : { loc: u.loc }));
@@ -330,6 +330,15 @@ function countOccurrences(haystack, needle) {
@@ -330,6 +330,15 @@ function countOccurrences(haystack, needle) {
assert.strictEqual(r.text, 'WEBVTT\n\n00:00:10.000 --> 00:00:30.000\nIntro & setup\n\n00:00:30.000 --> 00:00:45.000\nThe <main> part\n');
assert.strictEqual(r.text, 'WEBVTT\n\n00:00:10.000 --> 00:00:30.000\nIntro & setup\n\n00:00:30.000 --> 00:00:45.000\nThe <main> part\n');
});
});
+ await check('/updates: the shared update log on the video host, one heading, in the sitemap', async () => {
+ const r = await getVideo('/updates');
+ assert.strictEqual(r.status, 200);
+ assert.ok(r.text.includes('<h1>What shipped on OpenVibe.Video</h1>') && r.text.includes('data-ov-shipped="log" data-service="media-hub"'));
+ assert.strictEqual((r.text.match(/<h1[\s>]/g) || []).length, 1);
+ assert.match(r.text, /<script src="\/shared\/shipped\.js\?v=[0-9a-f]+" defer><\/script>/);
+ assert.match((await getVideo('/sitemap.xml')).text, /<loc>[^<]+\/updates<\/loc>/);
+ });
+
await check('the sitemap lists public items and leaves the unlisted VOD out', async () => {
await check('the sitemap lists public items and leaves the unlisted VOD out', async () => {
const r = await getVideo('/sitemap.xml');
const r = await getVideo('/sitemap.xml');
assert.match(r.text, /<loc>https:\/\/openvibe\.video\/<\/loc><lastmod>\d{4}-\d{2}-\d{2}<\/lastmod>/, 'the home, dated by the newest item');
assert.match(r.text, /<loc>https:\/\/openvibe\.video\/<\/loc><lastmod>\d{4}-\d{2}-\d{2}<\/lastmod>/, 'the home, dated by the newest item');