Stop replacing working FAAB thumbs with Gracenote URLs that 404, and only enrich highlights after verifying EventImages exist.
152 lines
5 KiB
TypeScript
152 lines
5 KiB
TypeScript
import {
|
|
artUrlsFromMergedId,
|
|
isLiveChannelThumb,
|
|
isReplayOrHighlightTitle,
|
|
isZiggoSportChannel,
|
|
needsZiggoArtEnrichment,
|
|
normalizeTitleTokens,
|
|
pickBestZiggoMatch,
|
|
segmentKeysForRange,
|
|
seriesAnchorTokens,
|
|
stripLiveThumbs,
|
|
titleOverlapScore,
|
|
timesOverlap,
|
|
type ZiggoEpgEvent,
|
|
} from "./ziggo-epg-art";
|
|
|
|
function assert(cond: unknown, msg: string) {
|
|
if (!cond) throw new Error(msg);
|
|
}
|
|
|
|
assert(isLiveChannelThumb("https://zst1-akm-cdn-triple.akamaized.net/live/zs1/thumb.jpg?scale=640x360"), "akamai live");
|
|
assert(isLiveChannelThumb("https://staticqbr-prod-nl.gnp.cloud.ziggogo.tv/image-service/latest/NL_000094_019321"), "latest");
|
|
assert(!isLiveChannelThumb("https://staticqbr-prod-nl.gnp.cloud.ziggogo.tv/image-service/ImagesEPG/EventImages/p24692584_bd_h8_aa.jpg"), "gracenote ok");
|
|
|
|
assert(isZiggoSportChannel("Ziggo Sport 1"), "zs1");
|
|
assert(isZiggoSportChannel("Ziggo Sport"), "zs");
|
|
assert(!isZiggoSportChannel("ESPN"), "espn");
|
|
assert(isReplayOrHighlightTitle("Moto3 BWIN Grand Prix of Austria (samenvatting)"), "samenvatting");
|
|
|
|
assert(
|
|
!needsZiggoArtEnrichment({
|
|
name: "ATP 250: Chengdu Open",
|
|
channel: "Ziggo Sport 1",
|
|
imageLandscape: "https://zst1-akm-cdn-triple.akamaized.net/live/zs1/thumb.jpg?scale=640",
|
|
images: [],
|
|
}),
|
|
"keep FAAB live thumb for normal events"
|
|
);
|
|
assert(
|
|
needsZiggoArtEnrichment({
|
|
name: "Moto3 BWIN Grand Prix of Austria (samenvatting)",
|
|
channel: "Ziggo Sport 1",
|
|
imageLandscape: "https://zst1-akm-cdn-triple.akamaized.net/live/zs1/thumb.jpg?scale=640",
|
|
images: [],
|
|
}),
|
|
"enrich highlight live thumb"
|
|
);
|
|
assert(
|
|
needsZiggoArtEnrichment({
|
|
name: "ATP 250",
|
|
channel: "Ziggo Sport 1",
|
|
imageLandscape: "https://go.ziggosporttotaal.nl/assets/channels/light/ziggo_sport_1.png",
|
|
images: [],
|
|
}),
|
|
"enrich logo-only"
|
|
);
|
|
|
|
const arts = artUrlsFromMergedId("24692584|nl");
|
|
assert(arts?.landscape.includes("p24692584_bd_h8_aa.jpg"), "landscape url");
|
|
assert(arts?.portrait.includes("p24692584_b_v12_aa.jpg"), "portrait url");
|
|
|
|
assert(titleOverlapScore("GT World Challenge: Nederland Race 2", "GT World Challenge Hoogtepunten Nederland: Race 2") >= 0.5, "overlap");
|
|
assert(normalizeTitleTokens("Ziggo Sport: GT World Challenge").has("gtworld"), "gtworld alias");
|
|
assert(normalizeTitleTokens("Grand Prix of Austria").has("oostenrijk"), "austria→oostenrijk");
|
|
assert(seriesAnchorTokens("Moto3 BWIN Grand Prix of Austria").has("moto3"), "anchor moto3");
|
|
|
|
const start = Date.parse("2026-09-20T23:00:00Z");
|
|
const end = Date.parse("2026-09-21T00:00:00Z");
|
|
assert(timesOverlap(start, end, 1789945200, 1789948800), "time overlap");
|
|
|
|
const candidates: ZiggoEpgEvent[] = [
|
|
{
|
|
id: "a",
|
|
channelId: "NL_000094_019321",
|
|
title: "GT World Challenge Hoogtepunten",
|
|
seriesName: "Nederland: Race 2",
|
|
startTime: 1789945200,
|
|
endTime: 1789948800,
|
|
mergedId: "24692584|nl",
|
|
},
|
|
{
|
|
id: "b",
|
|
channelId: "NL_000094_019321",
|
|
title: "Voetbalavond",
|
|
startTime: 1789945200,
|
|
endTime: 1789948800,
|
|
mergedId: "1|nl",
|
|
},
|
|
];
|
|
const hit = pickBestZiggoMatch(candidates, {
|
|
title: "GT World Challenge: Nederland Race 2 (hoogtepunten)",
|
|
startMs: start,
|
|
endMs: end,
|
|
});
|
|
assert(hit?.id === "a", "pick GT not football");
|
|
|
|
// Moto3 samenvatting days later than live session — must still resolve via loose match
|
|
const motoCands: ZiggoEpgEvent[] = [
|
|
{
|
|
id: "m3",
|
|
channelId: "NL_000094_019321",
|
|
title: "Moto3",
|
|
seriesName: "GP van Oostenrijk: Kwalificatie 2",
|
|
startTime: 1789815900,
|
|
endTime: 1789817700,
|
|
mergedId: "15289756|nl",
|
|
},
|
|
{
|
|
id: "foot",
|
|
channelId: "NL_000094_019321",
|
|
title: "Eredivisie samenvatting",
|
|
seriesName: "Ajax - PSV",
|
|
startTime: 1789972200,
|
|
endTime: 1789974000,
|
|
mergedId: "999|nl",
|
|
},
|
|
];
|
|
const motoHit = pickBestZiggoMatch(motoCands, {
|
|
title: "Moto3 BWIN Grand Prix of Austria (samenvatting)",
|
|
startMs: Date.parse("2026-09-21T06:30:00Z"),
|
|
endMs: Date.parse("2026-09-21T07:00:00Z"),
|
|
});
|
|
assert(motoHit?.id === "m3", `moto3 loose match got ${motoHit?.id}`);
|
|
assert(motoHit?.mergedId === "15289756|nl", "moto3 mergedId");
|
|
|
|
const stripped = stripLiveThumbs(
|
|
{
|
|
id: "x",
|
|
name: "Moto3",
|
|
channel: "Ziggo Sport 1",
|
|
network: "Ziggo Sport 1",
|
|
start: "2026-09-21T06:30:00Z",
|
|
stop: "2026-09-21T07:00:00Z",
|
|
imageLandscape: "https://zst1-akm-cdn-triple.akamaized.net/live/zs1/thumb.jpg?scale=640",
|
|
imageBackdrop: null,
|
|
imagePortrait: null,
|
|
logoUrl: null,
|
|
images: [
|
|
"https://go.ziggosporttotaal.nl/assets/channels/light/ziggo_sport_1.png",
|
|
"https://zst1-akm-cdn-triple.akamaized.net/live/zs1/thumb.jpg?scale=640",
|
|
],
|
|
},
|
|
"https://go.ziggosporttotaal.nl/assets/channels/light/ziggo_sport_1.png"
|
|
);
|
|
assert(!isLiveChannelThumb(stripped.imageLandscape), "stripped landscape");
|
|
assert(!(stripped.images ?? []).some(isLiveChannelThumb), "no live thumbs left");
|
|
|
|
const keys = segmentKeysForRange(start, end);
|
|
assert(keys.length >= 1, "segment keys");
|
|
assert(keys.every((k) => /^\d{14}$/.test(k)), "key format");
|
|
|
|
console.log("ziggo-epg-art tests ok");
|