This commit is contained in:
1 parent
74df7780fd
commit
d266a8258d
9 files changed
+32
-15
No files matched your search
@@ -20,6 +20,7 @@ ENV LISTEN_PORT=8080 \
|
||||
EVENT_DURATION_MIN=150 \
|
||||
START_GRACE_MIN=10 \
|
||||
REFRESH_INTERVAL_SEC=60 \
|
||||
SOURCE_TIMEZONE=UTC \
|
||||
TIMEZONE=Europe/Brussels \
|
||||
UPSTREAM_TIMEOUT_MS=15000 \
|
||||
PROXY_INSECURE_TLS=0 \
|
||||
|
||||
@@ -12,6 +12,10 @@ competitie, taal en starttijd, bijvoorbeeld:
|
||||
View BE| DAZN 03 [Standard de Liège - SK Beveren | Jupiler Pro League (nl) (2026-11-06 19:25:00)]
|
||||
```
|
||||
|
||||
De tijdstempels in de kanaalnamen worden standaard als **UTC** gelezen. De app toont ze
|
||||
vervolgens in `TIMEZONE` (standaard `Europe/Brussels`), dus `19:25:00` UTC wordt in de
|
||||
playlist en EPG als `20:25` getoond.
|
||||
|
||||
Alleen streams met taalcode `(nl)` of zonder taalcode worden gebruikt. Een expliciete
|
||||
`(fr)`- of andere taalcode wordt overgeslagen.
|
||||
|
||||
@@ -68,7 +72,8 @@ staat.
|
||||
| `EVENT_DURATION_MIN` | `150` | nee | Duur waarna een event het slot verlaat |
|
||||
| `START_GRACE_MIN` | `10` | nee | Minuten voor aanvang dat een event eligibel wordt |
|
||||
| `REFRESH_INTERVAL_SEC` | `60` | nee | Hoe vaak kanaalnamen opnieuw worden gelezen |
|
||||
| `TIMEZONE` | `Europe/Brussels` | nee | Tijdzone van de tijdstempels in kanaalnamen |
|
||||
| `SOURCE_TIMEZONE` | `UTC` | nee | Tijdzone van de tijdstempels in de kanaalnamen |
|
||||
| `TIMEZONE` | `Europe/Brussels` | nee | Tijdzone voor weergave in playlist en EPG |
|
||||
| `LISTEN_PORT` | `8080` | nee | HTTP-poort |
|
||||
| `UPSTREAM_TIMEOUT_MS` | `15000` | nee | Timeout voor upstream-verzoeken |
|
||||
| `PROXY_INSECURE_TLS` | `0` | nee | `1` = self-signed upstream-certificaten accepteren |
|
||||
|
||||
@@ -14,6 +14,7 @@ services:
|
||||
EVENT_DURATION_MIN: "150"
|
||||
START_GRACE_MIN: "10"
|
||||
REFRESH_INTERVAL_SEC: "600"
|
||||
SOURCE_TIMEZONE: "UTC"
|
||||
TIMEZONE: "Europe/Brussels"
|
||||
# PROXY_INSECURE_TLS: "1" # alleen nodig bij self-signed upstream-certificaten
|
||||
# LOG_LEVEL: "debug"
|
||||
|
||||
@@ -40,6 +40,7 @@ function statusPayload() {
|
||||
eventDurationMin: settings.eventDurationMin,
|
||||
startGraceMin: settings.startGraceMin,
|
||||
refreshIntervalSec: settings.refreshIntervalSec,
|
||||
sourceTimezone: settings.sourceTimezone,
|
||||
timezone: settings.timezone,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -160,7 +160,7 @@ function createScheduler() {
|
||||
const { events, warnings } = buildEvents(streams, {
|
||||
searchTerm: settings.searchTerm,
|
||||
language: settings.language,
|
||||
timezone: settings.timezone,
|
||||
timezone: settings.sourceTimezone,
|
||||
eventDurationMs: settings.eventDurationMs,
|
||||
});
|
||||
const now = Date.now();
|
||||
|
||||
@@ -18,6 +18,7 @@ const settings = {
|
||||
eventDurationMin: readNumber(process.env.EVENT_DURATION_MIN, 150, 1, 1440),
|
||||
startGraceMin: readNumber(process.env.START_GRACE_MIN, 10, 0, 1440),
|
||||
refreshIntervalSec: readNumber(process.env.REFRESH_INTERVAL_SEC, 60, 10, 3600),
|
||||
sourceTimezone: (process.env.SOURCE_TIMEZONE || 'UTC').trim() || 'UTC',
|
||||
timezone: (process.env.TIMEZONE || 'Europe/Brussels').trim() || 'Europe/Brussels',
|
||||
listenPort: Math.round(readNumber(process.env.LISTEN_PORT, 8080, 1, 65535)),
|
||||
upstreamTimeoutMs: readNumber(process.env.UPSTREAM_TIMEOUT_MS, 15000, 1000, 120000),
|
||||
@@ -32,11 +33,11 @@ const settings = {
|
||||
settings.eventDurationMs = settings.eventDurationMin * 60 * 1000;
|
||||
settings.startGraceMs = settings.startGraceMin * 60 * 1000;
|
||||
|
||||
function validateTimezone(timezone) {
|
||||
function validateTimezone(timezone, envName) {
|
||||
try {
|
||||
new Intl.DateTimeFormat('en-US', { timeZone: timezone });
|
||||
} catch {
|
||||
throw new Error(`Invalid TIMEZONE: ${timezone}`);
|
||||
throw new Error(`Invalid ${envName}: ${timezone}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +61,8 @@ function validate() {
|
||||
throw new Error('XTREAM_URL must use http or https');
|
||||
}
|
||||
|
||||
validateTimezone(settings.timezone);
|
||||
validateTimezone(settings.sourceTimezone, 'SOURCE_TIMEZONE');
|
||||
validateTimezone(settings.timezone, 'TIMEZONE');
|
||||
|
||||
if (!settings.language) {
|
||||
throw new Error('LANGUAGE must not be empty');
|
||||
|
||||
@@ -7,18 +7,23 @@ const { parseChannelName, normalizeText } = require('../src/channel-name');
|
||||
const sample =
|
||||
'View BE| DAZN 03 [Standard de Liège - SK Beveren | Jupiler Pro League (nl) (2026-11-06 19:25:00)]';
|
||||
|
||||
test('parses the DAZN sample', () => {
|
||||
const parsed = parseChannelName(sample, { timezone: 'Europe/Brussels' });
|
||||
test('parses the DAZN sample with UTC source timestamps', () => {
|
||||
const parsed = parseChannelName(sample, { timezone: 'UTC' });
|
||||
assert.equal(parsed.title, 'Standard de Liège - SK Beveren');
|
||||
assert.equal(parsed.league, 'Jupiler Pro League');
|
||||
assert.equal(parsed.language, 'nl');
|
||||
assert.equal(parsed.startAt.toISOString(), '2026-11-06T19:25:00.000Z');
|
||||
});
|
||||
|
||||
test('can parse the same timestamp in another source timezone', () => {
|
||||
const parsed = parseChannelName(sample, { timezone: 'Europe/Brussels' });
|
||||
assert.equal(parsed.startAt.toISOString(), '2026-11-06T18:25:00.000Z');
|
||||
});
|
||||
|
||||
test('parses a French stream', () => {
|
||||
const parsed = parseChannelName(
|
||||
'View BE| DAZN 03 [Standard de Liège - SK Beveren | Jupiler Pro League (fr) (2026-11-06 19:25:00)]',
|
||||
{ timezone: 'Europe/Brussels' }
|
||||
{ timezone: 'UTC' }
|
||||
);
|
||||
assert.equal(parsed.language, 'fr');
|
||||
});
|
||||
@@ -26,14 +31,14 @@ test('parses a French stream', () => {
|
||||
test('allows a missing language code', () => {
|
||||
const parsed = parseChannelName(
|
||||
'DAZN 03 [Standard de Liège - SK Beveren | Jupiler Pro League (2026-11-06 19:25:00)]',
|
||||
{ timezone: 'Europe/Brussels' }
|
||||
{ timezone: 'UTC' }
|
||||
);
|
||||
assert.equal(parsed.language, null);
|
||||
});
|
||||
|
||||
test('returns null for unparseable names', () => {
|
||||
assert.equal(parseChannelName('DAZN 03', { timezone: 'Europe/Brussels' }), null);
|
||||
assert.equal(parseChannelName('', { timezone: 'Europe/Brussels' }), null);
|
||||
assert.equal(parseChannelName('DAZN 03', { timezone: 'UTC' }), null);
|
||||
assert.equal(parseChannelName('', { timezone: 'UTC' }), null);
|
||||
});
|
||||
|
||||
test('normalizes diacritics and whitespace', () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { buildEvents, compareEvents, isEligible } = require('../src/events');
|
||||
|
||||
const timezone = 'Europe/Brussels';
|
||||
const timezone = 'UTC';
|
||||
|
||||
function stream(id, name) {
|
||||
return { stream_id: id, name };
|
||||
|
||||
Reference in new issue
Block a user