xtream bundler
Build and Push Docker Images / build-and-push (push) Successful in 36s

This commit is contained in:
Bram committed 2026-11-06 19:24:39 +01:00
1 parent d7aea0be65
commit 91f22b54b4
30 files changed
+2475

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
'use strict';
const { parseChannelName, normalizeText } = require('./channel-name');
const { liveUrlCandidates } = require('./xtream-client');
function defaultUrlBuilder(streamId) {
return liveUrlCandidates(streamId);
}
function compareEvents(a, b) {
const byStart = a.startAt.getTime() - b.startAt.getTime();
if (byStart !== 0) return byStart;
const bySeq = (a.firstSeenSeq ?? 0) - (b.firstSeenSeq ?? 0);
if (bySeq !== 0) return bySeq;
return a.key.localeCompare(b.key);
}
function isEligible(event, now, { startGraceMs }) {
return now >= event.startAt.getTime() - startGraceMs && now < event.endAt.getTime();
}
function buildEvents(streams, options) {
const {
searchTerm,
language,
timezone,
eventDurationMs,
urlBuilder = defaultUrlBuilder,
} = options;
const term = normalizeText(searchTerm);
const events = new Map();
const warnings = [];
for (const stream of streams || []) {
const rawName = String(stream && stream.name ? stream.name : '');
if (!rawName) continue;
if (!term || !normalizeText(rawName).includes(term)) continue;
const parsed = parseChannelName(rawName, { timezone });
if (!parsed) {
warnings.push({ streamId: stream.stream_id, name: rawName, reason: 'unparseable_name' });
continue;
}
if (parsed.language && parsed.language !== language) continue;
const key = `${normalizeText(parsed.title)}|${parsed.startAt.toISOString()}`;
let event = events.get(key);
if (!event) {
event = {
key,
title: parsed.title,
league: parsed.league,
language: parsed.language || language,
startAt: parsed.startAt,
endAt: new Date(parsed.startAt.getTime() + eventDurationMs),
sources: [],
};
events.set(key, event);
}
const streamId = String(stream.stream_id);
if (!event.sources.some((source) => source.streamId === streamId)) {
event.sources.push({
streamId,
name: rawName,
candidates: urlBuilder(stream.stream_id).slice(),
});
}
}
return { events, warnings };
}
module.exports = { buildEvents, isEligible, compareEvents };