` command.
- `api:generate`: generates a JSON file with all channels for the [iptv-org/api](https://github.com/iptv-org/api) repository.
- `channels:lint`: сhecks the channel lists for syntax errors.
- `channels:parse`: generates a list of channels based on the site configuration.
+- `channels:parse`: formats `*.channels.xml` files. The process involves removing invalid `xmltv_id`, adding missing Feed ID, and sorting the list.
- `channels:edit`: utility for quick channels mapping.
- `channels:validate`: checks the description of channels for errors.
- `sites:init`: creates a new site config from the template.
From 9d20d1f49e8496c5a46d693a9a97b29d8618a7c9 Mon Sep 17 00:00:00 2001
From: "iptv-bot[bot]" <84861620+iptv-bot[bot]@users.noreply.github.com>
Date: Thu, 23 Oct 2025 01:02:38 +0000
Subject: [PATCH 16/19] [Bot] Update SITES.md
Committed by [iptv-bot](https://github.com/apps/iptv-bot) via [update](https://github.com/iptv-org/epg/actions/runs/18734270264) workflow.
---
SITES.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/SITES.md b/SITES.md
index 1d86bef2..a9da004c 100644
--- a/SITES.md
+++ b/SITES.md
@@ -65,7 +65,7 @@
| gigatv.3bbtv.co.th | 79 | 38 | 🟢 | |
| guiadetv.com | 124 | 0 | 🟢 | |
| guida.tv | 88 | 88 | 🟢 | |
- | guidatv.sky.it | 154 | 154 | 🟢 | https://github.com/iptv-org/epg/issues/2849 |
+ | guidatv.sky.it | 154 | 154 | 🟢 | |
| guidetnt.com | 69 | 69 | 🟢 | |
| horizon.tv | 184 | 172 | 🟢 | |
| hoy.tv | 3 | 1 | 🟢 | |
@@ -93,7 +93,7 @@
| meuguia.tv | 102 | 97 | 🟢 | |
| mewatch.sg | 25 | 24 | 🟢 | |
| mi.tv | 2084 | 620 | 🟢 | |
- | mncvision.id | 276 | 223 | 🟢 | https://github.com/iptv-org/epg/issues/2848 |
+ | mncvision.id | 276 | 223 | 🟢 | |
| moji.id | 1 | 1 | 🟢 | |
| mojmaxtv.hrvatskitelekom.hr | 243 | 0 | 🟢 | |
| mon-programme-tv.be | 111 | 95 | 🟢 | |
@@ -101,7 +101,7 @@
| mtel.ba | 501 | 0 | 🟢 | |
| mts.rs | 457 | 0 | 🟢 | |
| mujtvprogram.cz | 216 | 202 | 🟢 | |
- | musor.tv | 181 | 145 | 🟢 | |
+ | musor.tv | 181 | 143 | 🟢 | |
| mysky.com.ph | 115 | 43 | 🟢 | |
| mytelly.co.uk | 488 | 401 | 🟢 | |
| mytvsuper.com | 108 | 99 | 🟢 | |
@@ -143,12 +143,12 @@
| ruv.is | 2 | 2 | 🟢 | |
| s.mxtv.jp | 2 | 2 | 🟢 | |
| sat.tv | 30308 | 249 | 🟢 | |
- | shahid.mbc.net | 225 | 183 | 🟢 | |
+ | shahid.mbc.net | 228 | 186 | 🟢 | |
| siba.com.co | 98 | 96 | 🟢 | |
| singtel.com | 155 | 113 | 🟢 | |
| sjonvarp.is | 13 | 13 | 🟢 | |
| sky.co.nz | 111 | 93 | 🟢 | |
- | sky.com | 559 | 458 | 🟡 | https://github.com/iptv-org/epg/issues/2763 |
+ | sky.com | 542 | 489 | 🟡 | https://github.com/iptv-org/epg/issues/2763 |
| sky.de | 75 | 75 | 🟢 | |
| skylife.co.kr | 251 | 0 | 🔴 | https://github.com/iptv-org/epg/issues/2845 |
| skyperfectv.co.jp | 137 | 130 | 🟢 | |
From 949286ed9f1a5a0bb1a46737fcaad7c7629255eb Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Thu, 23 Oct 2025 04:53:39 +0300
Subject: [PATCH 17/19] Change line endings with CRLF
---
scripts/templates/_config.js | 32 +++++++--------
scripts/templates/_readme.md | 42 ++++++++++----------
scripts/templates/_sites.md | 6 +--
scripts/templates/_test.js | 76 ++++++++++++++++++------------------
scripts/types/langs.d.ts | 2 +-
5 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/scripts/templates/_config.js b/scripts/templates/_config.js
index b4eb9b46..2e40921d 100644
--- a/scripts/templates/_config.js
+++ b/scripts/templates/_config.js
@@ -1,16 +1,16 @@
-module.exports = {
- site: '',
- url({ channel, date }) {
- return `https://example.com/api/${channel.site_id}/${date.format('YYYY-MM-DD')}`
- },
- parser({ content }) {
- try {
- return JSON.parse(content)
- } catch {
- return []
- }
- },
- channels() {
- return []
- }
-}
+module.exports = {
+ site: '',
+ url({ channel, date }) {
+ return `https://example.com/api/${channel.site_id}/${date.format('YYYY-MM-DD')}`
+ },
+ parser({ content }) {
+ try {
+ return JSON.parse(content)
+ } catch {
+ return []
+ }
+ },
+ channels() {
+ return []
+ }
+}
diff --git a/scripts/templates/_readme.md b/scripts/templates/_readme.md
index 0b807f7f..4aa94527 100644
--- a/scripts/templates/_readme.md
+++ b/scripts/templates/_readme.md
@@ -1,21 +1,21 @@
-#
-
-https://
-
-### Download the guide
-
-```sh
-npm run grab --- --site=
-```
-
-### Update channel list
-
-```sh
-npm run channels:parse --- --config=./sites//.config.js --output=./sites//.channels.xml
-```
-
-### Test
-
-```sh
-npm test ---
-```
+#
+
+https://
+
+### Download the guide
+
+```sh
+npm run grab --- --site=
+```
+
+### Update channel list
+
+```sh
+npm run channels:parse --- --config=./sites//.config.js --output=./sites//.channels.xml
+```
+
+### Test
+
+```sh
+npm test ---
+```
diff --git a/scripts/templates/_sites.md b/scripts/templates/_sites.md
index d0633a4c..46191a4e 100644
--- a/scripts/templates/_sites.md
+++ b/scripts/templates/_sites.md
@@ -1,3 +1,3 @@
-# Sites
-
-_TABLE_
+# Sites
+
+_TABLE_
diff --git a/scripts/templates/_test.js b/scripts/templates/_test.js
index b02a2648..6375d7e7 100644
--- a/scripts/templates/_test.js
+++ b/scripts/templates/_test.js
@@ -1,38 +1,38 @@
-const { parser, url } = require('./.config.js')
-const dayjs = require('dayjs')
-const utc = require('dayjs/plugin/utc')
-const customParseFormat = require('dayjs/plugin/customParseFormat')
-dayjs.extend(customParseFormat)
-dayjs.extend(utc)
-
-const date = dayjs.utc('2025-01-12', 'YYYY-MM-DD').startOf('d')
-const channel = { site_id: 'bbc1' }
-
-it('can generate valid url', () => {
- expect(url({ channel, date })).toBe('https://example.com/api/bbc1/2025-01-12')
-})
-
-it('can parse response', () => {
- const content =
- '[{"title":"Program 1","start":"2025-01-12T00:00:00.000Z","stop":"2025-01-12T00:30:00.000Z"},{"title":"Program 2","start":"2025-01-12T00:30:00.000Z","stop":"2025-01-12T01:00:00.000Z"}]'
-
- const results = parser({ content })
-
- expect(results.length).toBe(2)
- expect(results[0]).toMatchObject({
- title: 'Program 1',
- start: '2025-01-12T00:00:00.000Z',
- stop: '2025-01-12T00:30:00.000Z'
- })
- expect(results[1]).toMatchObject({
- title: 'Program 2',
- start: '2025-01-12T00:30:00.000Z',
- stop: '2025-01-12T01:00:00.000Z'
- })
-})
-
-it('can handle empty guide', () => {
- const results = parser({ content: '' })
-
- expect(results).toMatchObject([])
-})
+const { parser, url } = require('./.config.js')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const date = dayjs.utc('2025-01-12', 'YYYY-MM-DD').startOf('d')
+const channel = { site_id: 'bbc1' }
+
+it('can generate valid url', () => {
+ expect(url({ channel, date })).toBe('https://example.com/api/bbc1/2025-01-12')
+})
+
+it('can parse response', () => {
+ const content =
+ '[{"title":"Program 1","start":"2025-01-12T00:00:00.000Z","stop":"2025-01-12T00:30:00.000Z"},{"title":"Program 2","start":"2025-01-12T00:30:00.000Z","stop":"2025-01-12T01:00:00.000Z"}]'
+
+ const results = parser({ content })
+
+ expect(results.length).toBe(2)
+ expect(results[0]).toMatchObject({
+ title: 'Program 1',
+ start: '2025-01-12T00:00:00.000Z',
+ stop: '2025-01-12T00:30:00.000Z'
+ })
+ expect(results[1]).toMatchObject({
+ title: 'Program 2',
+ start: '2025-01-12T00:30:00.000Z',
+ stop: '2025-01-12T01:00:00.000Z'
+ })
+})
+
+it('can handle empty guide', () => {
+ const results = parser({ content: '' })
+
+ expect(results).toMatchObject([])
+})
diff --git a/scripts/types/langs.d.ts b/scripts/types/langs.d.ts
index 60fb498a..74921c68 100644
--- a/scripts/types/langs.d.ts
+++ b/scripts/types/langs.d.ts
@@ -1 +1 @@
-declare module 'langs'
+declare module 'langs'
From c372fc2f6bb5b8108c47ed66256c5b17dd0f42d7 Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Thu, 23 Oct 2025 04:54:18 +0300
Subject: [PATCH 18/19] Update api.ts
---
scripts/api.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/api.ts b/scripts/api.ts
index c24c6cfb..4535b721 100644
--- a/scripts/api.ts
+++ b/scripts/api.ts
@@ -80,8 +80,8 @@ async function downloadData() {
const dataManager = new sdk.DataManager({ dataDir: DATA_DIR })
- let requests: Promise[] = []
- for (let basename of files) {
+ const requests: Promise[] = []
+ for (const basename of files) {
const filename = `${basename}.json`
const progressBar = multiBar.create(0, 0, { filename })
const request = dataManager.downloadFileToDisk(basename, {
From 296b47db4d255259eb2ca6b2c8377d1f6791c62a Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Thu, 23 Oct 2025 04:56:54 +0300
Subject: [PATCH 19/19] Update check.yml
---
.github/workflows/check.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index d6c69ced..c8c72d5c 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -2,7 +2,7 @@ name: check
on:
workflow_dispatch:
pull_request:
- types: [opened, synchronize, reopened, edited]
+ types: [opened, synchronize, reopened]
branches:
- master
concurrency: