Resolve external embed previews and keep their real MIME types

This commit is contained in:
Fisto
2026-09-16 12:52:44 +02:00
parent 7fa6118b6f
commit 1b5fcfed2f
11 changed files with 313 additions and 41 deletions
+86 -5
View File
@@ -10,6 +10,7 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { downloadOne, downloadPreview, previewUrlFor, videoPoster } from "../src/download.js";
import { ogImageFromHtml, resolveEmbedPreview } from "../src/embed-preview.js";
import { ScrapeEngine, type FetchPage, type ScrapeBackend } from "../src/engine.js";
import { extractMedia } from "../src/extract.js";
import { PuppetBackend } from "../src/puppet-backend.js";
@@ -549,6 +550,17 @@ void (async () => {
assert.equal(outcome.state, "downloaded");
assert.equal(outcome.path, `${outcome.hash}.webp`);
assert.equal(existsSync(join(dir, `${outcome.hash}.webp`)), true);
const jpeg = await downloadPreview(
{ id: 10, url: "https://cdn.discordapp.com/attachments/1/2/pic.png", kind: "image", source: "attachment", preview_url: null },
dir,
{
fetchImpl: async () =>
new Response("jpeg-bytes", { status: 200, headers: { "content-type": "image/jpeg" } })
}
);
assert.equal(jpeg.path, `${jpeg.hash}.jpg`);
assert.equal(existsSync(join(dir, `${jpeg.hash}.jpg`)), true);
});
await test("embed thumbnails download only when enabled", async () => {
@@ -635,6 +647,7 @@ void (async () => {
const row = store.queryMedia({ kind: "image" })[0];
assert.ok(row.preview_hash);
assert.ok((row.preview_bytes ?? 0) > 0);
assert.equal(row.preview_ext, "webp");
store.close();
assert.equal(existsSync(join(root, started.id, "thumbs", `${row.preview_hash}.webp`)), true);
});
@@ -704,14 +717,82 @@ void (async () => {
const embed = store.queryMedia({ kind: "video" })[0];
assert.ok(embed.preview_hash);
assert.equal(
existsSync(join(dest, started.id, "thumbnails", `${embed.preview_hash}.webp`)),
true
);
assert.equal(existsSync(join(root, started.id, "thumbs", `${embed.preview_hash}.webp`)), true);
const previewFile = `${embed.preview_hash}.${embed.preview_ext ?? "webp"}`;
assert.equal(existsSync(join(dest, started.id, "thumbnails", previewFile)), true);
assert.equal(existsSync(join(root, started.id, "thumbs", previewFile)), true);
store.close();
});
await test("embed previews resolve from providers and og:image", async () => {
const fetchImpl = async (input: any) => {
const url = String(input);
if (url.includes("youtube.com/oembed")) {
return new Response(JSON.stringify({ thumbnail_url: "https://i.ytimg.com/ok.jpg" }), {
status: 200
});
}
if (url.includes("api.fxtwitter.com")) {
return new Response(
JSON.stringify({ tweet: { media: { videos: [{ thumbnail_url: "https://pbs.twimg.com/ok.jpg" }] } } }),
{ status: 200 }
);
}
if (url.includes("vxreddit.com")) {
return new Response(
'<html><head><meta property="og:image" content="https://i.redd.it/ok.jpg"></head></html>',
{ status: 200 }
);
}
return new Response("no", { status: 404 });
};
assert.equal(
await resolveEmbedPreview(
{ url: "https://youtu.be/abc", source: "embed", preview_url: null },
{ fetchImpl }
),
"https://i.ytimg.com/ok.jpg"
);
assert.equal(
await resolveEmbedPreview(
{ url: "https://fxtwitter.com/u/status/12345", source: "embed", preview_url: null },
{ fetchImpl }
),
"https://pbs.twimg.com/ok.jpg"
);
assert.equal(
await resolveEmbedPreview(
{ url: "https://vxreddit.com/r/x/comments/1", source: "embed", preview_url: null },
{ fetchImpl }
),
"https://i.redd.it/ok.jpg"
);
assert.equal(
await resolveEmbedPreview(
{ url: "https://x.com/u/status/1", source: "embed", preview_url: "https://stored/ok.jpg" },
{ fetchImpl }
),
"https://stored/ok.jpg"
);
assert.equal(
await resolveEmbedPreview(
{ url: "https://cdn.discordapp.com/x.png", source: "attachment", preview_url: null },
{ fetchImpl }
),
null
);
assert.equal(
ogImageFromHtml('<meta content="https://a/1.jpg" property="og:image">'),
"https://a/1.jpg"
);
assert.equal(
ogImageFromHtml('<meta name="twitter:image" content="https://a/2.jpg">'),
"https://a/2.jpg"
);
assert.equal(ogImageFromHtml("<html></html>"), null);
});
await test("videoPoster extracts a cached frame", async () => {
const dir = join(root, "poster-test");
mkdirSync(dir, { recursive: true });