Merge pull request #484 from iptv-org/update-update-readme-js

Update update-readme.js
This commit is contained in:
Aleksandr Statciuk 2022-02-03 06:37:15 +03:00 committed by GitHub
commit fd02200476
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 79 additions and 137 deletions

View file

@ -3,10 +3,11 @@
"scripts": {
"lint": "node scripts/commands/lint.js",
"validate": "node scripts/commands/validate.js",
"act": "act workflow_dispatch",
"test": "npx jest --runInBand",
"test:commands": "npx jest --runInBand -- commands",
"test:sites": "npx jest --runInBand -- sites"
"test:sites": "npx jest --runInBand -- sites",
"act": "act workflow_dispatch",
"update-readme": "node scripts/commands/update-readme.js"
},
"private": true,
"author": "Arhey",

View file

@ -1,37 +1,44 @@
const { file, markdown, parser, logger, api } = require('../core')
const { file, markdown, parser, logger, api, table } = require('../core')
const { program } = require('commander')
const _ = require('lodash')
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
const CHANNELS_PATH = process.env.CHANNELS_PATH || 'sites/**/*.channels.xml'
const options = program
.option('-c, --config <config>', 'Set path to config file', '.readme/config.json')
.parse(process.argv)
.opts()
const statuses = {
0: '🟢',
1: '🔴'
}
async function main() {
await api.countries.load()
await api.subdivisions.load()
const records = await getLogRecords()
await generateCountriesTable(records)
await generateUSStatesTable(records)
await generateCanadaProvincesTable(records)
const files = await file.list(CHANNELS_PATH)
const items = []
for (const filepath of files) {
const { site, channels } = await parser.parseChannels(filepath)
const filename = file.basename(filepath)
const [__, suffix] = filename.match(/\_(.*)\.channels\.xml$/) || [null, null]
const [code] = suffix.split('-')
items.push({
code,
site,
count: channels.length,
group: `${suffix}/${site}`
})
}
await generateCountriesTable(items)
await updateReadme()
}
main()
async function generateCountriesTable(items = []) {
logger.info('Generating countries table...')
logger.info('generating countries table...')
let rows = []
for (const item of items) {
const country = api.countries.find({ code: item.code })
const country = api.countries.find({ code: item.code.toUpperCase() })
if (!country) continue
rows.push({
@ -39,70 +46,25 @@ async function generateCountriesTable(items = []) {
name: country.name,
channels: item.count,
epg: `<code>https://iptv-org.github.io/epg/guides/${item.group}.epg.xml</code>`,
status: statuses[item.status]
status: `<a href="https://github.com/iptv-org/epg/actions/workflows/${item.site}.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/${item.site}.yml/badge.svg" alt="${item.site}" style="max-width: 100%;"></a>`
})
}
rows = _.orderBy(rows, ['name', 'channels'], ['asc', 'desc'])
rows = _.groupBy(rows, 'name')
const table = markdown.createTable(rows, ['Country', 'Channels', 'EPG', 'Status'])
const output = table.create(rows, [
'Country',
'Channels',
'EPG',
'Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
])
await file.create('./.readme/_countries.md', table)
}
async function generateUSStatesTable(items = []) {
logger.info('Generating US states table...')
let rows = []
for (const item of items) {
if (!item.code.startsWith('US-')) continue
const state = api.subdivisions.find({ code: item.code })
if (!state) continue
rows.push({
name: state.name,
channels: item.count,
epg: `<code>https://iptv-org.github.io/epg/guides/${item.group}.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(items = []) {
logger.info('Generating Canada provinces table...')
let rows = []
for (const item of items) {
if (!item.code.startsWith('CA-')) continue
const province = api.subdivisions.find({ code: item.code })
if (!province) continue
rows.push({
name: province.name,
channels: item.count,
epg: `<code>https://iptv-org.github.io/epg/guides/${item.group}.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)
await file.create('./.readme/_countries.md', output)
}
async function updateReadme() {
logger.info('Updating README.md...')
logger.info('updating readme.md...')
const config = require(file.resolve(options.config))
await file.createDir(file.dirname(config.build))

View file

@ -6,3 +6,4 @@ exports.timer = require('./timer')
exports.markdown = require('./markdown')
exports.api = require('./api')
exports.date = require('./date')
exports.table = require('./table')

View file

@ -3,38 +3,6 @@ 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) {
const name = item.flag ? `${item.flag} ${item.name}` : item.name
output += `<td align="left" valign="top" nowrap${rowspan}>${name}</td>`
}
output += `<td align="right">${item.channels}</td>`
output += `<td align="left" nowrap>${item.epg}</td>`
output += `<td align="center" nowrap>${item.status}</td>`
output += '</tr>\n'
}
}
output += ' </tbody>\n'
output += '</table>'
return output
}
markdown.compile = function (filepath) {
markdownInclude.compileFiles(file.resolve(filepath))
}

35
scripts/core/table.js Normal file
View file

@ -0,0 +1,35 @@
const table = {}
table.create = function (data, cols) {
let output = '<table>\n'
output += ' <thead>\n <tr>'
for (let column of cols) {
output += `<th>${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) {
const name = item.flag ? `${item.flag}&nbsp;${item.name}` : item.name
output += `<td valign="top"${rowspan}>${name}</td>`
}
output += `<td align="right">${item.channels}</td>`
output += `<td nowrap>${item.epg}</td>`
output += `<td>${item.status}</td>`
output += '</tr>\n'
}
}
output += ' </tbody>\n'
output += '</table>'
return output
}
module.exports = table

View file

@ -1,2 +1,2 @@
{"channel":{"lang":"ru","xmltv_id":"CNNInternationalEurope.us","site_id":"140","site":"example.com"},"configPath":"tests/__data__/input/sites/example.com.config.js","date":"2022-01-30T00:00:00.000Z","groups":["ca-nl/example.com"],"error":null,"cluster_id":1,"_id":"TYDwYLsrkmPtTLT2"}
{"channel":{"lang":"ru","xmltv_id":"CNNInternationalEurope.us","site_id":"140","site":"example.com"},"configPath":"tests/__data__/input/sites/example.com.config.js","date":"2022-01-31T00:00:00.000Z","groups":["ca-nl/example.com"],"error":null,"cluster_id":1,"_id":"98cKRthEhMmKEnwx"}
{"channel":{"lang":"ru","xmltv_id":"CNNInternationalEurope.us","site_id":"140","site":"example.com"},"date":"2022-02-03T00:00:00.000Z","configPath":"tests/__data__/input/sites/example.com.config.js","groups":["ca/example.com"],"error":null,"cluster_id":1,"_id":"vOpwztzvJ5pFSVws"}
{"channel":{"lang":"ru","xmltv_id":"CNNInternationalEurope.us","site_id":"140","site":"example.com"},"date":"2022-02-04T00:00:00.000Z","configPath":"tests/__data__/input/sites/example.com.config.js","groups":["ca/example.com"],"error":null,"cluster_id":1,"_id":"sP2A0zQSOoVg0BS1"}

View file

@ -1,7 +1,5 @@
# EPG
![auto-update](https://github.com/iptv-org/epg/actions/workflows/auto-update.yml/badge.svg)
EPG (Electronic Program Guide) for thousands of TV channels collected from different sources.
## Usage
@ -11,40 +9,17 @@ To load a program guide, all you need to do is copy the link to one or more of t
<!-- 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>
<tr><th>Country</th><th>Channels</th><th>EPG</th><th>Status&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th></tr>
</thead>
<tbody>
<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" nowrap>🟢</td></tr>
<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" nowrap>🟢</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" nowrap>🟢</td></tr>
<tr><td valign="top">🇨🇦&nbsp;Canada</td><td align="right">2</td><td nowrap><code>https://iptv-org.github.io/epg/guides/ca/example.com.epg.xml</code></td><td><a href="https://github.com/iptv-org/epg/actions/workflows/example.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/example.com.yml/badge.svg" alt="example.com" style="max-width: 100%;"></a></td></tr>
<tr><td valign="top">🇪🇪&nbsp;Estonia</td><td align="right">1</td><td nowrap><code>https://iptv-org.github.io/epg/guides/ee-en/ignore.com.epg.xml</code></td><td><a href="https://github.com/iptv-org/epg/actions/workflows/ignore.com.yml"><img src="https://github.com/iptv-org/epg/actions/workflows/ignore.com.yml/badge.svg" alt="ignore.com" style="max-width: 100%;"></a></td></tr>
</tbody>
</table>
### US States
## EPG Codes
<!-- 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" nowrap>🟢</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" nowrap>🔴</td></tr>
<tr><td align="right">0</td><td align="left" nowrap><code>https://iptv-org.github.io/epg/guides/us-pr/directv.com.epg.xml</code></td><td align="center" nowrap>🟢</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" nowrap>🟢</td></tr>
</tbody>
</table>
📋&nbsp;&nbsp;[iptv-org.github.io](https://iptv-org.github.io/)
## API

View file

@ -36,8 +36,8 @@ it('can create queue', () => {
})
it('can log errors', () => {
let output = content('tests/__data__/output/logs/errors/ca-nl/example.com.log')
let expected = content('tests/__data__/expected/logs/errors/ca-nl/example.com.log')
let output = content('tests/__data__/output/logs/errors/ca/example.com.log')
let expected = content('tests/__data__/expected/logs/errors/ca/example.com.log')
expect(output).toEqual(expected)
})

View file

@ -7,7 +7,7 @@ beforeEach(() => {
fs.mkdirSync('tests/__data__/output')
const stdout = execSync(
'LOGS_DIR=tests/__data__/input/logs DATA_DIR=tests/__data__/input/data node scripts/commands/update-readme.js --config=tests/__data__/input/_readme.json',
'CHANNELS_PATH=tests/__data__/input/sites/*.channels.xml DATA_DIR=tests/__data__/input/data node scripts/commands/update-readme.js --config=tests/__data__/input/_readme.json',
{ encoding: 'utf8' }
)
})