mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-10 09:00:07 -04:00
Merge branch 'patch-1'
This commit is contained in:
commit
73c9c005e5
52 changed files with 670 additions and 572 deletions
22
.github/workflows/_check.yml
vendored
22
.github/workflows/_check.yml
vendored
|
@ -10,12 +10,22 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
- name: Download channels from API
|
- name: Download data from API
|
||||||
run: |
|
run: |
|
||||||
mkdir -p scripts/data
|
mkdir -p scripts/data
|
||||||
curl -L -o scripts/data/channels.json https://iptv-org.github.io/api/channels.json
|
curl -L -o scripts/data/channels.json https://iptv-org.github.io/api/channels.json
|
||||||
- id: files
|
- uses: actions/setup-node@v2
|
||||||
uses: jitterbit/get-changed-files@v1
|
if: ${{ !env.ACT && steps.files.outputs.any_changed == 'true' }}
|
||||||
- run: npm install
|
with:
|
||||||
- run: npm run lint -- ${{ steps.files.outputs.added_modified }}
|
node-version: '14'
|
||||||
- run: npm run validate -- ${{ steps.files.outputs.added_modified }}
|
cache: 'npm'
|
||||||
|
- uses: tj-actions/changed-files@v12.2
|
||||||
|
id: files
|
||||||
|
with:
|
||||||
|
files: 'sites'
|
||||||
|
- name: validate
|
||||||
|
if: steps.files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run channels:lint -- ${{ steps.files.outputs.all_changed_files }}
|
||||||
|
npm run channels:validate -- ${{ steps.files.outputs.all_changed_files }}
|
||||||
|
|
9
.github/workflows/_load.yml
vendored
9
.github/workflows/_load.yml
vendored
|
@ -14,7 +14,6 @@ jobs:
|
||||||
load:
|
load:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- run: echo running on branch ${GITHUB_REF##*/}
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Download data from API
|
- name: Download data from API
|
||||||
run: |
|
run: |
|
||||||
|
@ -22,10 +21,10 @@ jobs:
|
||||||
curl -L -o scripts/data/channels.json https://iptv-org.github.io/api/channels.json
|
curl -L -o scripts/data/channels.json https://iptv-org.github.io/api/channels.json
|
||||||
- uses: FedericoCarboni/setup-ffmpeg@v1
|
- uses: FedericoCarboni/setup-ffmpeg@v1
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: CHANNELS_PATH=sites/${{inputs.site}}/*.channels.xml node scripts/commands/create-queue.js --max-clusters=1 --days=2
|
- run: CHANNELS_PATH=sites/${{inputs.site}}/*.channels.xml npm run queue:create -- --max-clusters=1 --days=2
|
||||||
- run: NODE_OPTIONS=--insecure-http-parser node scripts/commands/load-cluster.js --timeout=30000 --cluster-id=1
|
- run: NODE_OPTIONS=--insecure-http-parser npm run cluster:load -- --timeout=30000 --cluster-id=1
|
||||||
- run: node scripts/commands/save-results.js
|
- run: npm run programs:save
|
||||||
- run: node scripts/commands/update-guides.js
|
- run: npm run guides:update
|
||||||
- uses: tibdex/github-app-token@v1
|
- uses: tibdex/github-app-token@v1
|
||||||
if: ${{ !env.ACT }}
|
if: ${{ !env.ACT }}
|
||||||
id: create-app-token
|
id: create-app-token
|
||||||
|
|
2
.github/workflows/_update-api.yml
vendored
2
.github/workflows/_update-api.yml
vendored
|
@ -9,7 +9,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: node scripts/commands/update-api.js
|
- run: npm run api:update
|
||||||
- uses: tibdex/github-app-token@v1
|
- uses: tibdex/github-app-token@v1
|
||||||
if: ${{ !env.ACT }}
|
if: ${{ !env.ACT }}
|
||||||
id: create-app-token
|
id: create-app-token
|
||||||
|
|
52
.github/workflows/_update-readme.yml
vendored
Normal file
52
.github/workflows/_update-readme.yml
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
name: _update-readme
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 12 * * *'
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: echo "::set-output name=branch_name::$(date +'bot/auto-update-%s')"
|
||||||
|
id: create-branch-name
|
||||||
|
- run: git config user.name 'iptv-bot[bot]'
|
||||||
|
- run: git config user.email '84861620+iptv-bot[bot]@users.noreply.github.com'
|
||||||
|
- run: git checkout -b ${{ steps.create-branch-name.outputs.branch_name }}
|
||||||
|
- name: Download data from API
|
||||||
|
run: |
|
||||||
|
mkdir -p scripts/data
|
||||||
|
curl -L -o scripts/data/countries.json https://iptv-org.github.io/api/countries.json
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run readme:update
|
||||||
|
- name: Commit Changes
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
run: |
|
||||||
|
git add README.md
|
||||||
|
git commit -m "[Bot] Update README.md"
|
||||||
|
git status
|
||||||
|
git push -u origin ${{ steps.create-branch-name.outputs.branch_name }}
|
||||||
|
- uses: tibdex/github-app-token@v1
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
id: create-app-token
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.APP_ID }}
|
||||||
|
private_key: ${{ secrets.APP_PRIVATE_KEY }}
|
||||||
|
- uses: repo-sync/pull-request@v2
|
||||||
|
if: ${{ !env.ACT && github.ref == 'refs/heads/master' }}
|
||||||
|
id: pull-request
|
||||||
|
with:
|
||||||
|
github_token: ${{ steps.create-app-token.outputs.token }}
|
||||||
|
source_branch: ${{ steps.create-branch-name.outputs.branch_name }}
|
||||||
|
destination_branch: 'master'
|
||||||
|
pr_title: '[Bot] Daily update'
|
||||||
|
pr_body: |
|
||||||
|
This pull request is created via [update-readme][1] workflow.
|
||||||
|
|
||||||
|
[1]: https://github.com/iptv-org/epg/actions/runs/${{ github.run_id }}
|
||||||
|
- uses: juliangruber/merge-pull-request-action@v1
|
||||||
|
if: ${{ !env.ACT && github.ref == 'refs/heads/master' }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.PAT }}
|
||||||
|
number: ${{ steps.pull-request.outputs.pr_number }}
|
||||||
|
method: squash
|
|
@ -17,10 +17,6 @@ The API documentation can be found in the [iptv-org/api](https://github.com/iptv
|
||||||
|
|
||||||
Links to other useful IPTV-related resources can be found in the [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv) repository.
|
Links to other useful IPTV-related resources can be found in the [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv) repository.
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository.
|
|
||||||
|
|
||||||
## Contribution
|
## 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).
|
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).
|
||||||
|
|
74
package-lock.json
generated
74
package-lock.json
generated
|
@ -16,6 +16,7 @@
|
||||||
"epg-grabber": "^0.20.0",
|
"epg-grabber": "^0.20.0",
|
||||||
"epg-parser": "^0.1.6",
|
"epg-parser": "^0.1.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
|
"fs-extra": "^10.0.1",
|
||||||
"glob": "^7.2.0",
|
"glob": "^7.2.0",
|
||||||
"iconv-lite": "^0.4.24",
|
"iconv-lite": "^0.4.24",
|
||||||
"jest": "^27.3.1",
|
"jest": "^27.3.1",
|
||||||
|
@ -2377,6 +2378,27 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fs-extra": {
|
||||||
|
"version": "10.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
|
||||||
|
"integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fs-extra/node_modules/universalify": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs-minipass": {
|
"node_modules/fs-minipass": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
||||||
|
@ -3614,6 +3636,25 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsonfile": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"graceful-fs": "^4.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jsonfile/node_modules/universalify": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/keyv": {
|
"node_modules/keyv": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz",
|
||||||
|
@ -7382,6 +7423,23 @@
|
||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "10.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
|
||||||
|
"integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^6.0.1",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"universalify": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"fs-minipass": {
|
"fs-minipass": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
||||||
|
@ -8308,6 +8366,22 @@
|
||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"jsonfile": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.6",
|
||||||
|
"universalify": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"universalify": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"keyv": {
|
"keyv": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz",
|
||||||
|
|
17
package.json
17
package.json
|
@ -1,13 +1,21 @@
|
||||||
{
|
{
|
||||||
"name": "epg",
|
"name": "epg",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "node scripts/commands/lint.js",
|
"channels:validate": "node scripts/commands/channels/validate.js",
|
||||||
"validate": "node scripts/commands/validate.js",
|
"channels:lint": "node scripts/commands/channels/lint.js",
|
||||||
|
"channels:parse": "node scripts/commands/channels/parse.js",
|
||||||
|
"queue:create": "node scripts/commands/queue/create.js",
|
||||||
|
"cluster:load": "node scripts/commands/cluster/load.js",
|
||||||
|
"programs:save": "node scripts/commands/programs/save.js",
|
||||||
|
"guides:update": "node scripts/commands/guides/update.js",
|
||||||
|
"api:update": "node scripts/commands/api/update.js",
|
||||||
|
"readme:update": "node scripts/commands/readme/update.js",
|
||||||
"test": "npx jest --runInBand",
|
"test": "npx jest --runInBand",
|
||||||
"test:commands": "npx jest --runInBand -- commands",
|
"test:commands": "npx jest --runInBand -- commands",
|
||||||
"test:sites": "npx jest --runInBand -- sites",
|
"test:sites": "npx jest --runInBand -- sites",
|
||||||
"act": "act workflow_dispatch",
|
"act:check": "act workflow_dispatch -W .github/workflows/_check.yml",
|
||||||
"update-readme": "node scripts/commands/update-readme.js"
|
"act:update-readme": "act workflow_dispatch -W .github/workflows/_update-readme.yml",
|
||||||
|
"act:update-api": "act workflow_dispatch -W .github/workflows/_update-api.yml"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"author": "Arhey",
|
"author": "Arhey",
|
||||||
|
@ -25,6 +33,7 @@
|
||||||
"epg-grabber": "^0.20.0",
|
"epg-grabber": "^0.20.0",
|
||||||
"epg-parser": "^0.1.6",
|
"epg-parser": "^0.1.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
|
"fs-extra": "^10.0.1",
|
||||||
"glob": "^7.2.0",
|
"glob": "^7.2.0",
|
||||||
"iconv-lite": "^0.4.24",
|
"iconv-lite": "^0.4.24",
|
||||||
"jest": "^27.3.1",
|
"jest": "^27.3.1",
|
||||||
|
|
42
scripts/commands/api/update.js
Normal file
42
scripts/commands/api/update.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
const { file, parser, logger } = require('../../core')
|
||||||
|
const { program } = require('commander')
|
||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
const CHANNELS_PATH = process.env.CHANNELS_PATH || 'sites/**/*.channels.xml'
|
||||||
|
const OUTPUT_DIR = process.env.OUTPUT_DIR || '.gh-pages/api'
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
let guides = []
|
||||||
|
|
||||||
|
try {
|
||||||
|
const files = await file.list(CHANNELS_PATH)
|
||||||
|
for (const filepath of files) {
|
||||||
|
const { site, channels } = await parser.parseChannels(filepath)
|
||||||
|
const dir = file.dirname(filepath)
|
||||||
|
const config = require(file.resolve(`${dir}/${site}.config.js`))
|
||||||
|
if (config.ignore) continue
|
||||||
|
|
||||||
|
const filename = file.basename(filepath)
|
||||||
|
const [__, suffix] = filename.match(/\_(.*)\.channels\.xml$/) || [null, null]
|
||||||
|
|
||||||
|
for (const channel of channels) {
|
||||||
|
guides.push({
|
||||||
|
channel: channel.xmltv_id,
|
||||||
|
site,
|
||||||
|
lang: channel.lang,
|
||||||
|
url: `https://iptv-org.github.io/epg/guides/${suffix}/${site}.epg.xml`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
guides = _.sortBy(guides, 'channel')
|
||||||
|
|
||||||
|
const outputFilepath = `${OUTPUT_DIR}/guides.json`
|
||||||
|
await file.create(outputFilepath, JSON.stringify(guides))
|
||||||
|
logger.info(`saved to "${outputFilepath}"...`)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
|
@ -1,7 +1,7 @@
|
||||||
const chalk = require('chalk')
|
const chalk = require('chalk')
|
||||||
const libxml = require('libxmljs')
|
const libxml = require('libxmljs')
|
||||||
const { program } = require('commander')
|
const { program } = require('commander')
|
||||||
const { logger, file } = require('../core')
|
const { logger, file } = require('../../core')
|
||||||
|
|
||||||
const xsd = `<?xml version="1.0" encoding="UTF-8"?>
|
const xsd = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
43
scripts/commands/channels/parse.js
Normal file
43
scripts/commands/channels/parse.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
const { logger, file, xml } = require('../../core')
|
||||||
|
const { Command } = require('commander')
|
||||||
|
const path = require('path')
|
||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
const program = new Command()
|
||||||
|
program
|
||||||
|
.requiredOption('-c, --config <config>', 'Config file')
|
||||||
|
.option('-s, --set [args...]', 'Set custom arguments', [])
|
||||||
|
.option('-o, --output <output>', 'Output file')
|
||||||
|
.parse(process.argv)
|
||||||
|
|
||||||
|
const options = program.opts()
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const config = require(path.resolve(options.config))
|
||||||
|
const args = {}
|
||||||
|
options.set.forEach(arg => {
|
||||||
|
const [key, value] = arg.split(':')
|
||||||
|
args[key] = value
|
||||||
|
})
|
||||||
|
|
||||||
|
let channels = config.channels(args)
|
||||||
|
if (isPromise(channels)) {
|
||||||
|
channels = await channels
|
||||||
|
}
|
||||||
|
channels = _.sortBy(channels, 'xmltv_id')
|
||||||
|
|
||||||
|
const dir = file.dirname(options.config)
|
||||||
|
const outputFilepath = options.output || `${dir}/${config.site}.channels.xml`
|
||||||
|
|
||||||
|
const output = xml.create(channels, config.site)
|
||||||
|
|
||||||
|
await file.write(outputFilepath, output)
|
||||||
|
|
||||||
|
logger.info(`File '${output}' successfully saved`)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
function isPromise(promise) {
|
||||||
|
return !!promise && typeof promise.then === 'function'
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
const { parser, logger, api } = require('../core')
|
const { parser, logger, api } = require('../../core')
|
||||||
const { program } = require('commander')
|
const { program } = require('commander')
|
||||||
const chalk = require('chalk')
|
const chalk = require('chalk')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const grabber = require('epg-grabber')
|
const grabber = require('epg-grabber')
|
||||||
const { program } = require('commander')
|
const { program } = require('commander')
|
||||||
const { db, logger, timer, file, parser } = require('../core')
|
const { db, logger, timer, file, parser } = require('../../core')
|
||||||
|
|
||||||
const options = program
|
const options = program
|
||||||
.requiredOption('-c, --cluster-id <cluster-id>', 'The ID of cluster to load', parser.parseNumber)
|
.requiredOption('-c, --cluster-id <cluster-id>', 'The ID of cluster to load', parser.parseNumber)
|
||||||
|
@ -16,7 +16,7 @@ const options = program
|
||||||
.opts()
|
.opts()
|
||||||
|
|
||||||
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
|
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
|
||||||
const CLUSTER_PATH = `${LOGS_DIR}/load-cluster/cluster_${options.clusterId}.log`
|
const CLUSTER_PATH = `${LOGS_DIR}/cluster/load/cluster_${options.clusterId}.log`
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
logger.info('Starting...')
|
logger.info('Starting...')
|
|
@ -1,16 +0,0 @@
|
||||||
const { logger, db } = require('../core')
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
await db.queue.load()
|
|
||||||
const docs = await db.queue.find({}).sort({ cluster_id: 1 })
|
|
||||||
const cluster_id = docs.reduce((acc, curr) => {
|
|
||||||
if (!acc.includes(curr.cluster_id)) acc.push(curr.cluster_id)
|
|
||||||
return acc
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const matrix = { cluster_id }
|
|
||||||
const output = `::set-output name=matrix::${JSON.stringify(matrix)}`
|
|
||||||
logger.info(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
76
scripts/commands/guides/update.js
Normal file
76
scripts/commands/guides/update.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
const { db, logger, file, api } = require('../../core')
|
||||||
|
const grabber = require('epg-grabber')
|
||||||
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
const PUBLIC_DIR = process.env.PUBLIC_DIR || '.gh-pages'
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
logger.info(`Generating guides/...`)
|
||||||
|
|
||||||
|
logger.info('Loading "database/programs.db"...')
|
||||||
|
await db.programs.load()
|
||||||
|
await api.channels.load()
|
||||||
|
|
||||||
|
const grouped = groupByGroup(await loadQueue())
|
||||||
|
for (const key in grouped) {
|
||||||
|
let channels = {}
|
||||||
|
let programs = []
|
||||||
|
for (const item of grouped[key]) {
|
||||||
|
if (item.error) continue
|
||||||
|
|
||||||
|
const itemPrograms = await loadProgramsForItem(item)
|
||||||
|
programs = programs.concat(itemPrograms)
|
||||||
|
|
||||||
|
if (channels[item.channel.xmltv_id]) continue
|
||||||
|
const channel = api.channels.find({ id: item.channel.xmltv_id })
|
||||||
|
if (channel) {
|
||||||
|
channels[channel.id] = {
|
||||||
|
xmltv_id: channel.id,
|
||||||
|
name: item.channel.display_name,
|
||||||
|
logo: channel.logo,
|
||||||
|
site: item.channel.site
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
channels = Object.values(channels)
|
||||||
|
channels = _.sortBy(channels, 'xmltv_id')
|
||||||
|
programs = _.sortBy(programs, ['channel', 'start'])
|
||||||
|
|
||||||
|
const filepath = `${PUBLIC_DIR}/guides/${key}.epg.xml`
|
||||||
|
logger.info(`Creating "${filepath}"...`)
|
||||||
|
const output = grabber.convertToXMLTV({ channels, programs })
|
||||||
|
await file.create(filepath, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`Done`)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
function groupByGroup(items = []) {
|
||||||
|
const groups = {}
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
item.groups.forEach(key => {
|
||||||
|
if (!groups[key]) {
|
||||||
|
groups[key] = []
|
||||||
|
}
|
||||||
|
|
||||||
|
groups[key].push(item)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return groups
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadQueue() {
|
||||||
|
logger.info('Loading queue...')
|
||||||
|
|
||||||
|
await db.queue.load()
|
||||||
|
|
||||||
|
return await db.queue.find({}).sort({ xmltv_id: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadProgramsForItem(item) {
|
||||||
|
return await db.programs.find({ _qid: item._id }).sort({ channel: 1, start: 1 })
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
const { db, logger, file, parser } = require('../core')
|
const { db, logger, file, parser } = require('../../core')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
|
||||||
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
|
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
|
||||||
|
@ -7,7 +7,7 @@ async function main() {
|
||||||
await db.queue.load()
|
await db.queue.load()
|
||||||
await db.programs.load()
|
await db.programs.load()
|
||||||
await db.programs.reset()
|
await db.programs.reset()
|
||||||
const files = await file.list(`${LOGS_DIR}/load-cluster/cluster_*.log`)
|
const files = await file.list(`${LOGS_DIR}/cluster/load/cluster_*.log`)
|
||||||
for (const filepath of files) {
|
for (const filepath of files) {
|
||||||
logger.info(`Parsing "${filepath}"...`)
|
logger.info(`Parsing "${filepath}"...`)
|
||||||
const results = await parser.parseLogs(filepath)
|
const results = await parser.parseLogs(filepath)
|
|
@ -1,4 +1,4 @@
|
||||||
const { db, file, parser, logger, date, api } = require('../core')
|
const { db, file, parser, logger, date, api } = require('../../core')
|
||||||
const { program } = require('commander')
|
const { program } = require('commander')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ async function createQueue() {
|
||||||
const utcDate = date.getUTC()
|
const utcDate = date.getUTC()
|
||||||
const dates = Array.from({ length: options.days }, (_, i) => utcDate.add(i, 'd'))
|
const dates = Array.from({ length: options.days }, (_, i) => utcDate.add(i, 'd'))
|
||||||
for (const filepath of files) {
|
for (const filepath of files) {
|
||||||
|
try {
|
||||||
const dir = file.dirname(filepath)
|
const dir = file.dirname(filepath)
|
||||||
const { site, channels: items } = await parser.parseChannels(filepath)
|
const { site, channels: items } = await parser.parseChannels(filepath)
|
||||||
if (!site) continue
|
if (!site) continue
|
||||||
|
@ -85,6 +86,9 @@ async function createQueue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queue = Object.values(queue)
|
queue = Object.values(queue)
|
|
@ -1,4 +1,4 @@
|
||||||
const { file, markdown, parser, logger, api, table } = require('../core')
|
const { file, markdown, parser, logger, api, table } = require('../../core')
|
||||||
const { program } = require('commander')
|
const { program } = require('commander')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
|
||||||
|
@ -10,9 +10,11 @@ const options = program
|
||||||
.opts()
|
.opts()
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
const items = []
|
||||||
|
|
||||||
|
try {
|
||||||
await api.countries.load()
|
await api.countries.load()
|
||||||
const files = await file.list(CHANNELS_PATH)
|
const files = await file.list(CHANNELS_PATH)
|
||||||
const items = []
|
|
||||||
for (const filepath of files) {
|
for (const filepath of files) {
|
||||||
const { site, channels } = await parser.parseChannels(filepath)
|
const { site, channels } = await parser.parseChannels(filepath)
|
||||||
const dir = file.dirname(filepath)
|
const dir = file.dirname(filepath)
|
||||||
|
@ -30,6 +32,9 @@ async function main() {
|
||||||
group: `${suffix}/${site}`
|
group: `${suffix}/${site}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
await generateCountriesTable(items)
|
await generateCountriesTable(items)
|
||||||
await updateReadme()
|
await updateReadme()
|
|
@ -1,37 +0,0 @@
|
||||||
const { file, parser, logger } = require('../core')
|
|
||||||
const { program } = require('commander')
|
|
||||||
const _ = require('lodash')
|
|
||||||
|
|
||||||
const CHANNELS_PATH = process.env.CHANNELS_PATH || 'sites/**/*.channels.xml'
|
|
||||||
const OUTPUT_DIR = process.env.OUTPUT_DIR || '.gh-pages/api'
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const files = await file.list(CHANNELS_PATH)
|
|
||||||
let guides = []
|
|
||||||
for (const filepath of files) {
|
|
||||||
const { site, channels } = await parser.parseChannels(filepath)
|
|
||||||
const dir = file.dirname(filepath)
|
|
||||||
const config = require(file.resolve(`${dir}/${site}.config.js`))
|
|
||||||
if (config.ignore) continue
|
|
||||||
|
|
||||||
const filename = file.basename(filepath)
|
|
||||||
const [__, suffix] = filename.match(/\_(.*)\.channels\.xml$/) || [null, null]
|
|
||||||
|
|
||||||
for (const channel of channels) {
|
|
||||||
guides.push({
|
|
||||||
channel: channel.xmltv_id,
|
|
||||||
site,
|
|
||||||
lang: channel.lang,
|
|
||||||
url: `https://iptv-org.github.io/epg/guides/${suffix}/${site}.epg.xml`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
guides = _.sortBy(guides, 'channel')
|
|
||||||
|
|
||||||
const outputFilepath = `${OUTPUT_DIR}/guides.json`
|
|
||||||
await file.create(outputFilepath, JSON.stringify(guides))
|
|
||||||
logger.info(`saved to "${outputFilepath}"...`)
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
|
@ -1,149 +0,0 @@
|
||||||
const { db, logger, file, api } = require('../core')
|
|
||||||
const grabber = require('epg-grabber')
|
|
||||||
const _ = require('lodash')
|
|
||||||
|
|
||||||
const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs'
|
|
||||||
const PUBLIC_DIR = process.env.PUBLIC_DIR || '.gh-pages'
|
|
||||||
const GUIDES_PATH = `${LOGS_DIR}/guides.log`
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
await setUp()
|
|
||||||
await generateGuides()
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
async function generateGuides() {
|
|
||||||
logger.info(`Generating guides/...`)
|
|
||||||
|
|
||||||
logger.info('Loading "database/programs.db"...')
|
|
||||||
await db.programs.load()
|
|
||||||
await api.channels.load()
|
|
||||||
|
|
||||||
const grouped = groupByGroup(await loadQueue())
|
|
||||||
for (const key in grouped) {
|
|
||||||
const filepath = `${PUBLIC_DIR}/guides/${key}.epg.xml`
|
|
||||||
const criticalErrors = []
|
|
||||||
let channels = {}
|
|
||||||
let programs = []
|
|
||||||
for (const item of grouped[key]) {
|
|
||||||
const itemPrograms = await loadProgramsForItem(item)
|
|
||||||
programs = programs.concat(itemPrograms)
|
|
||||||
|
|
||||||
if (channels[item.channel.xmltv_id]) continue
|
|
||||||
|
|
||||||
if (item.error) {
|
|
||||||
const error = {
|
|
||||||
xmltv_id: item.channel.xmltv_id,
|
|
||||||
site: item.channel.site,
|
|
||||||
site_id: item.channel.site_id,
|
|
||||||
lang: item.channel.lang,
|
|
||||||
date: item.date,
|
|
||||||
error: item.error
|
|
||||||
}
|
|
||||||
criticalErrors.push(error)
|
|
||||||
await logError(key, error)
|
|
||||||
} else {
|
|
||||||
if (!itemPrograms.length) {
|
|
||||||
await logError(key, {
|
|
||||||
xmltv_id: item.channel.xmltv_id,
|
|
||||||
site: item.channel.site,
|
|
||||||
site_id: item.channel.site_id,
|
|
||||||
lang: item.channel.lang,
|
|
||||||
date: item.date,
|
|
||||||
error: 'Programs not found'
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
const channel = api.channels.find({ id: item.channel.xmltv_id })
|
|
||||||
if (!channel) {
|
|
||||||
await logError(key, {
|
|
||||||
xmltv_id: item.channel.xmltv_id,
|
|
||||||
site: item.channel.site,
|
|
||||||
site_id: item.channel.site_id,
|
|
||||||
lang: item.channel.lang,
|
|
||||||
date: item.date,
|
|
||||||
error: 'The channel has the wrong xmltv_id'
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
channels[channel.id] = {
|
|
||||||
xmltv_id: channel.id,
|
|
||||||
name: item.channel.display_name,
|
|
||||||
logo: channel.logo,
|
|
||||||
site: item.channel.site
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
channels = Object.values(channels)
|
|
||||||
channels = _.sortBy(channels, 'xmltv_id')
|
|
||||||
programs = _.sortBy(programs, ['channel', 'start'])
|
|
||||||
|
|
||||||
logger.info(`Creating "${filepath}"...`)
|
|
||||||
const output = grabber.convertToXMLTV({ channels, programs })
|
|
||||||
await file.create(filepath, output)
|
|
||||||
|
|
||||||
let status = 0
|
|
||||||
if (criticalErrors.length > 0 || !channels.length) {
|
|
||||||
status = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
await logGuide({
|
|
||||||
group: key,
|
|
||||||
count: channels.length,
|
|
||||||
status
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(`Done`)
|
|
||||||
}
|
|
||||||
|
|
||||||
function groupByGroup(items = []) {
|
|
||||||
const groups = {}
|
|
||||||
|
|
||||||
items.forEach(item => {
|
|
||||||
item.groups.forEach(key => {
|
|
||||||
if (!groups[key]) {
|
|
||||||
groups[key] = []
|
|
||||||
}
|
|
||||||
|
|
||||||
groups[key].push(item)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return groups
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadQueue() {
|
|
||||||
logger.info('Loading queue...')
|
|
||||||
|
|
||||||
await db.queue.load()
|
|
||||||
|
|
||||||
return await db.queue.find({}).sort({ xmltv_id: 1 })
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadProgramsForItem(item) {
|
|
||||||
return await db.programs.find({ _qid: item._id }).sort({ channel: 1, start: 1 })
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setUp() {
|
|
||||||
logger.info(`Creating '${GUIDES_PATH}'...`)
|
|
||||||
await file.create(GUIDES_PATH)
|
|
||||||
await file.createDir(`${LOGS_DIR}/errors`)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function logGuide(data) {
|
|
||||||
await file.append(GUIDES_PATH, JSON.stringify(data) + '\r\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
async function logError(key, data) {
|
|
||||||
const filepath = `${LOGS_DIR}/errors/${key}.log`
|
|
||||||
if (!(await file.exists(filepath))) {
|
|
||||||
await file.create(filepath)
|
|
||||||
}
|
|
||||||
|
|
||||||
await file.append(filepath, JSON.stringify(data) + '\r\n')
|
|
||||||
}
|
|
|
@ -7,3 +7,4 @@ exports.markdown = require('./markdown')
|
||||||
exports.api = require('./api')
|
exports.api = require('./api')
|
||||||
exports.date = require('./date')
|
exports.date = require('./date')
|
||||||
exports.table = require('./table')
|
exports.table = require('./table')
|
||||||
|
exports.xml = require('./xml')
|
||||||
|
|
|
@ -1,61 +1,6 @@
|
||||||
const { Command } = require('commander')
|
const xml = {}
|
||||||
const { db, logger } = require('../core')
|
|
||||||
const path = require('path')
|
|
||||||
const _ = require('lodash')
|
|
||||||
const fs = require('fs')
|
|
||||||
|
|
||||||
const program = new Command()
|
xml.create = function (items, site) {
|
||||||
program
|
|
||||||
.requiredOption('-c, --config <config>', 'Config file')
|
|
||||||
.option('-s, --set [args...]', 'Set custom arguments', [])
|
|
||||||
.option('-o, --output <output>', 'Output file')
|
|
||||||
.parse(process.argv)
|
|
||||||
|
|
||||||
const options = program.opts()
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
await db.channels.load()
|
|
||||||
const config = require(path.resolve(options.config))
|
|
||||||
const args = {}
|
|
||||||
options.set.forEach(arg => {
|
|
||||||
const [key, value] = arg.split(':')
|
|
||||||
args[key] = value
|
|
||||||
})
|
|
||||||
let channels = config.channels(args)
|
|
||||||
if (isPromise(channels)) {
|
|
||||||
channels = await channels
|
|
||||||
}
|
|
||||||
channels = _.uniqBy(channels, 'site_id')
|
|
||||||
|
|
||||||
const siteChannels = await db.channels.find({ site: config.site })
|
|
||||||
for (const channel of channels) {
|
|
||||||
if (channel.xmltv_id) continue
|
|
||||||
const data = siteChannels.find(c => c.site_id === channel.site_id.toString())
|
|
||||||
if (data) {
|
|
||||||
channel.xmltv_id = data.xmltv_id
|
|
||||||
channel.name = data.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
channels = _.sortBy(channels, 'xmltv_id')
|
|
||||||
|
|
||||||
const xml = json2xml(channels, config.site)
|
|
||||||
|
|
||||||
const dir = path.parse(options.config).dir
|
|
||||||
const output = options.output || `${dir}/${config.site}.channels.xml`
|
|
||||||
|
|
||||||
fs.writeFileSync(path.resolve(output), xml)
|
|
||||||
|
|
||||||
logger.info(`File '${output}' successfully saved`)
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
function isPromise(promise) {
|
|
||||||
return !!promise && typeof promise.then === 'function'
|
|
||||||
}
|
|
||||||
|
|
||||||
function json2xml(items, site) {
|
|
||||||
let output = `<?xml version="1.0" encoding="UTF-8"?>\r\n<site site="${site}">\r\n <channels>\r\n`
|
let output = `<?xml version="1.0" encoding="UTF-8"?>\r\n<site site="${site}">\r\n <channels>\r\n`
|
||||||
|
|
||||||
items.forEach(channel => {
|
items.forEach(channel => {
|
||||||
|
@ -101,4 +46,4 @@ function escapeString(string, defaultValue = '') {
|
||||||
.trim()
|
.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { json2xml }
|
module.exports = xml
|
0
tests/__data__/database/queue.db
Normal file
0
tests/__data__/database/queue.db
Normal file
|
@ -16,14 +16,14 @@ To load a program guide, all you need to do is copy the link to one or more of t
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
## EPG Codes
|
|
||||||
|
|
||||||
📋 [iptv-org.github.io](https://iptv-org.github.io/)
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository.
|
The API documentation can be found in the [iptv-org/api](https://github.com/iptv-org/api) repository.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
Links to other useful IPTV-related resources can be found in the [iptv-org/awesome-iptv](https://github.com/iptv-org/awesome-iptv) repository.
|
||||||
|
|
||||||
## Contribution
|
## 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).
|
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).
|
|
@ -1 +0,0 @@
|
||||||
{"xmltv_id":"CNNInternationalEurope2.us","site":"example.com","site_id":"141","lang":"en","error":"The channel has the wrong xmltv_id"}
|
|
|
@ -1 +0,0 @@
|
||||||
{"xmltv_id":"CNNInternationalEurope.us","site":"magticom.ge","site_id":"140","lang":"ru","date":"2022-01-21T00:00:00Z","error":"Programs not found"}
|
|
|
@ -1 +0,0 @@
|
||||||
{"xmltv_id":"Perviykanal.ru","site":"yandex.ru","site_id":"1","lang":"ru","date":"2022-01-21T00:00:00Z","error":"Some error"}
|
|
|
@ -1 +0,0 @@
|
||||||
{"xmltv_id":"BravoEast.us","site":"directv.com","site_id":"237","lang":"en","date":"2022-01-21T00:00:00Z","error":"Invalid header value char"}
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<site site="parse-channels.com">
|
||||||
|
<channels>
|
||||||
|
<channel lang="en" xmltv_id="CNNInternational.us" site_id="140">CNN International</channel>
|
||||||
|
</channels>
|
||||||
|
</site>
|
|
@ -1 +0,0 @@
|
||||||
{"lang":"en","xmltv_id":"BravoEast.us","site_id":"237","site":"directv.com","configPath":"sites/directv.com/directv.com.config.js","groups":["us/directv.com"],"cluster_id":84,"_id":"00AluKCrCnfgrl8W","date":"2022-01-21T00:00:00Z","error":"Invalid header value char"}
|
|
7
tests/__data__/input/sites/duplicate.channels.xml
Normal file
7
tests/__data__/input/sites/duplicate.channels.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<site site="duplicate.com">
|
||||||
|
<channels>
|
||||||
|
<channel lang="en" xmltv_id="CNNInternationalEurope.us" site_id="140">CNN International</channel>
|
||||||
|
<channel lang="en" xmltv_id="CNNInternationalEurope.us" site_id="140">CNN International</channel>
|
||||||
|
</channels>
|
||||||
|
</site>
|
6
tests/__data__/input/sites/lint.channels.xml
Normal file
6
tests/__data__/input/sites/lint.channels.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<site site="lint.com">
|
||||||
|
<channels>
|
||||||
|
<channel xmltv_id="CNNInternationalEurope.us" site_id="140">CNN International</channel>
|
||||||
|
</channels>
|
||||||
|
</site>
|
19
tests/__data__/input/sites/parse-channels.config.js
Normal file
19
tests/__data__/input/sites/parse-channels.config.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = {
|
||||||
|
site: 'parse-channels.com',
|
||||||
|
url() {
|
||||||
|
return `https://parse-channels.com`
|
||||||
|
},
|
||||||
|
parser() {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
channels() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
lang: 'en',
|
||||||
|
xmltv_id: 'CNNInternational.us',
|
||||||
|
site_id: 140,
|
||||||
|
name: 'CNN International'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
6
tests/__data__/input/sites/wrong_xmltv_id.channels.xml
Normal file
6
tests/__data__/input/sites/wrong_xmltv_id.channels.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<site site="wrong_xmltv_id.com">
|
||||||
|
<channels>
|
||||||
|
<channel lang="en" xmltv_id="CNNInternational" site_id="140">CNN International</channel>
|
||||||
|
</channels>
|
||||||
|
</site>
|
26
tests/commands/api/update.test.js
Normal file
26
tests/commands/api/update.test.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
|
|
||||||
|
const stdout = execSync(
|
||||||
|
'CHANNELS_PATH=tests/__data__/input/sites/example.com_ca.channels.xml OUTPUT_DIR=tests/__data__/output/api npm run api:update',
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can generate guides.json', () => {
|
||||||
|
expect(content('tests/__data__/output/api/guides.json')).toBe(
|
||||||
|
content('tests/__data__/expected/api/guides.json')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function content(filepath) {
|
||||||
|
const data = fs.readFileSync(path.resolve(filepath), {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
return JSON.stringify(data)
|
||||||
|
}
|
19
tests/commands/channels/lint.test.js
Normal file
19
tests/commands/channels/lint.test.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
|
||||||
|
it('will show a message if the file contains a syntax error', () => {
|
||||||
|
try {
|
||||||
|
const stdout = execSync(
|
||||||
|
'npm run channels:lint -- tests/__data__/input/sites/lint.channels.xml',
|
||||||
|
{
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
console.log(stdout)
|
||||||
|
process.exit(1)
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.status).toBe(1)
|
||||||
|
expect(err.stdout).toBe(
|
||||||
|
`\n> channels:lint\n> node scripts/commands/channels/lint.js "tests/__data__/input/sites/lint.channels.xml"\n\n\ntests/__data__/input/sites/lint.channels.xml\n 4:0 Element 'channel': The attribute 'lang' is required but missing.\n\n1 error(s)\n`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
24
tests/commands/channels/parse.test.js
Normal file
24
tests/commands/channels/parse.test.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
|
|
||||||
|
const stdout = execSync(
|
||||||
|
'npm run channels:parse -- --config=tests/__data__/input/sites/parse-channels.config.js --output=tests/__data__/output/channels.xml',
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can parse channels', () => {
|
||||||
|
expect(content('tests/__data__/output/channels.xml')).toEqual(
|
||||||
|
content('tests/__data__/expected/sites/parse-channels.channels.xml')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function content(filepath) {
|
||||||
|
return fs.readFileSync(path.resolve(filepath), {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
}
|
49
tests/commands/channels/validate.test.js
Normal file
49
tests/commands/channels/validate.test.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
|
||||||
|
it('will show a message if the file contains a duplicate', () => {
|
||||||
|
try {
|
||||||
|
const stdout = execSync(
|
||||||
|
'npm run channels:validate -- tests/__data__/input/sites/duplicate.channels.xml',
|
||||||
|
{
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
console.log(stdout)
|
||||||
|
process.exit(1)
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.status).toBe(1)
|
||||||
|
expect(err.stdout).toBe(
|
||||||
|
`\n> channels:validate\n> node scripts/commands/channels/validate.js "tests/__data__/input/sites/duplicate.channels.xml"\n\ntests/__data__/input/sites/duplicate.channels.xml
|
||||||
|
┌─────────┬─────────────┬──────┬─────────────────────────────┬─────────┬─────────────────────┐
|
||||||
|
│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
|
||||||
|
├─────────┼─────────────┼──────┼─────────────────────────────┼─────────┼─────────────────────┤
|
||||||
|
│ 0 │ 'duplicate' │ 'en' │ 'CNNInternationalEurope.us' │ '140' │ 'CNN International' │
|
||||||
|
└─────────┴─────────────┴──────┴─────────────────────────────┴─────────┴─────────────────────┘
|
||||||
|
\n1 error(s) in 1 file(s)\n`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('will show a message if the file contains a channel with wrong xmltv_id', () => {
|
||||||
|
try {
|
||||||
|
const stdout = execSync(
|
||||||
|
'npm run channels:validate -- tests/__data__/input/sites/wrong_xmltv_id.channels.xml',
|
||||||
|
{
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
console.log(stdout)
|
||||||
|
process.exit(1)
|
||||||
|
} catch (err) {
|
||||||
|
expect(err.status).toBe(1)
|
||||||
|
expect(err.stdout).toBe(
|
||||||
|
`\n> channels:validate\n> node scripts/commands/channels/validate.js "tests/__data__/input/sites/wrong_xmltv_id.channels.xml"\n\ntests/__data__/input/sites/wrong_xmltv_id.channels.xml
|
||||||
|
┌─────────┬──────────────────┬──────┬────────────────────┬─────────┬─────────────────────┐
|
||||||
|
│ (index) │ type │ lang │ xmltv_id │ site_id │ name │
|
||||||
|
├─────────┼──────────────────┼──────┼────────────────────┼─────────┼─────────────────────┤
|
||||||
|
│ 0 │ 'wrong_xmltv_id' │ 'en' │ 'CNNInternational' │ '140' │ 'CNN International' │
|
||||||
|
└─────────┴──────────────────┴──────┴────────────────────┴─────────┴─────────────────────┘
|
||||||
|
\n1 error(s) in 1 file(s)\n`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
32
tests/commands/cluster/load.test.js
Normal file
32
tests/commands/cluster/load.test.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
|
fs.copyFileSync('tests/__data__/input/database/queue.db', 'tests/__data__/output/queue.db')
|
||||||
|
|
||||||
|
execSync(
|
||||||
|
'DB_DIR=tests/__data__/output LOGS_DIR=tests/__data__/output/logs npm run cluster:load -- --cluster-id=1 --timeout=10000',
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can load cluster', () => {
|
||||||
|
expect(content('tests/__data__/output/logs/cluster/load/cluster_1.log')).toEqual(
|
||||||
|
content('tests/__data__/expected/logs/cluster/load/cluster_1.log')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function content(filepath) {
|
||||||
|
const data = fs.readFileSync(path.resolve(filepath), {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
return data
|
||||||
|
.split('\n')
|
||||||
|
.filter(l => l)
|
||||||
|
.map(l => {
|
||||||
|
return JSON.parse(l)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
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')
|
|
||||||
fs.mkdirSync('tests/__data__/temp/database', { recursive: true })
|
|
||||||
fs.copyFileSync('tests/__data__/input/database/queue.db', 'tests/__data__/temp/database/queue.db')
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
fs.rmdirSync('tests/__data__/temp', { recursive: true })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can create valid matrix', () => {
|
|
||||||
const result = execSync(
|
|
||||||
'DB_DIR=tests/__data__/temp/database node scripts/commands/create-matrix.js',
|
|
||||||
{
|
|
||||||
encoding: 'utf8'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(result).toBe('::set-output name=matrix::{"cluster_id":[1,4,84,120]}\n')
|
|
||||||
})
|
|
32
tests/commands/guides/update.test.js
Normal file
32
tests/commands/guides/update.test.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
|
fs.copyFileSync('tests/__data__/input/database/queue.db', 'tests/__data__/output/queue.db')
|
||||||
|
fs.copyFileSync('tests/__data__/input/database/programs.db', 'tests/__data__/output/programs.db')
|
||||||
|
|
||||||
|
const stdout = execSync(
|
||||||
|
'DB_DIR=tests/__data__/output DATA_DIR=tests/__data__/input/data PUBLIC_DIR=tests/__data__/output npm run guides:update',
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can generate /guides', () => {
|
||||||
|
expect(content('tests/__data__/output/guides/fr/chaines-tv.orange.fr.epg.xml')).toBe(
|
||||||
|
content('tests/__data__/expected/guides/fr/chaines-tv.orange.fr.epg.xml')
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(content('tests/__data__/output/guides/zw/dstv.com.epg.xml')).toBe(
|
||||||
|
content('tests/__data__/expected/guides/zw/dstv.com.epg.xml')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function content(filepath) {
|
||||||
|
const data = fs.readFileSync(path.resolve(filepath), {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
return JSON.stringify(data)
|
||||||
|
}
|
|
@ -1,40 +0,0 @@
|
||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const dayjs = require('dayjs')
|
|
||||||
const utc = require('dayjs/plugin/utc')
|
|
||||||
const { execSync } = require('child_process')
|
|
||||||
|
|
||||||
dayjs.extend(utc)
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fs.rmdirSync('tests/__data__/temp', { recursive: true })
|
|
||||||
fs.rmdirSync('tests/__data__/output', { recursive: true })
|
|
||||||
fs.mkdirSync('tests/__data__/output')
|
|
||||||
fs.mkdirSync('tests/__data__/temp/database', { recursive: true })
|
|
||||||
fs.copyFileSync('tests/__data__/input/database/queue.db', 'tests/__data__/temp/database/queue.db')
|
|
||||||
|
|
||||||
execSync(
|
|
||||||
'DB_DIR=tests/__data__/temp/database LOGS_DIR=tests/__data__/output/logs node scripts/commands/load-cluster.js --cluster-id=1 --timeout=10000',
|
|
||||||
{ encoding: 'utf8' }
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can load cluster', () => {
|
|
||||||
let output = content('tests/__data__/output/logs/load-cluster/cluster_1.log')
|
|
||||||
let expected = content('tests/__data__/expected/logs/load-cluster/cluster_1.log')
|
|
||||||
|
|
||||||
expect(output).toEqual(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
function content(filepath) {
|
|
||||||
const data = fs.readFileSync(path.resolve(filepath), {
|
|
||||||
encoding: 'utf8'
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
.split('\n')
|
|
||||||
.filter(l => l)
|
|
||||||
.map(l => {
|
|
||||||
return JSON.parse(l)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,25 +1,19 @@
|
||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fs.rmdirSync('tests/__data__/output', { recursive: true })
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
fs.mkdirSync('tests/__data__/output')
|
fs.copyFileSync('tests/__data__/input/database/queue.db', 'tests/__data__/output/queue.db')
|
||||||
fs.mkdirSync('tests/__data__/output/database', { recursive: true })
|
|
||||||
|
|
||||||
fs.copyFileSync(
|
|
||||||
'tests/__data__/input/database/queue.db',
|
|
||||||
'tests/__data__/output/database/queue.db'
|
|
||||||
)
|
|
||||||
|
|
||||||
const stdout = execSync(
|
const stdout = execSync(
|
||||||
'DB_DIR=tests/__data__/output/database LOGS_DIR=tests/__data__/input/logs node scripts/commands/save-results.js',
|
'DB_DIR=tests/__data__/output LOGS_DIR=tests/__data__/input/logs npm run programs:save',
|
||||||
{ encoding: 'utf8' }
|
{ encoding: 'utf8' }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can save programs to database', () => {
|
it('can save programs to database', () => {
|
||||||
let output = content('tests/__data__/output/database/programs.db')
|
let output = content('tests/__data__/output/programs.db')
|
||||||
let expected = content('tests/__data__/expected/database/programs.db')
|
let expected = content('tests/__data__/expected/database/programs.db')
|
||||||
|
|
||||||
output = output.map(i => {
|
output = output.map(i => {
|
||||||
|
@ -35,10 +29,9 @@ it('can save programs to database', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can update queue', () => {
|
it('can update queue', () => {
|
||||||
const output = content('tests/__data__/output/database/queue.db')
|
expect(content('tests/__data__/output/queue.db')).toEqual(
|
||||||
const expected = content('tests/__data__/expected/database/queue-with-errors.db')
|
content('tests/__data__/expected/database/queue-with-errors.db')
|
||||||
|
)
|
||||||
expect(output).toEqual(expected)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function content(filepath) {
|
function content(filepath) {
|
|
@ -1,13 +1,12 @@
|
||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fs.rmdirSync('tests/__data__/output', { recursive: true })
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
fs.mkdirSync('tests/__data__/output')
|
|
||||||
|
|
||||||
const stdout = execSync(
|
const stdout = execSync(
|
||||||
'DB_DIR=tests/__data__/output/database LOGS_DIR=tests/__data__/output/logs CHANNELS_PATH=tests/__data__/input/sites/*.channels.xml node scripts/commands/create-queue.js --max-clusters=1 --days=2',
|
'DB_DIR=tests/__data__/output/database LOGS_DIR=tests/__data__/output/logs CHANNELS_PATH=tests/__data__/input/sites/example.com_ca.channels.xml npm run queue:create -- --max-clusters=1 --days=2',
|
||||||
{ encoding: 'utf8' }
|
{ encoding: 'utf8' }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -35,13 +34,6 @@ it('can create queue', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('can log errors', () => {
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
|
|
||||||
function content(filepath) {
|
function content(filepath) {
|
||||||
const data = fs.readFileSync(path.resolve(filepath), {
|
const data = fs.readFileSync(path.resolve(filepath), {
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
26
tests/commands/readme/update.test.js
Normal file
26
tests/commands/readme/update.test.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
const { execSync } = require('child_process')
|
||||||
|
const fs = require('fs-extra')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.emptyDirSync('tests/__data__/output')
|
||||||
|
|
||||||
|
const stdout = execSync(
|
||||||
|
'CHANNELS_PATH=tests/__data__/input/sites/example.com_ca.channels.xml DATA_DIR=tests/__data__/input/data npm run readme:update -- --config=tests/__data__/input/readme.json',
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can update readme.md', () => {
|
||||||
|
expect(content('tests/__data__/output/readme.md')).toBe(
|
||||||
|
content('tests/__data__/expected/_readme.md')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function content(filepath) {
|
||||||
|
const data = fs.readFileSync(path.resolve(filepath), {
|
||||||
|
encoding: 'utf8'
|
||||||
|
})
|
||||||
|
|
||||||
|
return JSON.stringify(data)
|
||||||
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
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')
|
|
||||||
|
|
||||||
const stdout = execSync(
|
|
||||||
'CHANNELS_PATH=tests/__data__/input/sites/**.channels.xml OUTPUT_DIR=tests/__data__/output/api node scripts/commands/update-api.js',
|
|
||||||
{ encoding: 'utf8' }
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can generate guides.json', () => {
|
|
||||||
const output = content('tests/__data__/output/api/guides.json')
|
|
||||||
const expected = content('tests/__data__/expected/api/guides.json')
|
|
||||||
|
|
||||||
expect(output).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
function content(filepath) {
|
|
||||||
const data = fs.readFileSync(path.resolve(filepath), {
|
|
||||||
encoding: 'utf8'
|
|
||||||
})
|
|
||||||
|
|
||||||
return JSON.stringify(data)
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
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')
|
|
||||||
fs.mkdirSync('tests/__data__/temp/database', { recursive: true })
|
|
||||||
fs.copyFileSync('tests/__data__/input/database/queue.db', 'tests/__data__/temp/database/queue.db')
|
|
||||||
fs.copyFileSync(
|
|
||||||
'tests/__data__/input/database/programs.db',
|
|
||||||
'tests/__data__/temp/database/programs.db'
|
|
||||||
)
|
|
||||||
|
|
||||||
const stdout = execSync(
|
|
||||||
'DB_DIR=tests/__data__/temp/database DATA_DIR=tests/__data__/input/data PUBLIC_DIR=tests/__data__/output LOGS_DIR=tests/__data__/output/logs node scripts/commands/update-guides.js',
|
|
||||||
{ encoding: 'utf8' }
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
fs.rmdirSync('tests/__data__/temp', { recursive: true })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can generate /guides', () => {
|
|
||||||
const output1 = content('tests/__data__/output/guides/fr/chaines-tv.orange.fr.epg.xml')
|
|
||||||
const expected1 = content('tests/__data__/expected/guides/fr/chaines-tv.orange.fr.epg.xml')
|
|
||||||
|
|
||||||
expect(output1).toBe(expected1)
|
|
||||||
|
|
||||||
const output2 = content('tests/__data__/output/guides/zw/dstv.com.epg.xml')
|
|
||||||
const expected2 = content('tests/__data__/expected/guides/zw/dstv.com.epg.xml')
|
|
||||||
|
|
||||||
expect(output2).toBe(expected2)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can create guides.log', () => {
|
|
||||||
const output = content('tests/__data__/output/logs/guides.log')
|
|
||||||
const expected = content('tests/__data__/expected/logs/guides.log')
|
|
||||||
|
|
||||||
expect(output).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can log errors', () => {
|
|
||||||
const output1 = content('tests/__data__/output/logs/errors/ru/yandex.ru.log')
|
|
||||||
const expected1 = content('tests/__data__/expected/logs/errors/ru/yandex.ru.log')
|
|
||||||
|
|
||||||
expect(output1).toBe(expected1)
|
|
||||||
|
|
||||||
const output2 = content('tests/__data__/output/logs/errors/us/directv.com.log')
|
|
||||||
const expected2 = content('tests/__data__/expected/logs/errors/us/directv.com.log')
|
|
||||||
|
|
||||||
expect(output2).toBe(expected2)
|
|
||||||
|
|
||||||
const output3 = content('tests/__data__/output/logs/errors/ge/magticom.ge.log')
|
|
||||||
const expected3 = content('tests/__data__/expected/logs/errors/ge/magticom.ge.log')
|
|
||||||
|
|
||||||
expect(output3).toBe(expected3)
|
|
||||||
})
|
|
||||||
|
|
||||||
function content(filepath) {
|
|
||||||
const data = fs.readFileSync(path.resolve(filepath), {
|
|
||||||
encoding: 'utf8'
|
|
||||||
})
|
|
||||||
|
|
||||||
return JSON.stringify(data)
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
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')
|
|
||||||
|
|
||||||
const stdout = execSync(
|
|
||||||
'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' }
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
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