epg-grabber 0.46.2 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -368,7 +368,6 @@ And when the download is complete, a ready-to-use guide will appear in the locat
368
368
  <tv>
369
369
  <channel id="CNN.us">
370
370
  <display-name>CNN</display-name>
371
- <url>https://example.com</url>
372
371
  </channel>
373
372
  <programme start="20211116040000 +0000" stop="20211116050000 +0000" channel="CNN.us">
374
373
  <title lang="en">News at 10PM</title>
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env node
2
- import { n as name, v as version, d as description, p as parseNumber, l as loadJs, a as parseProxy, E as EPGGrabberMock, b as EPGGrabber, c as defaultConfig, i as isObject, g as getAbsPath, e as getUTCDate } from './index-Bnw63KMN.js';
1
+ #! /usr/bin/env node
2
+ import { n as name, v as version, d as description, p as parseNumber, l as loadJs, a as parseProxy, E as EPGGrabberMock, b as EPGGrabber, c as defaultConfig, i as isObject, g as getAbsPath, e as getUTCDate } from './index-B6SCP9dP.js';
3
3
  import { Collection, Template } from '@freearhey/core';
4
4
  import { Command, Option } from 'commander';
5
5
  import { SocksProxyAgent } from 'socks-proxy-agent';
@@ -220,7 +220,8 @@ async function main() {
220
220
  })
221
221
  );
222
222
  await Promise$1.all(requests.all());
223
- const xml = EPGGrabber.generateXMLTV(groupChannels.all(), programs.all(), utcDate);
223
+ const headers = { date: utcDate.format("YYYYMMDD") };
224
+ const xml = EPGGrabber.generateXMLTV(groupChannels.all(), programs.all(), headers);
224
225
  const channelSample = groupChannels.sample();
225
226
  let outputPath = template.format(channelSample.toObject());
226
227
  const outputDir = path$1.dirname(outputPath);
