openvibers/openvibe.mediahub Commits

Video, Pics and Download copy no longer advertises "no ads" (the network never promises it); Pics' title says it shares and embeds pictures (#107)

OP OpenVibers committed 22 days ago · ecc0805f1b · 4 files, +11 −11

Changes

ddiff --git a/server/http/pages.js b/server/http/pages.js
iindex 2b82182..345eb4e 100644
---- a/server/http/pages.js
++++ b/server/http/pages.js
@@@ -151,7 +151,7 @@ ${notice(p && p.detail ? p.detail : 'You are over the limit for this.', 'warn')}
// from config or rules, so the page cannot promise more than the service does.
const gb = (b) => rules.formatBytes(b).replace(/\.0 /, ' '); // "2 GB", not "2.0 GB"
const homeFaq = () => [
-- { q: 'Is OpenVibe.Download free?', a: `Yes. A free OpenVibe account gets ${gb(config.quotas.bytes)} of storage, files up to ${gb(config.quotas.maxFileBytes)} each and ${config.quotas.uploadsPerDay} uploads a day. There are no ads.` },
++ { q: 'Is OpenVibe.Download free?', a: `Yes. A free OpenVibe account gets ${gb(config.quotas.bytes)} of storage, files up to ${gb(config.quotas.maxFileBytes)} each and ${config.quotas.uploadsPerDay} uploads a day.` },
{ q: 'Who can open a file I share?', a: `Only the people you choose: named OpenVibe accounts, anyone signed in, or anyone with the link on a public download page. Every link expires in an hour to ${rules.EXPIRY_MAX_HOURS / 24} days, and you can revoke it at any time.` },
{ q: 'How do backups work?', a: 'Make a sync key on the Backups page and run the openvibe-download command on your computer, once or on a schedule. It sends only new or changed files into a folder of your drive, and it never deletes anything there unless you ask it to.' },
drops.enabled()
@@@ -170,7 +170,7 @@ ${notice(p && p.detail ? p.detail : 'You are over the limit for this.', 'warn')}
actions: signedIn(req)
? [{ label: 'Your files', href: '/files', primary: true }, { label: 'Back up a folder', href: '/sync' }]
: [{ label: 'Sign in with OpenVibe', href: '/auth/login?next=%2Ffiles', primary: true }, { label: 'How backups work', href: '#sc-back-up-a-folder-from-your-computer' }],
-- note: 'Open source, no ads. The bytes live in OpenVibe.Media; this service holds the names, the folders and the share links.',
++ note: 'Open source. The bytes live in OpenVibe.Media; this service holds the names, the folders and the share links.',
});
const faq = homeFaq();
page(req, res, {
@@@ -229,7 +229,7 @@ ${raw(showcase.nextSteps({
title: 'More on OpenVibe',
items: [
{ to: 'video', what: 'Upload a video', text: 'With AI captions and chapters, on your own channel.', href: `${config.video.url}/`, from: 'download' },
-- { to: 'pics', what: 'Share a picture', text: 'A link to share or embed anywhere, no ads.', href: `${config.pics.url}/`, from: 'download' },
++ { to: 'pics', what: 'Share a picture', text: 'A link to share or embed anywhere.', href: `${config.pics.url}/`, from: 'download' },
{ to: 'live', what: 'Go live from your browser', text: 'No OBS and no follower minimum.', href: 'https://openvibe.live/', from: 'download' },
{ to: 'chat', what: 'Talk it over', text: 'Rooms, servers and voice channels.', href: 'https://openvibe.chat/', from: 'download' },
],
ddiff --git a/server/pics/pages.js b/server/pics/pages.js
iindex c1e39dd..89be98e 100644
---- a/server/pics/pages.js
++++ b/server/pics/pages.js
@@@ -205,7 +205,7 @@ function createPicsRoutes(ctx) {
const FORMAT_NAMES = 'JPEG, PNG, GIF, WebP or AVIF';
const sizeText = (b) => formatBytes(b).replace(/\.0 /, ' ');
const homeFaq = () => [
-- { q: 'Is OpenVibe.Pics free?', a: `Yes, and there are no ads. A free OpenVibe account can upload ${cfg.imagesPerDay} pictures a day, each up to ${sizeText(cfg.maxImageBytes)}, and keep up to ${sizeText(cfg.quotaBytes)}.` },
++ { q: 'Is OpenVibe.Pics free?', a: `Yes. A free OpenVibe account can upload ${cfg.imagesPerDay} pictures a day, each up to ${sizeText(cfg.maxImageBytes)}, and keep up to ${sizeText(cfg.quotaBytes)}.` },
{ q: 'Who can see my pictures?', a: 'Only people you give the link to. Pictures are never listed, ranked or shown to search engines, and you can delete one at any time.' },
{ q: 'What is removed from my pictures?', a: 'Everything hidden in the file: the GPS position, the camera\'s serial number and the rest of its metadata. Every picture is decoded and saved again before anyone sees it.' },
{ q: 'Which files can I upload?', a: `${FORMAT_NAMES}, animated GIF and WebP included. SVG and other formats are refused, so nothing is ever served as it was uploaded.` },
@@@ -215,11 +215,11 @@ function createPicsRoutes(ctx) {
r.get('/', async (req, res) => {
const mine = signedIn(req) ? (await store.imagesOf(s, whoOf(req).requester, { limit: 12 })).rows : [];
const canUpload = signedIn(req) || cfg.anonymous;
-- const description = 'Upload a picture and get a link to share or embed anywhere. Albums, any size or format, no ads, with location and camera details removed.';
++ const description = 'Upload a picture and get a link to share or embed anywhere: albums, any size or format, and location and camera details removed from every picture.';
const faq = homeFaq();
return page(req, res, {
index: true,
-- title: `${SITE_NAME}: share pictures with a link, no ads`,
++ title: `${SITE_NAME}: share and embed pictures with a link`,
description,
jsonLd: [
seo.jsonLd.website({ name: SITE_NAME, url: base, description }),
@@@ -230,7 +230,7 @@ function createPicsRoutes(ctx) {
scripts: canUpload ? ['js/pics.js'] : [],
body: html`<header class="ovp-hero"><p class="ovp-eyebrow">${SITE_NAME}</p>
<h1>Share pictures. <span class="ovp-accent">Fast, open, yours.</span></h1>
--<p class="ovp-lede">Drop a picture, get a link to share or embed anywhere: on a forum, in a chat, on your site. No ads, no feed, and nothing about you hidden in the file.</p></header>
++<p class="ovp-lede">Drop a picture, get a link to share or embed anywhere: on a forum, in a chat, on your site. No feed to scroll, and nothing about you hidden in the file.</p></header>
${canUpload ? uploadForm(req) : html`<section class="ovp-drop ovp-drop--signin"><div class="ovp-drop-inner"><p class="ovp-drop-title">Sign in to upload</p><p class="ovp-drop-hint">Your OpenVibe account keeps your pictures and albums together, so you can delete them whenever you like.</p><p>${signInLink('/')}</p></div></section>`}
${signedIn(req) ? html`<section class="ovp-section" aria-labelledby="h-latest"><div class="ovp-section-head"><h2 id="h-latest">Your latest pictures</h2><a href="/mine">All of them</a></div>${grid(mine, 'Nothing yet: your uploads show up here.')}</section>` : ''}
<section class="ovp-section" aria-labelledby="h-how"><h2 id="h-how">How it works</h2><ol class="ovp-steps">
@@@ -579,7 +579,7 @@ ${row.state === 'hidden' ? html`<button class="ovp-btn" name="action" value="res
.send(seo.sitemapXml(['/', '/updates', ...legal.PATHS].map((p) => ({ loc: `${base}${p}` })))));
r.get('/llms.txt', (_req, res) => res.type('text/plain').set('Cache-Control', cache.htmlHeaders({ maxAge: 3600 })).send(seo.llmsTxt({
name: SITE_NAME,
-- summary: 'Picture hosting on the OpenVibe network: upload a picture, get a link to share or embed, albums, no ads.',
++ summary: 'Picture hosting on the OpenVibe network: upload a picture, get a link to share or embed, albums, any size or format.',
details: 'Pictures are unlisted (reachable only by their link). Each one is re-encoded with its metadata removed, and can be had resized and converted at /i/<slug>/w/<320|640|1280|1920|2560>.<webp|avif|jpg|png>. Alt text: the uploader writes it or asks OpenVibe.AI for a draft (POST /api/v1/images/<slug>/describe). API: POST /api/v1/images with the picture as the body (an OpenVibe sign-in token as a Bearer).',
sections: [{ title: 'Start here', links: [{ title: SITE_NAME, url: `${base}/` }, { title: 'Terms', url: `${base}/terms` }, { title: 'DMCA', url: `${base}/dmca` }] }],
})));
ddiff --git a/server/video/pages.js b/server/video/pages.js
iindex b39a3b9..3fdd839 100644
---- a/server/video/pages.js
++++ b/server/video/pages.js
@@@ -780,7 +780,7 @@ ${kind === 'vod' ? html`<label class="ovv-field"><span>Description</span><textar
}
const n = (v) => Number(v).toLocaleString('en-US');
const HOME_FAQ = (vu) => [
-- { q: 'Is OpenVibe.Video free?', a: `Yes. Watching needs no account, and uploading needs a free OpenVibe account. Each person can upload ${vu.perDay} videos a day and keep up to ${formatBytes(vu.quotaBytes)}. There are no ads.` },
++ { q: 'Is OpenVibe.Video free?', a: `Yes. Watching needs no account, and uploading needs a free OpenVibe account. Each person can upload ${vu.perDay} videos a day and keep up to ${formatBytes(vu.quotaBytes)}.` },
{ q: 'Which files can I upload?', a: `MP4 (MOV and M4V too), WebM and MKV, up to ${formatBytes(vu.maxBytes)} each. You can also record your camera or screen right in the browser.` },
{ q: 'How do streams from OpenVibe.Live get here?', a: 'When a stream on OpenVibe.Live is recorded, the recording appears here after the stream ends, on the streamer\'s channel at openvibe.video/@name, together with the clips people cut from it.' },
{ q: 'Where do the captions and chapters come from?', a: 'OpenVibe.AI turns the speech into captions, splits the video into chapters and writes a short summary. On your own uploads you can use the summary as the description.' },
@@@ -853,7 +853,7 @@ ${channels.length ? html`<section class="ovv-section" aria-labelledby="h-channel
<section class="ovv-section" aria-labelledby="h-faq"><h2 id="h-faq">Questions</h2><div class="ovv-faq">${faq.map((f) => html`<details><summary>${f.q}</summary><p>${f.a}</p></details>`)}</div></section>
<section class="ovv-section" aria-labelledby="h-more"><h2 id="h-more">More on OpenVibe</h2><ul class="ovv-more" role="list">
<li><a href="${livePublic}/"><strong>OpenVibe.Live</strong><span>Go live from your browser, no OBS needed.</span></a></li>
--<li><a href="${config.pics.url}/"><strong>OpenVibe.Pics</strong><span>Share pictures with a link, no ads.</span></a></li>
++<li><a href="${config.pics.url}/"><strong>OpenVibe.Pics</strong><span>Share and embed pictures with a link.</span></a></li>
<li><a href="${config.baseUrl}/"><strong>OpenVibe.Download</strong><span>Your files and backups, shared on your terms.</span></a></li>
<li><a href="https://openvibe.community/"><strong>OpenVibe.Community</strong><span>Forums and pastes for talking it over.</span></a></li>
</ul></section>`,
ddiff --git a/test/pics.test.js b/test/pics.test.js
iindex 353cffb..6e75721 100644
---- a/test/pics.test.js
++++ b/test/pics.test.js
@@@ -79,7 +79,7 @@ function multipart(fields, file) {
await check('the home: how it works, the links, the API, the limits from config, questions that match its FAQPage', async () => {
const home = (await t.get('/', { headers: PICS })).text;
assert.strictEqual((home.match(/<h1[\s>]/g) || []).length, 1, 'one h1');
-- assert.match(home, /<title>OpenVibe\.Pics: share pictures with a link, no ads<\/title>/);
++ assert.match(home, /<title>OpenVibe\.Pics: share and embed pictures with a link<\/title>/);
const sections = ['How it works', 'The links a picture gets', 'Upload from your own app', 'What a free account gets', 'Questions', 'More on OpenVibe'];
assert.deepStrictEqual(sections.filter((h) => !home.includes(`>${h}</h2>`)), [], 'every section is there');
assert.ok(home.includes('<td>20 MB</td>') && home.includes('<td>200</td>') && home.includes('<td>5 GB</td>'), 'the limits are the configured ones');