Merge pull request #19537 from iptv-org/patch-2025.02.2

Patch 2025.02.2
pull/19592/head
Ismaël Moret 6 days ago committed by GitHub
commit b1c2d7e7b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,38 +0,0 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"no-case-declarations": "off",
"indent": [
"error",
2,
{ "SwitchCase": 1 }
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
]
}
}

@ -15,7 +15,7 @@ body:
- type: markdown
attributes:
value: |
What exactly needs to be changed?
What exactly needs to be changed? To delete an existing value without replacement use the `~` symbol.
- type: input
attributes:
@ -35,6 +35,7 @@ body:
- 576p
- 480p
- 360p
- '~'
- type: dropdown
attributes:
@ -43,6 +44,7 @@ body:
options:
- 'Not 24/7'
- 'Geo-blocked'
- '~'
- type: input
attributes:

@ -0,0 +1,46 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import globals from "globals";
import tsParser from "@typescript-eslint/parser";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});
export default [
...compat.extends("eslint:recommended", "plugin:@typescript-eslint/recommended"),
{
plugins: {
"@typescript-eslint": typescriptEslint,
},
languageOptions: {
globals: {
...globals.browser,
},
parser: tsParser,
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
"no-case-declarations": "off",
indent: ["error", 2, {
SwitchCase: 1,
}],
"linebreak-style": ["error", "unix"],
quotes: ["error", "single"],
semi: ["error", "never"],
},
},
];

70
package-lock.json generated

