From 822e39dcf01bebf2184e2498aa6cb956b86349b7 Mon Sep 17 00:00:00 2001 From: Aleksandr Statciuk Date: Mon, 7 Feb 2022 08:39:55 +0300 Subject: [PATCH] Update update-readme.js --- .readme/template.md | 103 +---- scripts/commands/update-readme.js | 155 +++---- scripts/core/markdown.js | 29 -- scripts/core/table.js | 32 ++ tests/__data__/expected/_readme.md | 418 ++++++++++++++++++ .../expected/cleanup-database.streams.db | 5 - .../__data__/expected/save-results.streams.db | 6 - tests/__data__/expected/streams.db | 3 - .../input/{readme.json => _readme.json} | 0 .../input/logs/generators/categories.log | 32 +- .../input/logs/generators/countries.log | 255 ++++++++++- .../input/logs/generators/languages.log | 9 +- .../input/logs/generators/regions.log | 31 +- tests/__data__/input/readme.md | 180 -------- tests/commands/update-readme.test.js | 31 +- 15 files changed, 870 insertions(+), 419 deletions(-) create mode 100644 scripts/core/table.js create mode 100644 tests/__data__/expected/_readme.md delete mode 100644 tests/__data__/expected/cleanup-database.streams.db delete mode 100644 tests/__data__/expected/save-results.streams.db delete mode 100644 tests/__data__/expected/streams.db rename tests/__data__/input/{readme.json => _readme.json} (100%) delete mode 100644 tests/__data__/input/readme.md diff --git a/.readme/template.md b/.readme/template.md index af3e5895b8..9f23b4bcab 100644 --- a/.readme/template.md +++ b/.readme/template.md @@ -2,23 +2,20 @@ [![auto-update](https://github.com/iptv-org/iptv/actions/workflows/auto-update.yml/badge.svg)](https://github.com/iptv-org/iptv/actions/workflows/auto-update.yml) -Collection of publicly available IPTV channels from all over the world. +Collection of publicly available IPTV (Internet Protocol television) channels from all over the world. ## Usage -To watch IPTV you just need to paste this link `https://iptv-org.github.io/iptv/index.m3u` to any player which supports M3U-playlists. +![VLC Network Panel](https://github.com/iptv-org/iptv/raw/master/.readme/preview.png) -![VLC Network Panel](.readme/preview.png) +To watch IPTV, simply insert one of the links below into any player that supports M3U playlists: -Also you can instead use one of these playlists: - -- `https://iptv-org.github.io/iptv/index.category.m3u` (grouped by category) -- `https://iptv-org.github.io/iptv/index.language.m3u` (grouped by language) -- `https://iptv-org.github.io/iptv/index.country.m3u` (grouped by country) -- `https://iptv-org.github.io/iptv/index.region.m3u` (grouped by region) +- `https://iptv-org.github.io/iptv/index.m3u` - `https://iptv-org.github.io/iptv/index.nsfw.m3u` (includes adult channels) - -Or select one of the playlists from the list below. +- `https://iptv-org.github.io/iptv/index.category.m3u` (grouped by category) +- `https://iptv-org.github.io/iptv/index.country.m3u` (grouped by country) +- `https://iptv-org.github.io/iptv/index.language.m3u` (grouped by language) +- `https://iptv-org.github.io/iptv/index.region.m3u` (grouped by region) ### Playlists by category @@ -31,6 +28,17 @@ Or select one of the playlists from the list below. +### Playlists by country + +
+Expand +
+ + +#include "./.readme/_countries.md" + +
+ ### Playlists by language
@@ -53,76 +61,9 @@ Or select one of the playlists from the list below.
-### Playlists by country - -
-Expand -
- - -#include "./.readme/_countries.md" - -
- -## For Developers - -In addition to the above methods, you can also get a list of all available channels in JSON format. - -To do this, you just have to make a GET request to: - -``` -https://iptv-org.github.io/iptv/channels.json -``` - -If successful, you should get the following response: - -
-Expand -
- -``` -[ - ... - { - "name": "CNN", - "logo": "https://i.imgur.com/ilZJT5s.png", - "url": "http://ott-cdn.ucom.am/s27/index.m3u8", - "categories": [ - { - "name": "News", - "slug": "news" - } - ], - "countries": [ - { - "code": "us", - "name": "United States" - }, - { - "code": "ca", - "name": "Canada" - } - ], - "languages": [ - { - "code": "eng", - "name": "English" - } - ], - "tvg": { - "id": "cnn.us", - "name": "CNN", - "url": "http://epg.streamstv.me/epg/guide-usa.xml.gz" - } - }, - ... -] -``` -
- ## EPG -Playlists already have a built-in list of EPG, so players that support the `url-tvg` tag should load it automatically. If not, you can find a list of available programs here: +Playlists already have a built-in list of EPG, so players that support the `x-tvg-url` tag should load it automatically. If not, you can find a list of available programs here: https://github.com/iptv-org/epg @@ -130,6 +71,10 @@ https://github.com/iptv-org/epg You can find links to various IPTV related resources in this repository [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv). +## API + +The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository. + ## Contribution Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before sending an issue or making a pull request. diff --git a/scripts/commands/update-readme.js b/scripts/commands/update-readme.js index 12a42d5ee0..a3560cac1c 100644 --- a/scripts/commands/update-readme.js +++ b/scripts/commands/update-readme.js @@ -1,12 +1,8 @@ -const { file, markdown, parser, logger } = require('../core') +const { file, markdown, parser, logger, api } = require('../core') +const { create: createTable } = require('../core/table') const { program } = require('commander') -let categories = [] -let countries = [] -let languages = [] -let regions = [] - -const LOGS_PATH = process.env.LOGS_PATH || 'scripts/logs' +const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs/generators' const options = program .option('-c, --config ', 'Set path to config file', '.readme/config.json') @@ -14,97 +10,79 @@ const options = program .opts() async function main() { - await setUp() - - await generateCategoryTable() - await generateLanguageTable() - await generateRegionTable() - await generateCountryTable() - + await createCategoryTable() + await createCountryTable() + await createLanguageTable() + await createRegionTable() await updateReadme() } main() -async function generateCategoryTable() { - logger.info('Generating category table...') - +async function createCategoryTable() { + logger.info('creating category table...') const rows = [] - for (const category of categories) { + await api.categories.load() + const items = await parser.parseLogs(`${LOGS_DIR}/categories.log`) + for (const item of items) { + const id = file.getFilename(item.filepath) + const category = await api.categories.find({ id }) rows.push({ - category: category.name, - channels: category.count, - playlist: `https://iptv-org.github.io/iptv/categories/${category.slug}.m3u` + name: category ? category.name : 'Undefined', + channels: item.count, + playlist: `https://iptv-org.github.io/iptv/${item.filepath}` }) } - const table = markdown.createTable(rows, [ - { name: 'Category', align: 'left' }, + const table = createTable(rows, [ + { name: 'Category' }, { name: 'Channels', align: 'right' }, - { name: 'Playlist', align: 'left', nowrap: true } + { name: 'Playlist', nowrap: true } ]) await file.create('./.readme/_categories.md', table) } -async function generateCountryTable() { - logger.info('Generating country table...') - +async function createCountryTable() { + logger.info('creating country table...') const rows = [] - for (const country of countries) { - const flag = getCountryFlag(country.code) - const prefix = flag ? `${flag} ` : '' - + await api.countries.load() + const items = await parser.parseLogs(`${LOGS_DIR}/countries.log`) + for (const item of items) { + const code = file.getFilename(item.filepath) + const country = await api.countries.find({ code: code.toUpperCase() }) rows.push({ - country: prefix + country.name, - channels: country.count, - playlist: `https://iptv-org.github.io/iptv/countries/${country.code.toLowerCase()}.m3u` + name: country ? `${country.flag} ${country.name}` : 'Undefined', + channels: item.count, + playlist: `https://iptv-org.github.io/iptv/${item.filepath}` }) } - const table = markdown.createTable(rows, [ - { name: 'Country', align: 'left' }, + const table = createTable(rows, [ + { name: 'Country' }, { name: 'Channels', align: 'right' }, - { name: 'Playlist', align: 'left', nowrap: true } + { name: 'Playlist', nowrap: true } ]) await file.create('./.readme/_countries.md', table) } -async function generateRegionTable() { - logger.info('Generating region table...') - +async function createLanguageTable() { + logger.info('creating language table...') const rows = [] - for (const region of regions) { + await api.languages.load() + const items = await parser.parseLogs(`${LOGS_DIR}/languages.log`) + for (const item of items) { + const code = file.getFilename(item.filepath) + const language = await api.languages.find({ code }) rows.push({ - region: region.name, - channels: region.count, - playlist: `https://iptv-org.github.io/iptv/regions/${region.code.toLowerCase()}.m3u` + name: language ? language.name : 'Undefined', + channels: item.count, + playlist: `https://iptv-org.github.io/iptv/${item.filepath}` }) } - const table = markdown.createTable(rows, [ - { name: 'Region', align: 'left' }, - { name: 'Channels', align: 'right' }, - { name: 'Playlist', align: 'left', nowrap: true } - ]) - - await file.create('./.readme/_regions.md', table) -} - -async function generateLanguageTable() { - logger.info('Generating language table...') - - const rows = [] - for (const language of languages) { - rows.push({ - language: language.name, - channels: language.count, - playlist: `https://iptv-org.github.io/iptv/languages/${language.code}.m3u` - }) - } - - const table = markdown.createTable(rows, [ + const table = createTable(rows, [ { name: 'Language', align: 'left' }, { name: 'Channels', align: 'right' }, { name: 'Playlist', align: 'left', nowrap: true } @@ -113,28 +91,33 @@ async function generateLanguageTable() { await file.create('./.readme/_languages.md', table) } -async function updateReadme() { - logger.info('Updating README.md...') +async function createRegionTable() { + logger.info('creating region table...') + const rows = [] + await api.regions.load() + const items = await parser.parseLogs(`${LOGS_DIR}/regions.log`) + for (const item of items) { + const code = file.getFilename(item.filepath) + const region = await api.regions.find({ code: code.toUpperCase() }) + rows.push({ + name: region ? region.name : 'Undefined', + channels: item.count, + playlist: `https://iptv-org.github.io/iptv/${item.filepath}` + }) + } + const table = createTable(rows, [ + { name: 'Region', align: 'left' }, + { name: 'Channels', align: 'right' }, + { name: 'Playlist', align: 'left', nowrap: true } + ]) + + await file.create('./.readme/_regions.md', table) +} + +async function updateReadme() { + logger.info('updating readme.md...') const config = require(file.resolve(options.config)) await file.createDir(file.dirname(config.build)) await markdown.compile(options.config) } - -async function setUp() { - categories = await parser.parseLogs(`${LOGS_PATH}/generate-playlists/categories.log`) - countries = await parser.parseLogs(`${LOGS_PATH}/generate-playlists/countries.log`) - languages = await parser.parseLogs(`${LOGS_PATH}/generate-playlists/languages.log`) - regions = await parser.parseLogs(`${LOGS_PATH}/generate-playlists/regions.log`) -} - -function getCountryFlag(code) { - switch (code) { - case 'UK': - return '๐Ÿ‡ฌ๐Ÿ‡ง' - case 'UNDEFINED': - return '' - default: - return code.replace(/./g, char => String.fromCodePoint(char.charCodeAt(0) + 127397)) - } -} diff --git a/scripts/core/markdown.js b/scripts/core/markdown.js index 32dc1110ec..2729f0b7b8 100644 --- a/scripts/core/markdown.js +++ b/scripts/core/markdown.js @@ -3,35 +3,6 @@ const file = require('./file') const markdown = {} -markdown.createTable = function (data, cols) { - let output = '\n' - - output += ' \n ' - for (let column of cols) { - output += `` - } - output += '\n \n' - - output += ' \n' - for (let item of data) { - output += ' ' - let i = 0 - for (let prop in item) { - const column = cols[i] - let nowrap = column.nowrap - let align = column.align - output += `` - i++ - } - output += '\n' - } - output += ' \n' - - output += '
${column.name}
${item[prop]}
' - - return output -} - markdown.compile = function (filepath) { markdownInclude.compileFiles(file.resolve(filepath)) } diff --git a/scripts/core/table.js b/scripts/core/table.js new file mode 100644 index 0000000000..563cb9bfaa --- /dev/null +++ b/scripts/core/table.js @@ -0,0 +1,32 @@ +const table = {} + +table.create = function (data, cols) { + let output = '\n' + + output += ' \n ' + for (let column of cols) { + output += `` + } + output += '\n \n' + + output += ' \n' + for (let item of data) { + output += ' ' + let i = 0 + for (let prop in item) { + const column = cols[i] + let nowrap = column.nowrap ? ` nowrap` : '' + let align = column.align ? ` align="${column.align}"` : '' + output += `${item[prop]}` + i++ + } + output += '\n' + } + output += ' \n' + + output += '
${column.name}
' + + return output +} + +module.exports = table diff --git a/tests/__data__/expected/_readme.md b/tests/__data__/expected/_readme.md new file mode 100644 index 0000000000..f65bedd973 --- /dev/null +++ b/tests/__data__/expected/_readme.md @@ -0,0 +1,418 @@ +# IPTV + +[![auto-update](https://github.com/iptv-org/iptv/actions/workflows/auto-update.yml/badge.svg)](https://github.com/iptv-org/iptv/actions/workflows/auto-update.yml) + +Collection of publicly available IPTV (Internet Protocol television) channels from all over the world. + +## Usage + +![VLC Network Panel](https://github.com/iptv-org/iptv/raw/master/.readme/preview.png) + +To watch IPTV, simply insert one of the links below into any player that supports M3U playlists: + +- `https://iptv-org.github.io/iptv/index.m3u` +- `https://iptv-org.github.io/iptv/index.nsfw.m3u` (includes adult channels) +- `https://iptv-org.github.io/iptv/index.category.m3u` (grouped by category) +- `https://iptv-org.github.io/iptv/index.country.m3u` (grouped by country) +- `https://iptv-org.github.io/iptv/index.language.m3u` (grouped by language) +- `https://iptv-org.github.io/iptv/index.region.m3u` (grouped by region) + +### Playlists by category + +
+Expand +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryChannelsPlaylist
Auto0https://iptv-org.github.io/iptv/categories/auto.m3u
Animation0https://iptv-org.github.io/iptv/categories/animation.m3u
Business0https://iptv-org.github.io/iptv/categories/business.m3u
Classic0https://iptv-org.github.io/iptv/categories/classic.m3u
Comedy0https://iptv-org.github.io/iptv/categories/comedy.m3u
Cooking0https://iptv-org.github.io/iptv/categories/cooking.m3u
Culture0https://iptv-org.github.io/iptv/categories/culture.m3u
Documentary0https://iptv-org.github.io/iptv/categories/documentary.m3u
Education0https://iptv-org.github.io/iptv/categories/education.m3u
Entertainment0https://iptv-org.github.io/iptv/categories/entertainment.m3u
Family0https://iptv-org.github.io/iptv/categories/family.m3u
General2https://iptv-org.github.io/iptv/categories/general.m3u
Kids0https://iptv-org.github.io/iptv/categories/kids.m3u
Legislative0https://iptv-org.github.io/iptv/categories/legislative.m3u
Lifestyle0https://iptv-org.github.io/iptv/categories/lifestyle.m3u
Movies0https://iptv-org.github.io/iptv/categories/movies.m3u
Music0https://iptv-org.github.io/iptv/categories/music.m3u
News1https://iptv-org.github.io/iptv/categories/news.m3u
Outdoor0https://iptv-org.github.io/iptv/categories/outdoor.m3u
Relax0https://iptv-org.github.io/iptv/categories/relax.m3u
Religious0https://iptv-org.github.io/iptv/categories/religious.m3u
Series0https://iptv-org.github.io/iptv/categories/series.m3u
Science0https://iptv-org.github.io/iptv/categories/science.m3u
Shop0https://iptv-org.github.io/iptv/categories/shop.m3u
Sports0https://iptv-org.github.io/iptv/categories/sports.m3u
Travel0https://iptv-org.github.io/iptv/categories/travel.m3u
Weather1https://iptv-org.github.io/iptv/categories/weather.m3u
XXX1https://iptv-org.github.io/iptv/categories/xxx.m3u
Undefined3https://iptv-org.github.io/iptv/categories/undefined.m3u
+ +
+ +### Playlists by country + +
+Expand +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CountryChannelsPlaylist
๐Ÿ‡ฆ๐Ÿ‡ซ Afghanistan1https://iptv-org.github.io/iptv/countries/af.m3u
๐Ÿ‡ฆ๐Ÿ‡ฑ Albania1https://iptv-org.github.io/iptv/countries/al.m3u
๐Ÿ‡ฉ๐Ÿ‡ฟ Algeria1https://iptv-org.github.io/iptv/countries/dz.m3u
๐Ÿ‡ฆ๐Ÿ‡ธ American Samoa1https://iptv-org.github.io/iptv/countries/as.m3u
๐Ÿ‡ฆ๐Ÿ‡ฉ Andorra2https://iptv-org.github.io/iptv/countries/ad.m3u
๐Ÿ‡ฆ๐Ÿ‡ด Angola1https://iptv-org.github.io/iptv/countries/ao.m3u
๐Ÿ‡ฆ๐Ÿ‡ฎ Anguilla1https://iptv-org.github.io/iptv/countries/ai.m3u
๐Ÿ‡ฆ๐Ÿ‡ถ Antarctica1https://iptv-org.github.io/iptv/countries/aq.m3u
๐Ÿ‡ฆ๐Ÿ‡ฌ Antigua and Barbuda1https://iptv-org.github.io/iptv/countries/ag.m3u
๐Ÿ‡ฆ๐Ÿ‡ท Argentina1https://iptv-org.github.io/iptv/countries/ar.m3u
๐Ÿ‡ฆ๐Ÿ‡ฒ Armenia1https://iptv-org.github.io/iptv/countries/am.m3u
๐Ÿ‡ฆ๐Ÿ‡ผ Aruba1https://iptv-org.github.io/iptv/countries/aw.m3u
๐Ÿ‡ฆ๐Ÿ‡บ Australia1https://iptv-org.github.io/iptv/countries/au.m3u
๐Ÿ‡ฆ๐Ÿ‡น Austria1https://iptv-org.github.io/iptv/countries/at.m3u
๐Ÿ‡ฆ๐Ÿ‡ฟ Azerbaijan1https://iptv-org.github.io/iptv/countries/az.m3u
๐Ÿ‡ง๐Ÿ‡ธ Bahamas1https://iptv-org.github.io/iptv/countries/bs.m3u
๐Ÿ‡ง๐Ÿ‡ญ Bahrain1https://iptv-org.github.io/iptv/countries/bh.m3u
๐Ÿ‡ง๐Ÿ‡ฉ Bangladesh1https://iptv-org.github.io/iptv/countries/bd.m3u
๐Ÿ‡ง๐Ÿ‡ง Barbados1https://iptv-org.github.io/iptv/countries/bb.m3u
๐Ÿ‡ง๐Ÿ‡พ Belarus1https://iptv-org.github.io/iptv/countries/by.m3u
๐Ÿ‡ง๐Ÿ‡ช Belgium1https://iptv-org.github.io/iptv/countries/be.m3u
๐Ÿ‡ง๐Ÿ‡ฟ Belize1https://iptv-org.github.io/iptv/countries/bz.m3u
๐Ÿ‡ง๐Ÿ‡ฏ Benin1https://iptv-org.github.io/iptv/countries/bj.m3u
๐Ÿ‡ง๐Ÿ‡ฒ Bermuda1https://iptv-org.github.io/iptv/countries/bm.m3u
๐Ÿ‡ง๐Ÿ‡น Bhutan1https://iptv-org.github.io/iptv/countries/bt.m3u
๐Ÿ‡ง๐Ÿ‡ด Bolivia1https://iptv-org.github.io/iptv/countries/bo.m3u
๐Ÿ‡ง๐Ÿ‡ถ Bonaire1https://iptv-org.github.io/iptv/countries/bq.m3u
๐Ÿ‡ง๐Ÿ‡ฆ Bosnia and Herzegovina1https://iptv-org.github.io/iptv/countries/ba.m3u
๐Ÿ‡ง๐Ÿ‡ผ Botswana1https://iptv-org.github.io/iptv/countries/bw.m3u
๐Ÿ‡ง๐Ÿ‡ป Bouvet Island1https://iptv-org.github.io/iptv/countries/bv.m3u
๐Ÿ‡ง๐Ÿ‡ท Brazil1https://iptv-org.github.io/iptv/countries/br.m3u
๐Ÿ‡ฎ๐Ÿ‡ด British Indian Ocean Territory1https://iptv-org.github.io/iptv/countries/io.m3u
๐Ÿ‡ป๐Ÿ‡ฌ British Virgin Islands1https://iptv-org.github.io/iptv/countries/vg.m3u
๐Ÿ‡ง๐Ÿ‡ณ Brunei1https://iptv-org.github.io/iptv/countries/bn.m3u
๐Ÿ‡ง๐Ÿ‡ฌ Bulgaria1https://iptv-org.github.io/iptv/countries/bg.m3u
๐Ÿ‡ง๐Ÿ‡ซ Burkina Faso1https://iptv-org.github.io/iptv/countries/bf.m3u
๐Ÿ‡ง๐Ÿ‡ฎ Burundi1https://iptv-org.github.io/iptv/countries/bi.m3u
๐Ÿ‡ฐ๐Ÿ‡ญ Cambodia1https://iptv-org.github.io/iptv/countries/kh.m3u
๐Ÿ‡จ๐Ÿ‡ฒ Cameroon1https://iptv-org.github.io/iptv/countries/cm.m3u
๐Ÿ‡จ๐Ÿ‡ฆ Canada2https://iptv-org.github.io/iptv/countries/ca.m3u
๐Ÿ‡จ๐Ÿ‡ป Cape Verde1https://iptv-org.github.io/iptv/countries/cv.m3u
๐Ÿ‡ฐ๐Ÿ‡พ Cayman Islands1https://iptv-org.github.io/iptv/countries/ky.m3u
๐Ÿ‡จ๐Ÿ‡ซ Central African Republic1https://iptv-org.github.io/iptv/countries/cf.m3u
๐Ÿ‡น๐Ÿ‡ฉ Chad1https://iptv-org.github.io/iptv/countries/td.m3u
๐Ÿ‡จ๐Ÿ‡ฑ Chile1https://iptv-org.github.io/iptv/countries/cl.m3u
๐Ÿ‡จ๐Ÿ‡ณ China1https://iptv-org.github.io/iptv/countries/cn.m3u
๐Ÿ‡จ๐Ÿ‡ฝ Christmas Island1https://iptv-org.github.io/iptv/countries/cx.m3u
๐Ÿ‡จ๐Ÿ‡จ Cocos (Keeling) Islands1https://iptv-org.github.io/iptv/countries/cc.m3u
๐Ÿ‡จ๐Ÿ‡ด Colombia1https://iptv-org.github.io/iptv/countries/co.m3u
๐Ÿ‡ฐ๐Ÿ‡ฒ Comoros1https://iptv-org.github.io/iptv/countries/km.m3u
๐Ÿ‡จ๐Ÿ‡ฐ Cook Islands1https://iptv-org.github.io/iptv/countries/ck.m3u
๐Ÿ‡จ๐Ÿ‡ท Costa Rica1https://iptv-org.github.io/iptv/countries/cr.m3u
๐Ÿ‡ญ๐Ÿ‡ท Croatia1https://iptv-org.github.io/iptv/countries/hr.m3u
๐Ÿ‡จ๐Ÿ‡บ Cuba1https://iptv-org.github.io/iptv/countries/cu.m3u
๐Ÿ‡จ๐Ÿ‡ผ Curacao1https://iptv-org.github.io/iptv/countries/cw.m3u
๐Ÿ‡จ๐Ÿ‡พ Cyprus1https://iptv-org.github.io/iptv/countries/cy.m3u
๐Ÿ‡จ๐Ÿ‡ฟ Czech Republic1https://iptv-org.github.io/iptv/countries/cz.m3u
๐Ÿ‡จ๐Ÿ‡ฉ Democratic Republic of the Congo1https://iptv-org.github.io/iptv/countries/cd.m3u
๐Ÿ‡ฉ๐Ÿ‡ฐ Denmark1https://iptv-org.github.io/iptv/countries/dk.m3u
๐Ÿ‡ฉ๐Ÿ‡ฏ Djibouti1https://iptv-org.github.io/iptv/countries/dj.m3u
๐Ÿ‡ฉ๐Ÿ‡ฒ Dominica1https://iptv-org.github.io/iptv/countries/dm.m3u
๐Ÿ‡ฉ๐Ÿ‡ด Dominican Republic1https://iptv-org.github.io/iptv/countries/do.m3u
๐Ÿ‡น๐Ÿ‡ฑ East Timor1https://iptv-org.github.io/iptv/countries/tl.m3u
๐Ÿ‡ช๐Ÿ‡จ Ecuador1https://iptv-org.github.io/iptv/countries/ec.m3u
๐Ÿ‡ช๐Ÿ‡ฌ Egypt1https://iptv-org.github.io/iptv/countries/eg.m3u
๐Ÿ‡ธ๐Ÿ‡ป El Salvador1https://iptv-org.github.io/iptv/countries/sv.m3u
๐Ÿ‡ฌ๐Ÿ‡ถ Equatorial Guinea1https://iptv-org.github.io/iptv/countries/gq.m3u
๐Ÿ‡ช๐Ÿ‡ท Eritrea1https://iptv-org.github.io/iptv/countries/er.m3u
๐Ÿ‡ช๐Ÿ‡ช Estonia1https://iptv-org.github.io/iptv/countries/ee.m3u
๐Ÿ‡ช๐Ÿ‡น Ethiopia1https://iptv-org.github.io/iptv/countries/et.m3u
๐Ÿ‡ซ๐Ÿ‡ฐ Falkland Islands1https://iptv-org.github.io/iptv/countries/fk.m3u
๐Ÿ‡ซ๐Ÿ‡ด Faroe Islands1https://iptv-org.github.io/iptv/countries/fo.m3u
๐Ÿ‡ซ๐Ÿ‡ฏ Fiji1https://iptv-org.github.io/iptv/countries/fj.m3u
๐Ÿ‡ซ๐Ÿ‡ฎ Finland1https://iptv-org.github.io/iptv/countries/fi.m3u
๐Ÿ‡ซ๐Ÿ‡ท France1https://iptv-org.github.io/iptv/countries/fr.m3u
๐Ÿ‡ฌ๐Ÿ‡ซ French Guiana1https://iptv-org.github.io/iptv/countries/gf.m3u
๐Ÿ‡ต๐Ÿ‡ซ French Polynesia1https://iptv-org.github.io/iptv/countries/pf.m3u
๐Ÿ‡น๐Ÿ‡ซ French Southern Territories1https://iptv-org.github.io/iptv/countries/tf.m3u
๐Ÿ‡ฌ๐Ÿ‡ฆ Gabon1https://iptv-org.github.io/iptv/countries/ga.m3u
๐Ÿ‡ฌ๐Ÿ‡ฒ Gambia1https://iptv-org.github.io/iptv/countries/gm.m3u
๐Ÿ‡ฌ๐Ÿ‡ช Georgia1https://iptv-org.github.io/iptv/countries/ge.m3u
๐Ÿ‡ฉ๐Ÿ‡ช Germany1https://iptv-org.github.io/iptv/countries/de.m3u
๐Ÿ‡ฌ๐Ÿ‡ญ Ghana1https://iptv-org.github.io/iptv/countries/gh.m3u
๐Ÿ‡ฌ๐Ÿ‡ฎ Gibraltar1https://iptv-org.github.io/iptv/countries/gi.m3u
๐Ÿ‡ฌ๐Ÿ‡ท Greece1https://iptv-org.github.io/iptv/countries/gr.m3u
๐Ÿ‡ฌ๐Ÿ‡ฑ Greenland1https://iptv-org.github.io/iptv/countries/gl.m3u
๐Ÿ‡ฌ๐Ÿ‡ฉ Grenada1https://iptv-org.github.io/iptv/countries/gd.m3u
๐Ÿ‡ฌ๐Ÿ‡ต Guadeloupe1https://iptv-org.github.io/iptv/countries/gp.m3u
๐Ÿ‡ฌ๐Ÿ‡บ Guam1https://iptv-org.github.io/iptv/countries/gu.m3u
๐Ÿ‡ฌ๐Ÿ‡น Guatemala1https://iptv-org.github.io/iptv/countries/gt.m3u
๐Ÿ‡ฌ๐Ÿ‡ฌ Guernsey1https://iptv-org.github.io/iptv/countries/gg.m3u
๐Ÿ‡ฌ๐Ÿ‡ณ Guinea1https://iptv-org.github.io/iptv/countries/gn.m3u
๐Ÿ‡ฌ๐Ÿ‡ผ Guinea-Bissau1https://iptv-org.github.io/iptv/countries/gw.m3u
๐Ÿ‡ฌ๐Ÿ‡พ Guyana1https://iptv-org.github.io/iptv/countries/gy.m3u
๐Ÿ‡ญ๐Ÿ‡น Haiti1https://iptv-org.github.io/iptv/countries/ht.m3u
๐Ÿ‡ญ๐Ÿ‡ฒ Heard Island and McDonald Islands1https://iptv-org.github.io/iptv/countries/hm.m3u
๐Ÿ‡ญ๐Ÿ‡ณ Honduras1https://iptv-org.github.io/iptv/countries/hn.m3u
๐Ÿ‡ญ๐Ÿ‡ฐ Hong Kong1https://iptv-org.github.io/iptv/countries/hk.m3u
๐Ÿ‡ญ๐Ÿ‡บ Hungary1https://iptv-org.github.io/iptv/countries/hu.m3u
๐Ÿ‡ฎ๐Ÿ‡ธ Iceland1https://iptv-org.github.io/iptv/countries/is.m3u
๐Ÿ‡ฎ๐Ÿ‡ณ India1https://iptv-org.github.io/iptv/countries/in.m3u
๐Ÿ‡ฎ๐Ÿ‡ฉ Indonesia1https://iptv-org.github.io/iptv/countries/id.m3u
๐Ÿ‡ฎ๐Ÿ‡ท Iran1https://iptv-org.github.io/iptv/countries/ir.m3u
๐Ÿ‡ฎ๐Ÿ‡ถ Iraq1https://iptv-org.github.io/iptv/countries/iq.m3u
๐Ÿ‡ฎ๐Ÿ‡ช Ireland1https://iptv-org.github.io/iptv/countries/ie.m3u
๐Ÿ‡ฎ๐Ÿ‡ฒ Isle of Man1https://iptv-org.github.io/iptv/countries/im.m3u
๐Ÿ‡ฎ๐Ÿ‡ฑ Israel1https://iptv-org.github.io/iptv/countries/il.m3u
๐Ÿ‡ฎ๐Ÿ‡น Italy1https://iptv-org.github.io/iptv/countries/it.m3u
๐Ÿ‡จ๐Ÿ‡ฎ Ivory Coast1https://iptv-org.github.io/iptv/countries/ci.m3u
๐Ÿ‡ฏ๐Ÿ‡ฒ Jamaica1https://iptv-org.github.io/iptv/countries/jm.m3u
๐Ÿ‡ฏ๐Ÿ‡ต Japan1https://iptv-org.github.io/iptv/countries/jp.m3u
๐Ÿ‡ฏ๐Ÿ‡ช Jersey1https://iptv-org.github.io/iptv/countries/je.m3u
๐Ÿ‡ฏ๐Ÿ‡ด Jordan1https://iptv-org.github.io/iptv/countries/jo.m3u
๐Ÿ‡ฐ๐Ÿ‡ฟ Kazakhstan1https://iptv-org.github.io/iptv/countries/kz.m3u
๐Ÿ‡ฐ๐Ÿ‡ช Kenya1https://iptv-org.github.io/iptv/countries/ke.m3u
๐Ÿ‡ฐ๐Ÿ‡ฎ Kiribati1https://iptv-org.github.io/iptv/countries/ki.m3u
๐Ÿ‡ฝ๐Ÿ‡ฐ Kosovo1https://iptv-org.github.io/iptv/countries/xk.m3u
๐Ÿ‡ฐ๐Ÿ‡ผ Kuwait1https://iptv-org.github.io/iptv/countries/kw.m3u
๐Ÿ‡ฐ๐Ÿ‡ฌ Kyrgyzstan1https://iptv-org.github.io/iptv/countries/kg.m3u
๐Ÿ‡ฑ๐Ÿ‡ฆ Laos1https://iptv-org.github.io/iptv/countries/la.m3u
๐Ÿ‡ฑ๐Ÿ‡ป Latvia1https://iptv-org.github.io/iptv/countries/lv.m3u
๐Ÿ‡ฑ๐Ÿ‡ง Lebanon1https://iptv-org.github.io/iptv/countries/lb.m3u
๐Ÿ‡ฑ๐Ÿ‡ธ Lesotho1https://iptv-org.github.io/iptv/countries/ls.m3u
๐Ÿ‡ฑ๐Ÿ‡ท Liberia1https://iptv-org.github.io/iptv/countries/lr.m3u
๐Ÿ‡ฑ๐Ÿ‡พ Libya1https://iptv-org.github.io/iptv/countries/ly.m3u
๐Ÿ‡ฑ๐Ÿ‡ฎ Liechtenstein1https://iptv-org.github.io/iptv/countries/li.m3u
๐Ÿ‡ฑ๐Ÿ‡น Lithuania1https://iptv-org.github.io/iptv/countries/lt.m3u
๐Ÿ‡ฑ๐Ÿ‡บ Luxembourg1https://iptv-org.github.io/iptv/countries/lu.m3u
๐Ÿ‡ฒ๐Ÿ‡ด Macao1https://iptv-org.github.io/iptv/countries/mo.m3u
๐Ÿ‡ฒ๐Ÿ‡ฌ Madagascar1https://iptv-org.github.io/iptv/countries/mg.m3u
๐Ÿ‡ฒ๐Ÿ‡ผ Malawi1https://iptv-org.github.io/iptv/countries/mw.m3u
๐Ÿ‡ฒ๐Ÿ‡พ Malaysia1https://iptv-org.github.io/iptv/countries/my.m3u
๐Ÿ‡ฒ๐Ÿ‡ป Maldives1https://iptv-org.github.io/iptv/countries/mv.m3u
๐Ÿ‡ฒ๐Ÿ‡ฑ Mali1https://iptv-org.github.io/iptv/countries/ml.m3u
๐Ÿ‡ฒ๐Ÿ‡น Malta1https://iptv-org.github.io/iptv/countries/mt.m3u
๐Ÿ‡ฒ๐Ÿ‡ญ Marshall Islands1https://iptv-org.github.io/iptv/countries/mh.m3u
๐Ÿ‡ฒ๐Ÿ‡ถ Martinique1https://iptv-org.github.io/iptv/countries/mq.m3u
๐Ÿ‡ฒ๐Ÿ‡ท Mauritania1https://iptv-org.github.io/iptv/countries/mr.m3u
๐Ÿ‡ฒ๐Ÿ‡บ Mauritius1https://iptv-org.github.io/iptv/countries/mu.m3u
๐Ÿ‡พ๐Ÿ‡น Mayotte1https://iptv-org.github.io/iptv/countries/yt.m3u
๐Ÿ‡ฒ๐Ÿ‡ฝ Mexico1https://iptv-org.github.io/iptv/countries/mx.m3u
๐Ÿ‡ซ๐Ÿ‡ฒ Micronesia1https://iptv-org.github.io/iptv/countries/fm.m3u
๐Ÿ‡ฒ๐Ÿ‡ฉ Moldova1https://iptv-org.github.io/iptv/countries/md.m3u
๐Ÿ‡ฒ๐Ÿ‡จ Monaco1https://iptv-org.github.io/iptv/countries/mc.m3u
๐Ÿ‡ฒ๐Ÿ‡ณ Mongolia1https://iptv-org.github.io/iptv/countries/mn.m3u
๐Ÿ‡ฒ๐Ÿ‡ช Montenegro1https://iptv-org.github.io/iptv/countries/me.m3u
๐Ÿ‡ฒ๐Ÿ‡ธ Montserrat1https://iptv-org.github.io/iptv/countries/ms.m3u
๐Ÿ‡ฒ๐Ÿ‡ฆ Morocco1https://iptv-org.github.io/iptv/countries/ma.m3u
๐Ÿ‡ฒ๐Ÿ‡ฟ Mozambique1https://iptv-org.github.io/iptv/countries/mz.m3u
๐Ÿ‡ฒ๐Ÿ‡ฒ Myanmar (Burma)1https://iptv-org.github.io/iptv/countries/mm.m3u
๐Ÿ‡ณ๐Ÿ‡ฆ Namibia1https://iptv-org.github.io/iptv/countries/na.m3u
๐Ÿ‡ณ๐Ÿ‡ท Nauru1https://iptv-org.github.io/iptv/countries/nr.m3u
๐Ÿ‡ณ๐Ÿ‡ต Nepal1https://iptv-org.github.io/iptv/countries/np.m3u
๐Ÿ‡ณ๐Ÿ‡ฑ Netherlands1https://iptv-org.github.io/iptv/countries/nl.m3u
๐Ÿ‡ณ๐Ÿ‡จ New Caledonia1https://iptv-org.github.io/iptv/countries/nc.m3u
๐Ÿ‡ณ๐Ÿ‡ฟ New Zealand1https://iptv-org.github.io/iptv/countries/nz.m3u
๐Ÿ‡ณ๐Ÿ‡ฎ Nicaragua1https://iptv-org.github.io/iptv/countries/ni.m3u
๐Ÿ‡ณ๐Ÿ‡ช Niger1https://iptv-org.github.io/iptv/countries/ne.m3u
๐Ÿ‡ณ๐Ÿ‡ฌ Nigeria1https://iptv-org.github.io/iptv/countries/ng.m3u
๐Ÿ‡ณ๐Ÿ‡บ Niue1https://iptv-org.github.io/iptv/countries/nu.m3u
๐Ÿ‡ณ๐Ÿ‡ซ Norfolk Island1https://iptv-org.github.io/iptv/countries/nf.m3u
๐Ÿ‡ฐ๐Ÿ‡ต North Korea1https://iptv-org.github.io/iptv/countries/kp.m3u
๐Ÿ‡ฒ๐Ÿ‡ฐ North Macedonia1https://iptv-org.github.io/iptv/countries/mk.m3u
๐Ÿ‡ฒ๐Ÿ‡ต Northern Mariana Islands1https://iptv-org.github.io/iptv/countries/mp.m3u
๐Ÿ‡ณ๐Ÿ‡ด Norway1https://iptv-org.github.io/iptv/countries/no.m3u
๐Ÿ‡ด๐Ÿ‡ฒ Oman1https://iptv-org.github.io/iptv/countries/om.m3u
๐Ÿ‡ต๐Ÿ‡ฐ Pakistan1https://iptv-org.github.io/iptv/countries/pk.m3u
๐Ÿ‡ต๐Ÿ‡ผ Palau1https://iptv-org.github.io/iptv/countries/pw.m3u
๐Ÿ‡ต๐Ÿ‡ธ Palestine1https://iptv-org.github.io/iptv/countries/ps.m3u
๐Ÿ‡ต๐Ÿ‡ฆ Panama1https://iptv-org.github.io/iptv/countries/pa.m3u
๐Ÿ‡ต๐Ÿ‡ฌ Papua New Guinea1https://iptv-org.github.io/iptv/countries/pg.m3u
๐Ÿ‡ต๐Ÿ‡พ Paraguay1https://iptv-org.github.io/iptv/countries/py.m3u
๐Ÿ‡ต๐Ÿ‡ช Peru1https://iptv-org.github.io/iptv/countries/pe.m3u
๐Ÿ‡ต๐Ÿ‡ญ Philippines1https://iptv-org.github.io/iptv/countries/ph.m3u
๐Ÿ‡ต๐Ÿ‡ณ Pitcairn Islands1https://iptv-org.github.io/iptv/countries/pn.m3u
๐Ÿ‡ต๐Ÿ‡ฑ Poland1https://iptv-org.github.io/iptv/countries/pl.m3u
๐Ÿ‡ต๐Ÿ‡น Portugal1https://iptv-org.github.io/iptv/countries/pt.m3u
๐Ÿ‡ต๐Ÿ‡ท Puerto Rico1https://iptv-org.github.io/iptv/countries/pr.m3u
๐Ÿ‡ถ๐Ÿ‡ฆ Qatar1https://iptv-org.github.io/iptv/countries/qa.m3u
๐Ÿ‡จ๐Ÿ‡ฌ Republic of the Congo1https://iptv-org.github.io/iptv/countries/cg.m3u
๐Ÿ‡ท๐Ÿ‡ด Romania1https://iptv-org.github.io/iptv/countries/ro.m3u
๐Ÿ‡ท๐Ÿ‡บ Russia2https://iptv-org.github.io/iptv/countries/ru.m3u
๐Ÿ‡ท๐Ÿ‡ผ Rwanda1https://iptv-org.github.io/iptv/countries/rw.m3u
๐Ÿ‡ท๐Ÿ‡ช Rรฉunion1https://iptv-org.github.io/iptv/countries/re.m3u
๐Ÿ‡ง๐Ÿ‡ฑ Saint Barthรฉlemy1https://iptv-org.github.io/iptv/countries/bl.m3u
๐Ÿ‡ธ๐Ÿ‡ญ Saint Helena1https://iptv-org.github.io/iptv/countries/sh.m3u
๐Ÿ‡ฐ๐Ÿ‡ณ Saint Kitts and Nevis1https://iptv-org.github.io/iptv/countries/kn.m3u
๐Ÿ‡ฑ๐Ÿ‡จ Saint Lucia1https://iptv-org.github.io/iptv/countries/lc.m3u
๐Ÿ‡ฒ๐Ÿ‡ซ Saint Martin1https://iptv-org.github.io/iptv/countries/mf.m3u
๐Ÿ‡ต๐Ÿ‡ฒ Saint Pierre and Miquelon1https://iptv-org.github.io/iptv/countries/pm.m3u
๐Ÿ‡ป๐Ÿ‡จ Saint Vincent and the Grenadines1https://iptv-org.github.io/iptv/countries/vc.m3u
๐Ÿ‡ผ๐Ÿ‡ธ Samoa1https://iptv-org.github.io/iptv/countries/ws.m3u
๐Ÿ‡ธ๐Ÿ‡ฒ San Marino1https://iptv-org.github.io/iptv/countries/sm.m3u
๐Ÿ‡ธ๐Ÿ‡ฆ Saudi Arabia1https://iptv-org.github.io/iptv/countries/sa.m3u
๐Ÿ‡ธ๐Ÿ‡ณ Senegal1https://iptv-org.github.io/iptv/countries/sn.m3u
๐Ÿ‡ท๐Ÿ‡ธ Serbia1https://iptv-org.github.io/iptv/countries/rs.m3u
๐Ÿ‡ธ๐Ÿ‡จ Seychelles1https://iptv-org.github.io/iptv/countries/sc.m3u
๐Ÿ‡ธ๐Ÿ‡ฑ Sierra Leone1https://iptv-org.github.io/iptv/countries/sl.m3u
๐Ÿ‡ธ๐Ÿ‡ฌ Singapore1https://iptv-org.github.io/iptv/countries/sg.m3u
๐Ÿ‡ธ๐Ÿ‡ฝ Sint Maarten1https://iptv-org.github.io/iptv/countries/sx.m3u
๐Ÿ‡ธ๐Ÿ‡ฐ Slovakia1https://iptv-org.github.io/iptv/countries/sk.m3u
๐Ÿ‡ธ๐Ÿ‡ฎ Slovenia1https://iptv-org.github.io/iptv/countries/si.m3u
๐Ÿ‡ธ๐Ÿ‡ง Solomon Islands1https://iptv-org.github.io/iptv/countries/sb.m3u
๐Ÿ‡ธ๐Ÿ‡ด Somalia1https://iptv-org.github.io/iptv/countries/so.m3u
๐Ÿ‡ฟ๐Ÿ‡ฆ South Africa1https://iptv-org.github.io/iptv/countries/za.m3u
๐Ÿ‡ฌ๐Ÿ‡ธ South Georgia and the South Sandwich Islands1https://iptv-org.github.io/iptv/countries/gs.m3u
๐Ÿ‡ฐ๐Ÿ‡ท South Korea1https://iptv-org.github.io/iptv/countries/kr.m3u
๐Ÿ‡ธ๐Ÿ‡ธ South Sudan1https://iptv-org.github.io/iptv/countries/ss.m3u
๐Ÿ‡ช๐Ÿ‡ธ Spain1https://iptv-org.github.io/iptv/countries/es.m3u
๐Ÿ‡ฑ๐Ÿ‡ฐ Sri Lanka1https://iptv-org.github.io/iptv/countries/lk.m3u
๐Ÿ‡ธ๐Ÿ‡ฉ Sudan1https://iptv-org.github.io/iptv/countries/sd.m3u
๐Ÿ‡ธ๐Ÿ‡ท Suriname1https://iptv-org.github.io/iptv/countries/sr.m3u
๐Ÿ‡ธ๐Ÿ‡ฏ Svalbard and Jan Mayen1https://iptv-org.github.io/iptv/countries/sj.m3u
๐Ÿ‡ธ๐Ÿ‡ฟ Swaziland1https://iptv-org.github.io/iptv/countries/sz.m3u
๐Ÿ‡ธ๐Ÿ‡ช Sweden1https://iptv-org.github.io/iptv/countries/se.m3u
๐Ÿ‡จ๐Ÿ‡ญ Switzerland1https://iptv-org.github.io/iptv/countries/ch.m3u
๐Ÿ‡ธ๐Ÿ‡พ Syria1https://iptv-org.github.io/iptv/countries/sy.m3u
๐Ÿ‡ธ๐Ÿ‡น Sรฃo Tomรฉ and Prรญncipe1https://iptv-org.github.io/iptv/countries/st.m3u
๐Ÿ‡น๐Ÿ‡ผ Taiwan1https://iptv-org.github.io/iptv/countries/tw.m3u
๐Ÿ‡น๐Ÿ‡ฏ Tajikistan1https://iptv-org.github.io/iptv/countries/tj.m3u
๐Ÿ‡น๐Ÿ‡ฟ Tanzania1https://iptv-org.github.io/iptv/countries/tz.m3u
๐Ÿ‡น๐Ÿ‡ญ Thailand1https://iptv-org.github.io/iptv/countries/th.m3u
๐Ÿ‡น๐Ÿ‡ฌ Togo1https://iptv-org.github.io/iptv/countries/tg.m3u
๐Ÿ‡น๐Ÿ‡ฐ Tokelau1https://iptv-org.github.io/iptv/countries/tk.m3u
๐Ÿ‡น๐Ÿ‡ด Tonga1https://iptv-org.github.io/iptv/countries/to.m3u
๐Ÿ‡น๐Ÿ‡น Trinidad and Tobago1https://iptv-org.github.io/iptv/countries/tt.m3u
๐Ÿ‡น๐Ÿ‡ณ Tunisia1https://iptv-org.github.io/iptv/countries/tn.m3u
๐Ÿ‡น๐Ÿ‡ท Turkey1https://iptv-org.github.io/iptv/countries/tr.m3u
๐Ÿ‡น๐Ÿ‡ฒ Turkmenistan1https://iptv-org.github.io/iptv/countries/tm.m3u
๐Ÿ‡น๐Ÿ‡จ Turks and Caicos Islands1https://iptv-org.github.io/iptv/countries/tc.m3u
๐Ÿ‡น๐Ÿ‡ป Tuvalu1https://iptv-org.github.io/iptv/countries/tv.m3u
๐Ÿ‡บ๐Ÿ‡ฒ U.S. Minor Outlying Islands1https://iptv-org.github.io/iptv/countries/um.m3u
๐Ÿ‡ป๐Ÿ‡ฎ U.S. Virgin Islands1https://iptv-org.github.io/iptv/countries/vi.m3u
๐Ÿ‡บ๐Ÿ‡ฌ Uganda1https://iptv-org.github.io/iptv/countries/ug.m3u
๐Ÿ‡บ๐Ÿ‡ฆ Ukraine1https://iptv-org.github.io/iptv/countries/ua.m3u
๐Ÿ‡ฆ๐Ÿ‡ช United Arab Emirates1https://iptv-org.github.io/iptv/countries/ae.m3u
๐Ÿ‡ฌ๐Ÿ‡ง United Kingdom1https://iptv-org.github.io/iptv/countries/uk.m3u
๐Ÿ‡บ๐Ÿ‡ธ United States1https://iptv-org.github.io/iptv/countries/us.m3u
๐Ÿ‡บ๐Ÿ‡พ Uruguay1https://iptv-org.github.io/iptv/countries/uy.m3u
๐Ÿ‡บ๐Ÿ‡ฟ Uzbekistan1https://iptv-org.github.io/iptv/countries/uz.m3u
๐Ÿ‡ป๐Ÿ‡บ Vanuatu1https://iptv-org.github.io/iptv/countries/vu.m3u
๐Ÿ‡ป๐Ÿ‡ฆ Vatican City1https://iptv-org.github.io/iptv/countries/va.m3u
๐Ÿ‡ป๐Ÿ‡ช Venezuela1https://iptv-org.github.io/iptv/countries/ve.m3u
๐Ÿ‡ป๐Ÿ‡ณ Vietnam1https://iptv-org.github.io/iptv/countries/vn.m3u
๐Ÿ‡ผ๐Ÿ‡ซ Wallis and Futuna1https://iptv-org.github.io/iptv/countries/wf.m3u
๐Ÿ‡ช๐Ÿ‡ญ Western Sahara1https://iptv-org.github.io/iptv/countries/eh.m3u
๐Ÿ‡พ๐Ÿ‡ช Yemen1https://iptv-org.github.io/iptv/countries/ye.m3u
๐Ÿ‡ฟ๐Ÿ‡ฒ Zambia1https://iptv-org.github.io/iptv/countries/zm.m3u
๐Ÿ‡ฟ๐Ÿ‡ผ Zimbabwe1https://iptv-org.github.io/iptv/countries/zw.m3u
๐Ÿ‡ฆ๐Ÿ‡ฝ ร…land1https://iptv-org.github.io/iptv/countries/ax.m3u
Undefined2https://iptv-org.github.io/iptv/countries/undefined.m3u
+ +
+ +### Playlists by language + +
+Expand +
+ + + + + + + + + + + + + +
LanguageChannelsPlaylist
Catalan1https://iptv-org.github.io/iptv/languages/cat.m3u
English1https://iptv-org.github.io/iptv/languages/eng.m3u
French1https://iptv-org.github.io/iptv/languages/fra.m3u
Russian1https://iptv-org.github.io/iptv/languages/rus.m3u
Undefined2https://iptv-org.github.io/iptv/languages/undefined.m3u
+ +
+ +### Playlists by region + +
+Expand +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RegionChannelsPlaylist
Africa0https://iptv-org.github.io/iptv/regions/afr.m3u
Americas1https://iptv-org.github.io/iptv/regions/amer.m3u
Arab world0https://iptv-org.github.io/iptv/regions/arab.m3u
Asia1https://iptv-org.github.io/iptv/regions/asia.m3u
Asia-Pacific0https://iptv-org.github.io/iptv/regions/apac.m3u
Caribbean0https://iptv-org.github.io/iptv/regions/carib.m3u
Central Asia0https://iptv-org.github.io/iptv/regions/cas.m3u
Commonwealth of Independent States1https://iptv-org.github.io/iptv/regions/cis.m3u
Europe2https://iptv-org.github.io/iptv/regions/eur.m3u
Europe, the Middle East and Africa2https://iptv-org.github.io/iptv/regions/emea.m3u
Hispanic America0https://iptv-org.github.io/iptv/regions/hispam.m3u
Latin America0https://iptv-org.github.io/iptv/regions/latam.m3u
Latin America and the Caribbean0https://iptv-org.github.io/iptv/regions/lac.m3u
Maghreb0https://iptv-org.github.io/iptv/regions/maghreb.m3u
Middle East0https://iptv-org.github.io/iptv/regions/mideast.m3u
Middle East and North Africa0https://iptv-org.github.io/iptv/regions/mena.m3u
Nordics0https://iptv-org.github.io/iptv/regions/nord.m3u
North America1https://iptv-org.github.io/iptv/regions/noram.m3u
Northern America1https://iptv-org.github.io/iptv/regions/nam.m3u
Oceania0https://iptv-org.github.io/iptv/regions/oce.m3u
South Asia0https://iptv-org.github.io/iptv/regions/sas.m3u
Sub-Saharan Africa0https://iptv-org.github.io/iptv/regions/ssa.m3u
West Africa0https://iptv-org.github.io/iptv/regions/wafr.m3u
Worldwide4https://iptv-org.github.io/iptv/regions/int.m3u
Undefined2https://iptv-org.github.io/iptv/regions/undefined.m3u
+ +
+ +## EPG + +Playlists already have a built-in list of EPG, so players that support the `x-tvg-url` tag should load it automatically. If not, you can find a list of available programs here: + +https://github.com/iptv-org/epg + +## Resources + +You can find links to various IPTV related resources in this repository [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv). + +## API + +The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository. + +## Contribution + +Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before sending an issue or making a pull request. + +## Legal + +No video files are stored in this repository. The repository simply contains user-submitted links to publicly available video stream URLs, which to the best of our knowledge have been intentionally made publicly by the copyright holders. If any links in these playlists infringe on your rights as a copyright holder, they may be removed by sending a pull request or opening an issue. However, note that we have **no control** over the destination of the link, and just removing the link from the playlist will not remove its contents from the web. Note that linking does not directly infringe copyright because no copy is made on the site providing the link, and thus this is **not** a valid reason to send a DMCA notice to GitHub. To remove this content from the web, you should contact the web host that's actually hosting the content (**not** GitHub, nor the maintainers of this repository). diff --git a/tests/__data__/expected/cleanup-database.streams.db b/tests/__data__/expected/cleanup-database.streams.db deleted file mode 100644 index ffee4256c6..0000000000 --- a/tests/__data__/expected/cleanup-database.streams.db +++ /dev/null @@ -1,5 +0,0 @@ -{"channel_name":"ะ›ะ”ะŸะ  ะขะ’","channel_id":"LDPRTV.ru","filepath":"tests/__data__/output/channels/ru.m3u","resolution":{"height":1080,"width":null},"status":{"label":"","code":"online","level":1},"url":"http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":false,"cluster_id":1,"_id":"2ST8btby3mmsgPF0"} -{"channel_name":"BBC News HD","channel_id":"BBCNews.uk","filepath":"tests/__data__/output/channels/uk.m3u","resolution":{"height":720,"width":null},"status":{"label":"Not 24/7","code":"not_247","level":3},"url":"http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":false,"cluster_id":3,"_id":"3TbieV1ptnZVCIdn"} -{"channel_name":"ATV","channel_id":"AndorraTV.ad","filepath":"tests/__data__/output/channels/ad.m3u","resolution":{"height":720,"width":null},"status":{"label":"Offline","code":"offline","level":5},"url":"https://iptv-all.lanesh4d0w.repl.co/andorra/atv","http":{"referrer":"","user-agent":""},"is_broken":true,"updated":false,"cluster_id":1,"_id":"I6cjG2xCBRFFP4sz"} -{"channel_name":"Kayhan TV","channel_id":"KayhanTV.af","filepath":"channels/af.m3u","resolution":{"height":720,"width":null},"status":{"label":"Geo-blocked","code":"geo_blocked","level":2},"url":"http://208.93.117.113/live/Stream1/playlist.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":false,"cluster_id":1,"_id":"cFFpFVzSn6xFMUF3"} -{"channel_name":"Sharq","channel_id":"Sharq.af","filepath":"channels/af.m3u","resolution":{"height":576,"width":null},"status":{"label":"Offline","code":"offline","level":5},"url":"http://51.210.199.50/hls/stream.m3u8","http":{"referrer":"","user-agent":""},"is_broken":true,"updated":false,"cluster_id":1,"_id":"u7iyA6cjtf1iWWAZ"} diff --git a/tests/__data__/expected/save-results.streams.db b/tests/__data__/expected/save-results.streams.db deleted file mode 100644 index b577e30cd6..0000000000 --- a/tests/__data__/expected/save-results.streams.db +++ /dev/null @@ -1,6 +0,0 @@ -{"channel_name":"ะ›ะ”ะŸะ  ะขะ’","channel_id":"LDPRTV.ru","filepath":"tests/__data__/output/channels/ru.m3u","resolution":{"width":1920,"height":1080},"status":{"label":"","code":"online","level":1},"url":"http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":true,"cluster_id":1,"_id":"2ST8btby3mmsgPF0"} -{"channel_name":"BBC News HD","channel_id":"BBCNews.uk","filepath":"tests/__data__/output/channels/uk.m3u","resolution":{"height":720,"width":null},"status":{"label":"Not 24/7","code":"not_247","level":3},"url":"http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":false,"cluster_id":3,"_id":"3TbieV1ptnZVCIdn"} -{"channel_name":"ATV","channel_id":"AndorraTV.ad","filepath":"tests/__data__/output/channels/ad.m3u","resolution":{"height":720,"width":null},"status":{"label":"Offline","code":"offline","level":5},"url":"https://iptv-all.lanesh4d0w.repl.co/andorra/atv","http":{"referrer":"","user-agent":""},"is_broken":true,"updated":false,"cluster_id":1,"_id":"I6cjG2xCBRFFP4sz"} -{"channel_name":"BBC News HD","channel_id":"AndorraTV.ad","filepath":"tests/__data__/output/channels/uk.m3u","resolution":{"height":720,"width":null},"status":{"label":"Not 24/7","code":"not_247","level":3},"url":"http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":false,"cluster_id":3,"_id":"WTbieV1ptnZVCIdn"} -{"channel_name":"Kayhan TV","channel_id":"KayhanTV.af","filepath":"channels/af.m3u","resolution":{"height":720,"width":null},"status":{"label":"Geo-blocked","code":"geo_blocked","level":2},"url":"http://208.93.117.113/live/Stream1/playlist.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":false,"cluster_id":1,"_id":"cFFpFVzSn6xFMUF3"} -{"channel_name":"Sharq","channel_id":"Sharq.af","filepath":"channels/af.m3u","resolution":{"height":576,"width":null},"status":{"label":"Offline","code":"offline","level":5},"url":"http://51.210.199.50/hls/stream.m3u8","http":{"referrer":"","user-agent":""},"is_broken":true,"updated":false,"cluster_id":1,"_id":"u7iyA6cjtf1iWWAZ"} diff --git a/tests/__data__/expected/streams.db b/tests/__data__/expected/streams.db deleted file mode 100644 index 0d481168e2..0000000000 --- a/tests/__data__/expected/streams.db +++ /dev/null @@ -1,3 +0,0 @@ -{"channel_name":"ATV","channel_id":"ATV.ad","filepath":"tests/__data__/input/channels/ad.m3u","resolution":{"height":720,"width":null},"status":{"label":"Offline","code":"offline","level":5},"url":"https://iptv-all.lanesh4d0w.repl.co/andorra/atv","http":{"referrer":"","user-agent":""},"is_broken":true,"updated":false,"cluster_id":1,"_id":"verufR2ehwdsfou3"} -{"channel_name":"Fox Sports 2 Asia (Thai)","channel_id":"FoxSports2AsiaThai.us","filepath":"tests/__data__/input/channels/us_blocked.m3u","resolution":{"height":720,"width":null},"status":{"label":"","code":"online","level":1},"url":"https://example.com/playlist.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":true,"cluster_id":1,"_id":"sLG04kZhqlEcYc25"} -{"channel_id":null,"channel_name":"1A Network","filepath":"tests/__data__/input/channels/unsorted.m3u","resolution":{"height":720,"width":null},"status":{"label":"","code":"online","level":1},"url":"https://simultv.s.llnwi.net/n4s4/2ANetwork/interlink.m3u8","http":{"referrer":"","user-agent":""},"is_broken":false,"updated":true,"cluster_id":1,"_id":"Jruf9KFXRsa5BjYj"} diff --git a/tests/__data__/input/readme.json b/tests/__data__/input/_readme.json similarity index 100% rename from tests/__data__/input/readme.json rename to tests/__data__/input/_readme.json diff --git a/tests/__data__/input/logs/generators/categories.log b/tests/__data__/input/logs/generators/categories.log index 5f4d99cf2b..af68b09a9e 100644 --- a/tests/__data__/input/logs/generators/categories.log +++ b/tests/__data__/input/logs/generators/categories.log @@ -1,3 +1,29 @@ -{"name":"General","slug":"general","count":1} -{"name":"News","slug":"news","count":1} -{"name":"Other","slug":"other","count":0} +{"filepath":"categories/auto.m3u","count":0} +{"filepath":"categories/animation.m3u","count":0} +{"filepath":"categories/business.m3u","count":0} +{"filepath":"categories/classic.m3u","count":0} +{"filepath":"categories/comedy.m3u","count":0} +{"filepath":"categories/cooking.m3u","count":0} +{"filepath":"categories/culture.m3u","count":0} +{"filepath":"categories/documentary.m3u","count":0} +{"filepath":"categories/education.m3u","count":0} +{"filepath":"categories/entertainment.m3u","count":0} +{"filepath":"categories/family.m3u","count":0} +{"filepath":"categories/general.m3u","count":2} +{"filepath":"categories/kids.m3u","count":0} +{"filepath":"categories/legislative.m3u","count":0} +{"filepath":"categories/lifestyle.m3u","count":0} +{"filepath":"categories/movies.m3u","count":0} +{"filepath":"categories/music.m3u","count":0} +{"filepath":"categories/news.m3u","count":1} +{"filepath":"categories/outdoor.m3u","count":0} +{"filepath":"categories/relax.m3u","count":0} +{"filepath":"categories/religious.m3u","count":0} +{"filepath":"categories/series.m3u","count":0} +{"filepath":"categories/science.m3u","count":0} +{"filepath":"categories/shop.m3u","count":0} +{"filepath":"categories/sports.m3u","count":0} +{"filepath":"categories/travel.m3u","count":0} +{"filepath":"categories/weather.m3u","count":1} +{"filepath":"categories/xxx.m3u","count":1} +{"filepath":"categories/undefined.m3u","count":3} \ No newline at end of file diff --git a/tests/__data__/input/logs/generators/countries.log b/tests/__data__/input/logs/generators/countries.log index a173fd049e..9d56d14b6f 100644 --- a/tests/__data__/input/logs/generators/countries.log +++ b/tests/__data__/input/logs/generators/countries.log @@ -1,4 +1,251 @@ -{"name":"Andorra","code":"AD","count":0} -{"name":"Russia","code":"RU","count":1} -{"name":"United Kingdom","code":"UK","count":1} -{"name":"Undefined","code":"UNDEFINED","count":0} +{"filepath":"countries/af.m3u","count":1} +{"filepath":"countries/al.m3u","count":1} +{"filepath":"countries/dz.m3u","count":1} +{"filepath":"countries/as.m3u","count":1} +{"filepath":"countries/ad.m3u","count":2} +{"filepath":"countries/ao.m3u","count":1} +{"filepath":"countries/ai.m3u","count":1} +{"filepath":"countries/aq.m3u","count":1} +{"filepath":"countries/ag.m3u","count":1} +{"filepath":"countries/ar.m3u","count":1} +{"filepath":"countries/am.m3u","count":1} +{"filepath":"countries/aw.m3u","count":1} +{"filepath":"countries/au.m3u","count":1} +{"filepath":"countries/at.m3u","count":1} +{"filepath":"countries/az.m3u","count":1} +{"filepath":"countries/bs.m3u","count":1} +{"filepath":"countries/bh.m3u","count":1} +{"filepath":"countries/bd.m3u","count":1} +{"filepath":"countries/bb.m3u","count":1} +{"filepath":"countries/by.m3u","count":1} +{"filepath":"countries/be.m3u","count":1} +{"filepath":"countries/bz.m3u","count":1} +{"filepath":"countries/bj.m3u","count":1} +{"filepath":"countries/bm.m3u","count":1} +{"filepath":"countries/bt.m3u","count":1} +{"filepath":"countries/bo.m3u","count":1} +{"filepath":"countries/bq.m3u","count":1} +{"filepath":"countries/ba.m3u","count":1} +{"filepath":"countries/bw.m3u","count":1} +{"filepath":"countries/bv.m3u","count":1} +{"filepath":"countries/br.m3u","count":1} +{"filepath":"countries/io.m3u","count":1} +{"filepath":"countries/vg.m3u","count":1} +{"filepath":"countries/bn.m3u","count":1} +{"filepath":"countries/bg.m3u","count":1} +{"filepath":"countries/bf.m3u","count":1} +{"filepath":"countries/bi.m3u","count":1} +{"filepath":"countries/kh.m3u","count":1} +{"filepath":"countries/cm.m3u","count":1} +{"filepath":"countries/ca.m3u","count":2} +{"filepath":"countries/cv.m3u","count":1} +{"filepath":"countries/ky.m3u","count":1} +{"filepath":"countries/cf.m3u","count":1} +{"filepath":"countries/td.m3u","count":1} +{"filepath":"countries/cl.m3u","count":1} +{"filepath":"countries/cn.m3u","count":1} +{"filepath":"countries/cx.m3u","count":1} +{"filepath":"countries/cc.m3u","count":1} +{"filepath":"countries/co.m3u","count":1} +{"filepath":"countries/km.m3u","count":1} +{"filepath":"countries/ck.m3u","count":1} +{"filepath":"countries/cr.m3u","count":1} +{"filepath":"countries/hr.m3u","count":1} +{"filepath":"countries/cu.m3u","count":1} +{"filepath":"countries/cw.m3u","count":1} +{"filepath":"countries/cy.m3u","count":1} +{"filepath":"countries/cz.m3u","count":1} +{"filepath":"countries/cd.m3u","count":1} +{"filepath":"countries/dk.m3u","count":1} +{"filepath":"countries/dj.m3u","count":1} +{"filepath":"countries/dm.m3u","count":1} +{"filepath":"countries/do.m3u","count":1} +{"filepath":"countries/tl.m3u","count":1} +{"filepath":"countries/ec.m3u","count":1} +{"filepath":"countries/eg.m3u","count":1} +{"filepath":"countries/sv.m3u","count":1} +{"filepath":"countries/gq.m3u","count":1} +{"filepath":"countries/er.m3u","count":1} +{"filepath":"countries/ee.m3u","count":1} +{"filepath":"countries/et.m3u","count":1} +{"filepath":"countries/fk.m3u","count":1} +{"filepath":"countries/fo.m3u","count":1} +{"filepath":"countries/fj.m3u","count":1} +{"filepath":"countries/fi.m3u","count":1} +{"filepath":"countries/fr.m3u","count":1} +{"filepath":"countries/gf.m3u","count":1} +{"filepath":"countries/pf.m3u","count":1} +{"filepath":"countries/tf.m3u","count":1} +{"filepath":"countries/ga.m3u","count":1} +{"filepath":"countries/gm.m3u","count":1} +{"filepath":"countries/ge.m3u","count":1} +{"filepath":"countries/de.m3u","count":1} +{"filepath":"countries/gh.m3u","count":1} +{"filepath":"countries/gi.m3u","count":1} +{"filepath":"countries/gr.m3u","count":1} +{"filepath":"countries/gl.m3u","count":1} +{"filepath":"countries/gd.m3u","count":1} +{"filepath":"countries/gp.m3u","count":1} +{"filepath":"countries/gu.m3u","count":1} +{"filepath":"countries/gt.m3u","count":1} +{"filepath":"countries/gg.m3u","count":1} +{"filepath":"countries/gn.m3u","count":1} +{"filepath":"countries/gw.m3u","count":1} +{"filepath":"countries/gy.m3u","count":1} +{"filepath":"countries/ht.m3u","count":1} +{"filepath":"countries/hm.m3u","count":1} +{"filepath":"countries/hn.m3u","count":1} +{"filepath":"countries/hk.m3u","count":1} +{"filepath":"countries/hu.m3u","count":1} +{"filepath":"countries/is.m3u","count":1} +{"filepath":"countries/in.m3u","count":1} +{"filepath":"countries/id.m3u","count":1} +{"filepath":"countries/ir.m3u","count":1} +{"filepath":"countries/iq.m3u","count":1} +{"filepath":"countries/ie.m3u","count":1} +{"filepath":"countries/im.m3u","count":1} +{"filepath":"countries/il.m3u","count":1} +{"filepath":"countries/it.m3u","count":1} +{"filepath":"countries/ci.m3u","count":1} +{"filepath":"countries/jm.m3u","count":1} +{"filepath":"countries/jp.m3u","count":1} +{"filepath":"countries/je.m3u","count":1} +{"filepath":"countries/jo.m3u","count":1} +{"filepath":"countries/kz.m3u","count":1} +{"filepath":"countries/ke.m3u","count":1} +{"filepath":"countries/ki.m3u","count":1} +{"filepath":"countries/xk.m3u","count":1} +{"filepath":"countries/kw.m3u","count":1} +{"filepath":"countries/kg.m3u","count":1} +{"filepath":"countries/la.m3u","count":1} +{"filepath":"countries/lv.m3u","count":1} +{"filepath":"countries/lb.m3u","count":1} +{"filepath":"countries/ls.m3u","count":1} +{"filepath":"countries/lr.m3u","count":1} +{"filepath":"countries/ly.m3u","count":1} +{"filepath":"countries/li.m3u","count":1} +{"filepath":"countries/lt.m3u","count":1} +{"filepath":"countries/lu.m3u","count":1} +{"filepath":"countries/mo.m3u","count":1} +{"filepath":"countries/mg.m3u","count":1} +{"filepath":"countries/mw.m3u","count":1} +{"filepath":"countries/my.m3u","count":1} +{"filepath":"countries/mv.m3u","count":1} +{"filepath":"countries/ml.m3u","count":1} +{"filepath":"countries/mt.m3u","count":1} +{"filepath":"countries/mh.m3u","count":1} +{"filepath":"countries/mq.m3u","count":1} +{"filepath":"countries/mr.m3u","count":1} +{"filepath":"countries/mu.m3u","count":1} +{"filepath":"countries/yt.m3u","count":1} +{"filepath":"countries/mx.m3u","count":1} +{"filepath":"countries/fm.m3u","count":1} +{"filepath":"countries/md.m3u","count":1} +{"filepath":"countries/mc.m3u","count":1} +{"filepath":"countries/mn.m3u","count":1} +{"filepath":"countries/me.m3u","count":1} +{"filepath":"countries/ms.m3u","count":1} +{"filepath":"countries/ma.m3u","count":1} +{"filepath":"countries/mz.m3u","count":1} +{"filepath":"countries/mm.m3u","count":1} +{"filepath":"countries/na.m3u","count":1} +{"filepath":"countries/nr.m3u","count":1} +{"filepath":"countries/np.m3u","count":1} +{"filepath":"countries/nl.m3u","count":1} +{"filepath":"countries/nc.m3u","count":1} +{"filepath":"countries/nz.m3u","count":1} +{"filepath":"countries/ni.m3u","count":1} +{"filepath":"countries/ne.m3u","count":1} +{"filepath":"countries/ng.m3u","count":1} +{"filepath":"countries/nu.m3u","count":1} +{"filepath":"countries/nf.m3u","count":1} +{"filepath":"countries/kp.m3u","count":1} +{"filepath":"countries/mk.m3u","count":1} +{"filepath":"countries/mp.m3u","count":1} +{"filepath":"countries/no.m3u","count":1} +{"filepath":"countries/om.m3u","count":1} +{"filepath":"countries/pk.m3u","count":1} +{"filepath":"countries/pw.m3u","count":1} +{"filepath":"countries/ps.m3u","count":1} +{"filepath":"countries/pa.m3u","count":1} +{"filepath":"countries/pg.m3u","count":1} +{"filepath":"countries/py.m3u","count":1} +{"filepath":"countries/pe.m3u","count":1} +{"filepath":"countries/ph.m3u","count":1} +{"filepath":"countries/pn.m3u","count":1} +{"filepath":"countries/pl.m3u","count":1} +{"filepath":"countries/pt.m3u","count":1} +{"filepath":"countries/pr.m3u","count":1} +{"filepath":"countries/qa.m3u","count":1} +{"filepath":"countries/cg.m3u","count":1} +{"filepath":"countries/ro.m3u","count":1} +{"filepath":"countries/ru.m3u","count":2} +{"filepath":"countries/rw.m3u","count":1} +{"filepath":"countries/re.m3u","count":1} +{"filepath":"countries/bl.m3u","count":1} +{"filepath":"countries/sh.m3u","count":1} +{"filepath":"countries/kn.m3u","count":1} +{"filepath":"countries/lc.m3u","count":1} +{"filepath":"countries/mf.m3u","count":1} +{"filepath":"countries/pm.m3u","count":1} +{"filepath":"countries/vc.m3u","count":1} +{"filepath":"countries/ws.m3u","count":1} +{"filepath":"countries/sm.m3u","count":1} +{"filepath":"countries/sa.m3u","count":1} +{"filepath":"countries/sn.m3u","count":1} +{"filepath":"countries/rs.m3u","count":1} +{"filepath":"countries/sc.m3u","count":1} +{"filepath":"countries/sl.m3u","count":1} +{"filepath":"countries/sg.m3u","count":1} +{"filepath":"countries/sx.m3u","count":1} +{"filepath":"countries/sk.m3u","count":1} +{"filepath":"countries/si.m3u","count":1} +{"filepath":"countries/sb.m3u","count":1} +{"filepath":"countries/so.m3u","count":1} +{"filepath":"countries/za.m3u","count":1} +{"filepath":"countries/gs.m3u","count":1} +{"filepath":"countries/kr.m3u","count":1} +{"filepath":"countries/ss.m3u","count":1} +{"filepath":"countries/es.m3u","count":1} +{"filepath":"countries/lk.m3u","count":1} +{"filepath":"countries/sd.m3u","count":1} +{"filepath":"countries/sr.m3u","count":1} +{"filepath":"countries/sj.m3u","count":1} +{"filepath":"countries/sz.m3u","count":1} +{"filepath":"countries/se.m3u","count":1} +{"filepath":"countries/ch.m3u","count":1} +{"filepath":"countries/sy.m3u","count":1} +{"filepath":"countries/st.m3u","count":1} +{"filepath":"countries/tw.m3u","count":1} +{"filepath":"countries/tj.m3u","count":1} +{"filepath":"countries/tz.m3u","count":1} +{"filepath":"countries/th.m3u","count":1} +{"filepath":"countries/tg.m3u","count":1} +{"filepath":"countries/tk.m3u","count":1} +{"filepath":"countries/to.m3u","count":1} +{"filepath":"countries/tt.m3u","count":1} +{"filepath":"countries/tn.m3u","count":1} +{"filepath":"countries/tr.m3u","count":1} +{"filepath":"countries/tm.m3u","count":1} +{"filepath":"countries/tc.m3u","count":1} +{"filepath":"countries/tv.m3u","count":1} +{"filepath":"countries/um.m3u","count":1} +{"filepath":"countries/vi.m3u","count":1} +{"filepath":"countries/ug.m3u","count":1} +{"filepath":"countries/ua.m3u","count":1} +{"filepath":"countries/ae.m3u","count":1} +{"filepath":"countries/uk.m3u","count":1} +{"filepath":"countries/us.m3u","count":1} +{"filepath":"countries/uy.m3u","count":1} +{"filepath":"countries/uz.m3u","count":1} +{"filepath":"countries/vu.m3u","count":1} +{"filepath":"countries/va.m3u","count":1} +{"filepath":"countries/ve.m3u","count":1} +{"filepath":"countries/vn.m3u","count":1} +{"filepath":"countries/wf.m3u","count":1} +{"filepath":"countries/eh.m3u","count":1} +{"filepath":"countries/ye.m3u","count":1} +{"filepath":"countries/zm.m3u","count":1} +{"filepath":"countries/zw.m3u","count":1} +{"filepath":"countries/ax.m3u","count":1} +{"filepath":"countries/undefined.m3u","count":2} \ No newline at end of file diff --git a/tests/__data__/input/logs/generators/languages.log b/tests/__data__/input/logs/generators/languages.log index 4a5a060f85..a118205045 100644 --- a/tests/__data__/input/logs/generators/languages.log +++ b/tests/__data__/input/logs/generators/languages.log @@ -1,4 +1,5 @@ -{"name":"Catalan","code":"cat","count":0} -{"name":"English","code":"eng","count":1} -{"name":"Russian","code":"rus","count":1} -{"name":"Undefined","code":"undefined","count":0} +{"filepath":"languages/cat.m3u","count":1} +{"filepath":"languages/eng.m3u","count":1} +{"filepath":"languages/fra.m3u","count":1} +{"filepath":"languages/rus.m3u","count":1} +{"filepath":"languages/undefined.m3u","count":2} \ No newline at end of file diff --git a/tests/__data__/input/logs/generators/regions.log b/tests/__data__/input/logs/generators/regions.log index 50d3a6dbca..ddf9139e0a 100644 --- a/tests/__data__/input/logs/generators/regions.log +++ b/tests/__data__/input/logs/generators/regions.log @@ -1,6 +1,25 @@ -{"name":"Asia","code":"ASIA","count":1} -{"name":"Commonwealth of Independent States","code":"CIS","count":1} -{"name":"Europe","code":"EUR","count":2} -{"name":"Europe, the Middle East and Africa","code":"EMEA","count":2} -{"name":"Worldwide","code":"INT","count":1} -{"name":"Undefined","code":"UNDEFINED","count":0} +{"filepath":"regions/afr.m3u","count":0} +{"filepath":"regions/amer.m3u","count":1} +{"filepath":"regions/arab.m3u","count":0} +{"filepath":"regions/asia.m3u","count":1} +{"filepath":"regions/apac.m3u","count":0} +{"filepath":"regions/carib.m3u","count":0} +{"filepath":"regions/cas.m3u","count":0} +{"filepath":"regions/cis.m3u","count":1} +{"filepath":"regions/eur.m3u","count":2} +{"filepath":"regions/emea.m3u","count":2} +{"filepath":"regions/hispam.m3u","count":0} +{"filepath":"regions/latam.m3u","count":0} +{"filepath":"regions/lac.m3u","count":0} +{"filepath":"regions/maghreb.m3u","count":0} +{"filepath":"regions/mideast.m3u","count":0} +{"filepath":"regions/mena.m3u","count":0} +{"filepath":"regions/nord.m3u","count":0} +{"filepath":"regions/noram.m3u","count":1} +{"filepath":"regions/nam.m3u","count":1} +{"filepath":"regions/oce.m3u","count":0} +{"filepath":"regions/sas.m3u","count":0} +{"filepath":"regions/ssa.m3u","count":0} +{"filepath":"regions/wafr.m3u","count":0} +{"filepath":"regions/int.m3u","count":4} +{"filepath":"regions/undefined.m3u","count":2} \ No newline at end of file diff --git a/tests/__data__/input/readme.md b/tests/__data__/input/readme.md deleted file mode 100644 index 6b8eb4b1c1..0000000000 --- a/tests/__data__/input/readme.md +++ /dev/null @@ -1,180 +0,0 @@ -# IPTV - -[![auto-update](https://github.com/iptv-org/iptv/actions/workflows/auto-update.yml/badge.svg)](https://github.com/iptv-org/iptv/actions/workflows/auto-update.yml) - -Collection of publicly available IPTV channels from all over the world. - -## Usage - -To watch IPTV you just need to paste this link `https://iptv-org.github.io/iptv/index.m3u` to any player which supports M3U-playlists. - -![VLC Network Panel](.readme/preview.png) - -Also you can instead use one of these playlists: - -- `https://iptv-org.github.io/iptv/index.category.m3u` (grouped by category) -- `https://iptv-org.github.io/iptv/index.language.m3u` (grouped by language) -- `https://iptv-org.github.io/iptv/index.country.m3u` (grouped by country) -- `https://iptv-org.github.io/iptv/index.region.m3u` (grouped by region) -- `https://iptv-org.github.io/iptv/index.nsfw.m3u` (includes adult channels) - -Or select one of the playlists from the list below. - -### Playlists by category - -
-Expand -
- - - - - - - - - - - -
CategoryChannelsPlaylist
General1https://iptv-org.github.io/iptv/categories/general.m3u
News1https://iptv-org.github.io/iptv/categories/news.m3u
Other0https://iptv-org.github.io/iptv/categories/other.m3u
- -
- -### Playlists by language - -
-Expand -
- - - - - - - - - - - - -
LanguageChannelsPlaylist
Catalan0https://iptv-org.github.io/iptv/languages/cat.m3u
English1https://iptv-org.github.io/iptv/languages/eng.m3u
Russian1https://iptv-org.github.io/iptv/languages/rus.m3u
Undefined0https://iptv-org.github.io/iptv/languages/undefined.m3u
- -
- -### Playlists by region - -
-Expand -
- - - - - - - - - - - - - - -
RegionChannelsPlaylist
Asia1https://iptv-org.github.io/iptv/regions/asia.m3u
Commonwealth of Independent States1https://iptv-org.github.io/iptv/regions/cis.m3u
Europe2https://iptv-org.github.io/iptv/regions/eur.m3u
Europe, the Middle East and Africa2https://iptv-org.github.io/iptv/regions/emea.m3u
Worldwide1https://iptv-org.github.io/iptv/regions/int.m3u
Undefined0https://iptv-org.github.io/iptv/regions/undefined.m3u
- -
- -### Playlists by country - -
-Expand -
- - - - - - - - - - - - -
CountryChannelsPlaylist
๐Ÿ‡ฆ๐Ÿ‡ฉ Andorra0https://iptv-org.github.io/iptv/countries/ad.m3u
๐Ÿ‡ท๐Ÿ‡บ Russia1https://iptv-org.github.io/iptv/countries/ru.m3u
๐Ÿ‡ฌ๐Ÿ‡ง United Kingdom1https://iptv-org.github.io/iptv/countries/uk.m3u
Undefined0https://iptv-org.github.io/iptv/countries/undefined.m3u
- -
- -## For Developers - -In addition to the above methods, you can also get a list of all available channels in JSON format. - -To do this, you just have to make a GET request to: - -``` -https://iptv-org.github.io/iptv/channels.json -``` - -If successful, you should get the following response: - -
-Expand -
- -``` -[ - ... - { - "name": "CNN", - "logo": "https://i.imgur.com/ilZJT5s.png", - "url": "http://ott-cdn.ucom.am/s27/index.m3u8", - "categories": [ - { - "name": "News", - "slug": "news" - } - ], - "countries": [ - { - "code": "us", - "name": "United States" - }, - { - "code": "ca", - "name": "Canada" - } - ], - "languages": [ - { - "code": "eng", - "name": "English" - } - ], - "tvg": { - "id": "cnn.us", - "name": "CNN", - "url": "http://epg.streamstv.me/epg/guide-usa.xml.gz" - } - }, - ... -] -``` -
- -## EPG - -Playlists already have a built-in list of EPG, so players that support the `url-tvg` tag should load it automatically. If not, you can find a list of available programs here: - -https://github.com/iptv-org/epg - -## Resources - -You can find links to various IPTV related resources in this repository [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv). - -## Contribution - -Please make sure to read the [Contributing Guide](CONTRIBUTING.md) before sending an issue or making a pull request. - -## Legal - -No video files are stored in this repository. The repository simply contains user-submitted links to publicly available video stream URLs, which to the best of our knowledge have been intentionally made publicly by the copyright holders. If any links in these playlists infringe on your rights as a copyright holder, they may be removed by sending a pull request or opening an issue. However, note that we have **no control** over the destination of the link, and just removing the link from the playlist will not remove its contents from the web. Note that linking does not directly infringe copyright because no copy is made on the site providing the link, and thus this is **not** a valid reason to send a DMCA notice to GitHub. To remove this content from the web, you should contact the web host that's actually hosting the content (**not** GitHub, nor the maintainers of this repository). diff --git a/tests/commands/update-readme.test.js b/tests/commands/update-readme.test.js index 716215473e..029e45fc7e 100644 --- a/tests/commands/update-readme.test.js +++ b/tests/commands/update-readme.test.js @@ -1,23 +1,26 @@ -const fs = require('fs') +const fs = require('fs-extra') const path = require('path') const { execSync } = require('child_process') beforeEach(() => { - fs.rmdirSync(path.resolve('tests/__data__/output'), { recursive: true }) + fs.emptyDirSync('tests/__data__/output') + + const stdout = execSync( + 'DATA_DIR=tests/__data__/input/data LOGS_DIR=tests/__data__/input/logs/generators node scripts/commands/update-readme.js --config=tests/__data__/input/_readme.json', + { encoding: 'utf8' } + ) }) it('can update readme.md', () => { - const result = execSync( - 'LOGS_PATH=tests/__data__/input/logs node scripts/commands/update-readme.js --config=tests/__data__/input/readme.json', - { encoding: 'utf8' } + expect(content('tests/__data__/output/readme.md')).toEqual( + content('tests/__data__/expected/_readme.md') ) - - const readme = fs.readFileSync(path.resolve('tests/__data__/output/readme.md'), { - encoding: 'utf8' - }) - const expected = fs.readFileSync(path.resolve('tests/__data__/input/readme.md'), { - encoding: 'utf8' - }) - - expect(readme).toBe(expected) }) + +function content(filepath) { + const data = fs.readFileSync(path.resolve(filepath), { + encoding: 'utf8' + }) + + return JSON.stringify(data) +}