0.38.0 • Published 5 months ago

epg-grabber v0.38.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

EPG Grabber test

Node.js CLI tool for grabbing EPG from different websites.

Installation

npm install -g epg-grabber

Quick Start

epg-grabber --config=example.com.config.js

example.com.config.js

module.exports = {
  site: 'example.com',
  channels: 'example.com.channels.xml',
  url: function (context) {
    const { date, channel } = context

    return `https://api.example.com/${date.format('YYYY-MM-DD')}/channel/${channel.site_id}`
  },
  parser: function (context) {
    const programs = JSON.parse(context.content)

    return programs.map(program => {
      return {
        title: program.title,
        start: program.start,
        stop: program.stop
      }
    })
  }
}

example.com.channels.xml

<?xml version="1.0" ?>
<channels site="example.com">
  <channel site_id="cnn-23" xmltv_id="CNN.us">CNN</channel>
</channels>

Example Output

<tv>
  <channel id="CNN.us">
    <display-name>CNN</display-name>
    <url>https://example.com</url>
  </channel>
  <programme start="20211116040000 +0000" stop="20211116050000 +0000" channel="CNN.us">
    <title lang="en">News at 10PM</title>
  </programme>
  // ...
</tv>

CLI

epg-grabber --config=example.com.config.js

Arguments:

  • -c, --config: path to config file
  • -o, --output: path to output file or path template (example: guides/{site}.{lang}.xml; default: guide.xml)
  • -x, --proxy: use the specified proxy
  • --channels: path to list of channels; you can also use wildcard to specify the path to multiple files at once (example: example.com_*.channels.xml)
  • --lang: set default language for all programs (default: en)
  • --days: number of days for which to grab the program (default: 1)
  • --delay: delay between requests in milliseconds (default: 3000)
  • --timeout: set a timeout for each request in milliseconds (default: 5000)
  • --max-connections: set a limit on the number of concurrent requests per site (default: 1)
  • --cache-ttl: maximum time for storing each request in milliseconds (default: 0)
  • --gzip: compress the output (default: false)
  • --debug: enable debug mode (default: false)
  • --curl: display current request as CURL (default: false)
  • --log: path to log file (optional)
  • --log-level: set the log level (default: info)

Site Config

module.exports = {
  site: 'example.com', // site domain name (required)
  output: 'example.com.guide.xml', // path to output file or path template (example: 'guides/{site}.{lang}.xml'; default: 'guide.xml')
  channels: 'example.com.channels.xml', // path to list of channels; you can also use an array to specify the path to multiple files at once (example: ['channels1.xml', 'channels2.xml']; required)
  lang: 'fr', // default language for all programs (default: 'en')
  days: 3, // number of days for which to grab the program (default: 1)
  delay: 5000, // delay between requests (default: 3000)
  maxConnections: 200, // limit on the number of concurrent requests (default: 1)

  request: { // request options (details: https://github.com/axios/axios#request-config)

    method: 'GET',
    timeout: 5000,
    proxy: {
      protocol: 'https',
      host: '127.0.0.1',
      port: 9000,
      auth: {
        username: 'mikeymike',
        password: 'rapunz3l'
      }
    },
    cache: { // cache options (details: https://axios-cache-interceptor.js.org/#/pages/per-request-configuration)
      ttl: 60 * 1000 // 60s
    },

    /**
     * @param {object} context
     *
     * @return {string} The function should return headers for each request (optional)
     */
    headers: function(context) {
      return {
        'User-Agent':
          'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71'
      }
    },

    /**
     * @param {object} context
     *
     * @return {string} The function should return data for each request (optional)
     */
    data: function(context) {
      const { channel, date } = context

      return {
        channels: [channel.site_id],
        dateStart: date.format('YYYY-MM-DDT00:00:00-00:00'),
        dateEnd: date.add(1, 'd').format('YYYY-MM-DDT00:00:00-00:00')
      }
    }
  },

  /**
   * @param {object} context
   *
   * @return {string} The function should return URL of the program page for the channel
   */
  url: function (context) {
    return `https://example.com/${context.date.format('YYYY-MM-DD')}/channel/${context.channel.site_id}.html`
  },

  /**
   * @param {object} context
   *
   * @return {string} The function should return URL of the channel logo (optional)
   */
  logo: function (context) {
    return `https://example.com/logos/${context.channel.site_id}.png`
  },

  /**
   * @param {object} context
   *
   * @return {array} The function should return an array of programs with their descriptions
   */
  parser: function (context) {

    // content parsing...

    return [
      {
        title,
        start,
        stop
      },
      ...
    ]
  }
}

