Merge branch 'iptv-org:master' into dev-branch

This commit is contained in:
Arif Budiman authored and GitHub committed 2023-08-25 14:13:05 -07:00
commit b510b24a9f
30 files changed
+2036 -1479

No files matched your search

Vendored
-63
View File
@@ -1,63 +0,0 @@
List target_sites = (env.TARGET_SITES == null) ? [] : env.TARGET_SITES.split(';')
List exclude_sites = (env.EXCLUDE_SITES == null) ? [] : env.EXCLUDE_SITES.split(';')
target_sites.removeAll { it in exclude_sites }
Map matrix_axes = [
SITE: target_sites
]
@NonCPS
List getMatrixAxes(Map matrix_axes) {
List axes = []
matrix_axes.each { axis, values ->
List axisList = []
values.each { value ->
axisList << [(axis): value]
}
axes << axisList
}
axes.combinations()*.sum()
}
List axes = getMatrixAxes(matrix_axes)
Map tasks = [failFast: false]
for(int i = 0; i < axes.size(); i++) {
Map axis = axes[i]
List axisEnv = axis.collect { k, v ->
"${k}=${v}"
}
tasks[axisEnv.join(', ')] = { ->
env.NODEJS_HOME = "${tool 'node'}"
env.PATH="${env.NODEJS_HOME}/bin:${env.PATH}"
node {
skipDefaultCheckout()
withEnv(axisEnv) {
try {
cleanWs()
checkout scm
sh 'npm install'
sh "npm run grab"
} finally {
archiveArtifacts artifacts: "guides/**/*.xml", onlyIfSuccessful: true
cleanWs(
cleanWhenNotBuilt: false,
deleteDirs: true,
disableDeferredWipeout: true,
notFailBuild: true,
patterns: [[pattern: '.gitignore', type: 'INCLUDE'],
[pattern: '.propsfile', type: 'EXCLUDE']])
}
}
}
}
}
node {
stage('Load') {
parallel(tasks)
}
}
+22 -7
View File
@@ -42,19 +42,34 @@ npm install
Now choose one of the sources (their complete list can be found in the [/sites](https://github.com/iptv-org/epg/tree/master/sites) folder) and start downloading the guide using the command: Now choose one of the sources (their complete list can be found in the [/sites](https://github.com/iptv-org/epg/tree/master/sites) folder) and start downloading the guide using the command:
```sh ```sh
# Windows npm run grab -- --site=example.com
set SITE=example.com&& npm run grab ```
# Linux/macOS To download a guide in a specific language pass its [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code to the `--lang` argument:
SITE=example.com npm run grab
```sh
npm run grab -- --site=example.com --lang=fr
```
To also create a compressed version of the guide, add the `--gzip` flag:
```sh
npm run grab -- --site=example.com --gzip
``` ```
After the download is completed in the current directory will appear a new folder `guides`, which will store all XML files: After the download is completed in the current directory will appear a new folder `guides`, which will store all XML files:
```sh ```sh
guides guides
└── en └── fr
└── example.com.xml └── example.com.xml
└── example.com.xml.gz
```
If you want to download the guide automatically on a schedule, you need to pass a valid [cron expression](https://crontab.guru/) to the script using the `--cron` attribute:
```sh
npm run grab -- --site=example.com --cron="0 0 * * *"
``` ```
Also you can make these guides available via URL by running your own server: Also you can make these guides available via URL by running your own server:
@@ -66,13 +81,13 @@ npm run serve
After that all the downloaded guides will be available at a link like this: After that all the downloaded guides will be available at a link like this:
``` ```
http://localhost:3000/guides/en/example.com.xml http://localhost:3000/guides/fr/example.com.xml
``` ```
In addition, they will be available on your local network at: In addition, they will be available on your local network at:
``` ```
http://<your_local_ip_address>:3000/guides/en/example.com.xml http://<your_local_ip_address>:3000/guides/fr/example.com.xml
``` ```
## Playlists ## Playlists
+781 -699
View File
File diff suppressed because it is too large. Load diff
+4 -2
View File
@@ -11,7 +11,7 @@
"test:commands": "npx jest --runInBand -- commands", "test:commands": "npx jest --runInBand -- commands",
"test:sites": "TZ=Pacific/Nauru npx jest --runInBand -- sites", "test:sites": "TZ=Pacific/Nauru npx jest --runInBand -- sites",
"check": "npm run api:load && npm run channels:lint sites/**/*.js && npm run channels:validate sites/**/*.xml", "check": "npm run api:load && npm run channels:lint sites/**/*.js && npm run channels:validate sites/**/*.xml",
"grab": "cross-var epg-grabber --config=sites/$SITE/$SITE.config.js --channels=sites/$SITE/$SITE.channels.xml --output=guides/{lang}/{site}.xml", "grab": "node scripts/commands/epg/grab.js",
"serve": "npx serve" "serve": "npx serve"
}, },
"private": true, "private": true,
@@ -33,10 +33,12 @@
"chalk": "^4.1.2", "chalk": "^4.1.2",
"cheerio": "^1.0.0-rc.10", "cheerio": "^1.0.0-rc.10",
"commander": "^8.2.0", "commander": "^8.2.0",
"consola": "^3.2.3",
"cron": "^2.3.1",
"cross-var": "^1.1.0", "cross-var": "^1.1.0",
"csv-parser": "^3.0.0", "csv-parser": "^3.0.0",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"epg-grabber": "^0.31.0", "epg-grabber": "^0.32.0",
"epg-parser": "^0.2.0", "epg-parser": "^0.2.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fs-extra": "^10.0.1", "fs-extra": "^10.0.1",
+3 -3
View File
@@ -57,10 +57,10 @@ async function main() {
} }
if (localErrors.length) { if (localErrors.length) {
logger.info(`\n${chalk.underline(filepath)}`) console.log(`\n${chalk.underline(filepath)}`)
localErrors.forEach(error => { localErrors.forEach(error => {
const position = `${error.line}:${error.column}` const position = `${error.line}:${error.column}`
logger.error(` ${chalk.gray(position.padEnd(4, ' '))} ${error.message.trim()}`) console.log(` ${chalk.gray(position.padEnd(4, ' '))} ${error.message.trim()}`)
}) })
errors = errors.concat(localErrors) errors = errors.concat(localErrors)
@@ -68,7 +68,7 @@ async function main() {
} }
if (errors.length) { if (errors.length) {
logger.error(chalk.red(`\n${errors.length} error(s)`)) console.log(chalk.red(`\n${errors.length} error(s)`))
process.exit(1) process.exit(1)
} }
} }
+2 -2
View File
@@ -52,7 +52,7 @@ async function main() {
} }
if (errors.length) { if (errors.length) {
logger.info(chalk.underline(filepath)) console.log(chalk.underline(filepath))
console.table(errors, ['type', 'lang', 'xmltv_id', 'site_id', 'name']) console.table(errors, ['type', 'lang', 'xmltv_id', 'site_id', 'name'])
console.log() console.log()
stats.files++ stats.files++
@@ -60,7 +60,7 @@ async function main() {
} }
if (stats.errors > 0) { if (stats.errors > 0) {
logger.error(chalk.red(`${stats.errors} error(s) in ${stats.files} file(s)`)) console.log(chalk.red(`${stats.errors} error(s) in ${stats.files} file(s)`))
process.exit(1) process.exit(1)
} }
} }
+218
View File
@@ -0,0 +1,218 @@
const { program } = require('commander')
const _ = require('lodash')
const { EPGGrabber, generateXMLTV, Channel, Program } = require('epg-grabber')
const { db, logger, date, timer, file, parser, api, zip } = require('../../core')
const path = require('path')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const CronJob = require('cron').CronJob
dayjs.extend(utc)
const BASE_DIR = process.env.BASE_DIR || '.'
const CURR_DATE = process.env.CURR_DATE || new Date()
program
.requiredOption('-s, --site <name>', 'Name of the site to parse')
.option('-l, --lang <code>', 'Filter channels by language (ISO 639-2 code)')
.option('-o, --output <path>', 'Path to output file')
.option('--cron <expression>', 'Schedule a script run')
.option('--gzip', 'Create a compressed version of the guide as well', false)
.parse(process.argv)
const options = program.opts()
options.output = options.output || file.resolve(`${BASE_DIR}/guides/{lang}/{site}.xml`)
options.config = file.resolve(`${BASE_DIR}/sites/${options.site}/${options.site}.config.js`)
options.channels = file.resolve(`${BASE_DIR}/sites/${options.site}/${options.site}*.channels.xml`)
let channels = []
let programs = []
let runIndex = 0
async function main() {
logger.start('staring...')
logger.info('settings:')
for (let prop in options) {
logger.info(` ${prop}: ${options[prop]}`)
}
const config = await loadConfig(options.config)
const queue = await createQueue(options.channels, config)
const outputPath = options.output
if (options.cron) {
const job = new CronJob(options.cron, function () {
runJob(config, queue, outputPath)
})
job.start()
} else {
await runJob(config, queue, outputPath)
}
}
async function loadConfig(configPath) {
let config = require(file.resolve(configPath))
config = _.merge(config, {})
config.days = config.days || 1
logger.info('config:')
logConfig(config)
return config
}
function logConfig(config, level = 1) {
let padLeft = ' '.repeat(level)
for (let prop in config) {
if (typeof config[prop] === 'string' || typeof config[prop] === 'number') {
logger.info(`${padLeft}${prop}: ${config[prop]}`)
} else if (typeof config[prop] === 'object') {
level++
logger.info(`${padLeft}${prop}:`)
logConfig(config[prop], level)
}
}
}
async function runJob(config, queue, outputPath) {
runIndex++
logger.info(`run #${runIndex}:`)
timer.start()
await grab(queue, config)
await save(outputPath, channels, programs)
logger.success(` done in ${timer.format('HH[h] mm[m] ss[s]')}`)
}
async function grab(queue, config) {
const grabber = new EPGGrabber(config)
const total = queue.length
let i = 1
for (const item of queue) {
let channel = item.channel
let date = item.date
channels.push(item.channel)
await grabber
.grab(channel, date, (data, err) => {
logger.info(
` [${i}/${total}] ${channel.site} (${channel.lang}) - ${channel.xmltv_id} - ${dayjs
.utc(data.date)
.format('MMM D, YYYY')} (${data.programs.length} programs)`
)
if (i < total) i++
if (err) {
logger.info(` ERR: ${err.message}`)
}
})
.then(results => {
programs = programs.concat(results)
})
}
}
async function createQueue(channelsPath, config) {
logger.info('creating queue...')
let queue = {}
await api.channels.load().catch(logger.error)
const files = await file.list(channelsPath).catch(logger.error)
const utcDate = date.getUTC(CURR_DATE)
for (const filepath of files) {
logger.info(` loading "${filepath}"...`)
try {
const dir = file.dirname(filepath)
const { channels } = await parser.parseChannels(filepath)
const filename = file.basename(filepath)
const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
for (const channel of channels) {
if (!channel.site || !channel.xmltv_id) continue
if (options.lang && channel.lang !== options.lang) continue
const found = api.channels.find({ id: channel.xmltv_id })
if (found) {
channel.logo = found.logo
}
for (const d of dates) {
const dateString = d.toJSON()
const key = `${channel.site}:${channel.lang}:${channel.xmltv_id}:${dateString}`
if (!queue[key]) {
queue[key] = {
channel,
date: dateString,
config,
error: null
}
}
}
}
} catch (err) {
logger.error(err)
continue
}
}
queue = Object.values(queue)
logger.info(` added ${queue.length} items`)
return queue
}
async function save(template, parsedChannels, programs = []) {
const variables = file.templateVariables(template)
const groups = _.groupBy(parsedChannels, channel => {
let groupId = ''
for (let key in channel) {
if (variables.includes(key)) {
groupId += channel[key]
}
}
return groupId
})
for (let groupId in groups) {
const channels = groups[groupId]
let output = {
channels,
programs: [],
date: CURR_DATE
}
for (let program of programs) {
let programLang = program.titles[0].lang
let channel = channels.find(c => c.xmltv_id === program.channel && c.lang === programLang)
if (!channel) continue
output.programs.push(new Program(program, channel))
}
output.channels = _.sortBy(output.channels, 'id')
output.channels = _.uniqBy(output.channels, 'id')
output.programs = _.sortBy(output.programs, ['channel', 'start'])
output.programs = _.uniqBy(output.programs, p => p.channel + p.start)
const outputPath = file.templateFormat(template, output.channels[0])
const xmlFilepath = outputPath
const xmltv = generateXMLTV(output)
logger.info(` saving to "${xmlFilepath}"...`)
await file.create(xmlFilepath, xmltv)
if (options.gzip) {
const gzFilepath = `${outputPath}.gz`
const compressed = await zip.compress(xmltv)
logger.info(` saving to "${gzFilepath}"...`)
await file.create(gzFilepath, compressed)
}
}
}
main()
+17
View File
@@ -4,6 +4,23 @@ const fs = require('fs-extra')
const file = {} const file = {}
file.templateVariables = function (template) {
const match = template.match(/{[^}]+}/g)
return Array.isArray(match) ? match.map(s => s.substring(1, s.length - 1)) : []
}
file.templateFormat = function (template, obj) {
let output = template
for (let key in obj) {
const regex = new RegExp(`{${key}}`, 'g')
const value = obj[key] || undefined
output = output.replace(regex, value)
}
return output
}
file.list = function (pattern) { file.list = function (pattern) {
return new Promise(resolve => { return new Promise(resolve => {
glob(pattern, function (err, files) { glob(pattern, function (err, files) {
+2 -18
View File
@@ -1,19 +1,3 @@
const { Signale } = require('signale') const { consola } = require('consola')
const options = {} module.exports = consola
const logger = new Signale(options)
logger.config({
displayLabel: false,
displayScope: false,
displayBadge: false
})
logger.memoryUsage = function () {
const used = process.memoryUsage().heapUsed / 1024 / 1024
logger.info(`memory: ${Math.round(used * 100) / 100} MB`)
}
module.exports = logger
+1 -1
View File
@@ -1 +1 @@
{"timeSlices":[{"timeSlice":"0","contents":[{"contentID":"20482220_50001","title":"Le cercle","subtitle":"Emission du 06 janv. 2023","startTime":1673504880000,"onClick":{"displayTemplate":"detailSeason","displayName":"Le cercle","path":"/cinema/le-cercle/h/4501558_50001","URLPage":"https://hodor.canalplus.pro/api/v2/mycanal/detail/da2291af3b10e9900d1c55e1a65d3388/okapi/6564630_50001.json?detailType=detailSeason&objectType=season&broadcastID=PLM_1196447642&episodeId=20482220_50001&brandID=4501558_50001&fromDiff=true","parameters":[{"in":"parameters","id":"featureToggles","enum":["detailV5"]}]}}],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Matin","context_list_id":"198","context_list_type":"epgGrid","context_list_position":1}},{"timeSlice":"1","contents":[{"contentID":"17230453_50001","title":"Illusions perdues","subtitle":"Film Drame","startTime":1673525160000,"onClick":{"displayTemplate":"detailPage","displayName":"Illusions perdues","path":"/cinema/illusions-perdues-film-drame/h/17230453_50001","URLPage":"https://hodor.canalplus.pro/api/v2/mycanal/detail/da2291af3b10e9900d1c55e1a65d3388/okapi/17230453_50001.json?detailType=detailPage&objectType=unit&broadcastID=PLM_1196447637&fromDiff=true","parameters":[{"in":"parameters","id":"featureToggles","enum":["detailV5"]}]}}],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Apres-midi","context_list_id":"198","context_list_type":"epgGrid","context_list_position":2}},{"timeSlice":"2","contents":[],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Debut de soiree","context_list_id":"198","context_list_type":"epgGrid","context_list_position":3}},{"timeSlice":"3","contents":[],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Soiree","context_list_id":"198","context_list_type":"epgGrid","context_list_position":4}},{"timeSlice":"4","contents":[],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Nuit","context_list_id":"198","context_list_type":"epgGrid","context_list_position":5}}]} {"timeSlices":[{"timeSlice":"0","contents":[{"contentID":"20482220_50001","title":"Le cercle","subtitle":"Emission du 06 janv. 2023","startTime":1673504880000,"onClick":{"displayTemplate":"detailSeason","displayName":"Le cercle","path":"/cinema/le-cercle/h/4501558_50001","URLPage":"https://hodor.canalplus.pro/api/v2/mycanal/detail/f000c6f4ebf44647682b3a0fa66d7d99/okapi/6564630_50001.json?detailType=detailSeason&objectType=season&broadcastID=PLM_1196447642&episodeId=20482220_50001&brandID=4501558_50001&fromDiff=true","parameters":[{"in":"parameters","id":"featureToggles","enum":["detailV5"]}]}}],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Matin","context_list_id":"198","context_list_type":"epgGrid","context_list_position":1}},{"timeSlice":"1","contents":[{"contentID":"17230453_50001","title":"Illusions perdues","subtitle":"Film Drame","startTime":1673525160000,"onClick":{"displayTemplate":"detailPage","displayName":"Illusions perdues","path":"/cinema/illusions-perdues-film-drame/h/17230453_50001","URLPage":"https://hodor.canalplus.pro/api/v2/mycanal/detail/f000c6f4ebf44647682b3a0fa66d7d99/okapi/17230453_50001.json?detailType=detailPage&objectType=unit&broadcastID=PLM_1196447637&fromDiff=true","parameters":[{"in":"parameters","id":"featureToggles","enum":["detailV5"]}]}}],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Apres-midi","context_list_id":"198","context_list_type":"epgGrid","context_list_position":2}},{"timeSlice":"2","contents":[],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Debut de soiree","context_list_id":"198","context_list_type":"epgGrid","context_list_position":3}},{"timeSlice":"3","contents":[],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Soiree","context_list_id":"198","context_list_type":"epgGrid","context_list_position":4}},{"timeSlice":"4","contents":[],"context":{"context_type":"epg","context_page_title":"Guide - Grille TV - CANAL+ CINEMA","context_list_title":"CANAL+ CINEMA - J - Maintenant - Nuit","context_list_id":"198","context_list_type":"epgGrid","context_list_position":5}}]}
@@ -0,0 +1,29 @@
<!doctype html>
<html lang="fr-BI" data-device-type="" class="no-js" data-testid="html"><head><title data-react-helmet="true">Programme TV : que regarder maintenant et ce soir ? | myCANAL Burundi</title><meta data-react-helmet="true" charSet="utf-8"/><meta data-react-helmet="true" name="apple-mobile-web-app-capable" content="yes"/><meta data-react-helmet="true" name="mobile-web-app-capable" content="yes"/><meta data-react-helmet="true" name="apple-mobile-web-app-title" content="myCANAL"/><meta data-react-helmet="true" name="application-name" content="myCANAL"/><meta data-react-helmet="true" name="apple-mobile-web-app-status-bar-style" content="black"/><meta data-react-helmet="true" name="theme-color" content="#1A1A1A"/><meta data-react-helmet="true" name="msapplication-TileColor" content="#1A1A1A"/><meta data-react-helmet="true" name="msapplication-square70x70logo" content="smalltile.png"/><meta data-react-helmet="true" name="msapplication-square150x150logo" content="mediumtile.png"/><meta data-react-helmet="true" name="msapplication-wide310x150logo" content="widetile.png"/><meta data-react-helmet="true" name="msapplication-square310x310logo" content="largetile.png"/><meta data-react-helmet="true" property="og:site_name" content="myCANAL"/><meta data-react-helmet="true" property="og:image" content="https://thumb.canalplus.pro/http/unsafe/1200x630/filters:quality(80)/www.canalplus.com/largetile.png"/><meta data-react-helmet="true" property="og:image:width" content="1200"/><meta data-react-helmet="true" property="og:image:height" content="630"/><meta data-react-helmet="true" property="og:title" content="Programme TV : que regarder maintenant et ce soir ? | myCANAL Burundi"/><meta data-react-helmet="true" property="og:locale" content="fr-bi"/><meta data-react-helmet="true" property="og:description" content="Quel programme regarder à la télévision ? Retrouvez rapidement une émission, une série, un match ou un film sur toutes les chaines"/><meta data-react-helmet="true" property="og:card" content="summary"/><meta data-react-helmet="true" property="og:site" content="@myCANAL"/><meta data-react-helmet="true" property="og:creator" content="@myCANAL"/><meta data-react-helmet="true" property="og:url" content="https://www.canalplus.com/bi/programme-tv/"/><meta data-react-helmet="true" name="description" content="Quel programme regarder à la télévision ? Retrouvez rapidement une émission, une série, un match ou un film sur toutes les chaines"/><meta data-react-helmet="true" name="twitter:site" content="@myCANAL"/><meta data-react-helmet="true" name="twitter:title" content="Programme TV : que regarder maintenant et ce soir ? | myCANAL Burundi"/><meta data-react-helmet="true" name="twitter:description" content="Quel programme regarder à la télévision ? Retrouvez rapidement une émission, une série, un match ou un film sur toutes les chaines"/><meta data-react-helmet="true" name="twitter:image" content="https://thumb.canalplus.pro/http/unsafe/1200x630/filters:quality(80)/www.canalplus.com/largetile.png"/><meta data-react-helmet="true" name="twitter:card" content="summary"/><link data-react-helmet="true" rel="canonical" href="https://www.canalplus.com/bi/programme-tv/"/><link data-react-helmet="true" rel="apple-touch-icon" href="/apple-touch-icon.png"/><link data-react-helmet="true" rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png"/><link data-react-helmet="true" rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png"/><link data-react-helmet="true" rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png"/><link data-react-helmet="true" rel="apple-touch-icon-precomposed" href="/apple-touch-icon-precomposed.png"/><link data-react-helmet="true" rel="manifest" href="/manifest.json"/><link data-react-helmet="true" rel="icon" href="/favicon-16x16.png" sizes="16x16"/><link data-react-helmet="true" rel="icon" href="/favicon-32x32.png" sizes="32x32"/><link data-react-helmet="true" rel="apple-touch-startup-image" href="/apple-touch-startup-image-1536x2008.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)"/><link data-react-helmet="true" href="/apple-touch-startup-image-1496x2048.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/><link data-react-helmet="true" href="/apple-touch-startup-image-768x1004.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image"/><link data-react-helmet="true" href="/apple-touch-startup-image-748x1024.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image"/><link data-react-helmet="true" href="/apple-touch-startup-image-1242x2148.png" media="(device-width: Line truncated
c-7.5-7.5-18.2-12.9-30-12.9c-22.5,0-40.8,18.2-40.8,40.8c0,3.2,0,6.4,1.1,9.7C63.7,67.1,34.7,51,14.3,26.3C11.1,32.7,9,39.2,9,46.7
C9,60.6,16.5,73.5,27.2,81c-6.4,0-12.9-2.1-18.2-5.4c0,19.3,13.9,36.5,32.2,39.7c-3.2,1.1-7.5,1.1-10.7,1.1c-2.1,0-5.4,0-7.5-1.1
c5.4,16.1,20.4,27.9,37.5,27.9C46.5,154,29.4,160.4,10,160.4c-3.2,0-6.4,0-9.7-1.1c18.2,13.9,39.7,20.4,62.2,20.4
c75.1,0,115.9-62.2,115.9-115.9v-5.4C186,53.1,193.5,45.6,198.9,38.1z"></path></svg></span></a></li><li class="socials__items_77a0b3"><a href="https://www.dailymotion.com/CANALPLUS" title="dailymotion" target="_blank" rel="noopener"><span class="socials__socialIcon_77a0b3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="16" class="icon_Faffdb"><path d="M176.6 82.9v115h-41.5v-15.5c-12.4 12.4-25.9 16.6-43.5 16.6s-33.2-5.2-45.6-16.6c-16.6-14.5-25.9-33.2-25.9-56 0-20.7 8.3-38.3 22.8-52.8C56.4 61.2 73 53.9 91.6 53.9c17.6 0 32.1 6.2 42.5 17.6V9.3L175.6 1v81.9h1zm-76.7 7.3c-20.7 0-36.3 16.6-36.3 35.2 0 19.7 15.5 35.2 37.3 35.2 18.7 0 34.2-14.5 34.2-34.2s-15.5-36.2-35.2-36.2z"></path></svg></span></a></li><li class="socials__items_77a0b3"><a href="https://www.youtube.com/user/CanalplusAfrique" title="youtube" target="_blank" rel="noopener"><span class="socials__socialIcon_77a0b3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="16" class="icon_Faffdb"><path d="M124.1,161.9v-23.1c0-5.4-1.4-6.8-4.1-6.8c-1.4,0-2.7,1.4-5.4,2.7v34c1.4,1.4,2.7,2.7,5.4,2.7
C122.7,168.7,124.1,166,124.1,161.9z M151.3,142.9h9.5v-5.4c0-5.4-1.4-8.2-5.4-8.2c-2.7,0-5.4,2.7-5.4,8.2L151.3,142.9L151.3,142.9z
M65.6,103.4v10.9H53.3v62.6H42.4v-62.6H30.2v-10.9H65.6L65.6,103.4z M95.5,122.4v54.4H86v-5.4c-4.1,4.1-8.2,6.8-10.9,6.8
c-2.7,0-5.4-1.4-6.8-4.1c0-1.4-1.4-4.1-1.4-8.2v-43.5h9.5v44.9c0,1.4,1.4,2.7,2.7,2.7s4.1-1.4,6.8-4.1v-42.2L95.5,122.4L95.5,122.4z
M133.6,138.8v21.8c0,5.4,0,8.2-1.4,10.9c-1.4,4.1-4.1,6.8-8.2,6.8s-6.8-2.7-9.5-6.8v5.4H105v-73.5h9.5v24.5
c2.7-4.1,6.8-5.4,9.5-5.4c4.1,0,6.8,2.7,8.2,6.8C133.6,130.6,133.6,133.3,133.6,138.8z M170.3,157.8v8.2c0,2.7-1.4,4.1-2.7,5.4
c-2.7,4.1-6.8,5.4-12.2,5.4c-5.4,0-9.5-1.4-12.2-5.4c-2.7-2.7-2.7-6.8-2.7-12.2v-19c0-5.4,1.4-9.5,2.7-12.2
c2.7-4.1,6.8-5.4,12.2-5.4c5.4,0,9.5,1.4,12.2,5.4c2.7,2.7,2.7,6.8,2.7,12.2V151h-20.4v9.5c0,5.4,1.4,8.2,5.4,8.2
c2.7,0,4.1-1.4,4.1-4.1v-1.4v-5.4L170.3,157.8L170.3,157.8z M103.7,35.4v23.1c0,5.4-1.4,8.2-5.4,8.2c-2.7,0-5.4-2.7-5.4-8.2V35.4
c0-5.4,1.4-8.2,5.4-8.2C102.3,27.2,103.7,29.9,103.7,35.4z M182.6,141.5c0-17.7-1.4-29.9-2.7-39.5c-1.4-4.1-2.7-8.2-6.8-10.9
c-2.7-2.7-6.8-4.1-10.9-5.4c-13.6-1.4-34-2.7-61.2-2.7s-47.6,1.4-61.2,2.7c-4.1,0-8.2,2.7-10.9,5.4C26.1,93.9,23.4,98,22,102
c-1.4,8.2-2.7,21.8-2.7,39.5s1.4,29.9,2.7,39.5c1.4,4.1,2.7,8.2,6.8,10.9c2.7,2.7,6.8,4.1,10.9,5.4c13.6,1.4,34,2.7,61.2,2.7
s47.6-1.4,61.2-2.7c4.1,0,8.2-2.7,10.9-5.4c2.7-2.7,5.4-6.8,6.8-10.9C182.6,172.8,182.6,159.2,182.6,141.5z M69.7,44.9L83.3,0H72.4
l-8.2,28.6L56.1,0H43.8l4.1,10.9c0,0,1.4,4.1,4.1,10.9c4.1,10.9,5.4,17.7,6.8,23.1v29.9h10.9L69.7,44.9L69.7,44.9z M113.2,57.1v-19
c0-5.4-1.4-9.5-2.7-13.6c-2.7-4.1-6.8-5.4-12.2-5.4s-9.5,1.4-12.2,5.4c-2.7,2.7-2.7,6.8-2.7,13.6v19c0,5.4,1.4,9.5,2.7,13.6
c2.7,4.1,6.8,5.4,12.2,5.4s8.2-1.4,12.2-5.4C111.8,66.7,113.2,62.6,113.2,57.1z M140.4,74.8h9.5V19h-9.5v42.2
c-2.7,2.7-4.1,4.1-6.8,4.1c-1.4,0-2.7-1.4-2.7-2.7V17.7h-9.5v43.5c0,4.1,0,6.8,1.4,8.2c1.4,2.7,2.7,4.1,6.8,4.1
c4.1,0,6.8-2.7,10.9-6.8L140.4,74.8L140.4,74.8z"></path></svg></span></a></li></ul><div class="footer__zoneSelector_7f6616"><button class="zoneSelector___oSw8N" type="button"><span class="zoneSelector__country___KhkQP zoneSelector__country--dark___a8uVZ">Burundi<!-- --> (<!-- -->FR<!-- -->)</span><div class="zoneSelector__flag___ksHMD"></div></button></div><p class="footer__text_7f6616">Vivez l’expérience CANAL+<!-- -->, <!-- -->Le site de streaming le plus complet et le seul qui réunit vos films, vos séries (en HD, VF et VOST) et les plus belles compétitions sportives en direct ou en replay.</p><div class="footer__credits_7f6616">© CANAL+ 2023</div></li></ul></div></footer></div></div></main><script>
window.passDistributorId="D22024";
window.app_config={"overlay":"mycanal","mock":false,"documentHeader":{"default":{"app":{"title":"myCANAL","description":"Une nouvelle façon de regarder la télé. Retrouvez tous les meilleurs programmes sur myCANAL ! PC\u002FMAC - Tablette - Smartphone.","head":{"titleTemplate":"%s","twitter":{"twitterAccount":"@myCANAL","urlImageDefault":"https:\u002F\u002Fwww.canalplus.com\u002Flargetile.png"},"meta":[{"charset":"utf-8"},{"name":"apple-mobile-web-app-capable","content":"yes"},{"name":"mobile-web-app-capable","content":"yes"},{"name":"apple-mobile-web-app-title","content":"myCANAL"},{"name":"application-name","content":"myCANAL"},{"name":"apple-mobile-web-app-status-bar-style","content":"black"},{"name":"theme-color","content":"#1A1A1A"},{"name":"msapplication-TileColor","content":"#1A1A1A"},{"name":"msapplication-square70x70logo","content":"smalltile.png"},{"name":"msapplication-square150x150logo","content":"mediumtile.png"},{"name":"msapplication-wide310x150logo","content":"widetile.png"},{"name":"msapplication-square310x310logo","content":"largetile.png"},{"property":"og:site_name","content":"myCANAL"},{"property":"og:image","content":"https:\u002F\u002Fwww.canalplus.com\u002Flargetile.png"},{"property":"og:image:width","content":"1200"},{"property":"og:image:height","content":"630"},{"property":"og:title","content":"myCANAL"},{"property":"og:locale","content":"fr-fr"},{"property":"og:description","content":"Une nouvelle façon de regarder la télé. Retrouvez tous les meilleurs programmes sur myCANAL ! PC\u002FMAC - Tablette - Smartphone."},{"property":"og:card","content":"summary"},{"property":"og:site","content":"@myCANAL"},{"property":"og:creator","content":"@myCANAL"},{"property":"og:url","content":"www.canalplus.com"}],"link":[{"rel":"apple-touch-icon","href":"\u002Fapple-touch-icon.png"},{"rel":"apple-touch-icon","sizes":"120x120","href":"\u002Fapple-touch-icon-120x120.png"},{"rel":"apple-touch-icon","sizes":"152x152","href":"\u002Fapple-touch-icon-152x152.png"},{"rel":"apple-touch-icon","sizes":"180x180","href":"\u002Fapple-touch-icon-180x180.png"},{"rel":"apple-touch-icon-precomposed","href":"\u002Fapple-touch-icon-precomposed.png"},{"rel":"manifest","href":"\u002Fmanifest.json"},{"rel":"icon","href":"\u002Ffavicon-16x16.png","sizes":"16x16"},{"rel":"icon","href":"\u002Ffavicon-32x32.png","sizes":"32x32"},{"rel":"apple-touch-startup-image","href":"\u002Fapple-touch-startup-image-1536x2008.png","media":"(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)"},{"href":"\u002Fapple-touch-startup-image-1496x2048.png","media":"(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-768x1004.png","media":"(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 1)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-748x1024.png","media":"(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 1)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-1242x2148.png","media":"(device-width: 414px) and (device-height: 736px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 3)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-1182x2208.png","media":"(device-width: 414px) and (device-height: 736px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 3)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-750x1294.png","media":"(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-640x1096.png","media":"(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-640x920.png","media":"(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)","rel":"apple-touch-startup-image"},{"href":"\u002Fapple-touch-startup-image-320x640.png","media":"(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 1)","rel":"apple-touch-startup-image"}],"defaultHostname":"www.canalplus.com"}}},"pl":{"app":{"title":"CANAL+","description":"Odkryj NOWY CANAL+ telewizję przez internet. Tu znajdziesz najlepsze w swojej kategorii kanały na żywo, emocjonujący sport oraz filmy, seriale i programy na życzenie.","head":{"twitter":{"twitterAccount":"@nowycanalplus","urlImageDefault":"https:\u002F\u002Fwww.canalplus.com\u002FlargetilePL.png"},"titleTemplate":"%s","meta":[{"charset":"utf-8"},{"name":"apple-mobile-web-app-capable","content":"yes"},{"name":"mobile-web-app-capable","content":"yes"},{"name":"apple-mobile-web-app-title","content":"CANAL+"},{"name":Line truncated
window.PASS_CONF={"DEFAULT_CONF":{"msg_act_ok_gene":"msg_act_ok_myc","pwdreinit_gene_gene":"pwdreinit_gene_myc","pwdmod_gene_gene":"pwdmod_gene_myc"}};
window.__data={"actionBar":{},"adult":{"active":false,"adultBrowsing":false,"adultStatus":{"enabled":false},"disclaimerRead":false,"error":"","initialized":false,"isParentalCodeActivatedForUserOverloadableContents":false},"displayModes":{"isWebview":false,"isEmbedPlayer":false,"isAMP":false,"isTV":false},"contextFeature":{"isFeatIframeHeightAllowed":false,"isFeatImmersiveFullAllowed":false},"downloadToGo":{},"error":{},"immersive":{"active":false,"action":"","displayTemplate":"","displayName":"","pathname":"","persoUpdated":false,"meta":{}},"meta":{"title":"Programme TV : que regarder maintenant et ce soir ? | myCANAL Burundi","description":"Quel programme regarder à la télévision ? Retrouvez rapidement une émission, une série, un match ou un film sur toutes les chaines","canonical":"\u002Fbi\u002Fprogramme-tv\u002F"},"modal":{"modalType":"GENERIC_MODAL","modalTypes":[]},"mood":{"active":false},"newrelic":{"pageChange":null},"page":{"displayTemplate":"landing","displayName":"Programme TV","pathname":"\u002Fbi\u002Fprogramme-tv\u002F","uniqueId":"6c69ac2f-baad-48e3-ad15-117ada0609ee","adult":false,"style":"","URLPage":"https:\u002F\u002Fhodor.canalplus.pro\u002Fapi\u002Fv2\u002Fmycanal\u002Fpage\u002Ff000c6f4ebf44647682b3a0fa66d7d99\u002F102831.json?aegon=true&get=14","purchaseCode":false},"player":{"playerInstance":{},"playerElement":null,"playerType":null,"settings":null,"fatalError":false,"openFullScreen":false,"supportedPlatforms":{},"trackingContext":{},"infoTracking":{},"data":{}},"profilesModal":{"currentView":""},"profileProgress":{},"purchaseCode":{"initialized":false,"active":false,"error":"","purchaseCodeBrowsing":false,"purchaseCodeStatus":{"enabled":false,"disabled":false},"purchaseId":""},"sale":{"currentSale":"default","sales":{"default":{"rentals":{},"purchases":{},"URLSaleStatus":null,"isUnitContent":false,"voucherKey":null}},"preload":{}},"search":{"active":false,"query":""},"snacks":{},"stickyBar":{"headerBar":null,"originalBar":null},"templates":{"actionSuccess":{"buttonsDatas":[],"currentPage":{"displayTemplate":"actionSuccess"},"presentation":{"URLImage":"","subtitle":"","title":""}},"detail":{"header":{},"body":{},"isReady":false,"tracking":{},"hasFetchedClientSideContent":false}},"ui":{"noScroll":false,"displayMode":"windowed","screenWidth":300,"showSummaryEpisodes":false},"user":{"authenticated":false,"isFetching":false,"sale":{},"settings":{},"targetedAds":"0","macroEligibility":"","microEligibility":"ALD_CNL:[-1],ALD_CS:[],ALD_TVGRAT:[-1],APP_PARTNER:[],CATCHUP:[-1],CPALD_AFR:[],CPALD_MUS:[-1],CPL_INF:[-1],LIVE:[-1],L_GRAT:[-1],MYCANAL:[],OFFER:[],PARTNER:[-1],PRESSE:[-1],VOD:[],V_GRAT:[-1]","offerZone":"cpafr","epgidOTT":"","abTestingPercentage":"50","abTestingPopulation":2},"application":{"requestId":"fb518805-3738-4cf2-b5e8-7b25d7b62be9","isFetching":false,"renderSource":"server","onePlayerIsSupported":false,"zoneInfo":{"offerLocation":"bi","lang":"fr","appKey":"mycanal","portailId":"vbdTj7eb6aM.","offerZone":"cpafr"},"settings":{"hostname":"www.canalplus.com","showAdultDisclaimer":true,"appDownloadToGoDetected":false,"searchUrl":"https:\u002F\u002Fhodor.canalplus.pro\u002Fapi\u002Fv2\u002Fmycanal\u002Fsearch\u002Fmycanal_channel_discover\u002Ff000c6f4ebf44647682b3a0fa66d7d99\u002Fquery\u002F{searchKey}?distmodes=[\"tvod\",\"catchup\",\"svod\"]&channelImageColor=white&displayNBOLogo=true","userAgent":{"isMobile":{"isAny":true,"isAndroid":false,"isIOS":false,"isWindows":false},"isBrowser":{"isSafari":false},"isDesktop":{"isAny":false,"isMacOs":false,"isWindows":false}},"featPerso":true,"featRefreshLiveTV":false,"featStratePersoReco":true,"featPlaylist":true,"featProfile":false,"featMood":true,"featTVoD":true,"featClientCache":false,"featPlayerAds":false,"featPurchases":true,"featRentals":true,"featPromo":true,"featNewrelic":true,"featC2C":true,"featPushMood":true,"featCB1S":true,"featBuyNKeep":true,"featD2G":false,"featSW":true,"featCBDeleteNSave":true,"featABtesting":false,"featCreativeMediaRC":true,"featGalaxy":true,"featTag":true,"featTrailer":true,"featAssociatedContents":true,"featLocaleSwitcher":true,"featNotifications":false,"featPOCDownload":false,"featGraphReco":false,"featLowData":true,"featSocialNetworksFooter":true,"featSocialNetworksDetailPage":true,"featMultiLive":true,"featDarkMode":true,"featMacOsAppAvailable":false,"featLiveTvFavorites":true,"featPSD2":true,"featCBLimited":false,"featDetailV5":true,"featUserCentricConsentMode":true,"featIgnoreContentRowCarousel":true,"featDisplayPersoRecoToggle":true,"featPositionSeconds":false,"featDisplayHeaderMenu":true,"subscribeUrl":"https:\u002F\u002Fwww.canalplus-afrique.com\u002Foffres-tv?sc_intcmp=MYCANAL:WEB:MOVIEPAGE:STORE","appleStoreURL":"https:\u002F\u002Fapps.apple.com\u002Ffr\u002Fapp\u002Fmycanal\u002Fid694580816","googlePlayURL":"https:\u002F\u002Fplay.google.com\u002Fstore\u002Fapps\u002Fdetails?id=com.canal.android.canal&hl=fr","microsoftStoreURL":"https:\u002F\u002Fwww.microsoft.com\u002Ffr-fr\u002FstorLine truncated
window.REACT_QUERY_STATE = {"mutations":[],"queries":[{"state":{"data":{"currentPage":{"displayName":"Programme TV","path":"\u002Fbi\u002Fprogramme-tv\u002F","BOName":"J - Maintenant","BOLayoutName":"Web - Programme TV","alternate":{"fr":{"fr":{"path":"\u002Ffr\u002Fprogramme-tv\u002F"}},"ch":{"fr":{"path":"\u002Fch\u002Fprogramme-tv\u002F"}},"re":{"fr":{"path":"\u002Fre\u002Fprogramme-tv\u002F"}},"nc":{"fr":{"path":"\u002Fnc\u002Fprogramme-tv\u002F"}},"mu":{"fr":{"path":"\u002Fmu\u002Fprogramme-tv\u002F"}},"mg":{"fr":{"path":"\u002Fmg\u002Fprogramme-tv\u002F"}},"wf":{"fr":{"path":"\u002Fwf\u002Fprogramme-tv\u002F"}},"mq":{"fr":{"path":"\u002Fmq\u002Fprogramme-tv\u002F"}},"gp":{"fr":{"path":"\u002Fgp\u002Fprogramme-tv\u002F"}},"mf":{"fr":{"path":"\u002Fmf\u002Fprogramme-tv\u002F"}},"gf":{"fr":{"path":"\u002Fgf\u002Fprogramme-tv\u002F"}},"tt":{"fr":{"path":"\u002Ftt\u002Fprogramme-tv\u002F"}},"yt":{"fr":{"path":"\u002Fyt\u002Fprogramme-tv\u002F"}},"sn":{"fr":{"path":"\u002Fsn\u002Fprogramme-tv\u002F"}},"tg":{"fr":{"path":"\u002Ftg\u002Fprogramme-tv\u002F"}},"bf":{"fr":{"path":"\u002Fbf\u002Fprogramme-tv\u002F"}},"td":{"fr":{"path":"\u002Ftd\u002Fprogramme-tv\u002F"}},"bi":{"fr":{"path":"\u002Fbi\u002Fprogramme-tv\u002F"}},"sl":{"fr":{"path":"\u002Fsl\u002Fprogramme-tv\u002F"}},"bj":{"fr":{"path":"\u002Fbj\u002Fprogramme-tv\u002F"}},"rw":{"fr":{"path":"\u002Frw\u002Fprogramme-tv\u002F"}},"cg":{"fr":{"path":"\u002Fcg\u002Fprogramme-tv\u002F"}},"ci":{"fr":{"path":"\u002Fci\u002Fprogramme-tv\u002F"}},"cf":{"fr":{"path":"\u002Fcf\u002Fprogramme-tv\u002F"}},"cv":{"fr":{"path":"\u002Fcv\u002Fprogramme-tv\u002F"}},"cd":{"fr":{"path":"\u002Fcd\u002Fprogramme-tv\u002F"}},"ng":{"fr":{"path":"\u002Fng\u002Fprogramme-tv\u002F"}},"dj":{"fr":{"path":"\u002Fdj\u002Fprogramme-tv\u002F"}},"ga":{"fr":{"path":"\u002Fga\u002Fprogramme-tv\u002F"}},"ne":{"fr":{"path":"\u002Fne\u002Fprogramme-tv\u002F"}},"gh":{"fr":{"path":"\u002Fgh\u002Fprogramme-tv\u002F"}},"ml":{"fr":{"path":"\u002Fml\u002Fprogramme-tv\u002F"}},"gw":{"fr":{"path":"\u002Fgw\u002Fprogramme-tv\u002F"}},"gq":{"fr":{"path":"\u002Fgq\u002Fprogramme-tv\u002F"}},"gn":{"fr":{"path":"\u002Fgn\u002Fprogramme-tv\u002F"}},"gm":{"fr":{"path":"\u002Fgm\u002Fprogramme-tv\u002F"}},"mr":{"fr":{"path":"\u002Fmr\u002Fprogramme-tv\u002F"}},"pf":{"fr":{"path":"\u002Fpf\u002Fprogramme-tv\u002F"}}},"displayTemplate":"landing"},"strates":[{"type":"electronicProgramGuide","URLProgramGuide":"https:\u002F\u002Fhodor.canalplus.pro\u002Fapi\u002Fv2\u002Fmycanal\u002FprogramGuide\u002Ff000c6f4ebf44647682b3a0fa66d7d99","hash":"1945854091","button":{},"contents":[]},{"type":"plainTextHTML","css":"\u003Cstyle\u003E html.webview [data-heading] h1, html.embed [data-heading] h1 {display:none;}\u003C\u002Fstyle\u003E","hash":"1843955971","button":{},"contents":[]}],"tracking":{"omniture":{"prop4":"myCANAL - Guide","prop5":"myCANAL - Guide - Grille TV HAPI","prop6":"myCANAL - Guide - Grille TV HAPI - J - Maintenant","prop10":"Contenu","prop11":"Autres","prop12":"Consumer","eVar31":"Web - Programme TV","pageName":"myCANAL - Guide - Grille TV HAPI - J - Maintenant","channel":"myCANAL","page_level_1":"Guide","page_level_2":"Grille TV HAPI","page_level_3":"J - Maintenant","bo_layout":"Web - Programme TV","user_profile":"Consumer","page_name":"myCANAL - Guide - Grille TV HAPI - J - Maintenant","page_title":"Programme TV","page_display_title":"Programme TV","cover":false},"dataLayer":{"page_level_1":"Guide","page_level_2":"Grille TV HAPI","page_level_3":"J - Maintenant","bo_layout":"Web - Programme TV","user_profile":"Consumer","page_name":"myCANAL - Guide - Grille TV HAPI - J - Maintenant","page_title":"Programme TV","page_display_title":"Programme TV","cover":false}},"meta":{"title":"Programme TV : que regarder maintenant et ce soir ?","description":"Quel programme regarder à la télévision ? Retrouvez rapidement une émission, une série, un match ou un film sur toutes les chaines","canonical":"\u002Fbi\u002Fprogramme-tv\u002F"}},"dataUpdateCount":1,"dataUpdatedAt":1689115664701,"error":null,"errorUpdateCount":0,"errorUpdatedAt":0,"fetchFailureCount":0,"fetchFailureReason":null,"fetchMeta":null,"isInvalidated":false,"status":"success","fetchStatus":"idle"},"queryKey":["https:\u002F\u002Fhodor.canalplus.pro\u002Fapi\u002Fv2\u002Fmycanal\u002Fpage\u002Ff000c6f4ebf44647682b3a0fa66d7d99\u002F102831.json?aegon=true&get=14"],"queryHash":"[\"https:\u002F\u002Fhodor.canalplus.pro\u002Fapi\u002Fv2\u002Fmycanal\u002Fpage\u002Ff000c6f4ebf44647682b3a0fa66d7d99\u002F102831.json?aegon=true&get=14\"]"}]};
document.documentElement.classList.remove('no-js');</script><script src="/nr.js"></script><script id="__LOADABLE_REQUIRED_CHUNKS__" type="application/json">[5945,7905,1359,6412,4556,8918,8534,160,8035]</script><script id="__LOADABLE_REQUIRED_CHUNKS___ext" type="application/json">{"namedChunks":["components","PlainTextHtmlTemplate"]}</script><script async="" data-chunk="main" src="/assets/main.d1a03335a5f349d24e87.js"></script><script async="" data-chunk="components" src="/assets/5945.06f47fb7b21301ceeaf0.js"></script><script async="" data-chunk="components" src="/assets/7905.a52ad9e6573c62dfa740.js"></script><script async="" data-chunk="components" src="/assets/1359.d07c77cecdd3c82fd180.js"></script><script async="" data-chunk="components" src="/assets/6412.dabbd8e87c8c2d1137a8.js"></script><script async="" data-chunk="components" src="/assets/4556.d423ede2a2ac5b838942.js"></script><script async="" data-chunk="components" src="/assets/8918.c1e5f6484d584e7e033d.js"></script><script async="" data-chunk="components" src="/assets/8534.5b27b154e24e37153f7e.js"></script><script async="" data-chunk="components" src="/assets/components.92663f2aa89362d1ba19.js"></script><script async="" data-chunk="PlainTextHtmlTemplate" src="/assets/PlainTextHtmlTemplate.b95b22692c3e6007838a.js"></script></body></html>
+321 -226
View File
@@ -1,231 +1,326 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<site site="canalplus.com"> <site site="canalplus.com">
<channels> <channels>
<channel lang="fr" xmltv_id="6ter.fr" site_id="521">6TER</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#100">TEST03</channel> -->
<channel lang="fr" xmltv_id="AB1.fr" site_id="611">AB1</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1049">CANAL+SPORT 360 (CH)</channel> -->
<channel lang="fr" xmltv_id="Action.fr" site_id="504">ACTION</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1051">MULTISPORTS 7</channel> -->
<channel lang="en" xmltv_id="AlJazeeraEnglish.qa" site_id="675">AL JAZEERA ENG</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1053">CANAL+GRAND ECRAN (CH)</channel> -->
<channel lang="fr" xmltv_id="AlticeStudio.fr" site_id="820">ALTICE STUDIO</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1067">CHAINE: 1067</channel> -->
<channel lang="fr" xmltv_id="Animaux.fr" site_id="503">ANIMAUX</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1068">CHAINE: 1068</channel> -->
<channel lang="fr" xmltv_id="ArirangWorld.kr" site_id="252">ARIRANG TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1069">CHAINE: 1069</channel> -->
<channel lang="fr" xmltv_id="ARTEFrance.fr" site_id="154">ARTE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1070">CHAINE: 1070</channel> -->
<channel lang="fr" xmltv_id="AstrocenterTV.fr" site_id="632">ASTROCENTER TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#1071">CHAINE: 1071</channel> -->
<channel lang="fr" xmltv_id="Automotolachaine.fr" site_id="612">AUTOMOTO LA CHAINE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#184">DIEGO TV</channel> -->
<channel lang="en" xmltv_id="BBCWorldNewsEurope.uk" site_id="589">BBC WORLD NEWS</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#196">BOB TV</channel> -->
<channel lang="fr" xmltv_id="beINSports1France.fr" site_id="381">BEIN SPORTS 1</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#202">TEST04</channel> -->
<channel lang="fr" xmltv_id="beINSports2France.fr" site_id="384">BEIN SPORTS 2</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#21120">ARTE ALLEMAND</channel> -->
<channel lang="fr" xmltv_id="beINSports3France.fr" site_id="516">BEIN SPORTS 3</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#289">CHAINE EVENEMENT</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax10France.fr" site_id="605">BEIN SPORTS MAX 10</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#477">VOYAGE</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax4France.fr" site_id="596">BEIN SPORTS MAX 4</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#546">EVENEMENT SPORT 4K HDR UHD</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax5France.fr" site_id="597">BEIN SPORTS MAX 5</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#589">BBC WORLD NEWS</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax6France.fr" site_id="598">BEIN SPORTS MAX 6</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#639">LL EVENT UHD</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax7France.fr" site_id="599">BEIN SPORTS MAX 7</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#696">EURONEWS ALL</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax8France.fr" site_id="603">BEIN SPORTS MAX 8</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#700">CANAL+ FINALE UEFA CHAMPIONS LEAGUE</channel> -->
<channel lang="fr" xmltv_id="beINSportsMax9France.fr" site_id="604">BEIN SPORTS MAX 9</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#702">CANAL+ (CH)</channel> -->
<channel lang="fr" xmltv_id="BETFrance.fr" site_id="628">BET</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#726">EVENEMENT SPORT 4K UHD</channel> -->
<channel lang="fr" xmltv_id="BFMBusiness.fr" site_id="645">BFM BUSINESS</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#728">CANAL+ UHD</channel> -->
<channel lang="fr" xmltv_id="BFMTV.fr" site_id="633">BFM TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#737">RELIN PIWI</channel> -->
<channel lang="fr" xmltv_id="BloombergTVEurope.uk" site_id="47">BLOOMBERG TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#738">RELIN CINE+ CLASSIC</channel> -->
<channel lang="fr" xmltv_id="BlueZoomD.ch" site_id="893">BLUE ZOOM</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#739">TEST CSTAR</channel> -->
<channel lang="fr" xmltv_id="BoingFrance.fr" site_id="529">BOING</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#740">RELIN SEASONS</channel> -->
<channel lang="fr" xmltv_id="BoomerangFrance.fr" site_id="530">BOOMERANG</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#76">TEST05</channel> -->
<channel lang="fr" xmltv_id="BSmartTV.fr" site_id="849">BSMART TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#766">RMC SPORT LIVE 3</channel> -->
<channel lang="fr" xmltv_id="C8.fr" site_id="450">C8</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#767">RMC SPORT LIVE 4</channel> -->
<channel lang="fr" xmltv_id="CanalAlphaNE.ch" site_id="772">CANAL ALPHA NE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#768">CANAL 9</channel> -->
<channel lang="fr" xmltv_id="CanalJ.fr" site_id="525">CANAL J</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#77">TEST06</channel> -->
<channel lang="fr" xmltv_id="CanalPlusCinemaFrance.fr" site_id="198">CANAL+CINEMA</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#770">RTS 1</channel> -->
<channel lang="fr" xmltv_id="CanalPlusDocs.fr" site_id="899">CANAL+DOCS</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#771">RTS 2</channel> -->
<channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="19">CANAL+FOOT</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#776">RSI 1</channel> -->
<channel lang="fr" xmltv_id="CanalPlusFormula1.fr" site_id="824">CANAL+FORMULA1</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#777">RSI 2</channel> -->
<channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="301">CANAL+</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#779">SRF 2</channel> -->
<channel lang="fr" xmltv_id="CanalPlusGrandEcran.fr" site_id="900">CANAL+GRAND ECRAN</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#78">TEST07</channel> -->
<channel lang="fr" xmltv_id="CanalPlusKids.fr" site_id="259">CANAL+KIDS</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#780">3 SAT</channel> -->
<channel lang="fr" xmltv_id="CanalPlusMotoGP.fr" site_id="823">CANAL+MOTOGP</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#787">OCS MAX (CH)</channel> -->
<channel lang="fr" xmltv_id="CanalPlusPremierLeague.fr" site_id="815">CANAL+PREMIER LEAGUE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#788">OCS PULP (CH)</channel> -->
<channel lang="fr" xmltv_id="CanalPlusSeriesFrance.fr" site_id="481">CANAL+SERIES</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#789">OCS GEANTS (CH)</channel> -->
<channel lang="fr" xmltv_id="CanalPlusSport2.fr" site_id="861">CANAL+ SPORT 2 (CH)</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#79">TEST08</channel> -->
<channel lang="fr" xmltv_id="CanalPlusSport360.fr" site_id="83">CANAL+SPORT360</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#80">TEST09</channel> -->
<channel lang="fr" xmltv_id="CanalPlusSportFrance.fr" site_id="177">CANAL+SPORT</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#82">TEST10</channel> -->
<channel lang="fr" xmltv_id="CanalPlusTop14.fr" site_id="816">CANAL+TOP14</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#825">CANAL+ (CH)</channel> -->
<channel lang="fr" xmltv_id="CartoonNetworkFrance.fr" site_id="502">CARTOON NETWORK</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#827">CANAL+ CINEMA (CH)</channel> -->
<channel lang="fr" xmltv_id="ChassePeche.fr" site_id="681">CHASSE ET PECHE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#829">CINE+ PREMIER (CH)</channel> -->
<channel lang="fr" xmltv_id="Cherie25.fr" site_id="440">CHERIE 25</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#830">CINE+ FRISSON (CH)</channel> -->
<channel lang="fr" xmltv_id="CinePlusClassic.fr" site_id="531">CINE+ CLASSIC</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#831">C8 (CH)</channel> -->
<channel lang="fr" xmltv_id="CinePlusClub.fr" site_id="532">CINE+ CLUB</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#832">CSTAR (CH)</channel> -->
<channel lang="fr" xmltv_id="CinePlusEmotion.fr" site_id="396">CINE+ EMOTION</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#85">TEST11</channel> -->
<channel lang="fr" xmltv_id="CinePlusFamiz.fr" site_id="533">CINE+ FAMIZ</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#872">EVENEMENT SPORT 4K HLG UHD</channel> -->
<channel lang="fr" xmltv_id="CinePlusFrisson.fr" site_id="398">CINE+ FRISSON</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#873">CANAL+ SPORT (CH)</channel> -->
<channel lang="fr" xmltv_id="CinePlusPremier.fr" site_id="322">CINE+ PREMIER</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#874">CANAL+ UHD (CH)</channel> -->
<channel lang="fr" xmltv_id="CliqueTV.fr" site_id="665">CLIQUE TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#876">TEST01</channel> -->
<channel lang="fr" xmltv_id="CNBCEurope.uk" site_id="64">CNBC</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#877">TEST02</channel> -->
<channel lang="fr" xmltv_id="CNews.fr" site_id="480">CNEWS</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#882">EVENEMENT A LA CARTE</channel> -->
<channel lang="en" xmltv_id="CNNInternationalEurope.us" site_id="30">CNN INT.</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#89">TEST12</channel> -->
<channel lang="fr" xmltv_id="ColmaxTV.fr" site_id="643">COLMAX TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#894">CANAL+ LIGUE1</channel> -->
<channel lang="fr" xmltv_id="ComediePlus.fr" site_id="534">COMEDIE+</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#90">TEST13</channel> -->
<channel lang="fr" xmltv_id="ComedyCentralFrance.fr" site_id="806">COMEDY CENTRAL</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#970">CHAINE : 970</channel> -->
<channel lang="fr" xmltv_id="CStar.fr" site_id="513">CSTAR</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#971">CHAINE : 971</channel> -->
<channel lang="fr" xmltv_id="CStarHitsFrance.fr" site_id="723">CSTAR HITS FRANCE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#972">CHAINE : 972</channel> -->
<channel lang="fr" xmltv_id="DasErste.de" site_id="781">ARD DAS ERSTE</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#973">CHAINE : 973</channel> -->
<channel lang="fr" xmltv_id="DisneyChannelFrance.fr" site_id="282">DISNEY CHANNEL</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#974">CHAINE : 974</channel> -->
<channel lang="fr" xmltv_id="DisneyChannelFrancePlus1.fr" site_id="535">DISNEY CHANNEL+1</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#975">CHAINE : 975</channel> -->
<channel lang="fr" xmltv_id="DisneyJuniorFrance.fr" site_id="274">DISNEY JUNIOR</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#977">BEIN SPORTS 1</channel> -->
<channel lang="fr" xmltv_id="DorcelTV.nl" site_id="536">DORCEL TV</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#978">BEIN SPORTS 2</channel> -->
<channel lang="fr" xmltv_id="DorcelXXX.nl" site_id="537">DORCEL XXX</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#979">BEIN SPORTS 3</channel> -->
<channel lang="fr" xmltv_id="Equidia.fr" site_id="540">EQUIDIA</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#980">BEIN SPORTS MAX 4</channel> -->
<channel lang="fr" xmltv_id="EuronewsFrench.fr" site_id="324">EURONEWS</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#981">BEIN SPORTS MAX 5</channel> -->
<channel lang="fr" xmltv_id="Eurosport1.fr" site_id="101">EUROSPORT 1</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#982">BEIN SPORTS MAX 6</channel> -->
<channel lang="fr" xmltv_id="Eurosport2.fr" site_id="436">EUROSPORT 2</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#983">BEIN SPORTS MAX 7</channel> -->
<channel lang="fr" xmltv_id="Eurosport3.fr" site_id="985">EUROSPORT 3</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#984">CANAL+</channel> -->
<channel lang="fr" xmltv_id="Eurosport360HD1.fr" site_id="635">EUROSPORT 360 1</channel> <!-- <channel lang="fr" xmltv_id="" site_id="#993">CANAL+ UHD</channel> -->
<channel lang="fr" xmltv_id="Eurosport360HD2.fr" site_id="636">EUROSPORT 360 2</channel> <channel lang="en" xmltv_id="AlJazeeraEnglish.qa" site_id="#675">AL JAZEERA ENG</channel>
<channel lang="fr" xmltv_id="Eurosport360HD3.fr" site_id="637">EUROSPORT 360 3</channel> <channel lang="en" xmltv_id="BBCWorldNewsEurope.uk" site_id="#589">BBC WORLD NEWS</channel>
<channel lang="fr" xmltv_id="Eurosport360HD4.fr" site_id="638">EUROSPORT 360 4</channel> <channel lang="en" xmltv_id="CNNInternationalEurope.us" site_id="#30">CNN INT.</channel>
<channel lang="fr" xmltv_id="Eurosport360HD5.fr" site_id="650">EUROSPORT 360 5</channel> <channel lang="en" xmltv_id="France24English.fr" site_id="#311">FRANCE 24 ENG</channel>
<channel lang="fr" xmltv_id="Eurosport360HD6.fr" site_id="651">EUROSPORT 360 6</channel> <channel lang="en" xmltv_id="NHKWorldJapan.jp" site_id="#654">NHK WORLD-JAPAN</channel>
<channel lang="fr" xmltv_id="Eurosport360HD7.fr" site_id="652">EUROSPORT 360 7</channel> <channel lang="fr" xmltv_id="2STV.sn" site_id="sn#180122">2STV</channel>
<channel lang="fr" xmltv_id="Eurosport360HD8.fr" site_id="653">EUROSPORT 360 8</channel> <channel lang="fr" xmltv_id="6ter.fr" site_id="#521">6TER</channel>
<channel lang="fr" xmltv_id="Eurosport4.fr" site_id="986">EUROSPORT 4</channel> <channel lang="fr" xmltv_id="AB1.fr" site_id="#611">AB1</channel>
<channel lang="fr" xmltv_id="Eurosport5.fr" site_id="987">EUROSPORT 5</channel> <channel lang="fr" xmltv_id="Action.fr" site_id="#504">ACTION</channel>
<channel lang="fr" xmltv_id="FootPlus.fr" site_id="542">FOOT+ 24/24</channel> <channel lang="fr" xmltv_id="AlJazeeraEnglish.qa" site_id="#675">AL JAZEERA ENG</channel>
<channel lang="fr" xmltv_id="France2.fr" site_id="26">FRANCE 2</channel> <channel lang="fr" xmltv_id="AlticeStudio.fr" site_id="#820">ALTICE STUDIO</channel>
<channel lang="en" xmltv_id="France24English.fr" site_id="311">FRANCE 24 ENG</channel> <channel lang="fr" xmltv_id="Animaux.fr" site_id="#503">ANIMAUX</channel>
<channel lang="fr" xmltv_id="France24French.fr" site_id="310">FRANCE 24</channel> <channel lang="fr" xmltv_id="ArirangWorld.kr" site_id="#252">ARIRANG TV</channel>
<channel lang="fr" xmltv_id="France3.fr" site_id="543">FRANCE 3</channel> <channel lang="fr" xmltv_id="ARTEFrance.fr" site_id="#154">ARTE</channel>
<channel lang="fr" xmltv_id="France3Alpes.fr" site_id="926">F3 ALPES</channel> <channel lang="fr" xmltv_id="AstrocenterTV.fr" site_id="#632">ASTROCENTER TV</channel>
<channel lang="fr" xmltv_id="France3Alsace.fr" site_id="941">F3 ALSACE</channel> <channel lang="fr" xmltv_id="Automotolachaine.fr" site_id="#612">AUTOMOTO LA CHAINE</channel>
<channel lang="fr" xmltv_id="France3Aquitaine.fr" site_id="922">F3 AQUITAINE</channel> <channel lang="fr" xmltv_id="beINSports1France.fr" site_id="#381">BEIN SPORTS 1</channel>
<channel lang="fr" xmltv_id="France3Auvergne.fr" site_id="924">F3 AUVERGNE</channel> <channel lang="fr" xmltv_id="beINSports2France.fr" site_id="#384">BEIN SPORTS 2</channel>
<channel lang="fr" xmltv_id="France3BasseNormandie.fr" site_id="923">F3 BNORMANDIE</channel> <channel lang="fr" xmltv_id="beINSports3France.fr" site_id="#516">BEIN SPORTS 3</channel>
<channel lang="fr" xmltv_id="France3Bourgogne.fr" site_id="925">F3 BOURGOGNE</channel> <channel lang="fr" xmltv_id="beINSportsMax10France.fr" site_id="#605">BEIN SPORTS MAX 10</channel>
<channel lang="fr" xmltv_id="France3Bretagne.fr" site_id="939">F3 BRETAGNE</channel> <channel lang="fr" xmltv_id="beINSportsMax4France.fr" site_id="#596">BEIN SPORTS MAX 4</channel>
<channel lang="fr" xmltv_id="France3CentreValdeLoire.fr" site_id="935">F3 CENTRE</channel> <channel lang="fr" xmltv_id="beINSportsMax5France.fr" site_id="#597">BEIN SPORTS MAX 5</channel>
<channel lang="fr" xmltv_id="France3ChampagneArdenne.fr" site_id="938">F3 CHAMP ARDENNE</channel> <channel lang="fr" xmltv_id="beINSportsMax6France.fr" site_id="#598">BEIN SPORTS MAX 6</channel>
<channel lang="fr" xmltv_id="France3CorseViaStella.fr" site_id="943">F3 CORSEVIASTELLA</channel> <channel lang="fr" xmltv_id="beINSportsMax7France.fr" site_id="#599">BEIN SPORTS MAX 7</channel>
<channel lang="fr" xmltv_id="France3CotedAzur.fr" site_id="934">F3 COTE D&apos;AZUR</channel> <channel lang="fr" xmltv_id="beINSportsMax8France.fr" site_id="#603">BEIN SPORTS MAX 8</channel>
<channel lang="fr" xmltv_id="France3FrancheComte.fr" site_id="921">F3 FRANCHE COMTE</channel> <channel lang="fr" xmltv_id="beINSportsMax9France.fr" site_id="#604">BEIN SPORTS MAX 9</channel>
<channel lang="fr" xmltv_id="France3HauteNormandie.fr" site_id="940">F3 HNORMANDIE</channel> <channel lang="fr" xmltv_id="BETFrance.fr" site_id="#628">BET</channel>
<channel lang="fr" xmltv_id="France3LanguedocRoussillon.fr" site_id="931">F3 LANGUEDOCROU</channel> <channel lang="fr" xmltv_id="BFMBusiness.fr" site_id="#645">BFM BUSINESS</channel>
<channel lang="fr" xmltv_id="France3Limousin.fr" site_id="928">F3 LIMOUSIN</channel> <channel lang="fr" xmltv_id="BFMTV.fr" site_id="#633">BFM TV</channel>
<channel lang="fr" xmltv_id="France3Lorraine.fr" site_id="932">F3 LORRAINE</channel> <channel lang="fr" xmltv_id="BloombergTVEurope.uk" site_id="#47">BLOOMBERG TV</channel>
<channel lang="fr" xmltv_id="France3MidiPyrenees.fr" site_id="942">F3 MIDI PYRENEES</channel> <channel lang="fr" xmltv_id="BlueZoomD.ch" site_id="#893">BLUE ZOOM</channel>
<channel lang="fr" xmltv_id="France3NordPasdeCalais.fr" site_id="927">F3 NORD PDC</channel> <channel lang="fr" xmltv_id="BoingFrance.fr" site_id="#529">BOING</channel>
<channel lang="fr" xmltv_id="France3NouvelleAquitaine.fr" site_id="998">F3 NOUVELLE AQUITAINE</channel> <channel lang="fr" xmltv_id="BoomerangFrance.fr" site_id="#530">BOOMERANG</channel>
<channel lang="fr" xmltv_id="France3ParisIledeFrance.fr" site_id="936">F3 PARIS IDF</channel> <channel lang="fr" xmltv_id="BSmartTV.fr" site_id="#849">BSMART TV</channel>
<channel lang="fr" xmltv_id="France3PaysdelaLoire.fr" site_id="933">F3 PAYS DE LA LOIRE</channel> <channel lang="fr" xmltv_id="C8.fr" site_id="#450">C8</channel>
<channel lang="fr" xmltv_id="France3Picardie.fr" site_id="920">F3 PICARDIE</channel> <channel lang="fr" xmltv_id="CanalAlphaNE.ch" site_id="#772">CANAL ALPHA NE</channel>
<channel lang="fr" xmltv_id="France3PoitouCharentes.fr" site_id="937">F3 POITOUCHAR</channel> <channel lang="fr" xmltv_id="CanalJ.fr" site_id="#525">CANAL J</channel>
<channel lang="fr" xmltv_id="France3ProvenceAlpes.fr" site_id="930">F3 PROV ALPES</channel> <channel lang="fr" xmltv_id="CanalPlusCinemaFrance.fr" site_id="#198">CANAL+CINEMA</channel>
<channel lang="fr" xmltv_id="France3RhoneAlpes.fr" site_id="929">F3 RHONE ALPES</channel> <channel lang="fr" xmltv_id="CanalPlusDocs.fr" site_id="#899">CANAL+DOCS</channel>
<channel lang="fr" xmltv_id="France4.fr" site_id="544">FRANCE 4</channel> <channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="#1045">CANAL+FOOT</channel>
<channel lang="fr" xmltv_id="France5.fr" site_id="545">FRANCE 5</channel> <channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="#19">CANAL+FOOT</channel>
<channel lang="fr" xmltv_id="Franceinfo.fr" site_id="670">FRANCEINFO:</channel> <channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="#992">CANAL+FOOT</channel>
<channel lang="fr" xmltv_id="GameOne.fr" site_id="592">GAME ONE</channel> <channel lang="fr" xmltv_id="CanalPlusFormula1.fr" site_id="#824">CANAL+FORMULA1</channel>
<channel lang="fr" xmltv_id="GolfPlus.fr" site_id="378">GOLF+</channel> <channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="#301">CANAL+</channel>
<channel lang="fr" xmltv_id="Gulli.fr" site_id="549">GULLI</channel> <channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="#573">CANAL+</channel>
<channel lang="fr" xmltv_id="HistoireTV.fr" site_id="550">HISTOIRE TV</channel> <channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="#601">CANAL+</channel>
<channel lang="fr" xmltv_id="I24NewsFrench.il" site_id="362">I24 NEWS</channel> <channel lang="fr" xmltv_id="CanalPlusGrandEcran.fr" site_id="#900">CANAL+GRAND ECRAN</channel>
<channel lang="fr" xmltv_id="InfosportPlus.fr" site_id="551">INFOSPORT+</channel> <channel lang="fr" xmltv_id="CanalPlusKids.fr" site_id="#259">CANAL+KIDS</channel>
<channel lang="fr" xmltv_id="JacquieMichelTV.fr" site_id="850">JACQUIE &amp; MICHEL TV</channel> <channel lang="fr" xmltv_id="CanalPlusMotoGP.fr" site_id="#823">CANAL+MOTOGP</channel>
<channel lang="fr" xmltv_id="JOne.fr" site_id="484">J-ONE</channel> <channel lang="fr" xmltv_id="CanalPlusPremierLeague.fr" site_id="#815">CANAL+PREMIER LEAGUE</channel>
<channel lang="fr" xmltv_id="LaChaineMeteo.fr" site_id="552">LA CHAINE METEO</channel> <channel lang="fr" xmltv_id="CanalPlusSeriesFrance.fr" site_id="#481">CANAL+SERIES</channel>
<channel lang="fr" xmltv_id="LCI.fr" site_id="553">LCI</channel> <channel lang="fr" xmltv_id="CanalPlusSport2.fr" site_id="#861">CANAL+ SPORT 2 (CH)</channel>
<channel lang="fr" xmltv_id="LCP.fr" site_id="554">LCP</channel> <channel lang="fr" xmltv_id="CanalPlusSport360.fr" site_id="#1048">CANAL+SPORT360</channel>
<channel lang="fr" xmltv_id="LEquipe.fr" site_id="451">L&apos;EQUIPE</channel> <channel lang="fr" xmltv_id="CanalPlusSport360.fr" site_id="#83">CANAL+SPORT360</channel>
<channel lang="fr" xmltv_id="LFMTV.ch" site_id="879">LFM TV</channel> <channel lang="fr" xmltv_id="CanalPlusSportFrance.fr" site_id="#177">CANAL+SPORT</channel>
<channel lang="fr" xmltv_id="M6.fr" site_id="313">M6</channel> <channel lang="fr" xmltv_id="CanalPlusSportFrance.fr" site_id="#574">CANAL+SPORT</channel>
<channel lang="fr" xmltv_id="M6Music.fr" site_id="352">M6 MUSIC</channel> <channel lang="fr" xmltv_id="CanalPlusTop14.fr" site_id="#816">CANAL+TOP14</channel>
<channel lang="fr" xmltv_id="Mangas.fr" site_id="613">MANGAS</channel> <channel lang="fr" xmltv_id="CartoonNetworkFrance.fr" site_id="#502">CARTOON NETWORK</channel>
<channel lang="fr" xmltv_id="ManX.be" site_id="672">MAN X</channel> <channel lang="fr" xmltv_id="ChassePeche.fr" site_id="#681">CHASSE ET PECHE</channel>
<channel lang="fr" xmltv_id="MCM.fr" site_id="556">MCM</channel> <channel lang="fr" xmltv_id="Cherie25.fr" site_id="#440">CHERIE 25</channel>
<channel lang="fr" xmltv_id="Melody.fr" site_id="580">MELODY</channel> <channel lang="fr" xmltv_id="CinePlusClassic.fr" site_id="#531">CINE+ CLASSIC</channel>
<channel lang="fr" xmltv_id="Mezzo.fr" site_id="560">MEZZO</channel> <channel lang="fr" xmltv_id="CinePlusClub.fr" site_id="#532">CINE+ CLUB</channel>
<channel lang="fr" xmltv_id="MezzoLiveHD.fr" site_id="268">MEZZO LIVE</channel> <channel lang="fr" xmltv_id="CinePlusEmotion.fr" site_id="#396">CINE+ EMOTION</channel>
<channel lang="fr" xmltv_id="MGGTV.fr" site_id="819">MGG TV</channel> <channel lang="fr" xmltv_id="CinePlusFamiz.fr" site_id="#533">CINE+ FAMIZ</channel>
<channel lang="fr" xmltv_id="MTVFrance.fr" site_id="470">MTV</channel> <channel lang="fr" xmltv_id="CinePlusFrisson.fr" site_id="#398">CINE+ FRISSON</channel>
<channel lang="fr" xmltv_id="MTVHitsFrance.fr" site_id="629">MTV HITS</channel> <channel lang="fr" xmltv_id="CinePlusPremier.fr" site_id="#322">CINE+ PREMIER</channel>
<channel lang="fr" xmltv_id="MultiSports1.fr" site_id="562">MULTISPORTS 1</channel> <channel lang="fr" xmltv_id="CliqueTV.fr" site_id="#665">CLIQUE TV</channel>
<channel lang="fr" xmltv_id="MultiSports2.fr" site_id="563">MULTISPORTS 2</channel> <channel lang="fr" xmltv_id="CNBCEurope.uk" site_id="#64">CNBC</channel>
<channel lang="fr" xmltv_id="MultiSports3.fr" site_id="564">MULTISPORTS 3</channel> <channel lang="fr" xmltv_id="CNews.fr" site_id="#480">CNEWS</channel>
<channel lang="fr" xmltv_id="MultiSports4.fr" site_id="565">MULTISPORTS 4</channel> <channel lang="fr" xmltv_id="ColmaxTV.fr" site_id="#643">COLMAX TV</channel>
<channel lang="fr" xmltv_id="MultiSports5.fr" site_id="566">MULTISPORTS 5</channel> <channel lang="fr" xmltv_id="ComediePlus.fr" site_id="#534">COMEDIE+</channel>
<channel lang="fr" xmltv_id="MultiSports6.fr" site_id="567">MULTISPORTS 6</channel> <channel lang="fr" xmltv_id="ComedyCentralFrance.fr" site_id="#806">COMEDY CENTRAL</channel>
<channel lang="fr" xmltv_id="MuseumTV.fr" site_id="678">MUSEUM</channel> <channel lang="fr" xmltv_id="CStar.fr" site_id="#513">CSTAR</channel>
<channel lang="fr" xmltv_id="MyZenTV.fr" site_id="656">MY ZEN TV</channel> <channel lang="fr" xmltv_id="CStarHitsFrance.fr" site_id="#723">CSTAR HITS FRANCE</channel>
<channel lang="fr" xmltv_id="NationalGeographicFrance.fr" site_id="302">NATIONAL GEO</channel> <channel lang="fr" xmltv_id="DasErste.de" site_id="#781">ARD DAS ERSTE</channel>
<channel lang="fr" xmltv_id="NationalGeographicWildFrance.fr" site_id="290">NATIONAL GEOGRAPHIC WILD</channel> <channel lang="fr" xmltv_id="DisneyChannelFrance.fr" site_id="#282">DISNEY CHANNEL</channel>
<channel lang="en" xmltv_id="NHKWorldJapan.jp" site_id="654">NHK WORLD-JAPAN</channel> <channel lang="fr" xmltv_id="DisneyChannelFrancePlus1.fr" site_id="#535">DISNEY CHANNEL+1</channel>
<channel lang="fr" xmltv_id="NickelodeonFrance.fr" site_id="591">NICKELODEON</channel> <channel lang="fr" xmltv_id="DisneyJuniorFrance.fr" site_id="#274">DISNEY JUNIOR</channel>
<channel lang="fr" xmltv_id="NickelodeonJunior.fr" site_id="593">NICKELODEON JUNIOR</channel> <channel lang="fr" xmltv_id="DoraTVFrance.fr" site_id="#185">DORA TV</channel>
<channel lang="fr" xmltv_id="NickelodeonTeen.fr" site_id="518">NICKELODEON TEEN</channel> <channel lang="fr" xmltv_id="DorcelTV.nl" site_id="#536">DORCEL TV</channel>
<channel lang="fr" xmltv_id="NollywoodTV.fr" site_id="527">NOLLYWOOD TV</channel> <channel lang="fr" xmltv_id="DorcelXXX.nl" site_id="#537">DORCEL XXX</channel>
<channel lang="fr" xmltv_id="NonStopPeople.fr" site_id="434">NON STOP PEOPLE</channel> <channel lang="fr" xmltv_id="Equidia.fr" site_id="#540">EQUIDIA</channel>
<channel lang="fr" xmltv_id="NovelasTV.fr" site_id="693">NOVELAS TV</channel> <channel lang="fr" xmltv_id="EuronewsFrench.fr" site_id="#324">EURONEWS</channel>
<channel lang="fr" xmltv_id="NRJ12.fr" site_id="568">NRJ 12</channel> <channel lang="fr" xmltv_id="Eurosport1.fr" site_id="#101">EUROSPORT 1</channel>
<channel lang="fr" xmltv_id="NRJHits.fr" site_id="569">NRJ HITS</channel> <channel lang="fr" xmltv_id="Eurosport2.fr" site_id="#436">EUROSPORT 2</channel>
<channel lang="fr" xmltv_id="OCSChoc.fr" site_id="466">OCS CHOC</channel> <channel lang="fr" xmltv_id="Eurosport3.fr" site_id="#985">EUROSPORT 3</channel>
<channel lang="fr" xmltv_id="OCSCity.fr" site_id="467">OCS CITY</channel> <channel lang="fr" xmltv_id="Eurosport360HD1.fr" site_id="#635">EUROSPORT 360 1</channel>
<channel lang="fr" xmltv_id="OCSGeants.fr" site_id="468">OCS GEANTS</channel> <channel lang="fr" xmltv_id="Eurosport360HD2.fr" site_id="#636">EUROSPORT 360 2</channel>
<channel lang="fr" xmltv_id="OCSMax.fr" site_id="372">OCS MAX</channel> <channel lang="fr" xmltv_id="Eurosport360HD3.fr" site_id="#637">EUROSPORT 360 3</channel>
<channel lang="fr" xmltv_id="OlympiaTV.fr" site_id="813">OLYMPIA TV</channel> <channel lang="fr" xmltv_id="Eurosport360HD4.fr" site_id="#638">EUROSPORT 360 4</channel>
<channel lang="fr" xmltv_id="OneTV.ch" site_id="880">ONE TV</channel> <channel lang="fr" xmltv_id="Eurosport360HD5.fr" site_id="#650">EUROSPORT 360 5</channel>
<channel lang="fr" xmltv_id="ORF1.at" site_id="783">ORF 1</channel> <channel lang="fr" xmltv_id="Eurosport360HD6.fr" site_id="#651">EUROSPORT 360 6</channel>
<channel lang="fr" xmltv_id="ParamountChannelFrance.fr" site_id="487">PARAMOUNT CHANNEL</channel> <channel lang="fr" xmltv_id="Eurosport360HD7.fr" site_id="#652">EUROSPORT 360 7</channel>
<channel lang="fr" xmltv_id="ParisPremiere.fr" site_id="294">PARIS PREMIERE</channel> <channel lang="fr" xmltv_id="Eurosport360HD8.fr" site_id="#653">EUROSPORT 360 8</channel>
<channel lang="fr" xmltv_id="PenthouseBlack.us" site_id="686">PENTHOUSE BLACK</channel> <channel lang="fr" xmltv_id="Eurosport4.fr" site_id="#986">EUROSPORT 4</channel>
<channel lang="fr" xmltv_id="PenthouseGold.us" site_id="167">PENTHOUSE</channel> <channel lang="fr" xmltv_id="Eurosport5.fr" site_id="#987">EUROSPORT 5</channel>
<channel lang="fr" xmltv_id="PinkX.fr" site_id="575">PINK X</channel> <channel lang="fr" xmltv_id="Eurosport6.fr" site_id="#988">EUROSPORT 6</channel>
<channel lang="fr" xmltv_id="PiwiPlus.fr" site_id="576">PIWI+</channel> <channel lang="fr" xmltv_id="Eurosport7.fr" site_id="#989">EUROSPORT 7</channel>
<channel lang="fr" xmltv_id="PlanetePlus.fr" site_id="270">PLANETE+</channel> <channel lang="fr" xmltv_id="Eurosport8.fr" site_id="#990">EUROSPORT 8</channel>
<channel lang="fr" xmltv_id="PlanetePlusAE.fr" site_id="588">PLANETE+AVENTURE</channel> <channel lang="fr" xmltv_id="Eurosport9.fr" site_id="#991">EUROSPORT 9</channel>
<channel lang="fr" xmltv_id="PlanetePlusCI.fr" site_id="587">PLANETE+CRIME</channel> <channel lang="fr" xmltv_id="FootPlus.fr" site_id="#542">FOOT+ 24/24</channel>
<channel lang="fr" xmltv_id="PolarPlus.fr" site_id="692">POLAR+</channel> <channel lang="fr" xmltv_id="France2.fr" site_id="#26">FRANCE 2</channel>
<channel lang="fr" xmltv_id="Rai1.it" site_id="782">RAI UNO</channel> <channel lang="fr" xmltv_id="France24English.fr" site_id="#311">FRANCE 24 ENG</channel>
<channel lang="fr" xmltv_id="RFMTV.fr" site_id="557">RFM TV</channel> <channel lang="fr" xmltv_id="France24French.fr" site_id="#310">FRANCE 24</channel>
<channel lang="fr" xmltv_id="RMCDecouverte.fr" site_id="595">RMC DECOUVERTE</channel> <channel lang="fr" xmltv_id="France3.fr" site_id="#543">FRANCE 3</channel>
<channel lang="fr" xmltv_id="RMCSport1.fr" site_id="732">RMC SPORT 1</channel> <channel lang="fr" xmltv_id="France3Alpes.fr" site_id="#926">F3 ALPES</channel>
<channel lang="fr" xmltv_id="RMCSport2.fr" site_id="733">RMC SPORT 2</channel> <channel lang="fr" xmltv_id="France3Alsace.fr" site_id="#941">F3 ALSACE</channel>
<channel lang="fr" xmltv_id="RMCSport3.fr" site_id="734">RMC SPORT 3</channel> <channel lang="fr" xmltv_id="France3Aquitaine.fr" site_id="#922">F3 AQUITAINE</channel>
<channel lang="fr" xmltv_id="RMCSport4.fr" site_id="735">RMC SPORT 4</channel> <channel lang="fr" xmltv_id="France3Auvergne.fr" site_id="#924">F3 AUVERGNE</channel>
<channel lang="fr" xmltv_id="RMCSportLive5.fr" site_id="756">RMC SPORT LIVE 5</channel> <channel lang="fr" xmltv_id="France3BasseNormandie.fr" site_id="#923">F3 BNORMANDIE</channel>
<channel lang="fr" xmltv_id="RMCSportLive6.fr" site_id="757">RMC SPORT LIVE 6</channel> <channel lang="fr" xmltv_id="France3Bourgogne.fr" site_id="#925">F3 BOURGOGNE</channel>
<channel lang="fr" xmltv_id="RMCSportLive7.fr" site_id="758">RMC SPORT LIVE 7</channel> <channel lang="fr" xmltv_id="France3Bretagne.fr" site_id="#939">F3 BRETAGNE</channel>
<channel lang="fr" xmltv_id="RMCSportLive8.fr" site_id="759">RMC SPORT LIVE 8</channel> <channel lang="fr" xmltv_id="France3CentreValdeLoire.fr" site_id="#935">F3 CENTRE</channel>
<channel lang="fr" xmltv_id="RMCSportLive9.fr" site_id="760">RMC SPORT LIVE 9</channel> <channel lang="fr" xmltv_id="France3ChampagneArdenne.fr" site_id="#938">F3 CHAMP ARDENNE</channel>
<channel lang="fr" xmltv_id="RMCSportLive10.fr" site_id="761">RMC SPORT LIVE 10</channel> <channel lang="fr" xmltv_id="France3CorseViaStella.fr" site_id="#943">F3 CORSEVIASTELLA</channel>
<channel lang="fr" xmltv_id="RMCSportLive11.fr" site_id="762">RMC SPORT LIVE 11</channel> <channel lang="fr" xmltv_id="France3CotedAzur.fr" site_id="#934">F3 COTE D&apos;AZUR</channel>
<channel lang="fr" xmltv_id="RMCSportLive12.fr" site_id="763">RMC SPORT LIVE 12</channel> <channel lang="fr" xmltv_id="France3FrancheComte.fr" site_id="#921">F3 FRANCHE COMTE</channel>
<channel lang="fr" xmltv_id="RMCSportLive13.fr" site_id="764">RMC SPORT LIVE 13</channel> <channel lang="fr" xmltv_id="France3HauteNormandie.fr" site_id="#940">F3 HNORMANDIE</channel>
<channel lang="fr" xmltv_id="RMCSportLive14.fr" site_id="765">RMC SPORT LIVE 14</channel> <channel lang="fr" xmltv_id="France3LanguedocRoussillon.fr" site_id="#931">F3 LANGUEDOCROU</channel>
<channel lang="fr" xmltv_id="RMCStory.fr" site_id="571">RMC STORY</channel> <channel lang="fr" xmltv_id="France3Limousin.fr" site_id="#928">F3 LIMOUSIN</channel>
<channel lang="fr" xmltv_id="RougeTV.ch" site_id="878">ROUGE TV</channel> <channel lang="fr" xmltv_id="France3Lorraine.fr" site_id="#932">F3 LORRAINE</channel>
<channel lang="fr" xmltv_id="RTFrance.fr" site_id="479">RT FRANCE</channel> <channel lang="fr" xmltv_id="France3MidiPyrenees.fr" site_id="#942">F3 MIDI PYRENEES</channel>
<channel lang="fr" xmltv_id="RTL9.lu" site_id="505">RTL9</channel> <channel lang="fr" xmltv_id="France3NordPasdeCalais.fr" site_id="#927">F3 NORD PDC</channel>
<channel lang="fr" xmltv_id="ScienceVieTV.fr" site_id="614">SCIENCE ET VIE TV</channel> <channel lang="fr" xmltv_id="France3NouvelleAquitaine.fr" site_id="#998">F3 NOUVELLE AQUITAINE</channel>
<channel lang="fr" xmltv_id="Seasons.fr" site_id="577">SEASONS</channel> <channel lang="fr" xmltv_id="France3ParisIledeFrance.fr" site_id="#936">F3 PARIS IDF</channel>
<channel lang="fr" xmltv_id="SerieClub.fr" site_id="356">SERIE CLUB</channel> <channel lang="fr" xmltv_id="France3PaysdelaLoire.fr" site_id="#933">F3 PAYS DE LA LOIRE</channel>
<channel lang="fr" xmltv_id="SRF1.ch" site_id="778">SRF 1</channel> <channel lang="fr" xmltv_id="France3Picardie.fr" site_id="#920">F3 PICARDIE</channel>
<channel lang="fr" xmltv_id="StingrayClassica.ca" site_id="165">CLASSICA</channel> <channel lang="fr" xmltv_id="France3PoitouCharentes.fr" site_id="#937">F3 POITOUCHAR</channel>
<channel lang="fr" xmltv_id="StingrayDJAZZ.ca" site_id="407">DJAZZ</channel> <channel lang="fr" xmltv_id="France3ProvenceAlpes.fr" site_id="#930">F3 PROV ALPES</channel>
<channel lang="fr" xmltv_id="TCMCinema.fr" site_id="374">TCM CINEMA</channel> <channel lang="fr" xmltv_id="France3RhoneAlpes.fr" site_id="#929">F3 RHONE ALPES</channel>
<channel lang="fr" xmltv_id="TeleBielingue.ch" site_id="775">TELEBIELINGUE</channel> <channel lang="fr" xmltv_id="France4.fr" site_id="#544">FRANCE 4</channel>
<channel lang="fr" xmltv_id="TeletoonPlus.fr" site_id="581">TELETOON+</channel> <channel lang="fr" xmltv_id="France5.fr" site_id="#545">FRANCE 5</channel>
<channel lang="fr" xmltv_id="TeletoonPlus1.fr" site_id="582">TELETOON+1</channel> <channel lang="fr" xmltv_id="Franceinfo.fr" site_id="#670">FRANCEINFO:</channel>
<channel lang="fr" xmltv_id="Teva.fr" site_id="292">TEVA</channel> <channel lang="fr" xmltv_id="GameOne.fr" site_id="#592">GAME ONE</channel>
<channel lang="fr" xmltv_id="TF1.fr" site_id="312">TF1</channel> <channel lang="fr" xmltv_id="GolfPlus.fr" site_id="#378">GOLF+</channel>
<channel lang="fr" xmltv_id="TF1SeriesFilms.fr" site_id="526">TF1 SERIES FILMS</channel> <channel lang="fr" xmltv_id="Gulli.fr" site_id="#549">GULLI</channel>
<channel lang="fr" xmltv_id="TFX.fr" site_id="570">TFX</channel> <channel lang="fr" xmltv_id="HistoireTV.fr" site_id="#550">HISTOIRE TV</channel>
<channel lang="fr" xmltv_id="TiJi.fr" site_id="583">TIJI</channel> <channel lang="fr" xmltv_id="I24NewsFrench.il" site_id="#362">I24 NEWS</channel>
<channel lang="fr" xmltv_id="TMC.fr" site_id="584">TMC</channel> <channel lang="fr" xmltv_id="InfosportPlus.fr" site_id="#551">INFOSPORT+</channel>
<channel lang="fr" xmltv_id="ToonamiFrance.fr" site_id="683">TOONAMI</channel> <channel lang="fr" xmltv_id="JacquieMichelTV.fr" site_id="#850">JACQUIE &amp; MICHEL TV</channel>
<channel lang="fr" xmltv_id="ToutelHistoire.fr" site_id="620">TOUTE L&apos;HISTOIRE</channel> <channel lang="fr" xmltv_id="JOne.fr" site_id="#484">J-ONE</channel>
<channel lang="fr" xmltv_id="TraceUrban.fr" site_id="585">TRACE URBAN</channel> <channel lang="fr" xmltv_id="LaChaineMeteo.fr" site_id="#552">LA CHAINE METEO</channel>
<channel lang="fr" xmltv_id="TV5MondeFranceBelgiumSwitzerland.fr" site_id="520">TV5 MONDE</channel> <channel lang="fr" xmltv_id="LaTele.ch" site_id="#773">LA TELE</channel>
<channel lang="fr" xmltv_id="TVBreizh.fr" site_id="586">TV BREIZH</channel> <channel lang="fr" xmltv_id="LCI.fr" site_id="#553">LCI</channel>
<channel lang="fr" xmltv_id="UshuaiaTV.fr" site_id="142">USHUAIA TV</channel> <channel lang="fr" xmltv_id="LCP.fr" site_id="#554">LCP</channel>
<channel lang="fr" xmltv_id="VICETV.us" site_id="677">VICE TV</channel> <channel lang="fr" xmltv_id="LemanBleu.ch" site_id="#774">LEMAN BLEU</channel>
<channel lang="fr" xmltv_id="VixenTV.ca" site_id="547">VIXEN</channel> <channel lang="fr" xmltv_id="LEquipe.fr" site_id="#451">L&apos;EQUIPE</channel>
<channel lang="fr" xmltv_id="W9.fr" site_id="296">W9</channel> <channel lang="fr" xmltv_id="LFMTV.ch" site_id="#879">LFM TV</channel>
<channel lang="fr" xmltv_id="WarnerTVFrance.fr" site_id="694">WARNER TV</channel> <channel lang="fr" xmltv_id="M6.fr" site_id="#313">M6</channel>
<channel lang="fr" xmltv_id="XXL.fr" site_id="616">XXL</channel> <channel lang="fr" xmltv_id="M6Music.fr" site_id="#352">M6 MUSIC</channel>
<channel lang="fr" xmltv_id="Mangas.fr" site_id="#613">MANGAS</channel>
<channel lang="fr" xmltv_id="ManX.be" site_id="#672">MAN X</channel>
<channel lang="fr" xmltv_id="MCM.fr" site_id="#556">MCM</channel>
<channel lang="fr" xmltv_id="Melody.fr" site_id="#580">MELODY</channel>
<channel lang="fr" xmltv_id="Mezzo.fr" site_id="#560">MEZZO</channel>
<channel lang="fr" xmltv_id="MezzoLiveHD.fr" site_id="#268">MEZZO LIVE</channel>
<channel lang="fr" xmltv_id="MGGTV.fr" site_id="#819">MGG TV</channel>
<channel lang="fr" xmltv_id="MTVFrance.fr" site_id="#470">MTV</channel>
<channel lang="fr" xmltv_id="MTVHitsFrance.fr" site_id="#629">MTV HITS</channel>
<channel lang="fr" xmltv_id="MultiSports1.fr" site_id="#562">MULTISPORTS 1</channel>
<channel lang="fr" xmltv_id="MultiSports2.fr" site_id="#563">MULTISPORTS 2</channel>
<channel lang="fr" xmltv_id="MultiSports3.fr" site_id="#564">MULTISPORTS 3</channel>
<channel lang="fr" xmltv_id="MultiSports4.fr" site_id="#565">MULTISPORTS 4</channel>
<channel lang="fr" xmltv_id="MultiSports5.fr" site_id="#566">MULTISPORTS 5</channel>
<channel lang="fr" xmltv_id="MultiSports6.fr" site_id="#567">MULTISPORTS 6</channel>
<channel lang="fr" xmltv_id="MuseumTV.fr" site_id="#678">MUSEUM</channel>
<channel lang="fr" xmltv_id="MyZenTV.fr" site_id="#656">MY ZEN TV</channel>
<channel lang="fr" xmltv_id="NationalGeographicFrance.fr" site_id="#302">NATIONAL GEO</channel>
<channel lang="fr" xmltv_id="NationalGeographicWildFrance.fr" site_id="#290">NATIONAL GEOGRAPHIC WILD</channel>
<channel lang="fr" xmltv_id="NHKWorldJapan.jp" site_id="#654">NHK WORLD-JAPAN</channel>
<channel lang="fr" xmltv_id="NickelodeonFrance.fr" site_id="#591">NICKELODEON</channel>
<channel lang="fr" xmltv_id="NickelodeonJunior.fr" site_id="#593">NICKELODEON JUNIOR</channel>
<channel lang="fr" xmltv_id="NickelodeonTeen.fr" site_id="#518">NICKELODEON TEEN</channel>
<channel lang="fr" xmltv_id="NollywoodTV.fr" site_id="#527">NOLLYWOOD TV</channel>
<channel lang="fr" xmltv_id="NonStopPeople.fr" site_id="#434">NON STOP PEOPLE</channel>
<channel lang="fr" xmltv_id="NovelasTV.fr" site_id="#693">NOVELAS TV</channel>
<channel lang="fr" xmltv_id="NRJ12.fr" site_id="#568">NRJ 12</channel>
<channel lang="fr" xmltv_id="NRJHits.fr" site_id="#569">NRJ HITS</channel>
<channel lang="fr" xmltv_id="OCSChoc.fr" site_id="#466">OCS CHOC</channel>
<channel lang="fr" xmltv_id="OCSCity.fr" site_id="#467">OCS CITY</channel>
<channel lang="fr" xmltv_id="OCSGeants.fr" site_id="#468">OCS GEANTS</channel>
<channel lang="fr" xmltv_id="OCSMax.fr" site_id="#372">OCS MAX</channel>
<channel lang="fr" xmltv_id="OlympiaTV.fr" site_id="#813">OLYMPIA TV</channel>
<channel lang="fr" xmltv_id="OneTV.ch" site_id="#880">ONE TV</channel>
<channel lang="fr" xmltv_id="ORF1.at" site_id="#783">ORF 1</channel>
<channel lang="fr" xmltv_id="ParamountChannelFrance.fr" site_id="#487">PARAMOUNT CHANNEL</channel>
<channel lang="fr" xmltv_id="ParisPremiere.fr" site_id="#294">PARIS PREMIERE</channel>
<channel lang="fr" xmltv_id="PenthouseBlack.us" site_id="#686">PENTHOUSE BLACK</channel>
<channel lang="fr" xmltv_id="PenthouseGold.us" site_id="#167">PENTHOUSE</channel>
<channel lang="fr" xmltv_id="PinkX.fr" site_id="#575">PINK X</channel>
<channel lang="fr" xmltv_id="PiwiPlus.fr" site_id="#576">PIWI+</channel>
<channel lang="fr" xmltv_id="PlanetePlus.fr" site_id="#270">PLANETE+</channel>
<channel lang="fr" xmltv_id="PlanetePlusAE.fr" site_id="#588">PLANETE+AVENTURE</channel>
<channel lang="fr" xmltv_id="PlanetePlusCI.fr" site_id="#587">PLANETE+CRIME</channel>
<channel lang="fr" xmltv_id="PolarPlus.fr" site_id="#692">POLAR+</channel>
<channel lang="fr" xmltv_id="Rai1.it" site_id="#782">RAI UNO</channel>
<channel lang="fr" xmltv_id="RFMTV.fr" site_id="#557">RFM TV</channel>
<channel lang="fr" xmltv_id="RMCDecouverte.fr" site_id="#595">RMC DECOUVERTE</channel>
<channel lang="fr" xmltv_id="RMCSport1.fr" site_id="#732">RMC SPORT 1</channel>
<channel lang="fr" xmltv_id="RMCSport2.fr" site_id="#733">RMC SPORT 2</channel>
<channel lang="fr" xmltv_id="RMCSport3.fr" site_id="#734">RMC SPORT 3</channel>
<channel lang="fr" xmltv_id="RMCSport4.fr" site_id="#735">RMC SPORT 4</channel>
<channel lang="fr" xmltv_id="RMCSportLive10.fr" site_id="#761">RMC SPORT LIVE 10</channel>
<channel lang="fr" xmltv_id="RMCSportLive11.fr" site_id="#762">RMC SPORT LIVE 11</channel>
<channel lang="fr" xmltv_id="RMCSportLive12.fr" site_id="#763">RMC SPORT LIVE 12</channel>
<channel lang="fr" xmltv_id="RMCSportLive13.fr" site_id="#764">RMC SPORT LIVE 13</channel>
<channel lang="fr" xmltv_id="RMCSportLive14.fr" site_id="#765">RMC SPORT LIVE 14</channel>
<channel lang="fr" xmltv_id="RMCSportLive5.fr" site_id="#756">RMC SPORT LIVE 5</channel>
<channel lang="fr" xmltv_id="RMCSportLive6.fr" site_id="#757">RMC SPORT LIVE 6</channel>
<channel lang="fr" xmltv_id="RMCSportLive7.fr" site_id="#758">RMC SPORT LIVE 7</channel>
<channel lang="fr" xmltv_id="RMCSportLive8.fr" site_id="#759">RMC SPORT LIVE 8</channel>
<channel lang="fr" xmltv_id="RMCSportLive9.fr" site_id="#760">RMC SPORT LIVE 9</channel>
<channel lang="fr" xmltv_id="RMCStory.fr" site_id="#571">RMC STORY</channel>
<channel lang="fr" xmltv_id="RougeTV.ch" site_id="#878">ROUGE TV</channel>
<channel lang="fr" xmltv_id="RTFrance.fr" site_id="#479">RT FRANCE</channel>
<channel lang="fr" xmltv_id="RTL9.lu" site_id="#505">RTL9</channel>
<channel lang="fr" xmltv_id="ScienceVieTV.fr" site_id="#614">SCIENCE ET VIE TV</channel>
<channel lang="fr" xmltv_id="Seasons.fr" site_id="#577">SEASONS</channel>
<channel lang="fr" xmltv_id="SerieClub.fr" site_id="#356">SERIE CLUB</channel>
<channel lang="fr" xmltv_id="SRF1.ch" site_id="#778">SRF 1</channel>
<channel lang="fr" xmltv_id="StingrayClassica.ca" site_id="#165">CLASSICA</channel>
<channel lang="fr" xmltv_id="StingrayDJAZZ.ca" site_id="#407">DJAZZ</channel>
<channel lang="fr" xmltv_id="TCMCinema.fr" site_id="#374">TCM CINEMA</channel>
<channel lang="fr" xmltv_id="TeleBielingue.ch" site_id="#775">TELEBIELINGUE</channel>
<channel lang="fr" xmltv_id="TeletoonPlus.fr" site_id="#581">TELETOON+</channel>
<channel lang="fr" xmltv_id="TeletoonPlus1.fr" site_id="#582">TELETOON+1</channel>
<channel lang="fr" xmltv_id="Teva.fr" site_id="#292">TEVA</channel>
<channel lang="fr" xmltv_id="TF1.fr" site_id="#312">TF1</channel>
<channel lang="fr" xmltv_id="TF1SeriesFilms.fr" site_id="#526">TF1 SERIES FILMS</channel>
<channel lang="fr" xmltv_id="TFX.fr" site_id="#570">TFX</channel>
<channel lang="fr" xmltv_id="TiJi.fr" site_id="#583">TIJI</channel>
<channel lang="fr" xmltv_id="TMC.fr" site_id="#584">TMC</channel>
<channel lang="fr" xmltv_id="ToonamiFrance.fr" site_id="#683">TOONAMI</channel>
<channel lang="fr" xmltv_id="ToutelHistoire.fr" site_id="#620">TOUTE L&apos;HISTOIRE</channel>
<channel lang="fr" xmltv_id="TraceAfrica.fr" site_id="#674">TRACE AFRICA</channel>
<channel lang="fr" xmltv_id="TraceLatina.fr" site_id="#784">TRACE LATINA</channel>
<channel lang="fr" xmltv_id="TraceUrban.fr" site_id="#585">TRACE URBAN</channel>
<channel lang="fr" xmltv_id="TV5MondeFranceBelgiumSwitzerland.fr" site_id="#520">TV5 MONDE</channel>
<channel lang="fr" xmltv_id="TVBreizh.fr" site_id="#586">TV BREIZH</channel>
<channel lang="fr" xmltv_id="UshuaiaTV.fr" site_id="#142">USHUAIA TV</channel>
<channel lang="fr" xmltv_id="VICETV.us" site_id="#677">VICE TV</channel>
<channel lang="fr" xmltv_id="VixenTV.ca" site_id="#547">VIXEN</channel>
<channel lang="fr" xmltv_id="W9.fr" site_id="#296">W9</channel>
<channel lang="fr" xmltv_id="WarnerTVFrance.fr" site_id="#694">WARNER TV</channel>
<channel lang="fr" xmltv_id="XXL.fr" site_id="#616">XXL</channel>
</channels> </channels>
</site> </site>
+96 -38
View File
@@ -1,19 +1,20 @@
const dayjs = require('dayjs') const dayjs = require('dayjs')
const axios = require('axios') const axios = require('axios')
// TODO: calculate API_KEY based on the current date
//
// const API_KEY = 'f55e5c7ddf0afba59d1c64581358910d' // 03.2022
//const API_KEY = 'c71b6b8eb30125dab9d10a3850131ac6' // 05.2022
const API_KEY = 'da2291af3b10e9900d1c55e1a65d3388' // 10.2022
module.exports = { module.exports = {
site: 'canalplus.com', site: 'canalplus.com',
days: 2, days: 2,
url: function ({ channel, date }) { url: async function ({ channel, date }) {
const [region, site_id] = channel.site_id.split('#')
const data = await axios
.get(`https://www.canalplus.com/${region}/programme-tv/`)
.then(r => r.data.toString())
.catch(err => console.log(err))
const token = parseToken(data)
const diff = date.diff(dayjs.utc().startOf('d'), 'd') const diff = date.diff(dayjs.utc().startOf('d'), 'd')
return `https://hodor.canalplus.pro/api/v2/mycanal/channels/${API_KEY}/${channel.site_id}/broadcasts/day/${diff}` return `https://hodor.canalplus.pro/api/v2/mycanal/channels/${token}/${site_id}/broadcasts/day/${diff}`
}, },
async parser({ content }) { async parser({ content }) {
let programs = [] let programs = []
@@ -29,11 +30,11 @@ module.exports = {
title: item.title, title: item.title,
description: parseDescription(info), description: parseDescription(info),
icon: parseIcon(info), icon: parseIcon(info),
actors: parseCast(info,"Avec :"), actors: parseCast(info, 'Avec :'),
director: parseCast(info,"De :"), director: parseCast(info, 'De :'),
writer: parseCast(info,"Scénario :"), writer: parseCast(info, 'Scénario :'),
composer: parseCast(info,"Musique :"), composer: parseCast(info, 'Musique :'),
presenter: parseCast(info,"Présenté par :"), presenter: parseCast(info, 'Présenté par :'),
date: parseDate(info), date: parseDate(info),
rating: parseRating(info), rating: parseRating(info),
start, start,
@@ -44,21 +45,78 @@ module.exports = {
return programs return programs
}, },
async channels() { async channels() {
const data = await axios const endpoints = {
.get(`https://secure-webtv-static.canal-plus.com/metadata/cpfra/all/v2.2/globalchannels.json`) ad: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/ad/all/v2.2/globalchannels.json',
.then(r => r.data) bf: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/bf/all/v2.2/globalchannels.json',
.catch(console.log) bi: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/bi/all/v2.2/globalchannels.json',
bj: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/bj/all/v2.2/globalchannels.json',
bl: 'https://secure-webtv-static.canal-plus.com/metadata/cpant/bl/all/v2.2/globalchannels.json',
cd: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/cd/all/v2.2/globalchannels.json',
cf: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/cf/all/v2.2/globalchannels.json',
cg: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/cg/all/v2.2/globalchannels.json',
ch: 'https://secure-webtv-static.canal-plus.com/metadata/cpche/all/v2.2/globalchannels.json',
ci: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/ci/all/v2.2/globalchannels.json',
cm: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/cm/all/v2.2/globalchannels.json',
cv: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/cv/all/v2.2/globalchannels.json',
dj: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/dj/all/v2.2/globalchannels.json',
fr: 'https://secure-webtv-static.canal-plus.com/metadata/cpfra/all/v2.2/globalchannels.json',
ga: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/ga/all/v2.2/globalchannels.json',
gf: 'https://secure-webtv-static.canal-plus.com/metadata/cpant/gf/all/v2.2/globalchannels.json',
gh: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/gh/all/v2.2/globalchannels.json',
gm: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/gm/all/v2.2/globalchannels.json',
gn: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/gn/all/v2.2/globalchannels.json',
gp: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/gp/all/v2.2/globalchannels.json',
gp: 'https://secure-webtv-static.canal-plus.com/metadata/cpant/gp/all/v2.2/globalchannels.json',
gw: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/gw/all/v2.2/globalchannels.json',
mf: 'https://secure-webtv-static.canal-plus.com/metadata/cpant/mf/all/v2.2/globalchannels.json',
mg: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/mg/all/v2.2/globalchannels.json',
ml: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/ml/all/v2.2/globalchannels.json',
mq: 'https://secure-webtv-static.canal-plus.com/metadata/cpant/mq/all/v2.2/globalchannels.json',
mr: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/mr/all/v2.2/globalchannels.json',
mu: 'https://secure-webtv-static.canal-plus.com/metadata/cpmus/mu/all/v2.2/globalchannels.json',
nc: 'https://secure-webtv-static.canal-plus.com/metadata/cpncl/nc/all/v2.2/globalchannels.json',
ne: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/ne/all/v2.2/globalchannels.json',
pl: 'https://secure-webtv-static.canal-plus.com/metadata/cppol/all/v2.2/globalchannels.json',
re: 'https://secure-webtv-static.canal-plus.com/metadata/cpreu/re/all/v2.2/globalchannels.json',
rw: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/rw/all/v2.2/globalchannels.json',
sl: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/sl/all/v2.2/globalchannels.json',
sn: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/sn/all/v2.2/globalchannels.json',
td: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/td/all/v2.2/globalchannels.json',
tg: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/tg/all/v2.2/globalchannels.json',
wf: 'https://secure-webtv-static.canal-plus.com/metadata/cpncl/wf/all/v2.2/globalchannels.json',
yt: 'https://secure-webtv-static.canal-plus.com/metadata/cpreu/yt/all/v2.2/globalchannels.json'
}
return data.channels.map(item => { let channels = []
return { for (let [region, url] of Object.entries(endpoints)) {
lang: 'fr', const data = await axios
site_id: item.id, .get(url)
name: item.name .then(r => r.data)
} .catch(console.log)
})
data.channels.forEach(channel => {
const site_id = region === 'fr' ? `#${channel.id}` : `${region}#${channel.id}`
if (channel.name === '.') return
channels.push({
lang: 'fr',
site_id,
name: channel.name
})
})
}
return channels
} }
} }
function parseToken(data) {
const [, token] = data.match(/"token":"([^"]+)/) || [null, null]
return token
}
function parseStart(item) { function parseStart(item) {
return item && item.startTime ? dayjs(item.startTime) : null return item && item.startTime ? dayjs(item.startTime) : null
} }
@@ -101,7 +159,7 @@ function parseCast(info, type) {
if (info && info.personnalities) { if (info && info.personnalities) {
const personnalities = info.personnalities.find(i => i.prefix == type) const personnalities = info.personnalities.find(i => i.prefix == type)
if (!personnalities) return people if (!personnalities) return people
for(let person of personnalities.personnalitiesList) { for (let person of personnalities.personnalitiesList) {
people.push(person.title) people.push(person.title)
} }
} }
@@ -109,20 +167,20 @@ function parseCast(info, type) {
} }
function parseDate(info) { function parseDate(info) {
return (info && info.productionYear) ? info.productionYear : null return info && info.productionYear ? info.productionYear : null
} }
function parseRating(info) { function parseRating(info) {
if (!info || !info.parentalRatings) return null if (!info || !info.parentalRatings) return null
let rating = info.parentalRatings.find(i => i.authority === 'CSA') let rating = info.parentalRatings.find(i => i.authority === 'CSA')
if (!rating || Array.isArray(rating)) return null if (!rating || Array.isArray(rating)) return null
if (rating.value === '1') return null if (rating.value === '1') return null
if (rating.value === '2') rating.value = '-10' if (rating.value === '2') rating.value = '-10'
if (rating.value === '3') rating.value = '-12' if (rating.value === '3') rating.value = '-12'
if (rating.value === '4') rating.value = '-16' if (rating.value === '4') rating.value = '-16'
if (rating.value === '5') rating.value = '-18' if (rating.value === '5') rating.value = '-18'
return { return {
system: rating.authority, system: rating.authority,
value: rating.value value: rating.value
} }
} }
+45 -16
View File
@@ -1,5 +1,5 @@
// npm run channels:parse -- --config=./sites/canalplus.com/canalplus.com.config.js --output=./sites/canalplus.com/canalplus.com.channels.xml // npm run channels:parse -- --config=./sites/canalplus.com/canalplus.com.config.js --output=./sites/canalplus.com/canalplus.com.channels.xml
// npx epg-grabber --config=sites/canalplus.com/canalplus.com.config.js --channels=sites/canalplus.com/canalplus.com.channels.xml --output=guide.xml --days=2 // npx epg-grabber --config=sites/canalplus.com/canalplus.com.config.js --channels=sites/canalplus.com/canalplus.com.channels.xml --output=guide.xml
const { parser, url } = require('./canalplus.com.config.js') const { parser, url } = require('./canalplus.com.config.js')
const fs = require('fs') const fs = require('fs')
@@ -13,39 +13,68 @@ dayjs.extend(utc)
jest.mock('axios') jest.mock('axios')
const channel = { const channel = {
site_id: '198', site_id: 'bi#198',
xmltv_id: 'CanalPlusCinemaFrance.fr' xmltv_id: 'CanalPlusCinemaFrance.fr'
} }
it('can generate valid url for today', done => {
axios.get.mockImplementation(url => {
if (url === 'https://www.canalplus.com/bi/programme-tv/') {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/programme-tv.html'))
})
} else {
return Promise.resolve({ data: '' })
}
})
it('can generate valid url for today', () => {
const today = dayjs.utc().startOf('d') const today = dayjs.utc().startOf('d')
expect(url({ channel, date: today })).toBe( url({ channel, date: today })
'https://hodor.canalplus.pro/api/v2/mycanal/channels/da2291af3b10e9900d1c55e1a65d3388/198/broadcasts/day/0' .then(result => {
) expect(result).toBe(
'https://hodor.canalplus.pro/api/v2/mycanal/channels/f000c6f4ebf44647682b3a0fa66d7d99/198/broadcasts/day/0'
)
done()
})
.catch(done)
}) })
it('can generate valid url for tomorrow', () => { it('can generate valid url for tomorrow', done => {
axios.get.mockImplementation(url => {
if (url === 'https://www.canalplus.com/bi/programme-tv/') {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/programme-tv.html'))
})
} else {
return Promise.resolve({ data: '' })
}
})
const tomorrow = dayjs.utc().startOf('d').add(1, 'd') const tomorrow = dayjs.utc().startOf('d').add(1, 'd')
expect(url({ channel, date: tomorrow })).toBe( url({ channel, date: tomorrow })
'https://hodor.canalplus.pro/api/v2/mycanal/channels/da2291af3b10e9900d1c55e1a65d3388/198/broadcasts/day/1' .then(result => {
) expect(result).toBe(
'https://hodor.canalplus.pro/api/v2/mycanal/channels/f000c6f4ebf44647682b3a0fa66d7d99/198/broadcasts/day/1'
)
done()
})
.catch(done)
}) })
it('can parse response', done => { it('can parse response', done => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json')) const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
axios.get.mockImplementation(url => { axios.get.mockImplementation(url => {
if ( if (
url === url ===
'https://hodor.canalplus.pro/api/v2/mycanal/detail/da2291af3b10e9900d1c55e1a65d3388/okapi/6564630_50001.json?detailType=detailSeason&objectType=season&broadcastID=PLM_1196447642&episodeId=20482220_50001&brandID=4501558_50001&fromDiff=true' 'https://hodor.canalplus.pro/api/v2/mycanal/detail/f000c6f4ebf44647682b3a0fa66d7d99/okapi/6564630_50001.json?detailType=detailSeason&objectType=season&broadcastID=PLM_1196447642&episodeId=20482220_50001&brandID=4501558_50001&fromDiff=true'
) { ) {
return Promise.resolve({ return Promise.resolve({
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program1.json'))) data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program1.json')))
}) })
} else if ( } else if (
url === url ===
'https://hodor.canalplus.pro/api/v2/mycanal/detail/da2291af3b10e9900d1c55e1a65d3388/okapi/17230453_50001.json?detailType=detailPage&objectType=unit&broadcastID=PLM_1196447637&fromDiff=true' 'https://hodor.canalplus.pro/api/v2/mycanal/detail/f000c6f4ebf44647682b3a0fa66d7d99/okapi/17230453_50001.json?detailType=detailPage&objectType=unit&broadcastID=PLM_1196447637&fromDiff=true'
) { ) {
return Promise.resolve({ return Promise.resolve({
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program2.json'))) data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program2.json')))
@@ -110,7 +139,7 @@ it('can parse response', done => {
}) })
it('can handle empty guide', async () => { it('can handle empty guide', async () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/no_content.json')) const content = fs.readFileSync(path.resolve(__dirname, '__data__/no_content.json'))
const result = await parser({ content }) const result = await parser({ content })
expect(result).toMatchObject([]) expect(result).toMatchObject([])
}) })
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="6eren.dk"><display-name>6&apos;eren</display-name><icon src="https://upload.wikimedia.org/wikipedia/commons/6/64/6%27eren_2015.png"/><url>https://allente.se</url></channel>
<programme start="20221024040000 +0000" stop="20221024042500 +0000" channel="6eren.dk"><title lang="da">Diners, Drive-Ins and Dives</title><desc lang="da">Underholdning</desc><category lang="da">series</category><icon src="https://viasatps.api.comspace.se/PS/channeldate/image/viasat.ps/487/2022-10-24/se.cs.6eren.event.B_0254194276971024040000.jpg?size=2560x1440"/><episode-num system="xmltv_ns">23.5.0/1</episode-num><episode-num system="onscreen">S24E06</episode-num></programme>
</tv>
Binary file not shown.
@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="BravoEast.us"><display-name>Bravo East</display-name><icon src="https://www.directv.com/images/logos/channels/dark/large/579.png"/><url>https://directv.com</url></channel>
</tv>
Binary file not shown.
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="Channel1.us"><display-name>Channel 1</display-name><url>https://example.com</url></channel>
<programme start="20220306043000 +0000" stop="20220306071000 +0000" channel="Channel1.us"><title lang="en">Program1</title></programme>
</tv>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="BBCNews.uk"><display-name>BBC News</display-name><icon src="https://i.imgur.com/rPzH88J.png"/><url>https://sky.com</url></channel>
<programme start="20221027120000 +0000" stop="20221027123000 +0000" channel="BBCNews.uk"><title lang="en">BBC News at One</title><desc lang="en">The latest national and international news from the BBC. [S,SL]</desc><icon src="http://epgstatic.sky.com/epgdata/1.0/paimage/46/1/lisa/5.2.2/linear/channel/ca247bc8-6be0-48f9-88d1-865f87f7680e/2011"/></programme>
</tv>
Binary file not shown.
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="BBCNews.uk"><display-name>BBC News</display-name><icon src="https://i.imgur.com/rPzH88J.png"/><url>https://virginmedia.com</url></channel>
<programme start="20221027120000 +0000" stop="20221027123000 +0000" channel="BBCNews.uk"><title lang="en">BBC News at One</title><desc lang="en">The latest national and international news, followed by weather.</desc><category lang="en">News</category><episode-num system="xmltv_ns">96839999.145799123.0/1</episode-num><episode-num system="onscreen">S96840000E145799124</episode-num></programme>
</tv>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="Channel1.us"><display-name>Channel 1</display-name><url>https://example.com</url></channel>
<programme start="20220306043000 +0000" stop="20220306071000 +0000" channel="Channel1.us"><title lang="fr">Program1</title></programme>
</tv>
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
<channel id="BBCNews.uk"><display-name>BBC News</display-name><icon src="https://i.imgur.com/rPzH88J.png"/><url>https://sky.com</url></channel>
<channel id="CNN.us"><display-name>CNN</display-name><icon src="https://www.directv.com/images/logos/channels/dark/large/579.png"/><url>https://sky.com</url></channel>
<programme start="20221027120000 +0000" stop="20221027123000 +0000" channel="BBCNews.uk"><title lang="fr">BBC News at One</title><desc lang="fr">Les dernières nouvelles nationales et internationales de la BBC. [S,SL]</desc><icon src="http://epgstatic.sky.com/epgdata/1.0/paimage/46/1/lisa/5.2.2/linear/channel/ca247bc8-6be0-48f9-88d1-865f87f7680e/2011"/></programme>
<programme start="20221027120000 +0000" stop="20221027123000 +0000" channel="CNN.us"><title lang="fr">French title</title></programme>
</tv>
Binary file not shown.
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<site site="example.com">
<channels>
<channel lang="en" xmltv_id="Channel1.us" site_id="140">Channel 1</channel>
<channel lang="fr" xmltv_id="Channel1.us" site_id="140">Channel 1</channel>
</channels>
</site>
@@ -0,0 +1,16 @@
module.exports = {
site: 'example.com',
days: 2,
url() {
return `https://example.com`
},
parser() {
return [
{
title: 'Program1',
start: '2022-03-06T04:30:00.000Z',
stop: '2022-03-06T07:10:00.000Z'
}
]
}
}
+39
View File
@@ -0,0 +1,39 @@
const { execSync } = require('child_process')
const fs = require('fs-extra')
const path = require('path')
beforeEach(() => {
fs.emptyDirSync('tests/__data__/output')
})
it('can grab epg', () => {
const stdout = execSync(
'BASE_DIR=tests/__data__/input CURR_DATE=2022-10-20 DATA_DIR=tests/__data__/input/tmp/data npm run grab -- --site=epg-grab --output=tests/__data__/output/{lang}/{site}.xml',
{ encoding: 'utf8' }
)
expect(content('tests/__data__/output/en/example.com.xml')).toEqual(
content('tests/__data__/expected/guides/en/example.com.xml')
)
expect(content('tests/__data__/output/fr/example.com.xml')).toEqual(
content('tests/__data__/expected/guides/fr/example.com.xml')
)
})
it('can grab epg with language filter enabled', () => {
const stdout = execSync(
'BASE_DIR=tests/__data__/input CURR_DATE=2022-10-20 DATA_DIR=tests/__data__/input/tmp/data npm run grab -- --site=epg-grab --lang=fr --output=tests/__data__/output/fr/guide.xml',
{ encoding: 'utf8' }
)
expect(content('tests/__data__/output/fr/guide.xml')).toEqual(
content('tests/__data__/expected/guides/fr/example.com.xml')
)
})
function content(filepath) {
return fs.readFileSync(path.resolve(filepath), {
encoding: 'utf8'
})
}
+425 -383
View File
File diff suppressed because it is too large. Load diff