openvibers/openvibe.mediahub Commits

An upload with a short description gets a meta description that says what the video is (#280)

OP OpenVibers committed 10 days ago · f341e9d5c5 · 2 files, +17 −1

The SEO audit (11-03) found an indexable upload whose meta description was the uploader's
"Wheeeee" (7 characters). A description under 50 characters is kept and followed by the AI's
overview when there is one, or by who made the video, when and how long it is.

Changes

ddiff --git a/server/video/upload-routes.js b/server/video/upload-routes.js
iindex 6f4a700..6ec1a9a 100644
---- a/server/video/upload-routes.js
++++ b/server/video/upload-routes.js
@@@ -267,11 +267,19 @@ ${fresh.map((x) => html`<tr><td><a href="/u/${x.id}">${x.title}</a></td><td>${st
const reel = cutsOn ? await ctx.videoCuts.highlightsPlan(row) : null;
const original = own && row.edited_from ? await up.byId(row.edited_from) : null;
if (cutBusy) res.set('Refresh', '15');
++ // The description search results and share cards show: the uploader's own words when they say enough. A short one
++ // ("Wheeeee", SEO audit 11-03) is kept and followed by the AI's overview when there is one, or by who made the
++ // video, when and how long it is, so the snippet says what the page is.
++ const said = String(row.description || '').trim();
++ const { lengthWords, dayLabel } = require('./watch-ui');
++ const madeBy = `A video by @${channel || 'someone'} on OpenVibe.Video${dayLabel(row.created_at) ? `, uploaded ${dayLabel(row.created_at)}` : ''}${lengthWords(row.duration_seconds) ? `, ${lengthWords(row.duration_seconds)} long` : ''}.`;
++ const about = said.length >= 50 ? said.slice(0, 300)
++ : [said ? `${said.replace(/[\s.!?…]+$/u, '')}.` : '', aiDone && ai.overview ? String(ai.overview).trim() : madeBy].filter(Boolean).join(' ').slice(0, 300);
return page(req, res, {
index: listed, noindex: !listed,
...(listed ? {} : { cache: cache.htmlHeaders({ private: true }) }),
title: row.title,
-- description: row.description ? row.description.slice(0, 300) : `A video by @${channel || 'someone'} on OpenVibe.Video.`,
++ description: about,
...(listed && thumb ? { image: thumb, ogType: 'video.other' } : {}),
scripts: ready ? ['js/video.js'] : [],
player: !!(ready && vod),
ddiff --git a/test/video-uploads.test.js b/test/video-uploads.test.js
iindex c018561..d3a65a7 100644
---- a/test/video-uploads.test.js
++++ b/test/video-uploads.test.js
@@@ -145,6 +145,14 @@ function vreq(base, path, { method = 'GET', cookie, form, json, body, same = tru
await vreq(t.base, `/u/${id}/manage`, { method: 'POST', cookie: kimCookie, form: { title: 'Coast trip', visibility: 'public' } });
});
++ await check('a short description is kept, and the meta description says what the video is (SEO audit 11-03)', async () => {
++ const page = (await vreq(t.base, `/u/${id}`)).text;
++ const m = page.match(/<meta name="description" content="([^"]*)"/);
++ assert.ok(m, 'a meta description');
++ assert.ok(m[1].startsWith('x. '), `the uploader's own word first (${m[1]})`);
++ assert.ok(m[1].length >= 50 && m[1].length <= 300, `long enough for a search result (${m[1].length})`);
++ });
++
await check('a child-safety report hides it at once; one report per person; the owner sees why', async () => {
const r = await vreq(t.base, `/u/${id}/report`, { method: 'POST', cookie: samCookie, form: { reason: 'child_safety', note: 'look at 0:12' } });
assert.strictEqual(r.status, 303);