@@ -35,9 +35,6 @@ function parseNumber(value) {
35
35
  function sleep(ms) {
36
36
  return new Promise((resolve) => setTimeout(resolve, ms));
37
37
  }
38
- function isDate(date) {
39
- return dayjs(date).isValid();
40
- }
41
38
  function isObject(value) {
42
39
  return !!value && value.constructor === Object;
43
40
  }
@@ -65,9 +62,6 @@ function escapeString(value, defaultValue = "") {
65
62
  function formatDate(date, format) {
66
63
  return date ? dayjs.utc(date).format(format) : "";
67
64
  }
68
- function toURL(domain) {
69
- return domain ? `https://${domain}` : "";
70
- }
71
65
  function createXMLElement(name, attrs, children) {
72
66
  return convertXMLElementToString({ name, attrs, children });
73
67
  }
@@ -102,7 +96,7 @@ function toArray(value) {
102
96
  }
103
97
 
104
98
  var name = "epg-grabber";
105
- var version = "0.46.1";
99
+ var version = "0.48.0";
106
100
  var description = "Node.js CLI tool for grabbing EPG from different sites";
107
101
  var homepage = "https://github.com/freearhey/epg-grabber";
108
102
 
@@ -145,7 +139,7 @@ class Channel {
145
139
  this.site_id = data.site_id;
146
140
  this.lang = data.lang;
147
141
  this.logo = data.logo;
148
- this.url = data.url || toURL(data.site);
142
+ this.url = data.url;
149
143
  this.lcn = data.lcn;
150
144
  this.index = data.index !== void 0 ? data.index : -1;
151
145
  }
@@ -528,10 +522,13 @@ class Program {
528
522
  ...this.length.map(
529
523
  (length) => el("length", { units: length.units }, [escapeString(length.value)])
530
524
  ),
525
+ ...this.icons.map(
526
+ (icon) => el("icon", { src: icon.src, width: icon.width, height: icon.height })
527
+ ),
528
+ ...this.urls.map(createURLElement),
531
529
  ...this.countries.map(
532
530
  (country) => el("country", { lang: country.lang }, [escapeString(country.value)])
533
531
  ),
534
- ...this.urls.map(createURLElement),
535
532
  ...this.episodeNumbers.map(
536
533
  (episode) => el("episode-num", { system: episode.system }, [escapeString(episode.value)])
537
534
  ),
@@ -599,10 +596,7 @@ class Program {
599
596
  [escapeString(review.value || "")]
600
597
  )
601
598
  ),
602
- ...this.images.map(createImageElement),
603
- ...this.icons.map(
604
- (icon) => el("icon", { src: icon.src, width: icon.width, height: icon.height })
605
- )
599
+ ...this.images.map(createImageElement)
606
600
  ];
607
601
  return el(
608
602
  "programme",
@@ -799,18 +793,15 @@ class EPGGrabber {
799
793
  ).filter(Boolean);
800
794
  return channels;
801
795
  }
802
- static generateXMLTV(channels, programs, date = getUTCDate()) {
796
+ static generateXMLTV(channels, programs, headers) {
803
797
  if (!channels.every((channel) => channel instanceof Channel)) {
804
798
  throw new Error('"channels" must be an array of Channels');
805
799
  }
806
800
  if (!programs.every((program) => program instanceof Program)) {
807
801
  throw new Error('"programs" must be an array of Programs');
808
802
  }
809
- if (!isDate(date)) {
810
- throw new Error('"date" must be a valid date');
811
- }
812
803
  let output = `<?xml version="1.0" encoding="UTF-8" ?>`;
813
- output += createXMLElement("tv", { date: formatDate(date, "YYYYMMDD") }, [
804
+ output += createXMLElement("tv", headers, [
814
805
  ...channels.map((channel) => "\r\n" + channel.toXML()),
815
806
  ...programs.map((program) => "\r\n" + program.toXML()),
816
807
  "\r\n"
package/dist/index.d.ts CHANGED
@@ -710,7 +710,7 @@ declare class EPGGrabber {
710
710
  loadLogo(channel: Channel, date: string | number | Date | Dayjs | null, config?: SiteConfig): Promise<string | null>;
711
711
  grab(channel: Channel, date: string | number | Date | Dayjs | null, config?: SiteConfig | GrabCallback, callback?: GrabCallback): Promise<Program[]>;
712
712
  static parseChannelsXML(xml: string): Channel[];
713
- static generateXMLTV(channels: Channel[], programs: Program[], date?: Dayjs): string;
713
+ static generateXMLTV(channels: Channel[], programs: Program[], headers?: Record<string, string>): string;
714
714
  }
715
715
  declare class EPGGrabberMock extends EPGGrabber {
716
716
  grab(channel: Channel, date: string | number | Date | Dayjs | null, config?: SiteConfig | GrabCallback, callback?: GrabCallback): Promise<Program[]>;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env node
2
- export { C as Channel, b as EPGGrabber, E as EPGGrabberMock, P as Program } from './index-Bnw63KMN.js';
1
+ #! /usr/bin/env node
2
+ export { C as Channel, b as EPGGrabber, E as EPGGrabberMock, P as Program } from './index-B6SCP9dP.js';
3
3
  import 'axios-mock-adapter';
4
4
  import 'lodash.merge';
5
5
  import 'xml-js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "epg-grabber",
3
- "version": "0.46.2",
3
+ "version": "0.48.0",
4
4
  "description": "Node.js CLI tool for grabbing EPG from different sites",
5
5
  "homepage": "https://github.com/freearhey/epg-grabber",
6
6
  "preferGlobal": true,
@@ -18,7 +18,8 @@
18
18
  "build": "pkgroll --clean-dist",
19
19
  "dev": "pkgroll --watch",
20
20
  "lint": "npx eslint ./src/**/*.ts ./tests/**/*.ts",
21
- "test": "npx vitest run"
21
+ "test": "npx vitest run",
22
+ "prepublishOnly": "npm run build"
22
23
  },
23
24
  "publishConfig": {
24
25
  "registry": "https://registry.npmjs.org/"
package/src/cli.ts CHANGED
@@ -12,7 +12,6 @@ import defaultConfig from './default.config'
12
12
  import { Program, Channel } from './models'
13
13
  import { Logger } from './core/logger'
14
14
  import { SiteConfig } from './types'
15
- import { AxiosHeaders } from 'axios'
16
15
  import { TaskQueue } from 'cwait'
17
16
  import merge from 'lodash.merge'
18
17
  import Promise from 'bluebird'
@@ -265,7 +264,8 @@ async function main() {
265
264
 
266
265
  await Promise.all(requests.all())
267
266
 
268
- const xml = EPGGrabber.generateXMLTV(groupChannels.all(), programs.all(), utcDate)
267
+ const headers = { date: utcDate.format('YYYYMMDD') }
268
+ const xml = EPGGrabber.generateXMLTV(groupChannels.all(), programs.all(), headers)
269
269
  const channelSample = groupChannels.sample()
270
270
  let outputPath = template.format(channelSample.toObject() as { [key: string]: any })
271
271
  const outputDir = path.dirname(outputPath)
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { sleep, getUTCDate, isPromise, isDate, createXMLElement, formatDate } from './core/utils'
1
+ import { sleep, getUTCDate, isPromise, createXMLElement } from './core/utils'
2
2
  import { ProgramParserResult } from './types/program'
3
3
  import AxiosMockAdapter from 'axios-mock-adapter'
4
4
  import { SiteConfig } from './types/siteConfig'
@@ -136,7 +136,7 @@ export class EPGGrabber {
136
136
  static generateXMLTV(
137
137
  channels: Channel[],
138
138
  programs: Program[],
139
- date: Dayjs = getUTCDate()
139
+ headers?: Record<string, string>
140
140
  ): string {
141
141
  if (!channels.every((channel: Channel) => channel instanceof Channel)) {
142
142
  throw new Error('"channels" must be an array of Channels')
@@ -146,12 +146,8 @@ export class EPGGrabber {
146
146
  throw new Error('"programs" must be an array of Programs')
147
147
  }
148
148
 
149
- if (!isDate(date)) {
150
- throw new Error('"date" must be a valid date')
151
- }
152
-
153
149
  let output = `<?xml version="1.0" encoding="UTF-8" ?>`
154
- output += createXMLElement('tv', { date: formatDate(date, 'YYYYMMDD') }, [
150
+ output += createXMLElement('tv', headers, [
155
151
  ...channels.map((channel: Channel) => '\r\n' + channel.toXML()),
156
152
  ...programs.map((program: Program) => '\r\n' + program.toXML()),
157
153
  '\r\n'
@@ -1,4 +1,4 @@
1
- import { toURL, escapeString, createXMLElement } from '../core/utils'
1
+ import { escapeString, createXMLElement } from '../core/utils'
2
2
  import { ChannelData } from '../types/channel'
3
3
  import xmlJs from 'xml-js'
4
4
 
@@ -20,7 +20,7 @@ export class Channel {
20
20
  this.site_id = data.site_id
21
21
  this.lang = data.lang
22
22
  this.logo = data.logo
23
- this.url = data.url || toURL(data.site)
23
+ this.url = data.url
24
24
  this.lcn = data.lcn
25
25
  this.index = data.index !== undefined ? data.index : -1
26
26
  }
@@ -438,10 +438,13 @@ export class Program {
438
438
  ...this.length.map(length =>
439
439
  el('length', { units: length.units }, [escapeString(length.value)])
440
440
  ),
441
+ ...this.icons.map(icon =>
442
+ el('icon', { src: icon.src, width: icon.width, height: icon.height })
443
+ ),
444
+ ...this.urls.map(createURLElement),
441
445
  ...this.countries.map(country =>
442
446
  el('country', { lang: country.lang }, [escapeString(country.value)])
443
447
  ),
444
- ...this.urls.map(createURLElement),
445
448
  ...this.episodeNumbers.map(episode =>
446
449
  el('episode-num', { system: episode.system }, [escapeString(episode.value)])
447
450
  ),
@@ -513,10 +516,7 @@ export class Program {
513
516
  [escapeString(review.value || '')]
514
517
  )
515
518
  ),
516
- ...this.images.map(createImageElement),
517
- ...this.icons.map(icon =>
518
- el('icon', { src: icon.src, width: icon.width, height: icon.height })
519
- )
519
+ ...this.images.map(createImageElement)
520
520
  ]
521
521
 
522
522
  return el(
@@ -1,8 +1,8 @@
1
1
  <?xml version="1.0" encoding="UTF-8" ?><tv date="20251028">
2
- <channel id="3TV.com"><display-name>3 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example2.com</url></channel>
3
- <channel id="4TV.com"><display-name>4 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example2.com</url></channel>
4
- <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>
5
- <channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example.com</url></channel>
2
+ <channel id="3TV.com"><display-name>3 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
3
+ <channel id="4TV.com"><display-name>4 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
4
+ <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/></channel>
5
+ <channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
6
6
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="3TV.com"><title>Program1</title></programme>
7
7
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="3TV.com"><title>Program1</title></programme>
8
8
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="2TV.com"><title>Program1</title></programme>
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8" ?><tv date="20251028">
2
- <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url><lcn>36</lcn></channel>
3
- <channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example.com</url></channel>
2
+ <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><lcn>36</lcn></channel>
3
+ <channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
4
4
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="1TV.com"><title lang="fr">Program1</title></programme>
5
5
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="1TV.com"><title lang="fr">Program1</title></programme>
6
6
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="2TV.com"><title>Program1</title></programme>
@@ -1,3 +1,3 @@
1
1
  <?xml version="1.0" encoding="UTF-8" ?><tv date="20251028">
2
- <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url><lcn>36</lcn></channel>
2
+ <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><lcn>36</lcn></channel>
3
3
  </tv>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?><tv date="20220505">
2
+ <channel id="1TV.co"><display-name>1 TV</display-name><icon src="https://example.com/channel_one_icon.jpg"/><url>https://example.com/channel_one?foo=foo&amp;bar=bar</url><lcn>36</lcn></channel>
3
+ <channel id="2TV.co"><display-name>2 TV</display-name><icon src="https://example.com/logos/2TV.png"/></channel>
4
+ <channel id="3TV.co"><display-name>3 TV</display-name></channel>
5
+ <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><keyword lang="en">physical-comedy</keyword><keyword lang="en">romantic</keyword><language>English</language><orig-language lang="en">French</orig-language><length units="minutes">60</length><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/><url>http://example.com/title.html</url><country>US</country><episode-num system="xmltv_ns">8.238.0/1</episode-num><episode-num system="onscreen">S09E239</episode-num><video><present>yes</present><colour>no</colour><aspect>16:9</aspect><quality>HDTV</quality></video><audio><present>yes</present><stereo>Dolby Digital</stereo></audio><previously-shown/><premiere>First time on British TV</premiere><last-chance lang="en">Last time on this channel</last-chance><new/><subtitles type="teletext"><language>English</language></subtitles><subtitles type="onscreen"><language lang="en">Spanish</language></subtitles><rating system="MPAA"><value>P&amp;G</value><icon src="http://example.com/pg_symbol.png"/></rating><star-rating system="TV Guide"><value>4/5</value><icon src="stars.png"/></star-rating><star-rating system="IMDB"><value>8/10</value></star-rating><review type="text" source="Rotten Tomatoes" reviewer="Joe Bloggs" lang="en">This is a fantastic show!</review><review type="text" source="IDMB" reviewer="Jane Doe" lang="en">I love this show!</review><review type="url" source="Rotten Tomatoes" reviewer="Joe Bloggs" lang="en">https://example.com/programme_one_review</review><image type="poster" size="1" orient="P" system="tvdb">https://tvdb.com/programme_one_poster_1.jpg?foo=foo&amp;bar=bar</image><image type="poster" size="2" orient="P" system="tmdb">https://tmdb.com/programme_one_poster_2.jpg</image><image type="backdrop" size="3" orient="L" system="tvdb">https://tvdb.com/programme_one_backdrop_3.jpg</image><image type="backdrop" size="3" orient="L" system="tmdb">https://tmdb.com/programme_one_backdrop_3.jpg</image></programme>
6
+ <programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="2TV.co"><title lang="es">Program 2</title></programme>
7
+ </tv>
@@ -1,4 +1,4 @@
1
1
  <?xml version="1.0" encoding="UTF-8" ?><tv date="20251028">
2
- <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url><lcn>36</lcn></channel>
3
- <channel id="2TV.com"><display-name>2 TV</display-name><url>https://example.com</url></channel>
2
+ <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><lcn>36</lcn></channel>
3
+ <channel id="2TV.com"><display-name>2 TV</display-name></channel>
4
4
  </tv>
@@ -1,3 +1,3 @@
1
1
  <?xml version="1.0" encoding="UTF-8" ?><tv date="20251028">
2
- <channel id="2TV.com"><display-name>2 TV</display-name><url>https://example.com</url></channel>
2
+ <channel id="2TV.com"><display-name>2 TV</display-name></channel>
3
3
  </tv>
@@ -1,8 +1,8 @@
1
1
  <?xml version="1.0" encoding="UTF-8" ?><tv date="20251028">
2
- <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/><url>https://example.com</url></channel>
3
- <channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example.com</url></channel>
4
- <channel id="3TV.com"><display-name>3 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example2.com</url></channel>
5
- <channel id="4TV.com"><display-name>4 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/><url>https://example2.com</url></channel>
2
+ <channel id="1TV.com"><display-name>1 TV</display-name><icon src="https://example.com/logos/1TV.png"/></channel>
3
+ <channel id="2TV.com"><display-name>2 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
4
+ <channel id="3TV.com"><display-name>3 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
5
+ <channel id="4TV.com"><display-name>4 TV</display-name><icon src="http://example.com/logos/1TV.png?x=шеллы&amp;sid=777"/></channel>
6
6
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="1TV.com"><title lang="fr">Program1</title></programme>
7
7
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="4TV.com"><title>Program1</title></programme>
8
8
  <programme start="20220101000000 +0000" stop="20220101010000 +0000" channel="3TV.com"><title>Program1</title></programme>
@@ -7,8 +7,10 @@ import { EPGGrabber, EPGGrabberMock } from '../src/index'
7
7
  import { SiteConfig } from '../src/types/siteConfig'
8
8
  import * as epgGrabber from '../src/index'
9
9
  import { http, HttpResponse } from 'msw'
10
+ import { pathToFileURL } from 'node:url'
10
11
  import { setupServer } from 'msw/node'
11
12
  import path from 'node:path'
13
+ import dayjs from 'dayjs'
12
14
  import fs from 'fs-extra'
13
15
 
14
16
  describe('EPGGrabber', () => {
@@ -444,11 +446,11 @@ describe('EPGGrabber', () => {
444
446
  })
445
447
  ]
446
448
 
447
- const output = EPGGrabber.generateXMLTV(channels, programs)
449
+ const output = EPGGrabber.generateXMLTV(channels, programs, { date: dayjs.utc().format('YYYYMMDD') })
448
450
 
449
- expect(output).toBe(
450
- '<?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/channel_one_icon.jpg"/><url>https://example.com/channel_one?foo=foo&amp;bar=bar</url><lcn>36</lcn></channel>\r\n<channel id="2TV.co"><display-name>2 TV</display-name><icon src="https://example.com/logos/2TV.png"/><url>https://example.com</url></channel>\r\n<channel id="3TV.co"><display-name>3 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><keyword lang="en">physical-comedy</keyword><keyword lang="en">romantic</keyword><language>English</language><orig-language lang="en">French</orig-language><length units="minutes">60</length><country>US</country><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><video><present>yes</present><colour>no</colour><aspect>16:9</aspect><quality>HDTV</quality></video><audio><present>yes</present><stereo>Dolby Digital</stereo></audio><previously-shown/><premiere>First time on British TV</premiere><last-chance lang="en">Last time on this channel</last-chance><new/><subtitles type="teletext"><language>English</language></subtitles><subtitles type="onscreen"><language lang="en">Spanish</language></subtitles><rating system="MPAA"><value>P&amp;G</value><icon src="http://example.com/pg_symbol.png"/></rating><star-rating system="TV Guide"><value>4/5</value><icon src="stars.png"/></star-rating><star-rating system="IMDB"><value>8/10</value></star-rating><review type="text" source="Rotten Tomatoes" reviewer="Joe Bloggs" lang="en">This is a fantastic show!</review><review type="text" source="IDMB" reviewer="Jane Doe" lang="en">I love this show!</review><review type="url" source="Rotten Tomatoes" reviewer="Joe Bloggs" lang="en">https://example.com/programme_one_review</review><image type="poster" size="1" orient="P" system="tvdb">https://tvdb.com/programme_one_poster_1.jpg?foo=foo&amp;bar=bar</image><image type="poster" size="2" orient="P" system="tmdb">https://tmdb.com/programme_one_poster_2.jpg</image><image type="backdrop" size="3" orient="L" system="tvdb">https://tvdb.com/programme_one_backdrop_3.jpg</image><image type="backdrop" size="3" orient="L" system="tmdb">https://tmdb.com/programme_one_backdrop_3.jpg</image><icon src="https://example.com/images/Program1.png?x=шеллы&amp;sid=777"/></programme>\r\n<programme start="20210319060000 +0000" stop="20210319063000 +0000" channel="2TV.co"><title lang="es">Program 2</title></programme>\r\n</tv>'
451
- )
451
+ expect(output).toEqual(
452
+ fs.readFileSync(pathToFileURL('tests/__data__/expected/index.guide.xml'), 'utf8')
453
+ )
452
454
  })
453
455
  })
454
456
  })