This commit is contained in:
Aleksandr Statciuk 2022-02-07 02:27:15 +03:00
parent bad3eddf9d
commit 86e0c2f7da
31 changed files with 611 additions and 698 deletions

28
package-lock.json generated
View File

@ -23,8 +23,18 @@
"normalize-url": "^6.1.0",
"transliteration": "^2.2.0",
"winston": "^3.3.3"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
"jest-expect-message": "^1.0.2"
}
},
"node_modules/@alex_neo/jest-expect-message": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@alex_neo/jest-expect-message/-/jest-expect-message-1.0.5.tgz",
"integrity": "sha512-1eBykZCd0pPGl5qKtV6Z5ARA6yuhXzHsVN2h5GH5/H6svYa37Jr7vMio5OFpiw1LBHtscrZs7amSkZkcwm0cvQ==",
"dev": true
},
"node_modules/@babel/code-frame": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
@ -2413,6 +2423,12 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/jest-expect-message": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/jest-expect-message/-/jest-expect-message-1.0.2.tgz",
"integrity": "sha512-WFiXMgwS2lOqQZt1iJMI/hOXpUm32X+ApsuzYcQpW5m16Pv6/Gd9kgC+Q+Q1YVNU04kYcAOv9NXMnjg6kKUy6Q==",
"dev": true
},
"node_modules/jest-get-type": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",
@ -4220,6 +4236,12 @@
}
},
"dependencies": {
"@alex_neo/jest-expect-message": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@alex_neo/jest-expect-message/-/jest-expect-message-1.0.5.tgz",
"integrity": "sha512-1eBykZCd0pPGl5qKtV6Z5ARA6yuhXzHsVN2h5GH5/H6svYa37Jr7vMio5OFpiw1LBHtscrZs7amSkZkcwm0cvQ==",
"dev": true
},
"@babel/code-frame": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
@ -6071,6 +6093,12 @@
"jest-util": "^27.4.2"
}
},
"jest-expect-message": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/jest-expect-message/-/jest-expect-message-1.0.2.tgz",
"integrity": "sha512-WFiXMgwS2lOqQZt1iJMI/hOXpUm32X+ApsuzYcQpW5m16Pv6/Gd9kgC+Q+Q1YVNU04kYcAOv9NXMnjg6kKUy6Q==",
"dev": true
},
"jest-get-type": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz",

View File

@ -6,7 +6,10 @@
"test": "jest --runInBand"
},
"jest": {
"testRegex": "tests/(.*?/)?.*test.js$"
"testRegex": "tests/(.*?/)?.*test.js$",
"setupFilesAfterEnv": [
"@alex_neo/jest-expect-message"
]
},
"author": "Arhey",
"private": true,
@ -28,5 +31,9 @@
"normalize-url": "^6.1.0",
"transliteration": "^2.2.0",
"winston": "^3.3.3"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
"jest-expect-message": "^1.0.2"
}
}

View File

