From f8981e478e5b4434d034a17af6fa9ea3ddf2dd6e Mon Sep 17 00:00:00 2001 From: Aleksandr Statciuk Date: Mon, 10 Jan 2022 18:27:22 +0300 Subject: [PATCH] wip --- scripts/commands/update-api.js | 109 ++++++++++++++++++ .../{generate-guides.js => update-guides.js} | 50 +++----- ...rate-guides.test.js => update-api.test.js} | 9 +- tests/commands/update-guides.test.js | 41 +++++++ 4 files changed, 169 insertions(+), 40 deletions(-) create mode 100644 scripts/commands/update-api.js rename scripts/commands/{generate-guides.js => update-guides.js} (82%) rename tests/commands/{generate-guides.test.js => update-api.test.js} (79%) create mode 100644 tests/commands/update-guides.test.js diff --git a/scripts/commands/update-api.js b/scripts/commands/update-api.js new file mode 100644 index 00000000..35a9c4d8 --- /dev/null +++ b/scripts/commands/update-api.js @@ -0,0 +1,109 @@ +const { db, logger, file, xml } = require('../core') +const _ = require('lodash') + +let channels = [] +let programs = [] +let sources = {} + +const DB_DIR = process.env.DB_DIR || 'scripts/database' +const API_DIR = process.env.API_DIR || '.gh-pages/api' + +async function main() { + await setUp() + + await generateChannelsJson() + await generateProgramsJson() +} + +main() + +async function setUp() { + channels = await loadChannels() + programs = await loadPrograms() +} + +async function loadChannels() { + let items = await db.channels.find({}).sort({ xmltv_id: 1 }) + + let output = {} + items.forEach(item => { + if (!output[item.xmltv_id]) { + const countryCode = item.xmltv_id.split('.')[1] + + output[item.xmltv_id] = { + id: item.xmltv_id, + name: [item.name], + logo: item.logo || null, + country: countryCode ? countryCode.toUpperCase() : null + } + } else { + output[item.xmltv_id].logo = output[item.xmltv_id].logo || item.logo + output[item.xmltv_id].name.push(item.name) + } + + output[item.xmltv_id].name = _.uniq(output[item.xmltv_id].name) + }) + + return Object.values(output) +} + +async function loadPrograms() { + let items = await db.programs.find({}) + + items = _.sortBy(items, ['channel', 'start']) + items = _.groupBy(items, 'channel') + + for (let channel in items) { + let channelPrograms = items[channel] + channelPrograms = Object.values(_.groupBy(channelPrograms, i => i.site))[0] + let slots = _.groupBy(channelPrograms, i => `${i.start}_${i.stop}`) + + for (let slotId in slots) { + let program = { + channel, + title: [], + description: [], + categories: [], + image: null, + start: null, + stop: null + } + + slots[slotId].forEach(item => { + if (item.title) program.title.push({ lang: item.lang, value: item.title }) + if (item.description) + program.description.push({ + lang: item.lang, + value: item.description + }) + if (item.category) program.categories.push({ lang: item.lang, value: item.category }) + program.image = program.image || item.icon + program.start = item.start + program.stop = item.stop + sources[channel] = item.site + }) + + program.title = _.uniqBy(program.title, 'lang') + program.description = _.uniqBy(program.description, 'lang') + program.categories = _.uniqBy(program.categories, 'lang') + + slots[slotId] = program + } + + items[channel] = Object.values(slots) + } + + return items +} + +async function generateChannelsJson() { + logger.info('Generating channels.json...') + + await file.create(`${API_DIR}/channels.json`, JSON.stringify(channels)) +} + +async function generateProgramsJson() { + logger.info('Generating programs.json...') + + await file.create(`${API_DIR}/programs.json`, JSON.stringify(programs)) +} diff --git a/scripts/commands/generate-guides.js b/scripts/commands/update-guides.js similarity index 82% rename from scripts/commands/generate-guides.js rename to scripts/commands/update-guides.js index 21c6702a..79fca4e7 100644 --- a/scripts/commands/generate-guides.js +++ b/scripts/commands/update-guides.js @@ -6,18 +6,32 @@ let programs = [] let sources = {} const DB_DIR = process.env.DB_DIR || 'scripts/database' -const PUBLIC_DIR = process.env.PUBLIC_DIR || '.gh-pages' +const GUIDES_DIR = process.env.GUIDES_DIR || '.gh-pages/guides' async function main() { await setUp() - await generateChannelsJson() - await generateProgramsJson() - await generateEpgXML() + await generateMainXML() } main() +async function generateMainXML() { + logger.info(`Generating epg.xml...`) + + const output = {} + const filteredChannels = Object.keys(programs) + output.channels = channels + .filter(c => filteredChannels.includes(c.id)) + .map(c => { + c.site = sources[c.id] + return c + }) + output.programs = _.flatten(Object.values(programs)) + + await file.create(`${GUIDES_DIR}/epg.xml`, xml.create(output)) +} + async function setUp() { channels = await loadChannels() programs = await loadPrograms() @@ -96,31 +110,3 @@ async function loadPrograms() { return items } - -async function generateChannelsJson() { - logger.info('Generating channels.json...') - - await file.create(`${PUBLIC_DIR}/api/channels.json`, JSON.stringify(channels)) -} - -async function generateProgramsJson() { - logger.info('Generating programs.json...') - - await file.create(`${PUBLIC_DIR}/api/programs.json`, JSON.stringify(programs)) -} - -async function generateEpgXML() { - logger.info(`Generating epg.xml...`) - - const output = {} - const filteredChannels = Object.keys(programs) - output.channels = channels - .filter(c => filteredChannels.includes(c.id)) - .map(c => { - c.site = sources[c.id] - return c - }) - output.programs = _.flatten(Object.values(programs)) - - await file.create(`${PUBLIC_DIR}/guides/epg.xml`, xml.create(output)) -} diff --git a/tests/commands/generate-guides.test.js b/tests/commands/update-api.test.js similarity index 79% rename from tests/commands/generate-guides.test.js rename to tests/commands/update-api.test.js index 64fedf64..22bcec7b 100644 --- a/tests/commands/generate-guides.test.js +++ b/tests/commands/update-api.test.js @@ -16,7 +16,7 @@ beforeEach(() => { ) execSync( - 'DB_DIR=tests/__data__/temp/database PUBLIC_DIR=tests/__data__/output node scripts/commands/generate-guides.js', + 'DB_DIR=tests/__data__/temp/database API_DIR=tests/__data__/output/api node scripts/commands/update-api.js', { encoding: 'utf8' } ) }) @@ -39,13 +39,6 @@ it('can generate programs.json', () => { expect(output).toBe(expected) }) -it('can generate epg.xml', () => { - const output = content('tests/__data__/output/guides/epg.xml') - const expected = content('tests/__data__/expected/guides/epg.xml') - - expect(output).toBe(expected) -}) - function content(filepath) { const data = fs.readFileSync(path.resolve(filepath), { encoding: 'utf8' diff --git a/tests/commands/update-guides.test.js b/tests/commands/update-guides.test.js new file mode 100644 index 00000000..f048f83b --- /dev/null +++ b/tests/commands/update-guides.test.js @@ -0,0 +1,41 @@ +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/channels.db', + 'tests/__data__/temp/database/channels.db' + ) + fs.copyFileSync( + 'tests/__data__/input/database/programs.db', + 'tests/__data__/temp/database/programs.db' + ) + + execSync( + 'DB_DIR=tests/__data__/temp/database GUIDES_DIR=tests/__data__/output/guides node scripts/commands/update-guides.js', + { encoding: 'utf8' } + ) +}) + +afterEach(() => { + fs.rmdirSync('tests/__data__/temp', { recursive: true }) +}) + +it('can generate epg.xml', () => { + const output = content('tests/__data__/output/guides/epg.xml') + const expected = content('tests/__data__/expected/guides/epg.xml') + + expect(output).toBe(expected) +}) + +function content(filepath) { + const data = fs.readFileSync(path.resolve(filepath), { + encoding: 'utf8' + }) + + return JSON.stringify(data) +}