@ -8,6 +8,8 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@eslint/eslintrc": "^3.3.0",
"@eslint/js": "^9.21.0",
"@freearhey/core": "^0.2.1",
"@octokit/core": "^4.2.1",
"@octokit/plugin-paginate-rest": "^7.1.2",
@ -24,6 +26,7 @@
"cli-progress": "^3.12.0",
"commander": "^8.3.0",
"eslint": "^9.17.0",
"globals": "^16.0.0",
"iptv-playlist-parser": "^0.13.0",
"jest-expect-message": "^1.1.3",
"lodash": "^4.17.21",
@ -917,9 +920,9 @@
}
},
"node_modules/@eslint/eslintrc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
"integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
"integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
@ -938,10 +941,21 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@eslint/js": {
"version": "9.17.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz",
"integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==",
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz",
"integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
@ -2982,6 +2996,14 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/@eslint/js": {
"version": "9.17.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz",
"integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/eslint/node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@ -3522,9 +3544,9 @@
}
},
"node_modules/globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz",
"integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==",
"engines": {
"node": ">=18"
},
@ -6745,9 +6767,9 @@
}
},
"@eslint/eslintrc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
"integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
"integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
"requires": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
@ -6758,12 +6780,19 @@
"js-yaml": "^4.1.0",
"minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
"globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="
}
}
},
"@eslint/js": {
"version": "9.17.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz",
"integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w=="
"version": "9.21.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz",
"integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw=="
},
"@eslint/object-schema": {
"version": "2.1.5",
@ -8281,6 +8310,11 @@
"optionator": "^0.9.3"
},
"dependencies": {
"@eslint/js": {
"version": "9.17.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz",
"integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w=="
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@ -8685,9 +8719,9 @@
}
},
"globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="
"version": "16.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz",
"integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="
},
"graceful-fs": {
"version": "4.2.9",

@ -36,6 +36,8 @@
"private": true,
"license": "MIT",
"dependencies": {
"@eslint/eslintrc": "^3.3.0",
"@eslint/js": "^9.21.0",
"@freearhey/core": "^0.2.1",
"@octokit/core": "^4.2.1",
"@octokit/plugin-paginate-rest": "^7.1.2",
@ -52,6 +54,7 @@
"cli-progress": "^3.12.0",
"commander": "^8.3.0",
"eslint": "^9.17.0",
"globals": "^16.0.0",
"iptv-playlist-parser": "^0.13.0",
"jest-expect-message": "^1.1.3",
"lodash": "^4.17.21",

@ -56,7 +56,7 @@ async function removeStreams(loader: IssueLoader) {
const data = issue.data
if (data.missing('broken_links')) return
const brokenLinks = data.get('broken_links').split(/\r?\n/).filter(Boolean)
const brokenLinks = data.getString('broken_links').split(/\r?\n/).filter(Boolean)
let changed = false
brokenLinks.forEach(link => {
@ -79,27 +79,27 @@ async function editStreams(loader: IssueLoader) {
if (data.missing('stream_url')) return
let stream = streams.first(
(_stream: Stream) => _stream.url === data.get('stream_url')
(_stream: Stream) => _stream.url === data.getString('stream_url')
) as Stream
if (!stream) return
if (data.has('channel_id')) {
const channel = groupedChannels.get(data.get('channel_id'))
const channel = groupedChannels.get(data.getString('channel_id'))
if (!channel) return
stream.channel = data.get('channel_id')
stream.channel = data.getString('channel_id')
stream.filepath = `${channel.country.toLowerCase()}.m3u`
stream.line = -1
stream.name = channel.name
}
if (data.has('label')) stream.label = data.get('label')
if (data.has('quality')) stream.quality = data.get('quality')
if (data.has('timeshift')) stream.timeshift = data.get('timeshift')
if (data.has('user_agent')) stream.userAgent = data.get('user_agent')
if (data.has('http_referrer')) stream.httpReferrer = data.get('http_referrer')
if (data.has('label')) stream.label = data.getString('label')
if (data.has('quality')) stream.quality = data.getString('quality')
if (data.has('timeshift')) stream.timeshift = data.getString('timeshift')
if (data.has('user_agent')) stream.userAgent = data.getString('user_agent')
if (data.has('http_referrer')) stream.httpReferrer = data.getString('http_referrer')
processedIssues.add(issue.number)
})
@ -110,24 +110,24 @@ async function addStreams(loader: IssueLoader) {
issues.forEach((issue: Issue) => {
const data = issue.data
if (data.missing('channel_id') || data.missing('stream_url')) return
if (streams.includes((_stream: Stream) => _stream.url === data.get('stream_url'))) return
if (!validUrl.isUri(data.get('stream_url'))) return
if (streams.includes((_stream: Stream) => _stream.url === data.getString('stream_url'))) return
if (!validUrl.isUri(data.getString('stream_url'))) return
const channel = groupedChannels.get(data.get('channel_id'))
const channel = groupedChannels.get(data.getString('channel_id'))
if (!channel) return
const stream = new Stream({
channel: data.get('channel_id'),
url: data.get('stream_url'),
label: data.get('label'),
quality: data.get('quality'),
timeshift: data.get('timeshift'),
userAgent: data.get('user_agent'),
httpReferrer: data.get('http_referrer'),
channel: data.getString('channel_id'),
url: data.getString('stream_url'),
label: data.getString('label'),
quality: data.getString('quality'),
timeshift: data.getString('timeshift'),
userAgent: data.getString('user_agent'),
httpReferrer: data.getString('http_referrer'),
filepath: `${channel.country.toLowerCase()}.m3u`,
line: -1,
name: data.get('channel_name') || channel.name
name: data.getString('channel_name') || channel.name
})
streams.add(stream)

@ -35,8 +35,8 @@ async function main() {
const addRequests = await loader.load({ labels: ['streams:add'] })
const buffer = new Dictionary()
addRequests.forEach((issue: Issue) => {
const channelId = issue.data.get('channel_id') || undefined
const streamUrl = issue.data.get('stream_url') || undefined
const channelId = issue.data.getString('channel_id') || undefined
const streamUrl = issue.data.getString('stream_url')
const result = new Dictionary({
issueNumber: issue.number,
@ -61,8 +61,8 @@ async function main() {
logger.info('checking streams:edit requests...')
const editRequests = await loader.load({ labels: ['streams:edit'] })
editRequests.forEach((issue: Issue) => {
const channelId = issue.data.get('channel_id') || undefined
const streamUrl = issue.data.get('stream_url') || undefined
const channelId = issue.data.getString('channel_id') || undefined
const streamUrl = issue.data.getString('stream_url') || undefined
const result = new Dictionary({
issueNumber: issue.number,
@ -82,7 +82,7 @@ async function main() {
logger.info('checking broken streams reports...')
const brokenStreamReports = await loader.load({ labels: ['broken stream'] })
brokenStreamReports.forEach((issue: Issue) => {
const brokenLinks = issue.data.get('broken_links') || undefined
const brokenLinks = issue.data.getString('broken_links') || undefined
const result = new Dictionary({
issueNumber: issue.number,

@ -6,3 +6,4 @@ export * from './issueLoader'
export * from './issueParser'
export * from './htmlTable'
export * from './apiClient'
export * from './issueData'

@ -0,0 +1,32 @@
import { Dictionary } from '@freearhey/core'
export class IssueData {
_data: Dictionary
constructor(data: Dictionary) {
this._data = data
}
has(key: string): boolean {
return this._data.has(key)
}
missing(key: string): boolean {
return this._data.missing(key) || this._data.get(key) === undefined
}
getBoolean(key: string): boolean {
return Boolean(this._data.get(key))
}
getString(key: string): string {
const deleteSymbol = '~'
return this._data.get(key) === deleteSymbol ? '' : this._data.get(key)
}
getArray(key: string): string[] {
const deleteSymbol = '~'
return this._data.get(key) === deleteSymbol ? [] : this._data.get(key).split(';')
}
}

@ -15,22 +15,25 @@ export class IssueLoader {
if (TESTING) {
switch (labels) {
case 'streams:add':
issues = require('../../tests/__data__/input/issues/streams_add.js')
issues = (await import('../../tests/__data__/input/issues/streams_add.js')).default
break
case 'streams:edit':
issues = require('../../tests/__data__/input/issues/streams_edit.js')
issues = (await import('../../tests/__data__/input/issues/streams_edit.js')).default
break
case 'broken stream':
issues = require('../../tests/__data__/input/issues/broken_stream.js')
issues = (await import('../../tests/__data__/input/issues/broken_stream.js')).default
break
case 'streams:add,approved':
issues = require('../../tests/__data__/input/issues/streams_add_approved.js')
issues = (await import('../../tests/__data__/input/issues/streams_add_approved.js'))
.default
break
case 'streams:edit,approved':
issues = require('../../tests/__data__/input/issues/streams_edit_approved.js')
issues = (await import('../../tests/__data__/input/issues/streams_edit_approved.js'))
.default
break
case 'streams:remove,approved':
issues = require('../../tests/__data__/input/issues/streams_remove_approved.js')
issues = (await import('../../tests/__data__/input/issues/streams_remove_approved.js'))
.default
break
}
} else {

@ -1,5 +1,6 @@
import { Dictionary } from '@freearhey/core'
import { Issue } from '../models'
import { IssueData } from './issueData'
const FIELDS = new Dictionary({
'Channel ID': 'channel_id',
@ -28,7 +29,7 @@ export class IssueParser {
const data = new Dictionary()
fields.forEach((field: string) => {
let parsed = field.split(/\r?\n/).filter(Boolean)
const parsed = field.split(/\r?\n/).filter(Boolean)
let _label = parsed.shift()
_label = _label ? _label.trim() : ''
let _value = parsed.join('\r\n')
@ -46,6 +47,6 @@ export class IssueParser {
const labels = issue.labels.map(label => label.name)
return new Issue({ number: issue.number, labels, data })
return new Issue({ number: issue.number, labels, data: new IssueData(data) })
}
}

@ -1,15 +1,15 @@
import { Dictionary } from '@freearhey/core'
import { IssueData } from '../core'
type IssueProps = {
number: number
labels: string[]
data: Dictionary
data: IssueData
}
export class Issue {
number: number
labels: string[]
data: Dictionary
data: IssueData
constructor({ number, labels, data }: IssueProps) {
this.number = number

@ -1,5 +1,4 @@
#EXTM3U
#EXTINF:-1 tvg-id="BBCAmericaEast.us" tvg-shift="-4" user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246",BBC America East (720p) [Geo-blocked]
#EXTVLCOPT:http-referrer=https://example2.com/
#EXTINF:-1 tvg-id="BBCAmericaEast.us" tvg-shift="-4" user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246",BBC America East (720p)
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246
https://servilive.com:3126/live/tele2000live.m3u8

@ -61,7 +61,7 @@ module.exports = [
closed_at: null,
author_association: 'COLLABORATOR',
active_lock_reason: null,
body: '### Stream URL\n\nhttps://servilive.com:3126/live/tele2000live.m3u8\n\n### Channel ID\n\nBBCAmericaEast.us\n\n### Channel Name\n\nBBC America\n\n### Quality\n\n720p\n\n### Label\n\nGeo-blocked\n\n### Timeshift\n\n-4\n\n### HTTP User-Agent\n\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246\n\n### HTTP Referrer\n\n_No response_\n\n### Notes\n\n_No response_\n\n### Contributing Guide\n\n- [X] I have read [Contributing Guide](https://github.com/iptv-org/iptv/blob/master/CONTRIBUTING.md)',
body: '### Stream URL\n\nhttps://servilive.com:3126/live/tele2000live.m3u8\n\n### Channel ID\n\nBBCAmericaEast.us\n\n### Channel Name\n\nBBC America\n\n### Quality\n\n720p\n\n### Label\n\n~\n\n### Timeshift\n\n-4\n\n### HTTP User-Agent\n\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246\n\n### HTTP Referrer\n\n~\n\n### Notes\n\n_No response_\n\n### Contributing Guide\n\n- [X] I have read [Contributing Guide](https://github.com/iptv-org/iptv/blob/master/CONTRIBUTING.md)',
reactions: {
url: 'https://api.github.com/repos/iptv-org/iptv/issues/14110/reactions',
total_count: 0,
@ -77,5 +77,84 @@ module.exports = [
timeline_url: 'https://api.github.com/repos/iptv-org/iptv/issues/14110/timeline',
performed_via_github_app: null,
state_reason: null
},
{
url: 'https://api.github.com/repos/iptv-org/iptv/issues/14120',
repository_url: 'https://api.github.com/repos/iptv-org/iptv',
labels_url: 'https://api.github.com/repos/iptv-org/iptv/issues/14120/labels{/name}',
comments_url: 'https://api.github.com/repos/iptv-org/iptv/issues/14120/comments',
events_url: 'https://api.github.com/repos/iptv-org/iptv/issues/14120/events',
html_url: 'https://github.com/iptv-org/iptv/issues/14120',
id: 1884922249,
node_id: 'I_kwDOCWUK8M5wWaGJ',
number: 14120,
title: 'Edit: Tele2000',
user: {
login: 'freearhey',
id: 7253922,
node_id: 'MDQ6VXNlcjcyNTM5MjI=',
avatar_url: 'https://avatars.githubusercontent.com/u/7253922?v=4',
gravatar_id: '',
url: 'https://api.github.com/users/freearhey',
html_url: 'https://github.com/freearhey',
followers_url: 'https://api.github.com/users/freearhey/followers',
following_url: 'https://api.github.com/users/freearhey/following{/other_user}',
gists_url: 'https://api.github.com/users/freearhey/gists{/gist_id}',
starred_url: 'https://api.github.com/users/freearhey/starred{/owner}{/repo}',
subscriptions_url: 'https://api.github.com/users/freearhey/subscriptions',
organizations_url: 'https://api.github.com/users/freearhey/orgs',
repos_url: 'https://api.github.com/users/freearhey/repos',
events_url: 'https://api.github.com/users/freearhey/events{/privacy}',
received_events_url: 'https://api.github.com/users/freearhey/received_events',
type: 'User',
site_admin: false
},
labels: [
{
id: 5923498886,
node_id: 'LA_kwDOCWUK8M8AAAABYRFrhg',
url: 'https://api.github.com/repos/iptv-org/iptv/labels/approved',
name: 'approved',
color: '85ddde',
default: false,
description: ''
},
{
id: 5923508587,
node_id: 'LA_kwDOCWUK8M8AAAABYRGRaw',
url: 'https://api.github.com/repos/iptv-org/iptv/labels/streams:add',
name: 'streams:edit',
color: '017ff9',
default: false,
description: 'Request to add a new link to a playlist'
}
],
state: 'open',
locked: false,
assignee: null,
assignees: [],
milestone: null,
comments: 1,
created_at: '2023-09-07T00:30:51Z',
updated_at: '2023-09-07T00:48:23Z',
closed_at: null,
author_association: 'COLLABORATOR',
active_lock_reason: null,
body: '### Stream URL\n\nhttps://ythls.onrender.com/channel/UC40TUSUx490U5uR1lZt3Ajg.m3u8\n\n### Channel ID\n\n_No response_\n\n### Quality\n\nNone\n\n### Label\n\nNone\n\n### HTTP User-Agent\n\n_No response_\n\n### HTTP Referrer\n\n_No response_\n\n### Notes\n\n_No response_\n\n### Contributing Guide\n\n- [X] I have read [Contributing Guide](https://github.com/iptv-org/iptv/blob/master/CONTRIBUTING.md)',
reactions: {
url: 'https://api.github.com/repos/iptv-org/iptv/issues/14120/reactions',
total_count: 0,
'+1': 0,
'-1': 0,
laugh: 0,
hooray: 0,
confused: 0,
heart: 0,
rocket: 0,
eyes: 0
},
timeline_url: 'https://api.github.com/repos/iptv-org/iptv/issues/14120/timeline',
performed_via_github_app: null,
state_reason: null
}
]

@ -1,6 +1,6 @@
#EXTM3U
#EXTINF:-1 tvg-id="",VTV [Not 24/7]
https://ythls.onrender.com/channel/UC40TUSUx490U5uR1lZt3Ajg.m3u8
#EXTINF:-1 tvg-id="",Tele2000
#EXTINF:-1 tvg-id="",Tele2000 [Not 24/7]
#EXTVLCOPT:http-referrer=https://example2.com/
https://servilive.com:3126/live/tele2000live.m3u8

@ -25,7 +25,9 @@ it('can format playlists', () => {
)
})
expect(stdout).toBe('OUTPUT=closes #14151, closes #14140, closes #14110, closes #14178\n')
expect(stdout).toBe(
'OUTPUT=closes #14151, closes #14140, closes #14110, closes #14120, closes #14178\n'
)
})
function content(filepath: string) {

@ -306,10 +306,10 @@
dependencies:
"@types/json-schema" "^7.0.15"
"@eslint/eslintrc@^3.2.0":
version "3.2.0"
resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz"
integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==
"@eslint/eslintrc@^3.2.0", "@eslint/eslintrc@^3.3.0":
version "3.3.0"
resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz"
integrity sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
@ -321,6 +321,11 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@^9.21.0":
version "9.21.0"
resolved "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz"
integrity sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==
"@eslint/js@9.17.0":
version "9.17.0"
resolved "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz"
@ -1895,6 +1900,11 @@ globals@^14.0.0:
resolved "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
globals@^16.0.0:
version "16.0.0"
resolved "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz"
integrity sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9:
version "4.2.9"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz"

Loading…
Cancel
Save