@ -9,274 +9,17 @@ async function main() {
await generator.generate('countries', streams)
await generator.generate('languages', streams)
await generator.generate('regions', streams)
await generator.generate('index_m3u', streams)
// await generateRegions()
// await generateIndex()
// await generateIndexNSFW()
// await generateIndexCategory()
// await generateIndexCountry()
// await generateIndexLanguage()
// await generateIndexRegion()
// await generateChannelsJson()
// await saveLogs()
}
main()
// async function generateRegions() {
// logger.info(`Generating regions/...`)
// for (const region of regions) {
// const { count } = await generator.generate(
// `${PUBLIC_PATH}/regions/${region.code.toLowerCase()}.m3u`,
// {
// regions: { $elemMatch: region }
// }
// )
// await log('regions', {
// name: region.name,
// code: region.code,
// count
// })
// }
// const { count: undefinedCount } = await generator.generate(
// `${PUBLIC_PATH}/regions/undefined.m3u`,
// { regions: { $size: 0 } },
// {
// saveEmpty: true,
// onLoad: function (items) {
// return items.map(item => {
// item.group_title = 'Undefined'
// return item
// })
// }
// }
// )
// await log('regions', {
// name: 'Undefined',
// code: 'UNDEFINED',
// count: undefinedCount
// })
// }
async function generateIndexNSFW() {
logger.info(`Generating index.nsfw.m3u...`)
await generator.generate(
`${PUBLIC_PATH}/index.nsfw.m3u`,
{},
{
includeNSFW: true,
onLoad: function (items) {
return items.map(item => {
if (!item.categories || !item.categories.length) {
item.group_title = 'Other'
}
return item
})
},
sortBy: item => {
if (item.group_title === 'Other') return '_'
return item.group_title || ''
}
}
)
}
async function generateIndex() {
logger.info(`Generating index.m3u...`)
await generator.generate(
`${PUBLIC_PATH}/index.m3u`,
{},
{
onLoad: function (items) {
return items.map(item => {
if (!item.categories || !item.categories.length) {
item.group_title = 'Other'
}
return item
})
},
sortBy: item => {
if (item.group_title === 'Other') return '_'
return item.group_title || ''
}
}
)
}
async function generateIndexCategory() {
logger.info(`Generating index.category.m3u...`)
await generator.generate(
`${PUBLIC_PATH}/index.category.m3u`,
{},
{
onLoad: function (items) {
let results = items
.filter(item => !item.categories || !item.categories.length)
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = 'Other'
return newItem
})
for (const category of _.sortBy(Object.values(categories), ['name'])) {
let filtered = items
.filter(item => {
return (
Array.isArray(item.categories) &&
item.categories.map(c => c.slug).includes(category.slug)
)
})
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = category.name
return newItem
})
results = results.concat(filtered)
}
return results
},
sortBy: item => {
if (item.group_title === 'Other') return '_'
return item.group_title
}
}
)
}
async function generateIndexCountry() {
logger.info(`Generating index.country.m3u...`)
await generator.generate(
`${PUBLIC_PATH}/index.country.m3u`,
{},
{
onLoad: function (items) {
let results = items
.filter(item => !item.countries || !item.countries.length)
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = 'Undefined'
newItem.categories = []
return newItem
})
for (const country of _.sortBy(Object.values(countries), ['name'])) {
let filtered = items
.filter(item => {
return (
Array.isArray(item.countries) &&
item.countries.map(c => c.code).includes(country.code)
)
})
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = country.name
return newItem
})
results = results.concat(filtered)
}
return results
},
sortBy: item => {
if (item.group_title === 'Undefined') return '_'
return item.group_title
}
}
)
}
async function generateIndexLanguage() {
logger.info(`Generating index.language.m3u...`)
await generator.generate(
`${PUBLIC_PATH}/index.language.m3u`,
{},
{
onLoad: function (items) {
let results = items
.filter(item => !item.languages || !item.languages.length)
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = 'Undefined'
newItem.categories = []
return newItem
})
for (const language of languages) {
let filtered = items
.filter(item => {
return (
Array.isArray(item.languages) &&
item.languages.map(c => c.code).includes(language.code)
)
})
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = language.name
return newItem
})
results = results.concat(filtered)
}
return results
},
sortBy: item => {
if (item.group_title === 'Undefined') return '_'
return item.group_title
}
}
)
}
async function generateIndexRegion() {
logger.info(`Generating index.region.m3u...`)
await generator.generate(
`${PUBLIC_PATH}/index.region.m3u`,
{},
{
onLoad: function (items) {
let results = items
.filter(item => !item.regions.length)
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = 'Undefined'
newItem.categories = []
return newItem
})
for (const region of regions) {
let filtered = items
.filter(item => {
return item.regions.map(c => c.code).includes(region.code)
})
.map(item => {
const newItem = _.cloneDeep(item)
newItem.group_title = region.name
return newItem
})
results = results.concat(filtered)
}
return results
},
sortBy: item => {
if (item.group_title === 'Undefined') return '_'
return item.group_title
}
}
)
}
async function loadStreams() {
await api.channels.load()
let channels = await api.channels.all()
@ -318,3 +61,192 @@ async function loadStreams() {
return stream
})
}
// async function generateIndexNSFW() {
// logger.info(`Generating index.nsfw.m3u...`)
// await generator.generate(
// `${PUBLIC_PATH}/index.nsfw.m3u`,
// {},
// {
// includeNSFW: true,
// onLoad: function (items) {
// return items.map(item => {
// if (!item.categories || !item.categories.length) {
// item.group_title = 'Other'
// }
// return item
// })
// },
// sortBy: item => {
// if (item.group_title === 'Other') return '_'
// return item.group_title || ''
// }
// }
// )
// }
// async function generateIndexCategory() {
// logger.info(`Generating index.category.m3u...`)
// await generator.generate(
// `${PUBLIC_PATH}/index.category.m3u`,
// {},
// {
// onLoad: function (items) {
// let results = items
// .filter(item => !item.categories || !item.categories.length)
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = 'Other'
// return newItem
// })
// for (const category of _.sortBy(Object.values(categories), ['name'])) {
// let filtered = items
// .filter(item => {
// return (
// Array.isArray(item.categories) &&
// item.categories.map(c => c.slug).includes(category.slug)
// )
// })
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = category.name
// return newItem
// })
// results = results.concat(filtered)
// }
// return results
// },
// sortBy: item => {
// if (item.group_title === 'Other') return '_'
// return item.group_title
// }
// }
// )
// }
// async function generateIndexCountry() {
// logger.info(`Generating index.country.m3u...`)
// await generator.generate(
// `${PUBLIC_PATH}/index.country.m3u`,
// {},
// {
// onLoad: function (items) {
// let results = items
// .filter(item => !item.countries || !item.countries.length)
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = 'Undefined'
// newItem.categories = []
// return newItem
// })
// for (const country of _.sortBy(Object.values(countries), ['name'])) {
// let filtered = items
// .filter(item => {
// return (
// Array.isArray(item.countries) &&
// item.countries.map(c => c.code).includes(country.code)
// )
// })
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = country.name
// return newItem
// })
// results = results.concat(filtered)
// }
// return results
// },
// sortBy: item => {
// if (item.group_title === 'Undefined') return '_'
// return item.group_title
// }
// }
// )
// }
// async function generateIndexLanguage() {
// logger.info(`Generating index.language.m3u...`)
// await generator.generate(
// `${PUBLIC_PATH}/index.language.m3u`,
// {},
// {
// onLoad: function (items) {
// let results = items
// .filter(item => !item.languages || !item.languages.length)
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = 'Undefined'
// newItem.categories = []
// return newItem
// })
// for (const language of languages) {
// let filtered = items
// .filter(item => {
// return (
// Array.isArray(item.languages) &&
// item.languages.map(c => c.code).includes(language.code)
// )
// })
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = language.name
// return newItem
// })
// results = results.concat(filtered)
// }
// return results
// },
// sortBy: item => {
// if (item.group_title === 'Undefined') return '_'
// return item.group_title
// }
// }
// )
// }
// async function generateIndexRegion() {
// logger.info(`Generating index.region.m3u...`)
// await generator.generate(
// `${PUBLIC_PATH}/index.region.m3u`,
// {},
// {
// onLoad: function (items) {
// let results = items
// .filter(item => !item.regions.length)
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = 'Undefined'
// newItem.categories = []
// return newItem
// })
// for (const region of regions) {
// let filtered = items
// .filter(item => {
// return item.regions.map(c => c.code).includes(region.code)
// })
// .map(item => {
// const newItem = _.cloneDeep(item)
// newItem.group_title = region.name
// return newItem
// })
// results = results.concat(filtered)
// }
// return results
// },
// sortBy: item => {
// if (item.group_title === 'Undefined') return '_'
// return item.group_title
// }
// }
// )
// }

View File