Context Object

From each function in config.js you can access a context object containing the following data:

  • channel: The object describing the current channel (xmltv_id, site_id, name, lang)
  • date: The 'dayjs' instance with the requested date
  • content: The response data as a String
  • buffer: The response data as an ArrayBuffer
  • headers: The response headers
  • request: The request config
  • cached: A boolean to check whether this request was cached or not

Program Object

PropertyAliasesTypeRequired
startString or Number or Date()true
stopString or Number or Date()true
titletitlesString or Object or String[] or Object[]true
subTitlesubTitles, sub_title, sub_titlesString or Object or String[] or Object[]false
descriptiondesc, descriptionsString or Object or String[] or Object[]false
dateString or Number or Date()false
categorycategoriesString or Object or String[] or Object[]false
keywordkeywordsString or Object or String[] or Object[]false
languagelanguagesString or Object or String[] or Object[]false
origLanguageorigLanguagesString or Object or String[] or Object[]false
lengthString or Object or String[] or Object[]false
urlurlsString or Object or String[] or Object[]false
countrycountriesString or Object or String[] or Object[]false
videoObjectfalse
audioObjectfalse
seasonString or Numberfalse
episodeString or Numberfalse
episodeNumberepisodeNum, episodeNumbersObjectfalse
previouslyShownString or Object or String[] or Object[]false
premiereString or Object or String[] or Object[]false
lastChanceString or Object or String[] or Object[]false
newBooleanfalse
subtitlesObject or Object[]false
ratingratingsString or Object or String[] or Object[]false
starRatingstarRatingsString or Object or String[] or Object[]false
reviewreviewsString or Object or String[] or Object[]false
directordirectorsString or Object or String[] or Object[]false
actoractorsString or Object or String[] or Object[]false
writerwritersString or Object or String[] or Object[]false
adapteradaptersString or Object or String[] or Object[]false
producerproducersString or Object or String[] or Object[]false
presenterpresentersString or Object or String[] or Object[]false
composercomposersString or Object or String[] or Object[]false
editoreditorsString or Object or String[] or Object[]false
commentatorcommentatorsString or Object or String[] or Object[]false
guestguestsString or Object or String[] or Object[]false
imageimagesString or Object or String[] or Object[]false
iconiconsString or Object or String[] or Object[]false

Example:

{
  start: '2021-03-19T06:00:00.000Z',
  stop: '2021-03-19T06:30:00.000Z',
  title: 'Program 1',
  subTitle: 'Sub-title & 1',
  description: 'Description for Program 1',
  date: '2022-05-06',
  categories: ['Comedy', 'Drama'],
  keywords: [
    { lang: 'en', value: 'physical-comedy' },
    { lang: 'en', value: 'romantic' }
  ],
  language: 'English',
  origLanguage: { lang: 'en', value: 'French' },
  length: { units: 'minutes', value: '60' },
  url: 'http://example.com/title.html',
  country: 'US',
  video: {
    present: 'yes',
    colour: 'no',
    aspect: '16:9',
    quality: 'HDTV'
  },
  audio: {
    present: 'yes',
    stereo: 'Dolby Digital'
  },
  season: 9,
  episode: 239,
  previouslyShown: [{ start: '20080711000000', channel: 'channel-two.tv' }],
  premiere: 'First time on British TV',
  lastChance: [{ lang: 'en', value: 'Last time on this channel' }],
  new: true,
  subtitles: [
    { type: 'teletext', language: 'English' },
    { type: 'onscreen', language: [{ lang: 'en', value: 'Spanish' }] }
  ],
  rating: {
    system: 'MPAA',
    value: 'P&G',
    icon: 'http://example.com/pg_symbol.png'
  },
  starRatings: [
    {
      system: 'TV Guide',
      value: '4/5',
      icon: [{ src: 'stars.png', width: 100, height: 100 }]
    },
    {
      system: 'IMDB',
      value: '8/10'
    }
  ],
  reviews: [
    {
      type: 'text',
      source: 'Rotten Tomatoes',
      reviewer: 'Joe Bloggs',
      lang: 'en',
      value: 'This is a fantastic show!'
    },
    {
      type: 'text',
      source: 'IDMB',
      reviewer: 'Jane Doe',
      lang: 'en',
      value: 'I love this show!'
    },
    {
      type: 'url',
      source: 'Rotten Tomatoes',
      reviewer: 'Joe Bloggs',
      lang: 'en',
      value: 'https://example.com/programme_one_review'
    }
  ],
  directors: [
    {
      value: 'Director 1',
      url: { value: 'http://example.com/director1.html', system: 'TestSystem' },
      image: [
        'https://example.com/image1.jpg',
        {
          value: 'https://example.com/image2.jpg',
          type: 'person',
          size: '2',
          system: 'TestSystem',
          orient: 'P'
        }
      ]
    },
    'Director 2'
  ],
  actors: ['Actor 1', 'Actor 2'],
  writer: 'Writer 1',
  producers: 'Roger Dobkowitz',
  presenters: 'Drew Carey',
  images: [
    {
      type: 'poster',
      size: '1',
      orient: 'P',
      system: 'tvdb',
      value: 'https://tvdb.com/programme_one_poster_1.jpg'
    },
    {
      type: 'poster',
      size: '2',
      orient: 'P',
      system: 'tmdb',
      value: 'https://tmdb.com/programme_one_poster_2.jpg'
    },
    {
      type: 'backdrop',
      size: '3',
      orient: 'L',
      system: 'tvdb',
      value: 'https://tvdb.com/programme_one_backdrop_3.jpg'
    }
  ],
  icon: 'https://example.com/images/Program1.png?x=шеллы&sid=777'
}

Channels List

<?xml version="1.0" ?>
<channels site="example.com">
  <channel site_id="cnn-23" xmltv_id="CNN.us">CNN</channel>
  ...
</channels>

You can also specify the language, site, url, logo and LCN (Logical Channel Number) for each channel individually, like so:

<channel
  site="example.com"
  site_id="france-24"
  xmltv_id="France24.fr"
  lang="fr"
  logo="https://example.com/france24.png"
  url="https://example.com/"
  lcn="36"
>France 24</channel>

How to use SOCKS proxy?

epg-grabber --config=example.com.config.js --proxy=socks://localhost:9050

Contribution

If you find a bug or want to contribute to the code or documentation, you can help by submitting an issue or a pull request.

License

MIT

0.38.0

5 months ago

0.37.5

6 months ago

0.37.3

7 months ago

0.37.4

7 months ago

0.37.2

8 months ago

0.37.1

1 year ago

0.37.0

1 year ago

0.36.1

2 years ago

0.36.0

2 years ago

0.35.0

2 years ago

0.34.0

2 years ago

0.33.0

2 years ago

0.32.0

2 years ago

0.31.0

2 years ago

0.30.2

2 years ago

0.30.1

2 years ago

0.29.8

3 years ago

0.29.7

3 years ago

0.29.6

3 years ago

0.29.5

3 years ago

0.29.4

3 years ago

0.29.3

3 years ago

0.29.2

3 years ago

0.29.0

3 years ago

0.29.1

3 years ago

0.28.1

3 years ago

0.28.0

3 years ago

0.28.6

3 years ago

0.28.5

3 years ago

0.28.4

3 years ago

0.28.3

3 years ago

0.28.2

3 years ago

0.27.2

3 years ago

0.27.1

3 years ago

0.27.0

3 years ago

0.26.0

3 years ago

0.25.4

3 years ago

0.25.3

3 years ago

0.25.2

3 years ago

0.25.1

3 years ago

0.25.0

3 years ago

0.23.0

3 years ago

0.21.0

3 years ago

0.24.0

3 years ago

0.22.0

3 years ago

0.20.0

3 years ago

0.19.0

3 years ago

0.15.0

4 years ago

0.16.0

3 years ago

0.15.1

4 years ago

0.17.0

3 years ago

0.15.2

3 years ago

0.18.0

3 years ago

0.17.1

3 years ago

0.13.0

4 years ago

0.12.1

4 years ago

0.14.0

4 years ago

0.12.0

4 years ago

0.11.0

4 years ago

0.10.1

4 years ago

0.10.2

4 years ago

0.10.3

4 years ago

0.10.4

4 years ago

0.10.0

4 years ago

0.9.0

4 years ago

0.9.1

4 years ago

0.8.0

4 years ago

0.7.0

4 years ago

0.6.6

4 years ago

0.6.5

4 years ago

0.6.3

4 years ago

0.6.2

4 years ago

0.6.4

4 years ago

0.6.1

4 years ago

0.6.0

4 years ago

0.5.0

4 years ago

0.5.2

4 years ago

0.5.1

4 years ago

0.4.1

4 years ago

0.4.0

4 years ago

0.3.0

4 years ago

0.2.6

4 years ago

0.2.5

4 years ago

0.2.1

4 years ago

0.2.3

4 years ago

0.2.2

4 years ago

0.2.4

4 years ago

0.1.0

4 years ago