This commit is contained in:
Aleksandr Statciuk 2022-06-16 19:11:11 +03:00
parent cc54269b6b
commit 436bea6761
7 changed files with 147 additions and 75 deletions

View File

@ -1,13 +1,13 @@
class Channel {
constructor(c) {
const data = {
id: c.xmltv_id,
id: c.id || c.xmltv_id,
name: c.name,
site: c.site || '',
site_id: c.site_id,
lang: c.lang || '',
logo: c.logo || '',
url: c.site ? `https://${c.site}` : ''
url: c.url || toURL(c.site)
}
for (let key in data) {
@ -17,3 +17,7 @@ class Channel {
}
module.exports = Channel
function toURL(site) {
return site ? `https://${site}` : ''
}

View File

@ -2,18 +2,18 @@ const { padStart } = require('lodash')
const { toArray, toUnix, parseNumber } = require('./utils')
class Program {
constructor(p, c) {
constructor(p) {
const data = {
channel: c.id,
channel: p.channel,
title: p.title,
sub_title: p.sub_title || '',
description: p.description || p.desc,
description: [p.description, p.desc, ''].find(i => i !== undefined),
icon: toIconObject(p.icon),
episodeNumbers: getEpisodeNumbers(p.season, p.episode),
date: p.date ? toUnix(p.date) : null,
start: toUnix(p.start),
stop: toUnix(p.stop),
urls: toArray(p.url).map(toUrlObject),
urls: toArray(p.urls || p.url).map(toUrlObject),
ratings: toArray(p.ratings || p.rating).map(toRatingObject),
categories: toArray(p.categories || p.category),
directors: toArray(p.directors || p.director).map(toPersonObject),

View File

@ -18,12 +18,12 @@ function parseChannels(xml) {
const channels = channelsTag.elements
.filter(el => el.name === 'channel')
.map(el => {
const data = el.attributes
data.name = el.elements.find(el => el.type === 'text').text
data.site = data.site || rootSite
if (!data.name) throw new Error(`Channel '${data.xmltv_id}' has no valid name`)
const c = el.attributes
c.name = el.elements.find(el => el.type === 'text').text
c.site = c.site || rootSite
if (!c.name) throw new Error(`Channel '${c.xmltv_id}' has no valid name`)
return new Channel(data)
return new Channel(c)
})
return { site: rootSite, channels }
@ -41,5 +41,11 @@ async function parsePrograms(data) {
throw new Error('Parser should return an array')
}
return programs.filter(i => i).map(p => new Program(p, channel))
return programs
.filter(i => i)
.map(p => {
p.channel = p.channel || channel.id
return new Program(p)
})
}

View File

@ -64,7 +64,8 @@ function createElements(channels, programs, date) {
]
)
)
})
}),
'\r\n'
])
}

View File

@ -20,3 +20,24 @@ it('can create new Channel', () => {
logo: 'https://example.com/logos/1TV.png'
})
})
it('can create channel from exist object', () => {
const channel = new Channel({
name: '1 TV',
id: '1TV.com',
site_id: '1',
site: 'example.com',
lang: 'fr',
logo: 'https://example.com/logos/1TV.png'
})
expect(channel).toMatchObject({
name: '1 TV',
id: '1TV.com',
site_id: '1',
site: 'example.com',
url: 'https://example.com',
lang: 'fr',
logo: 'https://example.com/logos/1TV.png'
})
})

View File

@ -4,50 +4,48 @@ import Program from '../src/Program'
const channel = new Channel({ xmltv_id: '1tv', lang: 'en' })
it('can create new Program', () => {
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']
}
]
const program = new Program({
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'
},
channel
)
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']
}
]
})
expect(program).toMatchObject({
channel: '1tv',
@ -131,16 +129,60 @@ it('can create new Program', () => {
})
})
it('can create program without season number', () => {
const program = new Program(
{
title: 'Program 1',
start: '2021-03-19T06:00:00.000Z',
stop: '2021-03-19T06:30:00.000Z',
episode: 238
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'
},
channel
)
actors: [{ value: 'Actor1', url: [], image: [] }]
})
expect(program).toMatchObject({
channel: '1tv',
title: 'Program 1',
sub_title: '',
description: '',
urls: [],
categories: [],
icon: {},
episodeNumbers: [],
date: null,
start: 1616133600000,
stop: 1616135400000,
ratings: [
{
system: 'MPAA',
value: 'PG',
icon: 'http://example.com/pg_symbol.png'
}
],
directors: [],
actors: [{ value: 'Actor1', url: [], image: [] }],
writers: [],
adapters: [],
producers: [],
composers: [],
editors: [],
presenters: [],
commentators: [],
guests: []
})
})
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
})
expect(program.episodeNumbers).toMatchObject([
{ system: 'xmltv_ns', value: '0.237.0/1' },
@ -149,15 +191,13 @@ it('can create program without season number', () => {
})
it('can create program without episode number', () => {
const program = new Program(
{
title: 'Program 1',
start: '2021-03-19T06:00:00.000Z',
stop: '2021-03-19T06:30:00.000Z',
season: 3
},
channel
)
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
})
expect(program.episodeNumbers).toMatchObject([])
})

View File

@ -66,6 +66,6 @@ fit('can generate xmltv', () => {
const output = xmltv.generate({ channels, programs })
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></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</tv>'
)
})