@ -14,16 +14,17 @@ generator.generate = async function (name, items = []) {
try {
items = _.orderBy(
items,
['channel.name', 'status.level', 'resolution.height'],
['channel_name', 'status.level', 'resolution.height'],
['asc', 'asc', 'desc']
)
items = _.uniqBy(items, s => s.channel_id || _.uniqueId())
const output = await generators[name].bind()(items)
await file.create(`${LOGS_DIR}/${name}.log`, output.map(toJSON).join('\n'))
let output = await generators[name].bind()(items)
output = Array.isArray(output) ? output : [output]
for (const type of output) {
const playlist = createPlaylist(type.items, { public: true })
await file.create(`${PUBLIC_DIR}/${name}/${type.id}.m3u`, playlist.toString())
await file.create(`${PUBLIC_DIR}/${type.filepath}`, playlist.toString())
}
await file.create(`${LOGS_DIR}/${name}.log`, output.map(toJSON).join('\n'))
} catch (error) {
logger.error(`generators/${name}.js: ${error.message}`)
}
@ -33,5 +34,7 @@ generator.generate = async function (name, items = []) {
module.exports = generator
function toJSON(type) {
return JSON.stringify({ id: type.id, count: type.items.length })
type.count = type.items.length
delete type.items
return JSON.stringify(type)
}

View File

@ -7,11 +7,11 @@ module.exports = async function (streams = []) {
const categories = await api.categories.all()
for (const category of categories) {
let items = _.filter(streams, { channel: { categories: [category.id] } })
output.push({ id: category.id, items })
output.push({ filepath: `categories/${category.id}.m3u`, items })
}
let items = _.filter(streams, s => !s.categories.length)
output.push({ id: 'undefined', items })
output.push({ filepath: 'categories/undefined.m3u', items })
return output
}

View File

@ -11,11 +11,11 @@ module.exports = async function (streams = []) {
const areaCodes = _.filter(regions, { countries: [country.code] }).map(r => r.code)
areaCodes.push(country.code)
let items = _.filter(streams, s => _.intersection(areaCodes, s.broadcast_area).length)
output.push({ id: country.code.toLowerCase(), items })
output.push({ filepath: `countries/${country.code.toLowerCase()}.m3u`, items })
}
let items = _.filter(streams, s => !s.broadcast_area.length)
output.push({ id: 'undefined', items })
output.push({ filepath: 'countries/undefined.m3u', items })
return output
}

View File

@ -2,3 +2,4 @@ exports.categories = require('./categories')
exports.countries = require('./countries')
exports.languages = require('./languages')
exports.regions = require('./regions')
exports.index_m3u = require('./index_m3u')

View File

@ -0,0 +1,6 @@
const api = require('../core/api')
const _ = require('lodash')
module.exports = async function (streams = []) {
return { filepath: 'index.m3u', items: streams }
}

View File

@ -9,12 +9,12 @@ module.exports = async function (streams = []) {
for (const language of languages) {
let items = _.filter(streams, { channel: { languages: [language.code] } })
if (items.length) {
output.push({ id: language.code, items })
output.push({ filepath: `languages/${language.code}.m3u`, items })
}
}
let items = _.filter(streams, s => !s.languages.length)
output.push({ id: 'undefined', items })
output.push({ filepath: 'languages/undefined.m3u', items })
return output
}

View File

@ -9,11 +9,11 @@ module.exports = async function (streams = []) {
const areaCodes = region.countries
areaCodes.push(region.code)
let items = _.filter(streams, s => _.intersection(areaCodes, s.broadcast_area).length)
output.push({ id: region.code.toLowerCase(), items })
output.push({ filepath: `regions/${region.code.toLowerCase()}.m3u`, items })
}
let items = _.filter(streams, s => !s.broadcast_area.length)
output.push({ id: 'undefined', items })
output.push({ filepath: 'regions/undefined.m3u', items })
return output
}

View File

@ -1,7 +1,7 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ad/andorradifusio.ad.epg.xml"
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",ATV (720p) [Offline]
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8

View File

@ -0,0 +1,3 @@
#EXTM3U x-tvg-url=""
#EXTINF:-1 tvg-id="VisitXTV.nl" tvg-country="INT" tvg-language="Flemish" tvg-logo="https://i.imgur.com/RJ9wbNF.jpg" group-title="XXX",Visit-X TV
https://stream.visit-x.tv/vxtv/ngrp:live_all/playlist.m3u8

View File

@ -1,7 +1,7 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ch/tv.blue.ch.epg.xml,https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml,https://iptv-org.github.io/epg/guides/uk/ontvtonight.com.epg.xml,https://iptv-org.github.io/epg/guides/uk/sky.com.epg.xml"
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="INT" tvg-language="English" tvg-logo="https://raw.githubusercontent.com/Tapiosinn/tv-logos/master/countries/united-kingdom/bbc-news-uk.png" group-title="News",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="VisitXTV.nl" tvg-country="INT" tvg-language="Flemish" tvg-logo="https://i.imgur.com/RJ9wbNF.jpg" group-title="XXX",Visit-X TV
https://stream.visit-x.tv/vxtv/ngrp:live_all/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8

View File

@ -1,5 +1,5 @@
#EXTM3U x-tvg-url=""
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8

View File

@ -1,11 +0,0 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Cooking",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Legislative",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="News",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Other",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8

View File

@ -1,13 +0,0 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Andorra",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Russia",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Russia",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="United Kingdom",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="United Kingdom",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8

View File

@ -1,9 +0,0 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="English",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Russian",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8

View File

@ -1,9 +1,13 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="News",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Cooking",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General;Legislative",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Other",Daawah TV
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ad/andorradifusio.ad.epg.xml,https://iptv-org.github.io/epg/guides/ch/tv.blue.ch.epg.xml,https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml,https://iptv-org.github.io/epg/guides/uk/ontvtonight.com.epg.xml,https://iptv-org.github.io/epg/guides/uk/sky.com.epg.xml"
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",ATV (720p) [Offline]
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="INT" tvg-language="English" tvg-logo="https://raw.githubusercontent.com/Tapiosinn/tv-logos/master/countries/united-kingdom/bbc-news-uk.png" group-title="News",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="VisitXTV.nl" tvg-country="INT" tvg-language="Flemish" tvg-logo="https://i.imgur.com/RJ9wbNF.jpg" group-title="XXX",Visit-X TV
https://stream.visit-x.tv/vxtv/ngrp:live_all/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8

