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'
)
})