From dd54b9f0ef4b6778b627e0f050b7941e0a9ef919 Mon Sep 17 00:00:00 2001 From: Aleksandr Statciuk Date: Fri, 1 Jul 2022 02:45:59 +0300 Subject: [PATCH] Added support of lang attribute --- src/Program.js | 32 +++++++-- src/parser.js | 9 +-- src/xmltv.js | 16 +++-- tests/Program.test.js | 161 ++++++++++++++++++++++-------------------- tests/parser.test.js | 4 +- tests/xmltv.test.js | 16 +++-- 6 files changed, 138 insertions(+), 100 deletions(-) diff --git a/src/Program.js b/src/Program.js index 6bbd7ae..677fa84 100644 --- a/src/Program.js +++ b/src/Program.js @@ -1,14 +1,21 @@ const { padStart } = require('lodash') const { toArray, toUnix, parseNumber } = require('./utils') +const Channel = require('./Channel') class Program { - constructor(p) { + constructor(p, c) { + if (!(c instanceof Channel)) { + throw new Error('The second argument in the constructor must be the "Channel" class') + } + const data = { - site: p.site || '', - channel: p.channel || '', - title: p.title || '', - sub_title: p.sub_title || '', - description: [p.description, p.desc].find(i => i) || '', + site: p.site || c.site || '', + channel: p.channel || c.id || '', + titles: toArray(p.titles || p.title).map(text => toTextObject(text, c.lang)), + sub_titles: toArray(p.sub_titles || p.sub_title).map(text => toTextObject(text, c.lang)), + descriptions: toArray(p.descriptions || p.description || p.desc).map(text => + toTextObject(text, c.lang) + ), icon: toIconObject(p.icon), episodeNumbers: p.episodeNumbers || getEpisodeNumbers(p.season, p.episode), date: p.date ? toUnix(p.date) : null, @@ -16,7 +23,7 @@ class Program { stop: p.stop ? toUnix(p.stop) : null, urls: toArray(p.urls || p.url).map(toUrlObject), ratings: toArray(p.ratings || p.rating).map(toRatingObject), - categories: toArray(p.categories || p.category), + categories: toArray(p.categories || p.category).map(text => toTextObject(text, c.lang)), directors: toArray(p.directors || p.director).map(toPersonObject), actors: toArray(p.actors || p.actor).map(toPersonObject), writers: toArray(p.writers || p.writer).map(toPersonObject), @@ -37,6 +44,17 @@ class Program { module.exports = Program +function toTextObject(text, lang) { + if (typeof text === 'string') { + return { value: text, lang } + } + + return { + value: text.value, + lang: text.lang + } +} + function toPersonObject(person) { if (typeof person === 'string') { return { diff --git a/src/parser.js b/src/parser.js index c33ef76..46ba301 100644 --- a/src/parser.js +++ b/src/parser.js @@ -41,12 +41,5 @@ async function parsePrograms(data) { throw new Error('Parser should return an array') } - return programs - .filter(i => i) - .map(p => { - p.site = channel.site - p.channel = p.channel || channel.id - - return new Program(p) - }) + return programs.filter(i => i).map(p => new Program(p, channel)) } diff --git a/src/xmltv.js b/src/xmltv.js index 6f441db..bc2aed5 100644 --- a/src/xmltv.js +++ b/src/xmltv.js @@ -47,9 +47,15 @@ function createElements(channels, programs, date) { channel: program.channel }, [ - el('title', {}, [escapeString(program.title)]), - el('sub-title', {}, [escapeString(program.sub_title)]), - el('desc', {}, [escapeString(program.description)]), + ...program.titles.map(title => + el('title', { lang: title.lang }, [escapeString(title.value)]) + ), + ...program.sub_titles.map(sub_title => + el('sub-title', { lang: sub_title.lang }, [escapeString(sub_title.value)]) + ), + ...program.descriptions.map(desc => + el('desc', { lang: desc.lang }, [escapeString(desc.value)]) + ), el('credits', {}, [ ...program.directors.map(data => createCastMember('director', data)), ...program.actors.map(data => createCastMember('actor', data)), @@ -63,7 +69,9 @@ function createElements(channels, programs, date) { ...program.guests.map(data => createCastMember('guest', data)) ]), el('date', {}, [formatDate(program.date, 'YYYYMMDD')]), - ...program.categories.map(category => el('category', {}, [escapeString(category)])), + ...program.categories.map(category => + el('category', { lang: category.lang }, [escapeString(category.value)]) + ), el('icon', { src: program.icon.src }), ...program.urls.map(createURL), ...program.episodeNumbers.map(episode => diff --git a/tests/Program.test.js b/tests/Program.test.js index 3faa54a..78a8308 100644 --- a/tests/Program.test.js +++ b/tests/Program.test.js @@ -1,61 +1,65 @@ import Channel from '../src/Channel' import Program from '../src/Program' -const channel = new Channel({ xmltv_id: '1tv', lang: 'en', site: 'example.com' }) +const channel = new Channel({ xmltv_id: '1tv', lang: 'fr', site: 'example.com' }) it('can create new Program', () => { - const program = new Program({ - site: channel.site, - channel: channel.id, - title: 'Title', - sub_title: 'Subtitle', - description: 'Description', - icon: 'https://example.com/image.jpg', - season: 9, - episode: 238, - date: '20220506', - start: 1616133600000, - stop: '2021-03-19T06:30:00.000Z', - url: 'http://example.com/title.html', - category: ['Category1', 'Category2'], - rating: { - system: 'MPAA', - value: 'PG', - icon: 'http://example.com/pg_symbol.png' + const program = new Program( + { + title: 'Title', + sub_title: 'Subtitle', + description: 'Description', + icon: 'https://example.com/image.jpg', + season: 9, + episode: 238, + date: '20220506', + start: 1616133600000, + stop: '2021-03-19T06:30:00.000Z', + url: 'http://example.com/title.html', + category: ['Category1', 'Category2'], + rating: { + system: 'MPAA', + value: 'PG', + icon: 'http://example.com/pg_symbol.png' + }, + directors: 'Director1', + actors: [ + 'Actor1', + { value: 'Actor2', url: 'http://actor2.com', image: 'http://actor2.com/image.png' } + ], + writer: { + value: 'Writer1', + url: { system: 'imdb', value: 'http://imdb.com/p/writer1' }, + image: { + value: 'https://example.com/image.jpg', + type: 'person', + size: '2', + system: 'TestSystem', + orient: 'P' + } + }, + adapters: [ + { + value: 'Adapter1', + url: ['http://imdb.com/p/adapter1', 'http://imdb.com/p/adapter2'], + image: ['https://example.com/image1.jpg', 'https://example.com/image2.jpg'] + } + ] }, - directors: 'Director1', - actors: [ - 'Actor1', - { value: 'Actor2', url: 'http://actor2.com', image: 'http://actor2.com/image.png' } - ], - writer: { - value: 'Writer1', - url: { system: 'imdb', value: 'http://imdb.com/p/writer1' }, - image: { - value: 'https://example.com/image.jpg', - type: 'person', - size: '2', - system: 'TestSystem', - orient: 'P' - } - }, - adapters: [ - { - value: 'Adapter1', - url: ['http://imdb.com/p/adapter1', 'http://imdb.com/p/adapter2'], - image: ['https://example.com/image1.jpg', 'https://example.com/image2.jpg'] - } - ] - }) + channel + ) expect(program).toMatchObject({ site: 'example.com', channel: '1tv', - title: 'Title', - sub_title: 'Subtitle', - description: 'Description', + titles: [{ value: 'Title', lang: 'fr' }], + sub_titles: [{ value: 'Subtitle', lang: 'fr' }], + descriptions: [{ value: 'Description', lang: 'fr' }], urls: [{ system: '', value: 'http://example.com/title.html' }], - categories: ['Category1', 'Category2'], + categories: [ + { value: 'Category1', lang: 'fr' }, + { value: 'Category2', lang: 'fr' } + ], icon: { src: 'https://example.com/image.jpg' }, episodeNumbers: [ { system: 'xmltv_ns', value: '8.237.0/1' }, @@ -132,24 +136,26 @@ it('can create new Program', () => { }) it('can create program from exist object', () => { - const program = new Program({ - channel: channel.id, - title: 'Program 1', - start: '2021-03-19T06:00:00.000Z', - stop: '2021-03-19T06:30:00.000Z', - ratings: { - system: 'MPAA', - value: 'PG', - icon: 'http://example.com/pg_symbol.png' + const program = new Program( + { + titles: [{ value: 'Program 1', lang: 'de' }], + start: '2021-03-19T06:00:00.000Z', + stop: '2021-03-19T06:30:00.000Z', + ratings: { + system: 'MPAA', + value: 'PG', + icon: 'http://example.com/pg_symbol.png' + }, + actors: [{ value: 'Actor1', url: [], image: [] }] }, - actors: [{ value: 'Actor1', url: [], image: [] }] - }) + channel + ) expect(program).toMatchObject({ channel: '1tv', - title: 'Program 1', - sub_title: '', - description: '', + titles: [{ value: 'Program 1', lang: 'de' }], + sub_titles: [], + descriptions: [], urls: [], categories: [], icon: {}, @@ -178,13 +184,15 @@ it('can create program from exist object', () => { }) it('can create program without season number', () => { - const program = new Program({ - channel: channel.id, - title: 'Program 1', - start: '2021-03-19T06:00:00.000Z', - stop: '2021-03-19T06:30:00.000Z', - episode: 238 - }) + const program = new Program( + { + title: 'Program 1', + start: '2021-03-19T06:00:00.000Z', + stop: '2021-03-19T06:30:00.000Z', + episode: 238 + }, + channel + ) expect(program.episodeNumbers).toMatchObject([ { system: 'xmltv_ns', value: '0.237.0/1' }, @@ -193,13 +201,16 @@ it('can create program without season number', () => { }) it('can create program without episode number', () => { - const program = new Program({ - channel: channel.id, - title: 'Program 1', - start: '2021-03-19T06:00:00.000Z', - stop: '2021-03-19T06:30:00.000Z', - season: 3 - }) + const program = new Program( + { + channel: channel.id, + title: 'Program 1', + start: '2021-03-19T06:00:00.000Z', + stop: '2021-03-19T06:30:00.000Z', + season: 3 + }, + channel + ) expect(program.episodeNumbers).toMatchObject([]) }) diff --git a/tests/parser.test.js b/tests/parser.test.js index 6c57e50..6660db9 100644 --- a/tests/parser.test.js +++ b/tests/parser.test.js @@ -14,7 +14,7 @@ it('can parse valid channels.xml', () => { }) it('can parse programs', done => { - const channel = { xmltv_id: '1tv' } + const channel = new Channel({ xmltv_id: '1tv' }) const config = require('./input/example.config.js') parsePrograms({ channel, config }) @@ -27,7 +27,7 @@ it('can parse programs', done => { }) it('can parse programs async', done => { - const channel = { xmltv_id: '1tv' } + const channel = new Channel({ xmltv_id: '1tv' }) const config = require('./input/async.config.js') parsePrograms({ channel, config }) diff --git a/tests/xmltv.test.js b/tests/xmltv.test.js index 41cfe58..9be7711 100644 --- a/tests/xmltv.test.js +++ b/tests/xmltv.test.js @@ -14,11 +14,12 @@ const channels = [ new Channel({ xmltv_id: '2TV.co', name: '2 TV', - site: 'example.com' + site: 'example.com', + lang: 'es' }) ] -fit('can generate xmltv', () => { +it('can generate xmltv', () => { const programs = [ new Program( { @@ -33,7 +34,6 @@ fit('can generate xmltv', () => { season: 9, episode: 239, icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777', - channel: '1TV.co', rating: { system: 'MPAA', value: 'PG', @@ -60,12 +60,20 @@ fit('can generate xmltv', () => { writer: 'Writer 1' }, channels[0] + ), + new Program( + { + title: 'Program 2', + start: '2021-03-19T06:00:00.000Z', + stop: '2021-03-19T06:30:00.000Z' + }, + channels[1] ) ] const output = xmltv.generate({ channels, programs }) expect(output).toBe( - '\r\n1 TVhttps://example.com\r\n2 TVhttps://example.com\r\nProgram 1Sub-title & 1Description for Program 1Director 1http://example.com/director1.htmlhttps://example.com/image1.jpghttps://example.com/image2.jpgDirector 2Actor 1Actor 2Writer 120220506Testhttp://example.com/title.html8.238.0/1S09E239PG\r\n' + '\r\n1 TVhttps://example.com\r\n2 TVhttps://example.com\r\nProgram 1Sub-title & 1Description for Program 1Director 1http://example.com/director1.htmlhttps://example.com/image1.jpghttps://example.com/image2.jpgDirector 2Actor 1Actor 2Writer 120220506Testhttp://example.com/title.html8.238.0/1S09E239PG\r\nProgram 2\r\n' ) })