View File

@ -1,11 +0,0 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="News",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Cooking",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="XXX",Visit-X TV
https://stream.visit-x.tv/vxtv/ngrp:live_all/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General;Legislative",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Other",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8

View File

@ -1,17 +0,0 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Asia",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Commonwealth of Independent States",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="Europe",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Europe",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="UK" tvg-language="English" tvg-logo="https://i.imgur.com/eNPIQ9f.png" group-title="Europe, the Middle East and Africa",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Europe, the Middle East and Africa",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="INT" tvg-language="" tvg-logo="" group-title="Worldwide",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8

View File

@ -1,3 +1,3 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ad/andorradifusio.ad.epg.xml"
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",ATV (720p) [Offline]
https://iptv-all.lanesh4d0w.repl.co/andorra/atv

View File

@ -1,5 +1,5 @@
#EXTM3U x-tvg-url=""
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8

View File

@ -1,5 +1,5 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ad/andorradifusio.ad.epg.xml,https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",ATV (720p) [Offline]
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8

View File

@ -1,5 +1,5 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ad/andorradifusio.ad.epg.xml,https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml"
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",ATV (720p) [Offline]
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8

View File

@ -1,9 +1,9 @@
#EXTM3U x-tvg-url="https://iptv-org.github.io/epg/guides/ad/andorradifusio.ad.epg.xml,https://iptv-org.github.io/epg/guides/ch/tv.blue.ch.epg.xml,https://iptv-org.github.io/epg/guides/ru/tv.yandex.ru.epg.xml,https://iptv-org.github.io/epg/guides/uk/ontvtonight.com.epg.xml,https://iptv-org.github.io/epg/guides/uk/sky.com.epg.xml"
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-country="AD" tvg-language="Valencian" tvg-logo="" group-title="Undefined",ATV (720p) [Offline]
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-country="INT" tvg-language="English" tvg-logo="https://raw.githubusercontent.com/Tapiosinn/tv-logos/master/countries/united-kingdom/bbc-news-uk.png" group-title="News",BBC News HD (720p) [Not 24/7]
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8
#EXTINF:-1 tvg-id="VisitXTV.nl" tvg-country="INT" tvg-language="Flemish" tvg-logo="https://i.imgur.com/RJ9wbNF.jpg" group-title="XXX",Visit-X TV
https://stream.visit-x.tv/vxtv/ngrp:live_all/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-country="RU" tvg-language="Russian" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/playlist.m3u8

View File

@ -1,5 +1,5 @@
#EXTM3U x-tvg-url=""
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Daawah TV
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
#EXTINF:-1 tvg-id="" tvg-country="" tvg-language="" tvg-logo="" group-title="Undefined",Tastemade
https://tastemade-freetv16min-plex.amagi.tv/hls/amagi_hls_data_tastemade-tastemadefreetv16-plex/CDN/playlist.m3u8

View File

@ -1,29 +1,29 @@
{"id":"auto","count":0}
{"id":"animation","count":0}
{"id":"business","count":0}
{"id":"classic","count":0}
{"id":"comedy","count":0}
{"id":"cooking","count":0}
{"id":"culture","count":0}
{"id":"documentary","count":0}
{"id":"education","count":0}
{"id":"entertainment","count":0}
{"id":"family","count":0}
{"id":"general","count":1}
{"id":"kids","count":0}
{"id":"legislative","count":0}
{"id":"lifestyle","count":0}
{"id":"movies","count":0}
{"id":"music","count":0}
{"id":"news","count":1}
{"id":"outdoor","count":0}
{"id":"relax","count":0}
{"id":"religious","count":0}
{"id":"series","count":0}
{"id":"science","count":0}
{"id":"shop","count":0}
{"id":"sports","count":0}
{"id":"travel","count":0}
{"id":"weather","count":0}
{"id":"xxx","count":1}
{"id":"undefined","count":3}
{"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":1}
{"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":0}
{"filepath":"categories/xxx.m3u","count":1}
{"filepath":"categories/undefined.m3u","count":3}

View File

@ -1,251 +1,251 @@
{"id":"af","count":2}
{"id":"al","count":2}
{"id":"dz","count":2}
{"id":"as","count":2}
{"id":"ad","count":3}
{"id":"ao","count":2}
{"id":"ai","count":2}
{"id":"aq","count":2}
{"id":"ag","count":2}
{"id":"ar","count":2}
{"id":"am","count":2}
{"id":"aw","count":2}
{"id":"au","count":2}
{"id":"at","count":2}
{"id":"az","count":2}
{"id":"bs","count":2}
{"id":"bh","count":2}
{"id":"bd","count":2}
{"id":"bb","count":2}
{"id":"by","count":2}
{"id":"be","count":2}
{"id":"bz","count":2}
{"id":"bj","count":2}
{"id":"bm","count":2}
{"id":"bt","count":2}
{"id":"bo","count":2}
{"id":"bq","count":2}
{"id":"ba","count":2}
{"id":"bw","count":2}
{"id":"bv","count":2}
{"id":"br","count":2}
{"id":"io","count":2}
{"id":"vg","count":2}
{"id":"bn","count":2}
{"id":"bg","count":2}
{"id":"bf","count":2}
{"id":"bi","count":2}
{"id":"kh","count":2}
{"id":"cm","count":2}
{"id":"ca","count":2}
{"id":"cv","count":2}
{"id":"ky","count":2}
{"id":"cf","count":2}
{"id":"td","count":2}
{"id":"cl","count":2}
{"id":"cn","count":2}
{"id":"cx","count":2}
{"id":"cc","count":2}
{"id":"co","count":2}
{"id":"km","count":2}
{"id":"ck","count":2}
{"id":"cr","count":2}
{"id":"hr","count":2}
{"id":"cu","count":2}
{"id":"cw","count":2}
{"id":"cy","count":2}
{"id":"cz","count":2}
{"id":"cd","count":2}
{"id":"dk","count":2}
{"id":"dj","count":2}
{"id":"dm","count":2}
{"id":"do","count":2}
{"id":"tl","count":2}
{"id":"ec","count":2}
{"id":"eg","count":2}
{"id":"sv","count":2}
{"id":"gq","count":2}
{"id":"er","count":2}
{"id":"ee","count":2}
{"id":"et","count":2}
{"id":"fk","count":2}
{"id":"fo","count":2}
{"id":"fj","count":2}
{"id":"fi","count":2}
{"id":"fr","count":2}
{"id":"gf","count":2}
{"id":"pf","count":2}
{"id":"tf","count":2}
{"id":"ga","count":2}
{"id":"gm","count":2}
{"id":"ge","count":2}
{"id":"de","count":2}
{"id":"gh","count":2}
{"id":"gi","count":2}
{"id":"gr","count":2}
{"id":"gl","count":2}
{"id":"gd","count":2}
{"id":"gp","count":2}
{"id":"gu","count":2}
{"id":"gt","count":2}
{"id":"gg","count":2}
{"id":"gn","count":2}
{"id":"gw","count":2}
{"id":"gy","count":2}
{"id":"ht","count":2}
{"id":"hm","count":2}
{"id":"hn","count":2}
{"id":"hk","count":2}
{"id":"hu","count":2}
{"id":"is","count":2}
{"id":"in","count":2}
{"id":"id","count":2}
{"id":"ir","count":2}
{"id":"iq","count":2}
{"id":"ie","count":2}
{"id":"im","count":2}
{"id":"il","count":2}
{"id":"it","count":2}
{"id":"ci","count":2}
{"id":"jm","count":2}
{"id":"jp","count":2}
{"id":"je","count":2}
{"id":"jo","count":2}
{"id":"kz","count":2}
{"id":"ke","count":2}
{"id":"ki","count":2}
{"id":"xk","count":2}
{"id":"kw","count":2}
{"id":"kg","count":2}
{"id":"la","count":2}
{"id":"lv","count":2}
{"id":"lb","count":2}
{"id":"ls","count":2}
{"id":"lr","count":2}
{"id":"ly","count":2}
{"id":"li","count":2}
{"id":"lt","count":2}
{"id":"lu","count":2}
{"id":"mo","count":2}
{"id":"mg","count":2}
{"id":"mw","count":2}
{"id":"my","count":2}
{"id":"mv","count":2}
{"id":"ml","count":2}
{"id":"mt","count":2}
{"id":"mh","count":2}
{"id":"mq","count":2}
{"id":"mr","count":2}
{"id":"mu","count":2}
{"id":"yt","count":2}
{"id":"mx","count":2}
{"id":"fm","count":2}
{"id":"md","count":2}
{"id":"mc","count":2}
{"id":"mn","count":2}
{"id":"me","count":2}
{"id":"ms","count":2}
{"id":"ma","count":2}
{"id":"mz","count":2}
{"id":"mm","count":2}
{"id":"na","count":2}
{"id":"nr","count":2}
{"id":"np","count":2}
{"id":"nl","count":2}
{"id":"nc","count":2}
{"id":"nz","count":2}
{"id":"ni","count":2}
{"id":"ne","count":2}
{"id":"ng","count":2}
{"id":"nu","count":2}
{"id":"nf","count":2}
{"id":"kp","count":2}
{"id":"mk","count":2}
{"id":"mp","count":2}
{"id":"no","count":2}
{"id":"om","count":2}
{"id":"pk","count":2}
{"id":"pw","count":2}
{"id":"ps","count":2}
{"id":"pa","count":2}
{"id":"pg","count":2}
{"id":"py","count":2}
{"id":"pe","count":2}
{"id":"ph","count":2}
{"id":"pn","count":2}
{"id":"pl","count":2}
{"id":"pt","count":2}
{"id":"pr","count":2}
{"id":"qa","count":2}
{"id":"cg","count":2}
{"id":"ro","count":2}
{"id":"ru","count":3}
{"id":"rw","count":2}
{"id":"re","count":2}
{"id":"bl","count":2}
{"id":"sh","count":2}
{"id":"kn","count":2}
{"id":"lc","count":2}
{"id":"mf","count":2}
{"id":"pm","count":2}
{"id":"vc","count":2}
{"id":"ws","count":2}
{"id":"sm","count":2}
{"id":"sa","count":2}
{"id":"sn","count":2}
{"id":"rs","count":2}
{"id":"sc","count":2}
{"id":"sl","count":2}
{"id":"sg","count":2}
{"id":"sx","count":2}
{"id":"sk","count":2}
{"id":"si","count":2}
{"id":"sb","count":2}
{"id":"so","count":2}
{"id":"za","count":2}
{"id":"gs","count":2}
{"id":"kr","count":2}
{"id":"ss","count":2}
{"id":"es","count":2}
{"id":"lk","count":2}
{"id":"sd","count":2}
{"id":"sr","count":2}
{"id":"sj","count":2}
{"id":"sz","count":2}
{"id":"se","count":2}
{"id":"ch","count":2}
{"id":"sy","count":2}
{"id":"st","count":2}
{"id":"tw","count":2}
{"id":"tj","count":2}
{"id":"tz","count":2}
{"id":"th","count":2}
{"id":"tg","count":2}
{"id":"tk","count":2}
{"id":"to","count":2}
{"id":"tt","count":2}
{"id":"tn","count":2}
{"id":"tr","count":2}
{"id":"tm","count":2}
{"id":"tc","count":2}
{"id":"tv","count":2}
{"id":"um","count":2}
{"id":"vi","count":2}
{"id":"ug","count":2}
{"id":"ua","count":2}
{"id":"ae","count":2}
{"id":"uk","count":2}
{"id":"us","count":2}
{"id":"uy","count":2}
{"id":"uz","count":2}
{"id":"vu","count":2}
{"id":"va","count":2}
{"id":"ve","count":2}
{"id":"vn","count":2}
{"id":"wf","count":2}
{"id":"eh","count":2}
{"id":"ye","count":2}
{"id":"zm","count":2}
{"id":"zw","count":2}
{"id":"ax","count":2}
{"id":"undefined","count":2}
{"filepath":"countries/af.m3u","count":2}
{"filepath":"countries/al.m3u","count":2}
{"filepath":"countries/dz.m3u","count":2}
{"filepath":"countries/as.m3u","count":2}
{"filepath":"countries/ad.m3u","count":3}
{"filepath":"countries/ao.m3u","count":2}
{"filepath":"countries/ai.m3u","count":2}
{"filepath":"countries/aq.m3u","count":2}
{"filepath":"countries/ag.m3u","count":2}
{"filepath":"countries/ar.m3u","count":2}
{"filepath":"countries/am.m3u","count":2}
{"filepath":"countries/aw.m3u","count":2}
{"filepath":"countries/au.m3u","count":2}
{"filepath":"countries/at.m3u","count":2}
{"filepath":"countries/az.m3u","count":2}
{"filepath":"countries/bs.m3u","count":2}
{"filepath":"countries/bh.m3u","count":2}
{"filepath":"countries/bd.m3u","count":2}
{"filepath":"countries/bb.m3u","count":2}
{"filepath":"countries/by.m3u","count":2}
{"filepath":"countries/be.m3u","count":2}
{"filepath":"countries/bz.m3u","count":2}
{"filepath":"countries/bj.m3u","count":2}
{"filepath":"countries/bm.m3u","count":2}
{"filepath":"countries/bt.m3u","count":2}
{"filepath":"countries/bo.m3u","count":2}
{"filepath":"countries/bq.m3u","count":2}
{"filepath":"countries/ba.m3u","count":2}
{"filepath":"countries/bw.m3u","count":2}
{"filepath":"countries/bv.m3u","count":2}
{"filepath":"countries/br.m3u","count":2}
{"filepath":"countries/io.m3u","count":2}
{"filepath":"countries/vg.m3u","count":2}
{"filepath":"countries/bn.m3u","count":2}
{"filepath":"countries/bg.m3u","count":2}
{"filepath":"countries/bf.m3u","count":2}
{"filepath":"countries/bi.m3u","count":2}
{"filepath":"countries/kh.m3u","count":2}
{"filepath":"countries/cm.m3u","count":2}
{"filepath":"countries/ca.m3u","count":2}
{"filepath":"countries/cv.m3u","count":2}
{"filepath":"countries/ky.m3u","count":2}
{"filepath":"countries/cf.m3u","count":2}
{"filepath":"countries/td.m3u","count":2}
{"filepath":"countries/cl.m3u","count":2}
{"filepath":"countries/cn.m3u","count":2}
{"filepath":"countries/cx.m3u","count":2}
{"filepath":"countries/cc.m3u","count":2}
{"filepath":"countries/co.m3u","count":2}
{"filepath":"countries/km.m3u","count":2}
{"filepath":"countries/ck.m3u","count":2}
{"filepath":"countries/cr.m3u","count":2}
{"filepath":"countries/hr.m3u","count":2}
{"filepath":"countries/cu.m3u","count":2}
{"filepath":"countries/cw.m3u","count":2}
{"filepath":"countries/cy.m3u","count":2}
{"filepath":"countries/cz.m3u","count":2}
{"filepath":"countries/cd.m3u","count":2}
{"filepath":"countries/dk.m3u","count":2}
{"filepath":"countries/dj.m3u","count":2}
{"filepath":"countries/dm.m3u","count":2}
{"filepath":"countries/do.m3u","count":2}
{"filepath":"countries/tl.m3u","count":2}
{"filepath":"countries/ec.m3u","count":2}
{"filepath":"countries/eg.m3u","count":2}
{"filepath":"countries/sv.m3u","count":2}
{"filepath":"countries/gq.m3u","count":2}
{"filepath":"countries/er.m3u","count":2}
{"filepath":"countries/ee.m3u","count":2}
{"filepath":"countries/et.m3u","count":2}
{"filepath":"countries/fk.m3u","count":2}
{"filepath":"countries/fo.m3u","count":2}
{"filepath":"countries/fj.m3u","count":2}
{"filepath":"countries/fi.m3u","count":2}
{"filepath":"countries/fr.m3u","count":2}
{"filepath":"countries/gf.m3u","count":2}
{"filepath":"countries/pf.m3u","count":2}
{"filepath":"countries/tf.m3u","count":2}
{"filepath":"countries/ga.m3u","count":2}
{"filepath":"countries/gm.m3u","count":2}
{"filepath":"countries/ge.m3u","count":2}
{"filepath":"countries/de.m3u","count":2}
{"filepath":"countries/gh.m3u","count":2}
{"filepath":"countries/gi.m3u","count":2}
{"filepath":"countries/gr.m3u","count":2}
{"filepath":"countries/gl.m3u","count":2}
{"filepath":"countries/gd.m3u","count":2}
{"filepath":"countries/gp.m3u","count":2}
{"filepath":"countries/gu.m3u","count":2}
{"filepath":"countries/gt.m3u","count":2}
{"filepath":"countries/gg.m3u","count":2}
{"filepath":"countries/gn.m3u","count":2}
{"filepath":"countries/gw.m3u","count":2}
{"filepath":"countries/gy.m3u","count":2}
{"filepath":"countries/ht.m3u","count":2}
{"filepath":"countries/hm.m3u","count":2}
{"filepath":"countries/hn.m3u","count":2}
{"filepath":"countries/hk.m3u","count":2}
{"filepath":"countries/hu.m3u","count":2}
{"filepath":"countries/is.m3u","count":2}
{"filepath":"countries/in.m3u","count":2}
{"filepath":"countries/id.m3u","count":2}
{"filepath":"countries/ir.m3u","count":2}
{"filepath":"countries/iq.m3u","count":2}
{"filepath":"countries/ie.m3u","count":2}
{"filepath":"countries/im.m3u","count":2}
{"filepath":"countries/il.m3u","count":2}
{"filepath":"countries/it.m3u","count":2}
{"filepath":"countries/ci.m3u","count":2}
{"filepath":"countries/jm.m3u","count":2}
{"filepath":"countries/jp.m3u","count":2}
{"filepath":"countries/je.m3u","count":2}
{"filepath":"countries/jo.m3u","count":2}
{"filepath":"countries/kz.m3u","count":2}
{"filepath":"countries/ke.m3u","count":2}
{"filepath":"countries/ki.m3u","count":2}
{"filepath":"countries/xk.m3u","count":2}
{"filepath":"countries/kw.m3u","count":2}
{"filepath":"countries/kg.m3u","count":2}
{"filepath":"countries/la.m3u","count":2}
{"filepath":"countries/lv.m3u","count":2}
{"filepath":"countries/lb.m3u","count":2}
{"filepath":"countries/ls.m3u","count":2}
{"filepath":"countries/lr.m3u","count":2}
{"filepath":"countries/ly.m3u","count":2}
{"filepath":"countries/li.m3u","count":2}
{"filepath":"countries/lt.m3u","count":2}
{"filepath":"countries/lu.m3u","count":2}
{"filepath":"countries/mo.m3u","count":2}
{"filepath":"countries/mg.m3u","count":2}
{"filepath":"countries/mw.m3u","count":2}
{"filepath":"countries/my.m3u","count":2}
{"filepath":"countries/mv.m3u","count":2}
{"filepath":"countries/ml.m3u","count":2}
{"filepath":"countries/mt.m3u","count":2}
{"filepath":"countries/mh.m3u","count":2}
{"filepath":"countries/mq.m3u","count":2}
{"filepath":"countries/mr.m3u","count":2}
{"filepath":"countries/mu.m3u","count":2}
{"filepath":"countries/yt.m3u","count":2}
{"filepath":"countries/mx.m3u","count":2}
{"filepath":"countries/fm.m3u","count":2}
{"filepath":"countries/md.m3u","count":2}
{"filepath":"countries/mc.m3u","count":2}
{"filepath":"countries/mn.m3u","count":2}
{"filepath":"countries/me.m3u","count":2}
{"filepath":"countries/ms.m3u","count":2}
{"filepath":"countries/ma.m3u","count":2}
{"filepath":"countries/mz.m3u","count":2}
{"filepath":"countries/mm.m3u","count":2}
{"filepath":"countries/na.m3u","count":2}
{"filepath":"countries/nr.m3u","count":2}
{"filepath":"countries/np.m3u","count":2}
{"filepath":"countries/nl.m3u","count":2}
{"filepath":"countries/nc.m3u","count":2}
{"filepath":"countries/nz.m3u","count":2}
{"filepath":"countries/ni.m3u","count":2}
{"filepath":"countries/ne.m3u","count":2}
{"filepath":"countries/ng.m3u","count":2}
{"filepath":"countries/nu.m3u","count":2}
{"filepath":"countries/nf.m3u","count":2}
{"filepath":"countries/kp.m3u","count":2}
{"filepath":"countries/mk.m3u","count":2}
{"filepath":"countries/mp.m3u","count":2}
{"filepath":"countries/no.m3u","count":2}
{"filepath":"countries/om.m3u","count":2}
{"filepath":"countries/pk.m3u","count":2}
{"filepath":"countries/pw.m3u","count":2}
{"filepath":"countries/ps.m3u","count":2}
{"filepath":"countries/pa.m3u","count":2}
{"filepath":"countries/pg.m3u","count":2}
{"filepath":"countries/py.m3u","count":2}
{"filepath":"countries/pe.m3u","count":2}
{"filepath":"countries/ph.m3u","count":2}
{"filepath":"countries/pn.m3u","count":2}
{"filepath":"countries/pl.m3u","count":2}
{"filepath":"countries/pt.m3u","count":2}
{"filepath":"countries/pr.m3u","count":2}
{"filepath":"countries/qa.m3u","count":2}
{"filepath":"countries/cg.m3u","count":2}
{"filepath":"countries/ro.m3u","count":2}
{"filepath":"countries/ru.m3u","count":3}
{"filepath":"countries/rw.m3u","count":2}
{"filepath":"countries/re.m3u","count":2}
{"filepath":"countries/bl.m3u","count":2}
{"filepath":"countries/sh.m3u","count":2}
{"filepath":"countries/kn.m3u","count":2}
{"filepath":"countries/lc.m3u","count":2}
{"filepath":"countries/mf.m3u","count":2}
{"filepath":"countries/pm.m3u","count":2}
{"filepath":"countries/vc.m3u","count":2}
{"filepath":"countries/ws.m3u","count":2}
{"filepath":"countries/sm.m3u","count":2}
{"filepath":"countries/sa.m3u","count":2}
{"filepath":"countries/sn.m3u","count":2}
{"filepath":"countries/rs.m3u","count":2}
{"filepath":"countries/sc.m3u","count":2}
{"filepath":"countries/sl.m3u","count":2}
{"filepath":"countries/sg.m3u","count":2}
{"filepath":"countries/sx.m3u","count":2}
{"filepath":"countries/sk.m3u","count":2}
{"filepath":"countries/si.m3u","count":2}
{"filepath":"countries/sb.m3u","count":2}
{"filepath":"countries/so.m3u","count":2}
{"filepath":"countries/za.m3u","count":2}
{"filepath":"countries/gs.m3u","count":2}
{"filepath":"countries/kr.m3u","count":2}
{"filepath":"countries/ss.m3u","count":2}
{"filepath":"countries/es.m3u","count":2}
{"filepath":"countries/lk.m3u","count":2}
{"filepath":"countries/sd.m3u","count":2}
{"filepath":"countries/sr.m3u","count":2}
{"filepath":"countries/sj.m3u","count":2}
{"filepath":"countries/sz.m3u","count":2}
{"filepath":"countries/se.m3u","count":2}
{"filepath":"countries/ch.m3u","count":2}
{"filepath":"countries/sy.m3u","count":2}
{"filepath":"countries/st.m3u","count":2}
{"filepath":"countries/tw.m3u","count":2}
{"filepath":"countries/tj.m3u","count":2}
{"filepath":"countries/tz.m3u","count":2}
{"filepath":"countries/th.m3u","count":2}
{"filepath":"countries/tg.m3u","count":2}
{"filepath":"countries/tk.m3u","count":2}
{"filepath":"countries/to.m3u","count":2}
{"filepath":"countries/tt.m3u","count":2}
{"filepath":"countries/tn.m3u","count":2}
{"filepath":"countries/tr.m3u","count":2}
{"filepath":"countries/tm.m3u","count":2}
{"filepath":"countries/tc.m3u","count":2}
{"filepath":"countries/tv.m3u","count":2}
{"filepath":"countries/um.m3u","count":2}
{"filepath":"countries/vi.m3u","count":2}
{"filepath":"countries/ug.m3u","count":2}
{"filepath":"countries/ua.m3u","count":2}
{"filepath":"countries/ae.m3u","count":2}
{"filepath":"countries/uk.m3u","count":2}
{"filepath":"countries/us.m3u","count":2}
{"filepath":"countries/uy.m3u","count":2}
{"filepath":"countries/uz.m3u","count":2}
{"filepath":"countries/vu.m3u","count":2}
{"filepath":"countries/va.m3u","count":2}
{"filepath":"countries/ve.m3u","count":2}
{"filepath":"countries/vn.m3u","count":2}
{"filepath":"countries/wf.m3u","count":2}
{"filepath":"countries/eh.m3u","count":2}
{"filepath":"countries/ye.m3u","count":2}
{"filepath":"countries/zm.m3u","count":2}
{"filepath":"countries/zw.m3u","count":2}
{"filepath":"countries/ax.m3u","count":2}
{"filepath":"countries/undefined.m3u","count":2}

