From d4f07c0a4c2d2b1006cea644c93c1cbc96b43e4f Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Thu, 3 Sep 2026 14:53:13 +0300 Subject: [PATCH] Update scripts --- scripts/commands/playlist/format.ts | 5 +- scripts/commands/playlist/generate.ts | 7 +-- scripts/commands/playlist/test.ts | 12 ++--- scripts/commands/playlist/update.ts | 5 +- scripts/core/dataSet.ts | 10 ++-- scripts/models/stream.ts | 67 ++++++++++++++++++--------- scripts/utils.ts | 14 +++++- 7 files changed, 81 insertions(+), 39 deletions(-) diff --git a/scripts/commands/playlist/format.ts b/scripts/commands/playlist/format.ts index a7c69ee013..a40596e472 100644 --- a/scripts/commands/playlist/format.ts +++ b/scripts/commands/playlist/format.ts @@ -114,11 +114,12 @@ async function main() { streams = streams.sortBy( [ (stream: Stream) => stream.title, + (stream: Stream) => (stream.isGeoBlocked ? -1 : 0), + (stream: Stream) => (stream.isNot247 ? -1 : 0), (stream: Stream) => stream.getVerticalResolution(), - (stream: Stream) => stream.label, (stream: Stream) => stream.url ], - ['asc', 'desc', 'asc', 'asc'] + ['asc', 'desc', 'desc', 'desc', 'asc'] ) logger.info('saving...') diff --git a/scripts/commands/playlist/generate.ts b/scripts/commands/playlist/generate.ts index 4a2dc14eb5..ccd40abcca 100644 --- a/scripts/commands/playlist/generate.ts +++ b/scripts/commands/playlist/generate.ts @@ -48,10 +48,11 @@ async function main() { streams = streams.sortBy( [ (stream: Stream) => stream.getId(), - (stream: Stream) => stream.getVerticalResolution(), - (stream: Stream) => stream.label + (stream: Stream) => (stream.isGeoBlocked ? -1 : 0), + (stream: Stream) => (stream.isNot247 ? -1 : 0), + (stream: Stream) => stream.getVerticalResolution() ], - ['asc', 'desc', 'desc'] + ['asc', 'desc', 'desc', 'desc', 'asc'] ) logger.info('filtering streams...') diff --git a/scripts/commands/playlist/test.ts b/scripts/commands/playlist/test.ts index 447455b7fb..b3bfb5506b 100644 --- a/scripts/commands/playlist/test.ts +++ b/scripts/commands/playlist/test.ts @@ -108,7 +108,7 @@ async function runTest(stream: Stream) { stream.statusCode = result.status.code if (stream.statusCode === 'OK') return - if (errorStatusCodes.includes(stream.statusCode) && !stream.label) { + if (errorStatusCodes.includes(stream.statusCode) && !stream.getLabels().length) { errors++ } else { warnings++ @@ -128,7 +128,7 @@ function drawTable() { { name: '', alignment: 'center', minLen: 3, maxLen: 3 }, { name: 'tvg-id', alignment: 'left', color: 'green', minLen: 25, maxLen: 25 }, { name: 'url', alignment: 'left', color: 'green', minLen: 100, maxLen: 100 }, - { name: 'label', alignment: 'left', color: 'yellow', minLen: 13, maxLen: 13 }, + { name: 'labels', alignment: 'left', color: 'yellow', minLen: 13, maxLen: 13 }, { name: 'status', alignment: 'left', minLen: 25, maxLen: 25 } ] }) @@ -137,14 +137,14 @@ function drawTable() { const tvgId = truncate(stream.getTvgId(), 25) const url = truncate(stream.url, 100) const color = getColor(stream) - const label = stream.label || '' + const labels = stream.getLabels().join(';') const status = stream.statusCode || 'PENDING' const row = { '': index, 'tvg-id': chalk[color](tvgId), url: chalk[color](url), - label: chalk[color](label), + labels: chalk[color](labels), status: chalk[color](status) } table.append(row) @@ -208,14 +208,14 @@ function getColor(stream: Stream): string { if (!stream.statusCode) return 'gray' if (stream.statusCode === 'LOADING...') return 'white' if (stream.statusCode === 'OK') return 'green' - if (errorStatusCodes.includes(stream.statusCode) && !stream.label) return 'red' + if (errorStatusCodes.includes(stream.statusCode) && !stream.getLabels().length) return 'red' return 'yellow' } function isBroken(stream: Stream): boolean { if (!stream.statusCode) return false - if (stream.label) return false + if (stream.getLabels().length) return false if (!errorStatusCodes.includes(stream.statusCode)) return false return true diff --git a/scripts/commands/playlist/update.ts b/scripts/commands/playlist/update.ts index 7b0a6dbdad..4bb50a3f8a 100644 --- a/scripts/commands/playlist/update.ts +++ b/scripts/commands/playlist/update.ts @@ -261,9 +261,12 @@ async function addStream(issue: Issue) { user_agent: httpUserAgent, referrer: httpReferrer, quality, - label: data.getString('label') || '' + label: null }) + stream.isNot247 = data.has('live_247') ? !data.getBoolean('live_247') : false + stream.isGeoBlocked = data.has('geo_blocked') ? data.getBoolean('geo_blocked') : false + stream.updateTitle().updateFilepath() stream.setGuides(apiData.guidesGroupedByStreamId.get(stream.getId())) diff --git a/scripts/core/dataSet.ts b/scripts/core/dataSet.ts index 9e41de55ac..ac1700ee5b 100644 --- a/scripts/core/dataSet.ts +++ b/scripts/core/dataSet.ts @@ -11,7 +11,9 @@ export class DataSet { } missing(key: string): boolean { - return this._data.missing(key) || this._data.get(key) === undefined + const keys = Array.isArray(key) ? key : [key] + + return keys.every(_key => this._data.get(_key) === undefined) } isDeleted(key: string): boolean { @@ -20,8 +22,10 @@ export class DataSet { return this._data.get(key) === deleteSymbol } - getBoolean(key: string): boolean { - return Boolean(this._data.get(key)) + getBoolean(key: string): boolean | undefined { + if (this.missing(key)) return undefined + + return this._data.get(key) === 'TRUE' ? true : false } getString(key: string): string | undefined { diff --git a/scripts/models/stream.ts b/scripts/models/stream.ts index 9bc3fbff4a..0cdbf9e041 100644 --- a/scripts/models/stream.ts +++ b/scripts/models/stream.ts @@ -14,6 +14,8 @@ export class Stream extends sdk.Models.Stream { tvgId?: string statusCode?: string guides = new Collection() + isNot247?: boolean + isGeoBlocked?: boolean setGuides(guides?: sdk.Models.Guide[]) { this.guides = new Collection(guides) @@ -48,47 +50,51 @@ export class Stream extends sdk.Models.Stream { } } - const data = { - label: dataSet.isDeleted('label') ? '' : dataSet.getString('label'), - quality: dataSet.isDeleted('quality') ? '' : dataSet.getString('quality'), - httpUserAgent: dataSet.isDeleted('http_user_agent') - ? '' - : dataSet.getString('http_user_agent'), - httpReferrer: dataSet.isDeleted('http_referrer') ? '' : dataSet.getString('http_referrer') - } + const live247 = dataSet.getBoolean('live_247') + const geoBlocked = dataSet.getBoolean('geo_blocked') - if (data.label !== undefined) this.label = data.label - if (data.quality !== undefined) this.quality = data.quality - if (data.httpUserAgent !== undefined) this.user_agent = data.httpUserAgent - if (data.httpReferrer !== undefined) this.referrer = data.httpReferrer + if (live247) this.isNot247 = live247 + if (geoBlocked) this.isGeoBlocked = geoBlocked + + const quality = dataSet.isDeleted('quality') ? '' : dataSet.getString('quality') + const httpUserAgent = dataSet.isDeleted('http_user_agent') + ? '' + : dataSet.getString('http_user_agent') + const httpReferrer = dataSet.isDeleted('http_referrer') + ? '' + : dataSet.getString('http_referrer') + + if (quality !== undefined) this.quality = quality + if (httpUserAgent !== undefined) this.user_agent = httpUserAgent + if (httpReferrer !== undefined) this.referrer = httpReferrer return this } static fromPlaylistItem(data: parser.PlaylistItem): Stream { - function escapeRegExp(text) { + function escapeRegExp(text: string) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') } function parseName(name: string): { title: string - label: string + labels: string[] quality: string } { let title = name - const [, label] = title.match(/ \[(.*)\]$/) || [null, ''] - title = title.replace(new RegExp(` \\[${escapeRegExp(label)}\\]$`), '') + const [, labels] = title.match(/ \[(.*)\]$/) || [null, ''] + title = title.replace(new RegExp(` \\[${escapeRegExp(labels)}\\]$`), '') const [, quality] = title.match(/ \(([0-9]+[p|i])\)$/) || [null, ''] title = title.replace(new RegExp(` \\(${quality}\\)$`), '') - return { title, label, quality } + return { title, labels: labels.split(';'), quality } } if (!data.name) throw new Error('"name" property is required') if (!data.url) throw new Error('"url" property is required') const [channelId, feedId] = data.tvg.id.split('@') - const { title, label, quality } = parseName(data.name) + const { title, labels, quality } = parseName(data.name) const stream = new Stream({ channel: channelId || null, @@ -98,11 +104,13 @@ export class Stream extends sdk.Models.Stream { url: data.url, referrer: data.http.referrer || null, user_agent: data.http['user-agent'] || null, - label: label || null + label: null }) stream.tvgId = data.tvg.id stream.line = data.line + stream.isNot247 = labels.includes('Not 24/7') + stream.isGeoBlocked = labels.includes('Geo-blocked') return stream } @@ -416,13 +424,28 @@ export class Stream extends sdk.Models.Stream { title += ` (${this.quality})` } - if (this.label) { - title += ` [${this.label}]` + const labels = this.getLabels() + + if (labels.length) { + title += ` [${labels.join(';')}]` } return title } + getLabels(): string[] { + let labels: string[] = [] + if (this.isNot247 === true) { + labels.push('Not 24/7') + } + + if (this.isGeoBlocked === true) { + labels.push('Geo-blocked') + } + + return labels + } + toString(options: { public?: boolean } = {}) { options = { ...{ public: false }, ...options } @@ -470,7 +493,7 @@ export class Stream extends sdk.Models.Stream { title: this.title, url: this.url, quality: this.quality, - label: this.label, + labels: this.getLabels(), user_agent: this.user_agent, referrer: this.referrer } diff --git a/scripts/utils.ts b/scripts/utils.ts index 6e31eafc9b..ed893e932a 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -200,7 +200,8 @@ export function parseIssueBody(body: string): DataSet { 'Channel ID': 'channel_id', 'Feed ID': 'feed_id', 'Stream URL': 'stream_url', - Label: 'label', + 'Live 24/7': 'live_247', + 'Geo-blocked': 'geo_blocked', Quality: 'quality', 'HTTP User-Agent': 'http_user_agent', 'HTTP User Agent': 'http_user_agent', @@ -223,7 +224,16 @@ export function parseIssueBody(body: string): DataSet { if (!_label || !_value) return data const id = FIELDS.get(_label) - const value: string = _value === '_No response_' || _value === 'None' ? '' : _value + let value: string = '' + if (_value === '_No response_' || _value === 'None') { + value = '' + } else if (_value === 'Yes') { + value = 'TRUE' + } else if (_value === 'No') { + value = 'FALSE' + } else { + value = _value + } if (!id) return