Update update-readme.js

This commit is contained in:
Aleksandr Statciuk 2022-01-14 23:57:03 +03:00
parent 61dbd2a1b3
commit cf0f2472d1
11 changed files with 653 additions and 461 deletions

View 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`)
}

View file

@ -4,3 +4,4 @@ exports.file = require('./file')
exports.parser = require('./parser')
exports.timer = require('./timer')
exports.xml = require('./xml')
exports.markdown = require('./markdown')

39
scripts/core/markdown.js Normal file
View 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

View 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"
}
}

View file

@ -157,61 +157,7 @@
"CA": {
"flag": "🇨🇦",
"name": "Canada",
"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"
}
}
"code": "CA"
},
"CV": {
"flag": "🇨🇻",
@ -1086,245 +1032,7 @@
"US": {
"flag": "🇺🇸",
"name": "United States",
"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"
}
}
"code": "US"
},
"UY": {
"flag": "🇺🇾",

297
scripts/data/us-states.json Normal file
View 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"
}
}

View file

@ -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}&nbsp;${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()