View File

@ -1,5 +1,5 @@
{"id":"cat","count":1}
{"id":"eng","count":1}
{"id":"nld","count":1}
{"id":"rus","count":1}
{"id":"undefined","count":2}
{"filepath":"languages/cat.m3u","count":1}
{"filepath":"languages/eng.m3u","count":1}
{"filepath":"languages/nld.m3u","count":1}
{"filepath":"languages/rus.m3u","count":1}
{"filepath":"languages/undefined.m3u","count":2}

View File

@ -1,25 +1,25 @@
{"id":"afr","count":0}
{"id":"amer","count":0}
{"id":"arab","count":0}
{"id":"asia","count":1}
{"id":"apac","count":0}
{"id":"carib","count":0}
{"id":"cas","count":0}
{"id":"cis","count":1}
{"id":"eur","count":2}
{"id":"emea","count":2}
{"id":"hispam","count":0}
{"id":"latam","count":0}
{"id":"lac","count":0}
{"id":"maghreb","count":0}
{"id":"mideast","count":0}
{"id":"mena","count":0}
{"id":"nord","count":0}
{"id":"noram","count":0}
{"id":"nam","count":0}
{"id":"oce","count":0}
{"id":"sas","count":0}
{"id":"ssa","count":0}
{"id":"wafr","count":0}
{"id":"int","count":4}
{"id":"undefined","count":2}
{"filepath":"regions/afr.m3u","count":0}
{"filepath":"regions/amer.m3u","count":0}
{"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":0}
{"filepath":"regions/nam.m3u","count":0}
{"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}

View File

@ -1,5 +1,6 @@
const fs = require('fs-extra')
const path = require('path')
const glob = require('glob')
const { execSync } = require('child_process')
beforeEach(() => {
@ -19,33 +20,22 @@ beforeEach(() => {
})
it('can generate playlists', () => {
const files = [
'.gh-pages/categories/general.m3u',
'.gh-pages/categories/legislative.m3u',
'.gh-pages/categories/news.m3u',
'.gh-pages/categories/undefined.m3u',
'logs/generators/categories.log',
'.gh-pages/countries/ru.m3u',
'.gh-pages/countries/uk.m3u',
'.gh-pages/countries/undefined.m3u',
'logs/generators/countries.log',
'.gh-pages/languages/cat.m3u',
'.gh-pages/languages/eng.m3u',
'.gh-pages/languages/nld.m3u',
'.gh-pages/languages/rus.m3u',
'.gh-pages/languages/undefined.m3u',
'logs/generators/languages.log',
'.gh-pages/regions/asia.m3u',
'.gh-pages/regions/cis.m3u',
'.gh-pages/regions/emea.m3u',
'.gh-pages/regions/eur.m3u',
'.gh-pages/regions/int.m3u',
'.gh-pages/regions/undefined.m3u',
'logs/generators/regions.log'
]
const files = glob
.sync('tests/__data__/expected/.gh-pages/**/*.m3u')
.map(f => f.replace('tests/__data__/expected/', ''))
files.forEach(filepath => {
expect(content(`output/${filepath}`)).toBe(content(`expected/${filepath}`))
expect(content(`output/${filepath}`), filepath).toBe(content(`expected/${filepath}`))
})
})
it('can generate logs', () => {
const files = glob
.sync('tests/__data__/expected/logs/generators/*.log')
.map(f => f.replace('tests/__data__/expected/', ''))
files.forEach(filepath => {
expect(content(`output/${filepath}`), filepath).toBe(content(`expected/${filepath}`))
})
})