Added support of lang attribute

This commit is contained in:
Aleksandr Statciuk 2022-07-01 02:45:59 +03:00
parent 953c43a4b5
commit dd54b9f0ef
6 changed files with 138 additions and 100 deletions

View File

@ -1,14 +1,21 @@
const { padStart } = require('lodash') const { padStart } = require('lodash')
const { toArray, toUnix, parseNumber } = require('./utils') const { toArray, toUnix, parseNumber } = require('./utils')
const Channel = require('./Channel')
class Program { 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 = { const data = {
site: p.site || '', site: p.site || c.site || '',
channel: p.channel || '', channel: p.channel || c.id || '',
title: p.title || '', titles: toArray(p.titles || p.title).map(text => toTextObject(text, c.lang)),
sub_title: p.sub_title || '', sub_titles: toArray(p.sub_titles || p.sub_title).map(text => toTextObject(text, c.lang)),
description: [p.description, p.desc].find(i => i) || '', descriptions: toArray(p.descriptions || p.description || p.desc).map(text =>
toTextObject(text, c.lang)
),
icon: toIconObject(p.icon), icon: toIconObject(p.icon),
episodeNumbers: p.episodeNumbers || getEpisodeNumbers(p.season, p.episode), episodeNumbers: p.episodeNumbers || getEpisodeNumbers(p.season, p.episode),
date: p.date ? toUnix(p.date) : null, date: p.date ? toUnix(p.date) : null,
@ -16,7 +23,7 @@ class Program {
stop: p.stop ? toUnix(p.stop) : null, stop: p.stop ? toUnix(p.stop) : null,
urls: toArray(p.urls || p.url).map(toUrlObject), urls: toArray(p.urls || p.url).map(toUrlObject),
ratings: toArray(p.ratings || p.rating).map(toRatingObject), 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), directors: toArray(p.directors || p.director).map(toPersonObject),
actors: toArray(p.actors || p.actor).map(toPersonObject), actors: toArray(p.actors || p.actor).map(toPersonObject),
writers: toArray(p.writers || p.writer).map(toPersonObject), writers: toArray(p.writers || p.writer).map(toPersonObject),
@ -37,6 +44,17 @@ class Program {
module.exports = 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) { function toPersonObject(person) {
if (typeof person === 'string') { if (typeof person === 'string') {
return { return {

View File

@ -41,12 +41,5 @@ async function parsePrograms(data) {
throw new Error('Parser should return an array') throw new Error('Parser should return an array')
} }
return programs return programs.filter(i => i).map(p => new Program(p, channel))
.filter(i => i)
.map(p => {
p.site = channel.site
p.channel = p.channel || channel.id
return new Program(p)
})
} }

View File

@ -47,9 +47,15 @@ function createElements(channels, programs, date) {
channel: program.channel channel: program.channel
}, },
[ [
el('title', {}, [escapeString(program.title)]), ...program.titles.map(title =>
el('sub-title', {}, [escapeString(program.sub_title)]), el('title', { lang: title.lang }, [escapeString(title.value)])
el('desc', {}, [escapeString(program.description)]), ),
...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', {}, [ el('credits', {}, [
...program.directors.map(data => createCastMember('director', data)), ...program.directors.map(data => createCastMember('director', data)),
...program.actors.map(data => createCastMember('actor', data)), ...program.actors.map(data => createCastMember('actor', data)),
@ -63,7 +69,9 @@ function createElements(channels, programs, date) {
...program.guests.map(data => createCastMember('guest', data)) ...program.guests.map(data => createCastMember('guest', data))
]), ]),
el('date', {}, [formatDate(program.date, 'YYYYMMDD')]), 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 }), el('icon', { src: program.icon.src }),
...program.urls.map(createURL), ...program.urls.map(createURL),
...program.episodeNumbers.map(episode => ...program.episodeNumbers.map(episode =>

View File

@ -1,61 +1,65 @@
import Channel from '../src/Channel' import Channel from '../src/Channel'
import Program from '../src/Program' 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', () => { it('can create new Program', () => {
const program = new Program({ const program = new Program(
site: channel.site, {
channel: channel.id, title: 'Title',
title: 'Title', sub_title: 'Subtitle',
sub_title: 'Subtitle', description: 'Description',
description: 'Description', icon: 'https://example.com/image.jpg',
icon: 'https://example.com/image.jpg', season: 9,
season: 9, episode: 238,
episode: 238, date: '20220506',
date: '20220506', start: 1616133600000,
start: 1616133600000, stop: '2021-03-19T06:30:00.000Z',
stop: '2021-03-19T06:30:00.000Z', url: 'http://example.com/title.html',
url: 'http://example.com/title.html', category: ['Category1', 'Category2'],
category: ['Category1', 'Category2'], rating: {
rating: { system: 'MPAA',
system: 'MPAA', value: 'PG',
value: 'PG', icon: 'http://example.com/pg_symbol.png'
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', channel
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']
}
]
})
expect(program).toMatchObject({ expect(program).toMatchObject({
site: 'example.com', site: 'example.com',
channel: '1tv', channel: '1tv',
title: 'Title', titles: [{ value: 'Title', lang: 'fr' }],
sub_title: 'Subtitle', sub_titles: [{ value: 'Subtitle', lang: 'fr' }],
description: 'Description', descriptions: [{ value: 'Description', lang: 'fr' }],
urls: [{ system: '', value: 'http://example.com/title.html' }], 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' }, icon: { src: 'https://example.com/image.jpg' },
episodeNumbers: [ episodeNumbers: [
{ system: 'xmltv_ns', value: '8.237.0/1' }, { system: 'xmltv_ns', value: '8.237.0/1' },
@ -132,24 +136,26 @@ it('can create new Program', () => {
}) })
it('can create program from exist object', () => { it('can create program from exist object', () => {
const program = new Program({ const program = new Program(
channel: channel.id, {
title: 'Program 1', titles: [{ value: 'Program 1', lang: 'de' }],
start: '2021-03-19T06:00:00.000Z', start: '2021-03-19T06:00:00.000Z',
stop: '2021-03-19T06:30:00.000Z', stop: '2021-03-19T06:30:00.000Z',
ratings: { ratings: {
system: 'MPAA', system: 'MPAA',
value: 'PG', value: 'PG',
icon: 'http://example.com/pg_symbol.png' icon: 'http://example.com/pg_symbol.png'
},
actors: [{ value: 'Actor1', url: [], image: [] }]
}, },
actors: [{ value: 'Actor1', url: [], image: [] }] channel
}) )
expect(program).toMatchObject({ expect(program).toMatchObject({
channel: '1tv', channel: '1tv',
title: 'Program 1', titles: [{ value: 'Program 1', lang: 'de' }],
sub_title: '', sub_titles: [],
description: '', descriptions: [],
urls: [], urls: [],
categories: [], categories: [],
icon: {}, icon: {},
@ -178,13 +184,15 @@ it('can create program from exist object', () => {
}) })
it('can create program without season number', () => { it('can create program without season number', () => {
const program = new Program({ const program = new Program(
channel: channel.id, {
title: 'Program 1', title: 'Program 1',
start: '2021-03-19T06:00:00.000Z', start: '2021-03-19T06:00:00.000Z',
stop: '2021-03-19T06:30:00.000Z', stop: '2021-03-19T06:30:00.000Z',
episode: 238 episode: 238
}) },
channel
)
expect(program.episodeNumbers).toMatchObject([ expect(program.episodeNumbers).toMatchObject([
{ system: 'xmltv_ns', value: '0.237.0/1' }, { 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', () => { it('can create program without episode number', () => {
const program = new Program({ const program = new Program(
channel: channel.id, {
title: 'Program 1', channel: channel.id,
start: '2021-03-19T06:00:00.000Z', title: 'Program 1',
stop: '2021-03-19T06:30:00.000Z', start: '2021-03-19T06:00:00.000Z',
season: 3 stop: '2021-03-19T06:30:00.000Z',
}) season: 3
},
channel
)
expect(program.episodeNumbers).toMatchObject([]) expect(program.episodeNumbers).toMatchObject([])
}) })

View File

@ -14,7 +14,7 @@ it('can parse valid channels.xml', () => {
}) })
it('can parse programs', done => { it('can parse programs', done => {
const channel = { xmltv_id: '1tv' } const channel = new Channel({ xmltv_id: '1tv' })
const config = require('./input/example.config.js') const config = require('./input/example.config.js')
parsePrograms({ channel, config }) parsePrograms({ channel, config })
@ -27,7 +27,7 @@ it('can parse programs', done => {
}) })
it('can parse programs async', 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') const config = require('./input/async.config.js')
parsePrograms({ channel, config }) parsePrograms({ channel, config })

View File

@ -14,11 +14,12 @@ const channels = [
new Channel({ new Channel({
xmltv_id: '2TV.co', xmltv_id: '2TV.co',
name: '2 TV', name: '2 TV',
site: 'example.com' site: 'example.com',
lang: 'es'
}) })
] ]
fit('can generate xmltv', () => { it('can generate xmltv', () => {
const programs = [ const programs = [
new Program( new Program(
{ {
@ -33,7 +34,6 @@ fit('can generate xmltv', () => {
season: 9, season: 9,
episode: 239, episode: 239,
icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777', icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777',
channel: '1TV.co',
rating: { rating: {
system: 'MPAA', system: 'MPAA',
value: 'PG', value: 'PG',
@ -60,12 +60,20 @@ fit('can generate xmltv', () => {
writer: 'Writer 1' writer: 'Writer 1'
}, },
channels[0] 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 }) const output = xmltv.generate({ channels, programs })
expect(output).toBe( expect(output).toBe(
'<?xml version="1.0" encoding="UTF-8" ?><tv date="20220505">\r\n<channel id="1TV.co"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>\r\n<channel id="2TV.co"><display-name>2 TV</display-name><url>https://example.com</url></channel>\r\n<programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="1TV.co"><title>Program 1</title><sub-title>Sub-title &amp; 1</sub-title><desc>Description for Program 1</desc><credits><director>Director 1<url system="TestSystem">http://example.com/director1.html</url><image>https://example.com/image1.jpg</image><image type="person" size="2" orient="P" system="TestSystem">https://example.com/image2.jpg</image></director><director>Director 2</director><actor>Actor 1</actor><actor>Actor 2</actor><writer>Writer 1</writer></credits><date>20220506</date><category>Test</category><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/><url>http://example.com/title.html</url><episode-num system="xmltv_ns">8.238.0/1</episode-num><episode-num system="onscreen">S09E239</episode-num><rating system="MPAA"><value>PG</value><icon src="http://example.com/pg_symbol.png"/></rating></programme>\r\n</tv>' '<?xml version="1.0" encoding="UTF-8" ?><tv date="20220505">\r\n<channel id="1TV.co"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>\r\n<channel id="2TV.co"><display-name>2 TV</display-name><url>https://example.com</url></channel>\r\n<programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="1TV.co"><title>Program 1</title><sub-title>Sub-title &amp; 1</sub-title><desc>Description for Program 1</desc><credits><director>Director 1<url system="TestSystem">http://example.com/director1.html</url><image>https://example.com/image1.jpg</image><image type="person" size="2" orient="P" system="TestSystem">https://example.com/image2.jpg</image></director><director>Director 2</director><actor>Actor 1</actor><actor>Actor 2</actor><writer>Writer 1</writer></credits><date>20220506</date><category>Test</category><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/><url>http://example.com/title.html</url><episode-num system="xmltv_ns">8.238.0/1</episode-num><episode-num system="onscreen">S09E239</episode-num><rating system="MPAA"><value>PG</value><icon src="http://example.com/pg_symbol.png"/></rating></programme>\r\n<programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="2TV.co"><title lang="es">Program 2</title></programme>\r\n</tv>'
) )
}) })