mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-10 00:50:09 -04:00
Update update-readme.js
This commit is contained in:
parent
61dbd2a1b3
commit
cf0f2472d1
11 changed files with 653 additions and 461 deletions
|
@ -30,7 +30,7 @@ https://iptv-org.github.io/epg/index.html
|
||||||
You can also get a list of all available channels and their codes in JSON format by sending a GET request to:
|
You can also get a list of all available channels and their codes in JSON format by sending a GET request to:
|
||||||
|
|
||||||
```
|
```
|
||||||
https://iptv-org.github.io/epg/codes.json
|
https://iptv-org.github.io/epg/api/channels.json
|
||||||
```
|
```
|
||||||
|
|
||||||
If successful, you should get the following response:
|
If successful, you should get the following response:
|
||||||
|
@ -43,10 +43,12 @@ If successful, you should get the following response:
|
||||||
[
|
[
|
||||||
...
|
...
|
||||||
{
|
{
|
||||||
"tvg_id": "CNNUSA.us",
|
"id": "CNNUSA.us",
|
||||||
"display_name": "CNN USA",
|
"name": [
|
||||||
|
"CNN USA"
|
||||||
|
],
|
||||||
"logo": "https://cdn.tvpassport.com/image/station/100x100/cnn.png",
|
"logo": "https://cdn.tvpassport.com/image/station/100x100/cnn.png",
|
||||||
"country": "us",
|
"country": "US",
|
||||||
"guides": [
|
"guides": [
|
||||||
"https://iptv-org.github.io/epg/guides/tvtv.us.guide.xml",
|
"https://iptv-org.github.io/epg/guides/tvtv.us.guide.xml",
|
||||||
...
|
...
|
||||||
|
|
119
scripts/commands/update-readme.js
Normal file
119
scripts/commands/update-readme.js
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
const { file, markdown, parser, logger } = require('../core')
|
||||||
|
const countries = require('../data/countries.json')
|
||||||
|
const states = require('../data/us-states.json')
|
||||||
|
const provinces = require('../data/ca-provinces.json')
|
||||||
|
const { program } = require('commander')
|
||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
let log = []
|
||||||
|
|
||||||
|
const statuses = {
|
||||||
|
0: '✗',
|
||||||
|
1: '✓'
|
||||||
|
}
|
||||||
|
|
||||||
|
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
|
||||||
|
|
||||||
|
const options = program
|
||||||
|
.option('-c, --config <config>', 'Set path to config file', '.readme/config.json')
|
||||||
|
.parse(process.argv)
|
||||||
|
.opts()
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
await setUp()
|
||||||
|
|
||||||
|
await generateCountriesTable()
|
||||||
|
await generateUSStatesTable()
|
||||||
|
await generateCanadaProvincesTable()
|
||||||
|
|
||||||
|
await updateReadme()
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
async function generateCountriesTable() {
|
||||||
|
logger.info('Generating countries table...')
|
||||||
|
|
||||||
|
const items = log.filter(i => i.gid.length === 2)
|
||||||
|
let rows = []
|
||||||
|
for (const item of items) {
|
||||||
|
const code = item.gid.toUpperCase()
|
||||||
|
const country = countries[code]
|
||||||
|
|
||||||
|
rows.push({
|
||||||
|
name: `${country.flag} ${country.name}`,
|
||||||
|
channels: item.count,
|
||||||
|
epg: `<code>https://iptv-org.github.io/epg/guides/${item.gid}/${item.site}.epg.xml</code>`,
|
||||||
|
status: statuses[item.status]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = _.orderBy(rows, ['name', 'channels'], ['asc', 'desc'])
|
||||||
|
rows = _.groupBy(rows, 'name')
|
||||||
|
|
||||||
|
const table = markdown.createTable(rows, ['Country', 'Channels', 'EPG', 'Status'])
|
||||||
|
|
||||||
|
await file.create('./.readme/_countries.md', table)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateUSStatesTable() {
|
||||||
|
logger.info('Generating US states table...')
|
||||||
|
|
||||||
|
const items = log.filter(i => i.gid.startsWith('us-'))
|
||||||
|
let rows = []
|
||||||
|
for (const item of items) {
|
||||||
|
const code = item.gid.toUpperCase()
|
||||||
|
const state = states[code]
|
||||||
|
|
||||||
|
rows.push({
|
||||||
|
name: state.name,
|
||||||
|
channels: item.count,
|
||||||
|
epg: `<code>https://iptv-org.github.io/epg/guides/${item.gid}/${item.site}.epg.xml</code>`,
|
||||||
|
status: statuses[item.status]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = _.orderBy(rows, ['name', 'channels'], ['asc', 'desc'])
|
||||||
|
rows = _.groupBy(rows, 'name')
|
||||||
|
|
||||||
|
const table = markdown.createTable(rows, ['State', 'Channels', 'EPG', 'Status'])
|
||||||
|
|
||||||
|
await file.create('./.readme/_us-states.md', table)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateCanadaProvincesTable() {
|
||||||
|
logger.info('Generating Canada provinces table...')
|
||||||
|
|
||||||
|
const items = log.filter(i => i.gid.startsWith('ca-'))
|
||||||
|
let rows = []
|
||||||
|
for (const item of items) {
|
||||||
|
const code = item.gid.toUpperCase()
|
||||||
|
const province = provinces[code]
|
||||||
|
|
||||||
|
rows.push({
|
||||||
|
name: province.name,
|
||||||
|
channels: item.count,
|
||||||
|
epg: `<code>https://iptv-org.github.io/epg/guides/${item.gid}/${item.site}.epg.xml</code>`,
|
||||||
|
status: statuses[item.status]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = _.orderBy(rows, ['name', 'channels'], ['asc', 'desc'])
|
||||||
|
rows = _.groupBy(rows, 'name')
|
||||||
|
|
||||||
|
const table = markdown.createTable(rows, ['Province', 'Channels', 'EPG', 'Status'])
|
||||||
|
|
||||||
|
await file.create('./.readme/_ca-provinces.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() {
|
||||||
|
log = await parser.parseLogs(`${LOGS_DIR}/update-guides.log`)
|
||||||
|
}
|
|
@ -4,3 +4,4 @@ exports.file = require('./file')
|
||||||
exports.parser = require('./parser')
|
exports.parser = require('./parser')
|
||||||
exports.timer = require('./timer')
|
exports.timer = require('./timer')
|
||||||
exports.xml = require('./xml')
|
exports.xml = require('./xml')
|
||||||
|
exports.markdown = require('./markdown')
|
||||||
|
|
39
scripts/core/markdown.js
Normal file
39
scripts/core/markdown.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
const markdownInclude = require('markdown-include')
|
||||||
|
const file = require('./file')
|
||||||
|
|
||||||
|
const markdown = {}
|
||||||
|
|
||||||
|
markdown.createTable = function (data, cols) {
|
||||||
|
let output = '<table>\n'
|
||||||
|
|
||||||
|
output += ' <thead>\n <tr>'
|
||||||
|
for (let column of cols) {
|
||||||
|
output += `<th align="left">${column}</th>`
|
||||||
|
}
|
||||||
|
output += '</tr>\n </thead>\n'
|
||||||
|
|
||||||
|
output += ' <tbody>\n'
|
||||||
|
for (let groupId in data) {
|
||||||
|
const group = data[groupId]
|
||||||
|
for (let [i, item] of group.entries()) {
|
||||||
|
const rowspan = group.length > 1 ? ` rowspan="${group.length}"` : ''
|
||||||
|
output += ' <tr>'
|
||||||
|
if (i === 0) output += `<td align="left" valign="top" nowrap${rowspan}>${item.name}</td>`
|
||||||
|
output += `<td align="right">${item.channels}</td>`
|
||||||
|
output += `<td align="left" nowrap>${item.epg}</td>`
|
||||||
|
output += `<td align="center">${item.status}</td>`
|
||||||
|
output += '</tr>\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += ' </tbody>\n'
|
||||||
|
|
||||||
|
output += '</table>'
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown.compile = function (filepath) {
|
||||||
|
markdownInclude.compileFiles(file.resolve(filepath))
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = markdown
|
67
scripts/data/ca-provinces.json
Normal file
67
scripts/data/ca-provinces.json
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{
|
||||||
|
"CA-AB":
|
||||||
|
{
|
||||||
|
"name": "Alberta",
|
||||||
|
"code": "CA-AB"
|
||||||
|
},
|
||||||
|
"CA-BC":
|
||||||
|
{
|
||||||
|
"name": "British Columbia",
|
||||||
|
"code": "CA-BC"
|
||||||
|
},
|
||||||
|
"CA-MB":
|
||||||
|
{
|
||||||
|
"name": "Manitoba",
|
||||||
|
"code": "CA-MB"
|
||||||
|
},
|
||||||
|
"CA-NB":
|
||||||
|
{
|
||||||
|
"name": "New Brunswick",
|
||||||
|
"code": "CA-NB"
|
||||||
|
},
|
||||||
|
"CA-NL":
|
||||||
|
{
|
||||||
|
"name": "Newfoundland and Labrador",
|
||||||
|
"code": "CA-NL"
|
||||||
|
},
|
||||||
|
"CA-NT":
|
||||||
|
{
|
||||||
|
"name": "Northwest Territories",
|
||||||
|
"code": "CA-NT"
|
||||||
|
},
|
||||||
|
"CA-NS":
|
||||||
|
{
|
||||||
|
"name": "Nova Scotia",
|
||||||
|
"code": "CA-NS"
|
||||||
|
},
|
||||||
|
"CA-NU":
|
||||||
|
{
|
||||||
|
"name": "Nunavut",
|
||||||
|
"code": "CA-NU"
|
||||||
|
},
|
||||||
|
"CA-ON":
|
||||||
|
{
|
||||||
|
"name": "Ontario",
|
||||||
|
"code": "CA-ON"
|
||||||
|
},
|
||||||
|
"CA-PE":
|
||||||
|
{
|
||||||
|
"name": "Prince Edward Island",
|
||||||
|
"code": "CA-PE"
|
||||||
|
},
|
||||||
|
"CA-QC":
|
||||||
|
{
|
||||||
|
"name": "Quebec",
|
||||||
|
"code": "CA-QC"
|
||||||
|
},
|
||||||
|
"CA-SK":
|
||||||
|
{
|
||||||
|
"name": "Saskatchewan",
|
||||||
|
"code": "CA-SK"
|
||||||
|
},
|
||||||
|
"CA-YT":
|
||||||
|
{
|
||||||
|
"name": "Yukon Territory",
|
||||||
|
"code": "CA-YT"
|
||||||
|
}
|
||||||
|
}
|
|
@ -157,61 +157,7 @@
|
||||||
"CA": {
|
"CA": {
|
||||||
"flag": "🇨🇦",
|
"flag": "🇨🇦",
|
||||||
"name": "Canada",
|
"name": "Canada",
|
||||||
"code": "CA",
|
"code": "CA"
|
||||||
"states": {
|
|
||||||
"AB": {
|
|
||||||
"name": "Alberta",
|
|
||||||
"code": "AB"
|
|
||||||
},
|
|
||||||
"BC": {
|
|
||||||
"name": "British Columbia",
|
|
||||||
"code": "BC"
|
|
||||||
},
|
|
||||||
"MB": {
|
|
||||||
"name": "Manitoba",
|
|
||||||
"code": "MB"
|
|
||||||
},
|
|
||||||
"NB": {
|
|
||||||
"name": "New Brunswick",
|
|
||||||
"code": "NB"
|
|
||||||
},
|
|
||||||
"NL": {
|
|
||||||
"name": "Newfoundland and Labrador",
|
|
||||||
"code": "NL"
|
|
||||||
},
|
|
||||||
"NT": {
|
|
||||||
"name": "Northwest Territories",
|
|
||||||
"code": "NT"
|
|
||||||
},
|
|
||||||
"NS": {
|
|
||||||
"name": "Nova Scotia",
|
|
||||||
"code": "NS"
|
|
||||||
},
|
|
||||||
"NU": {
|
|
||||||
"name": "Nunavut",
|
|
||||||
"code": "NU"
|
|
||||||
},
|
|
||||||
"ON": {
|
|
||||||
"name": "Ontario",
|
|
||||||
"code": "ON"
|
|
||||||
},
|
|
||||||
"PE": {
|
|
||||||
"name": "Prince Edward Island",
|
|
||||||
"code": "PE"
|
|
||||||
},
|
|
||||||
"QC": {
|
|
||||||
"name": "Quebec",
|
|
||||||
"code": "QC"
|
|
||||||
},
|
|
||||||
"SK": {
|
|
||||||
"name": "Saskatchewan",
|
|
||||||
"code": "SK"
|
|
||||||
},
|
|
||||||
"YT": {
|
|
||||||
"name": "Yukon Territory",
|
|
||||||
"code": "YT"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"CV": {
|
"CV": {
|
||||||
"flag": "🇨🇻",
|
"flag": "🇨🇻",
|
||||||
|
@ -1086,245 +1032,7 @@
|
||||||
"US": {
|
"US": {
|
||||||
"flag": "🇺🇸",
|
"flag": "🇺🇸",
|
||||||
"name": "United States",
|
"name": "United States",
|
||||||
"code": "US",
|
"code": "US"
|
||||||
"states": {
|
|
||||||
"AL": {
|
|
||||||
"name": "Alabama",
|
|
||||||
"code": "AL"
|
|
||||||
},
|
|
||||||
"AK": {
|
|
||||||
"name": "Alaska",
|
|
||||||
"code": "AK"
|
|
||||||
},
|
|
||||||
"AS": {
|
|
||||||
"name": "American Samoa",
|
|
||||||
"code": "AS"
|
|
||||||
},
|
|
||||||
"AZ": {
|
|
||||||
"name": "Arizona",
|
|
||||||
"code": "AZ"
|
|
||||||
},
|
|
||||||
"AR": {
|
|
||||||
"name": "Arkansas",
|
|
||||||
"code": "AR"
|
|
||||||
},
|
|
||||||
"CA": {
|
|
||||||
"name": "California",
|
|
||||||
"code": "CA"
|
|
||||||
},
|
|
||||||
"CO": {
|
|
||||||
"name": "Colorado",
|
|
||||||
"code": "CO"
|
|
||||||
},
|
|
||||||
"CT": {
|
|
||||||
"name": "Connecticut",
|
|
||||||
"code": "CT"
|
|
||||||
},
|
|
||||||
"DE": {
|
|
||||||
"name": "Delaware",
|
|
||||||
"code": "DE"
|
|
||||||
},
|
|
||||||
"DC": {
|
|
||||||
"name": "District Of Columbia",
|
|
||||||
"code": "DC"
|
|
||||||
},
|
|
||||||
"FM": {
|
|
||||||
"name": "Federated States Of Micronesia",
|
|
||||||
"code": "FM"
|
|
||||||
},
|
|
||||||
"FL": {
|
|
||||||
"name": "Florida",
|
|
||||||
"code": "FL"
|
|
||||||
},
|
|
||||||
"GA": {
|
|
||||||
"name": "Georgia",
|
|
||||||
"code": "GA"
|
|
||||||
},
|
|
||||||
"GU": {
|
|
||||||
"name": "Guam",
|
|
||||||
"code": "GU"
|
|
||||||
},
|
|
||||||
"HI": {
|
|
||||||
"name": "Hawaii",
|
|
||||||
"code": "HI"
|
|
||||||
},
|
|
||||||
"ID": {
|
|
||||||
"name": "Idaho",
|
|
||||||
"code": "ID"
|
|
||||||
},
|
|
||||||
"IL": {
|
|
||||||
"name": "Illinois",
|
|
||||||
"code": "IL"
|
|
||||||
},
|
|
||||||
"IN": {
|
|
||||||
"name": "Indiana",
|
|
||||||
"code": "IN"
|
|
||||||
},
|
|
||||||
"IA": {
|
|
||||||
"name": "Iowa",
|
|
||||||
"code": "IA"
|
|
||||||
},
|
|
||||||
"KS": {
|
|
||||||
"name": "Kansas",
|
|
||||||
"code": "KS"
|
|
||||||
},
|
|
||||||
"KY": {
|
|
||||||
"name": "Kentucky",
|
|
||||||
"code": "KY"
|
|
||||||
},
|
|
||||||
"LA": {
|
|
||||||
"name": "Louisiana",
|
|
||||||
"code": "LA"
|
|
||||||
},
|
|
||||||
"ME": {
|
|
||||||
"name": "Maine",
|
|
||||||
"code": "ME"
|
|
||||||
},
|
|
||||||
"MH": {
|
|
||||||
"name": "Marshall Islands",
|
|
||||||
"code": "MH"
|
|
||||||
},
|
|
||||||
"MD": {
|
|
||||||
"name": "Maryland",
|
|
||||||
"code": "MD"
|
|
||||||
},
|
|
||||||
"MA": {
|
|
||||||
"name": "Massachusetts",
|
|
||||||
"code": "MA"
|
|
||||||
},
|
|
||||||
"MI": {
|
|
||||||
"name": "Michigan",
|
|
||||||
"code": "MI"
|
|
||||||
},
|
|
||||||
"MN": {
|
|
||||||
"name": "Minnesota",
|
|
||||||
"code": "MN"
|
|
||||||
},
|
|
||||||
"MS": {
|
|
||||||
"name": "Mississippi",
|
|
||||||
"code": "MS"
|
|
||||||
},
|
|
||||||
"MO": {
|
|
||||||
"name": "Missouri",
|
|
||||||
"code": "MO"
|
|
||||||
},
|
|
||||||
"MT": {
|
|
||||||
"name": "Montana",
|
|
||||||
"code": "MT"
|
|
||||||
},
|
|
||||||
"NE": {
|
|
||||||
"name": "Nebraska",
|
|
||||||
"code": "NE"
|
|
||||||
},
|
|
||||||
"NV": {
|
|
||||||
"name": "Nevada",
|
|
||||||
"code": "NV"
|
|
||||||
},
|
|
||||||
"NH": {
|
|
||||||
"name": "New Hampshire",
|
|
||||||
"code": "NH"
|
|
||||||
},
|
|
||||||
"NJ": {
|
|
||||||
"name": "New Jersey",
|
|
||||||
"code": "NJ"
|
|
||||||
},
|
|
||||||
"NM": {
|
|
||||||
"name": "New Mexico",
|
|
||||||
"code": "NM"
|
|
||||||
},
|
|
||||||
"NY": {
|
|
||||||
"name": "New York",
|
|
||||||
"code": "NY"
|
|
||||||
},
|
|
||||||
"NC": {
|
|
||||||
"name": "North Carolina",
|
|
||||||
"code": "NC"
|
|
||||||
},
|
|
||||||
"ND": {
|
|
||||||
"name": "North Dakota",
|
|
||||||
"code": "ND"
|
|
||||||
},
|
|
||||||
"MP": {
|
|
||||||
"name": "Northern Mariana Islands",
|
|
||||||
"code": "MP"
|
|
||||||
},
|
|
||||||
"OH": {
|
|
||||||
"name": "Ohio",
|
|
||||||
"code": "OH"
|
|
||||||
},
|
|
||||||
"OK": {
|
|
||||||
"name": "Oklahoma",
|
|
||||||
"code": "OK"
|
|
||||||
},
|
|
||||||
"OR": {
|
|
||||||
"name": "Oregon",
|
|
||||||
"code": "OR"
|
|
||||||
},
|
|
||||||
"PW": {
|
|
||||||
"name": "Palau",
|
|
||||||
"code": "PW"
|
|
||||||
},
|
|
||||||
"PA": {
|
|
||||||
"name": "Pennsylvania",
|
|
||||||
"code": "PA"
|
|
||||||
},
|
|
||||||
"PR": {
|
|
||||||
"name": "Puerto Rico",
|
|
||||||
"code": "PR"
|
|
||||||
},
|
|
||||||
"RI": {
|
|
||||||
"name": "Rhode Island",
|
|
||||||
"code": "RI"
|
|
||||||
},
|
|
||||||
"SC": {
|
|
||||||
"name": "South Carolina",
|
|
||||||
"code": "SC"
|
|
||||||
},
|
|
||||||
"SD": {
|
|
||||||
"name": "South Dakota",
|
|
||||||
"code": "SD"
|
|
||||||
},
|
|
||||||
"TN": {
|
|
||||||
"name": "Tennessee",
|
|
||||||
"code": "TN"
|
|
||||||
},
|
|
||||||
"TX": {
|
|
||||||
"name": "Texas",
|
|
||||||
"code": "TX"
|
|
||||||
},
|
|
||||||
"UT": {
|
|
||||||
"name": "Utah",
|
|
||||||
"code": "UT"
|
|
||||||
},
|
|
||||||
"VT": {
|
|
||||||
"name": "Vermont",
|
|
||||||
"code": "VT"
|
|
||||||
},
|
|
||||||
"VI": {
|
|
||||||
"name": "Virgin Islands",
|
|
||||||
"code": "VI"
|
|
||||||
},
|
|
||||||
"VA": {
|
|
||||||
"name": "Virginia",
|
|
||||||
"code": "VA"
|
|
||||||
},
|
|
||||||
"WA": {
|
|
||||||
"name": "Washington",
|
|
||||||
"code": "WA"
|
|
||||||
},
|
|
||||||
"WV": {
|
|
||||||
"name": "West Virginia",
|
|
||||||
"code": "WV"
|
|
||||||
},
|
|
||||||
"WI": {
|
|
||||||
"name": "Wisconsin",
|
|
||||||
"code": "WI"
|
|
||||||
},
|
|
||||||
"WY": {
|
|
||||||
"name": "Wyoming",
|
|
||||||
"code": "WY"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"UY": {
|
"UY": {
|
||||||
"flag": "🇺🇾",
|
"flag": "🇺🇾",
|
||||||
|
|
297
scripts/data/us-states.json
Normal file
297
scripts/data/us-states.json
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
{
|
||||||
|
"US-AL":
|
||||||
|
{
|
||||||
|
"name": "Alabama",
|
||||||
|
"code": "US-AL"
|
||||||
|
},
|
||||||
|
"US-AK":
|
||||||
|
{
|
||||||
|
"name": "Alaska",
|
||||||
|
"code": "US-AK"
|
||||||
|
},
|
||||||
|
"US-AS":
|
||||||
|
{
|
||||||
|
"name": "American Samoa",
|
||||||
|
"code": "US-AS"
|
||||||
|
},
|
||||||
|
"US-AZ":
|
||||||
|
{
|
||||||
|
"name": "Arizona",
|
||||||
|
"code": "US-AZ"
|
||||||
|
},
|
||||||
|
"US-AR":
|
||||||
|
{
|
||||||
|
"name": "Arkansas",
|
||||||
|
"code": "US-AR"
|
||||||
|
},
|
||||||
|
"US-CA":
|
||||||
|
{
|
||||||
|
"name": "California",
|
||||||
|
"code": "US-CA"
|
||||||
|
},
|
||||||
|
"US-CO":
|
||||||
|
{
|
||||||
|
"name": "Colorado",
|
||||||
|
"code": "US-CO"
|
||||||
|
},
|
||||||
|
"US-CT":
|
||||||
|
{
|
||||||
|
"name": "Connecticut",
|
||||||
|
"code": "US-CT"
|
||||||
|
},
|
||||||
|
"US-DE":
|
||||||
|
{
|
||||||
|
"name": "Delaware",
|
||||||
|
"code": "US-DE"
|
||||||
|
},
|
||||||
|
"US-DC":
|
||||||
|
{
|
||||||
|
"name": "District Of Columbia",
|
||||||
|
"code": "US-DC"
|
||||||
|
},
|
||||||
|
"US-FM":
|
||||||
|
{
|
||||||
|
"name": "Federated States Of Micronesia",
|
||||||
|
"code": "US-FM"
|
||||||
|
},
|
||||||
|
"US-FL":
|
||||||
|
{
|
||||||
|
"name": "Florida",
|
||||||
|
"code": "US-FL"
|
||||||
|
},
|
||||||
|
"US-GA":
|
||||||
|
{
|
||||||
|
"name": "Georgia",
|
||||||
|
"code": "US-GA"
|
||||||
|
},
|
||||||
|
"US-GU":
|
||||||
|
{
|
||||||
|
"name": "Guam",
|
||||||
|
"code": "US-GU"
|
||||||
|
},
|
||||||
|
"US-HI":
|
||||||
|
{
|
||||||
|
"name": "Hawaii",
|
||||||
|
"code": "US-HI"
|
||||||
|
},
|
||||||
|
"US-ID":
|
||||||
|
{
|
||||||
|
"name": "Idaho",
|
||||||
|
"code": "US-ID"
|
||||||
|
},
|
||||||
|
"US-IL":
|
||||||
|
{
|
||||||
|
"name": "Illinois",
|
||||||
|
"code": "US-IL"
|
||||||
|
},
|
||||||
|
"US-IN":
|
||||||
|
{
|
||||||
|
"name": "Indiana",
|
||||||
|
"code": "US-IN"
|
||||||
|
},
|
||||||
|
"US-IA":
|
||||||
|
{
|
||||||
|
"name": "Iowa",
|
||||||
|
"code": "US-IA"
|
||||||
|
},
|
||||||
|
"US-KS":
|
||||||
|
{
|
||||||
|
"name": "Kansas",
|
||||||
|
"code": "US-KS"
|
||||||
|
},
|
||||||
|
"US-KY":
|
||||||
|
{
|
||||||
|
"name": "Kentucky",
|
||||||
|
"code": "US-KY"
|
||||||
|
},
|
||||||
|
"US-LA":
|
||||||
|
{
|
||||||
|
"name": "Louisiana",
|
||||||
|
"code": "US-LA"
|
||||||
|
},
|
||||||
|
"US-ME":
|
||||||
|
{
|
||||||
|
"name": "Maine",
|
||||||
|
"code": "US-ME"
|
||||||
|
},
|
||||||
|
"US-MH":
|
||||||
|
{
|
||||||
|
"name": "Marshall Islands",
|
||||||
|
"code": "US-MH"
|
||||||
|
},
|
||||||
|
"US-MD":
|
||||||
|
{
|
||||||
|
"name": "Maryland",
|
||||||
|
"code": "US-MD"
|
||||||
|
},
|
||||||
|
"US-MA":
|
||||||
|
{
|
||||||
|
"name": "Massachusetts",
|
||||||
|
"code": "US-MA"
|
||||||
|
},
|
||||||
|
"US-MI":
|
||||||
|
{
|
||||||
|
"name": "Michigan",
|
||||||
|
"code": "US-MI"
|
||||||
|
},
|
||||||
|
"US-MN":
|
||||||
|
{
|
||||||
|
"name": "Minnesota",
|
||||||
|
"code": "US-MN"
|
||||||
|
},
|
||||||
|
"US-MS":
|
||||||
|
{
|
||||||
|
"name": "Mississippi",
|
||||||
|
"code": "US-MS"
|
||||||
|
},
|
||||||
|
"US-MO":
|
||||||
|
{
|
||||||
|
"name": "Missouri",
|
||||||
|
"code": "US-MO"
|
||||||
|
},
|
||||||
|
"US-MT":
|
||||||
|
{
|
||||||
|
"name": "Montana",
|
||||||
|
"code": "US-MT"
|
||||||
|
},
|
||||||
|
"US-NE":
|
||||||
|
{
|
||||||
|
"name": "Nebraska",
|
||||||
|
"code": "US-NE"
|
||||||
|
},
|
||||||
|
"US-NV":
|
||||||
|
{
|
||||||
|
"name": "Nevada",
|
||||||
|
"code": "US-NV"
|
||||||
|
},
|
||||||
|
"US-NH":
|
||||||
|
{
|
||||||
|
"name": "New Hampshire",
|
||||||
|
"code": "US-NH"
|
||||||
|
},
|
||||||
|
"US-NJ":
|
||||||
|
{
|
||||||
|
"name": "New Jersey",
|
||||||
|
"code": "US-NJ"
|
||||||
|
},
|
||||||
|
"US-NM":
|
||||||
|
{
|
||||||
|
"name": "New Mexico",
|
||||||
|
"code": "US-NM"
|
||||||
|
},
|
||||||
|
"US-NY":
|
||||||
|
{
|
||||||
|
"name": "New York",
|
||||||
|
"code": "US-NY"
|
||||||
|
},
|
||||||
|
"US-NC":
|
||||||
|
{
|
||||||
|
"name": "North Carolina",
|
||||||
|
"code": "US-NC"
|
||||||
|
},
|
||||||
|
"US-ND":
|
||||||
|
{
|
||||||
|
"name": "North Dakota",
|
||||||
|
"code": "US-ND"
|
||||||
|
},
|
||||||
|
"US-MP":
|
||||||
|
{
|
||||||
|
"name": "Northern Mariana Islands",
|
||||||
|
"code": "US-MP"
|
||||||
|
},
|
||||||
|
"US-OH":
|
||||||
|
{
|
||||||
|
"name": "Ohio",
|
||||||
|
"code": "US-OH"
|
||||||
|
},
|
||||||
|
"US-OK":
|
||||||
|
{
|
||||||
|
"name": "Oklahoma",
|
||||||
|
"code": "US-OK"
|
||||||
|
},
|
||||||
|
"US-OR":
|
||||||
|
{
|
||||||
|
"name": "Oregon",
|
||||||
|
"code": "US-OR"
|
||||||
|
},
|
||||||
|
"US-PW":
|
||||||
|
{
|
||||||
|
"name": "Palau",
|
||||||
|
"code": "US-PW"
|
||||||
|
},
|
||||||
|
"US-PA":
|
||||||
|
{
|
||||||
|
"name": "Pennsylvania",
|
||||||
|
"code": "US-PA"
|
||||||
|
},
|
||||||
|
"US-PR":
|
||||||
|
{
|
||||||
|
"name": "Puerto Rico",
|
||||||
|
"code": "US-PR"
|
||||||
|
},
|
||||||
|
"US-RI":
|
||||||
|
{
|
||||||
|
"name": "Rhode Island",
|
||||||
|
"code": "US-RI"
|
||||||
|
},
|
||||||
|
"US-SC":
|
||||||
|
{
|
||||||
|
"name": "South Carolina",
|
||||||
|
"code": "US-SC"
|
||||||
|
},
|
||||||
|
"US-SD":
|
||||||
|
{
|
||||||
|
"name": "South Dakota",
|
||||||
|
"code": "US-SD"
|
||||||
|
},
|
||||||
|
"US-TN":
|
||||||
|
{
|
||||||
|
"name": "Tennessee",
|
||||||
|
"code": "US-TN"
|
||||||
|
},
|
||||||
|
"US-TX":
|
||||||
|
{
|
||||||
|
"name": "Texas",
|
||||||
|
"code": "US-TX"
|
||||||
|
},
|
||||||
|
"US-UT":
|
||||||
|
{
|
||||||
|
"name": "Utah",
|
||||||
|
"code": "US-UT"
|
||||||
|
},
|
||||||
|
"US-VT":
|
||||||
|
{
|
||||||
|
"name": "Vermont",
|
||||||
|
"code": "US-VT"
|
||||||
|
},
|
||||||
|
"US-VI":
|
||||||
|
{
|
||||||
|
"name": "Virgin Islands",
|
||||||
|
"code": "US-VI"
|
||||||
|
},
|
||||||
|
"US-VA":
|
||||||
|
{
|
||||||
|
"name": "Virginia",
|
||||||
|
"code": "US-VA"
|
||||||
|
},
|
||||||
|
"US-WA":
|
||||||
|
{
|
||||||
|
"name": "Washington",
|
||||||
|
"code": "US-WA"
|
||||||
|
},
|
||||||
|
"US-WV":
|
||||||
|
{
|
||||||
|
"name": "West Virginia",
|
||||||
|
"code": "US-WV"
|
||||||
|
},
|
||||||
|
"US-WI":
|
||||||
|
{
|
||||||
|
"name": "Wisconsin",
|
||||||
|
"code": "US-WI"
|
||||||
|
},
|
||||||
|
"US-WY":
|
||||||
|
{
|
||||||
|
"name": "Wyoming",
|
||||||
|
"code": "US-WY"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,163 +0,0 @@
|
||||||
const parser = require('epg-parser')
|
|
||||||
const markdownInclude = require('markdown-include')
|
|
||||||
const countries = require('./countries.json')
|
|
||||||
const file = require('./file')
|
|
||||||
|
|
||||||
type EPG = {
|
|
||||||
channels: Channel[]
|
|
||||||
programs: Program[]
|
|
||||||
}
|
|
||||||
|
|
||||||
type Country = {
|
|
||||||
flag: string
|
|
||||||
name: string
|
|
||||||
code: string
|
|
||||||
states?: State[]
|
|
||||||
}
|
|
||||||
|
|
||||||
type State = {
|
|
||||||
name: string
|
|
||||||
code: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Channel = {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Program = {
|
|
||||||
channel: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Guide = {
|
|
||||||
name?: string
|
|
||||||
flag: string
|
|
||||||
url: string
|
|
||||||
channelCount: number
|
|
||||||
programCount: number
|
|
||||||
errorCount: number
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
console.log('Starting...')
|
|
||||||
file
|
|
||||||
.list('.gh-pages/guides/**/*.xml')
|
|
||||||
.then((files: string[]) => {
|
|
||||||
const guidesByCountry: Guide[] = []
|
|
||||||
const guidesByUSState: Guide[] = []
|
|
||||||
const guidesByCanadaProvince: Guide[] = []
|
|
||||||
files.forEach((filename: string) => {
|
|
||||||
console.log(`Loading '${filename}'...`)
|
|
||||||
const [_, code, site]: string[] = filename.match(
|
|
||||||
/\.gh\-pages\/guides\/(.*)\/(.*)\.epg\.xml/i
|
|
||||||
) || ['', '', '']
|
|
||||||
if (!code || !site) return
|
|
||||||
|
|
||||||
const xml: string = file.read(filename)
|
|
||||||
const epg: EPG = parser.parse(xml)
|
|
||||||
|
|
||||||
if (!epg.channels.length) return
|
|
||||||
|
|
||||||
const log = file.read(`logs/${site}_${code}.log`)
|
|
||||||
const errorCount = (log.match(/ERROR/gi) || []).length
|
|
||||||
|
|
||||||
const guide: Guide = {
|
|
||||||
flag: '',
|
|
||||||
url: filename.replace('.gh-pages', 'https://iptv-org.github.io/epg'),
|
|
||||||
channelCount: epg.channels.length,
|
|
||||||
programCount: epg.programs.length,
|
|
||||||
errorCount
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code.startsWith('us-')) {
|
|
||||||
const [_, stateCode] = code.split('-')
|
|
||||||
const state: State | undefined = countries['us']
|
|
||||||
? countries['us'].states[stateCode]
|
|
||||||
: undefined
|
|
||||||
if (!state) return
|
|
||||||
guide.name = state.name
|
|
||||||
guidesByUSState.push(guide)
|
|
||||||
} else if (code.startsWith('ca-')) {
|
|
||||||
const [_, provinceCode] = code.split('-')
|
|
||||||
const province: State | undefined = countries['ca']
|
|
||||||
? countries['ca'].states[provinceCode]
|
|
||||||
: undefined
|
|
||||||
if (!province) return
|
|
||||||
guide.name = province.name
|
|
||||||
guidesByCanadaProvince.push(guide)
|
|
||||||
} else {
|
|
||||||
const [countryCode] = code.split('-')
|
|
||||||
const country: Country | undefined = countries[countryCode]
|
|
||||||
if (!country) return
|
|
||||||
guide.flag = country.flag
|
|
||||||
guide.name = country.name
|
|
||||||
guidesByCountry.push(guide)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log('Generating country table...')
|
|
||||||
const countryTable = generateTable(guidesByCountry, ['Country', 'Channels', 'EPG', 'Status'])
|
|
||||||
file.write('.readme/_countries.md', countryTable)
|
|
||||||
|
|
||||||
console.log('Generating US states table...')
|
|
||||||
const usStatesTable = generateTable(guidesByUSState, ['State', 'Channels', 'EPG', 'Status'])
|
|
||||||
file.write('.readme/_us-states.md', usStatesTable)
|
|
||||||
|
|
||||||
console.log('Generating Canada provinces table...')
|
|
||||||
const caProvincesTable = generateTable(guidesByCanadaProvince, [
|
|
||||||
'Province',
|
|
||||||
'Channels',
|
|
||||||
'EPG',
|
|
||||||
'Status'
|
|
||||||
])
|
|
||||||
file.write('.readme/_ca-provinces.md', caProvincesTable)
|
|
||||||
|
|
||||||
console.log('Updating README.md...')
|
|
||||||
markdownInclude.compileFiles('.readme/config.json')
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
console.log('Finish')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateTable(guides: Guide[], header: string[]) {
|
|
||||||
guides = sortGuides(guides)
|
|
||||||
|
|
||||||
let output = '<table>\n'
|
|
||||||
|
|
||||||
output += '\t<thead>\n\t\t<tr>'
|
|
||||||
for (let column of header) {
|
|
||||||
output += `<th align="left">${column}</th>`
|
|
||||||
}
|
|
||||||
output += '</tr>\n\t</thead>\n'
|
|
||||||
|
|
||||||
output += '\t<tbody>\n'
|
|
||||||
for (let guide of guides) {
|
|
||||||
const size = guides.filter((g: Guide) => g.name === guide.name).length
|
|
||||||
if (!guide.name) continue
|
|
||||||
const name = `${guide.flag} ${guide.name}`
|
|
||||||
let root = output.indexOf(name) === -1
|
|
||||||
const rowspan = root && size > 1 ? ` rowspan="${size}"` : ''
|
|
||||||
let status = '🟢'
|
|
||||||
if (guide.programCount === 0) status = '🔴'
|
|
||||||
else if (guide.errorCount > 0) status = '🟡'
|
|
||||||
const cell1 = root ? `<td align="left" valign="top" nowrap${rowspan}>${name}</td>` : ''
|
|
||||||
output += `\t\t<tr>${cell1}<td align="right" nowrap>${guide.channelCount}</td><td align="left" nowrap><code>${guide.url}</code></td><td align="center">${status}</td></tr>\n`
|
|
||||||
}
|
|
||||||
output += '\t</tbody>\n'
|
|
||||||
|
|
||||||
output += '</table>'
|
|
||||||
|
|
||||||
return output
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortGuides(guides: Guide[]): Guide[] {
|
|
||||||
return guides.sort((a, b) => {
|
|
||||||
var nameA = a.name ? a.name.toLowerCase() : ''
|
|
||||||
var nameB = b.name ? b.name.toLowerCase() : ''
|
|
||||||
if (nameA < nameB) return -1
|
|
||||||
if (nameA > nameB) return 1
|
|
||||||
return b.channelCount - a.channelCount
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
90
tests/__data__/expected/readme.md
Normal file
90
tests/__data__/expected/readme.md
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# EPG
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
EPG (Electronic Program Guide) for thousands of TV channels collected from different sources.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To load a program guide, all you need to do is copy the link to one or more of the guides from the list below and paste it into your favorite player.
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th align="left">Country</th><th align="left">Channels</th><th align="left">EPG</th><th align="left">Status</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td align="left" valign="top" nowrap rowspan="2">🇺🇸 United States</td><td align="right">372</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/us/tvtv.us.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
<tr><td align="right">74</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/us/magticom.ge.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
<tr><td align="left" valign="top" nowrap>🇿🇦 South Africa</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/za/dstv.com.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
### US States
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th align="left">State</th><th align="left">Channels</th><th align="left">EPG</th><th align="left">Status</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td align="left" valign="top" nowrap rowspan="3">Puerto Rico</td><td align="right">14</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/us-pr/tvtv.us.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
<tr><td align="right">7</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/us-pr/gatotv.com.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
<tr><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/us-pr/directv.com.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
### Provinces of Canada
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th align="left">Province</th><th align="left">Channels</th><th align="left">EPG</th><th align="left">Status</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td align="left" valign="top" nowrap>Newfoundland and Labrador</td><td align="right">1</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/ca-nl/tvtv.us.epg.xml</code></td><td align="center">✓</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
## List of supported channels
|
||||||
|
|
||||||
|
https://iptv-org.github.io/epg/index.html
|
||||||
|
|
||||||
|
## For Developers
|
||||||
|
|
||||||
|
You can also get a list of all available channels and their codes in JSON format by sending a GET request to:
|
||||||
|
|
||||||
|
```
|
||||||
|
https://iptv-org.github.io/epg/api/channels.json
|
||||||
|
```
|
||||||
|
|
||||||
|
If successful, you should get the following response:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Expand</summary>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
...
|
||||||
|
{
|
||||||
|
"id": "CNNUSA.us",
|
||||||
|
"name": [
|
||||||
|
"CNN USA"
|
||||||
|
],
|
||||||
|
"logo": "https://cdn.tvpassport.com/image/station/100x100/cnn.png",
|
||||||
|
"country": "US",
|
||||||
|
"guides": [
|
||||||
|
"https://iptv-org.github.io/epg/guides/tvtv.us.guide.xml",
|
||||||
|
...
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
If you find a bug or want to contribute to the code or documentation, you can help by submitting an [issue](https://github.com/iptv-org/epg/issues) or a [pull request](https://github.com/iptv-org/epg/pulls).
|
4
tests/__data__/input/readme.json
Normal file
4
tests/__data__/input/readme.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"build" : "tests/__data__/output/readme.md",
|
||||||
|
"files" : ["./.readme/template.md"]
|
||||||
|
}
|
28
tests/commands/update-readme.test.js
Normal file
28
tests/commands/update-readme.test.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.rmdirSync('tests/__data__/output', { recursive: true })
|
||||||
|
fs.mkdirSync('tests/__data__/output')
|
||||||
|
|
||||||
|
execSync(
|
||||||
|
'LOGS_DIR=tests/__data__/input/logs node scripts/commands/update-readme.js --config=tests/__data__/input/readme.json',
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can update readme.md', () => {
|
||||||
|
const output = content('tests/__data__/output/readme.md')
|
||||||
|
const expected = content('tests/__data__/expected/readme.md')
|
||||||
|
|
||||||
|
expect(output).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
function content(filepath) {
|
||||||
|
const data = fs.readFileSync(path.resolve(filepath), {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
return JSON.stringify(data)
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue