mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-10 00:50:09 -04:00
Merge branch 'dev-branch' of https://github.com/arifbudiman/epg into dev-branch
This commit is contained in:
commit
16370d2c2e
30 changed files with 2036 additions and 1479 deletions
63
Jenkinsfile
vendored
63
Jenkinsfile
vendored
|
@ -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)
|
||||
}
|
||||
}
|
29
README.md
29
README.md
|
@ -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:
|
||||
|
||||
```sh
|
||||
# Windows
|
||||
set SITE=example.com&& npm run grab
|
||||
npm run grab -- --site=example.com
|
||||
```
|
||||
|
||||
# Linux/macOS
|
||||
SITE=example.com npm run grab
|
||||
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:
|
||||
|
||||
```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:
|
||||
|
||||
```sh
|
||||
guides
|
||||
└── en
|
||||
└── fr
|
||||
└── 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:
|
||||
|
@ -66,13 +81,13 @@ npm run serve
|
|||
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:
|
||||
|
||||
```
|
||||
http://<your_local_ip_address>:3000/guides/en/example.com.xml
|
||||
http://<your_local_ip_address>:3000/guides/fr/example.com.xml
|
||||
```
|
||||
|
||||
## Playlists
|
||||
|
|
1480
package-lock.json
generated
1480
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,7 @@
|
|||
"test:commands": "npx jest --runInBand -- commands",
|
||||
"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",
|
||||
"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"
|
||||
},
|
||||
"private": true,
|
||||
|
@ -33,10 +33,12 @@
|
|||
"chalk": "^4.1.2",
|
||||
"cheerio": "^1.0.0-rc.10",
|
||||
"commander": "^8.2.0",
|
||||
"consola": "^3.2.3",
|
||||
"cron": "^2.3.1",
|
||||
"cross-var": "^1.1.0",
|
||||
"csv-parser": "^3.0.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"epg-grabber": "^0.31.0",
|
||||
"epg-grabber": "^0.32.0",
|
||||
"epg-parser": "^0.2.0",
|
||||
"form-data": "^4.0.0",
|
||||
"fs-extra": "^10.0.1",
|
||||
|
|
|
@ -57,10 +57,10 @@ async function main() {
|
|||
}
|
||||
|
||||
if (localErrors.length) {
|
||||
logger.info(`\n${chalk.underline(filepath)}`)
|
||||
console.log(`\n${chalk.underline(filepath)}`)
|
||||
localErrors.forEach(error => {
|
||||
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)
|
||||
|
@ -68,7 +68,7 @@ async function main() {
|
|||
}
|
||||
|
||||
if (errors.length) {
|
||||
logger.error(chalk.red(`\n${errors.length} error(s)`))
|
||||
console.log(chalk.red(`\n${errors.length} error(s)`))
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ async function main() {
|
|||
}
|
||||
|
||||
if (errors.length) {
|
||||
logger.info(chalk.underline(filepath))
|
||||
console.log(chalk.underline(filepath))
|
||||
console.table(errors, ['type', 'lang', 'xmltv_id', 'site_id', 'name'])
|
||||
console.log()
|
||||
stats.files++
|
||||
|
@ -60,7 +60,7 @@ async function main() {
|
|||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
218
scripts/commands/epg/grab.js
Normal file
218
scripts/commands/epg/grab.js
Normal 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()
|
|
@ -4,6 +4,23 @@ const fs = require('fs-extra')
|
|||
|
||||
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) {
|
||||
return new Promise(resolve => {
|
||||
glob(pattern, function (err, files) {
|
||||
|
|
|
@ -1,19 +1,3 @@
|
|||
const { Signale } = require('signale')
|
||||
const { consola } = require('consola')
|
||||
|
||||
const options = {}
|
||||
|
||||
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
|
||||
module.exports = consola
|
||||
|
|
|
@ -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}}]}
|
29
sites/canalplus.com/__data__/programme-tv.html
Normal file
29
sites/canalplus.com/__data__/programme-tv.html
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,231 +1,326 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<site site="canalplus.com">
|
||||
<channels>
|
||||
<channel lang="fr" xmltv_id="6ter.fr" site_id="521">6TER</channel>
|
||||
<channel lang="fr" xmltv_id="AB1.fr" site_id="611">AB1</channel>
|
||||
<channel lang="fr" xmltv_id="Action.fr" site_id="504">ACTION</channel>
|
||||
<channel lang="en" xmltv_id="AlJazeeraEnglish.qa" site_id="675">AL JAZEERA ENG</channel>
|
||||
<channel lang="fr" xmltv_id="AlticeStudio.fr" site_id="820">ALTICE STUDIO</channel>
|
||||
<channel lang="fr" xmltv_id="Animaux.fr" site_id="503">ANIMAUX</channel>
|
||||
<channel lang="fr" xmltv_id="ArirangWorld.kr" site_id="252">ARIRANG TV</channel>
|
||||
<channel lang="fr" xmltv_id="ARTEFrance.fr" site_id="154">ARTE</channel>
|
||||
<channel lang="fr" xmltv_id="AstrocenterTV.fr" site_id="632">ASTROCENTER TV</channel>
|
||||
<channel lang="fr" xmltv_id="Automotolachaine.fr" site_id="612">AUTOMOTO LA CHAINE</channel>
|
||||
<channel lang="en" xmltv_id="BBCWorldNewsEurope.uk" site_id="589">BBC WORLD NEWS</channel>
|
||||
<channel lang="fr" xmltv_id="beINSports1France.fr" site_id="381">BEIN SPORTS 1</channel>
|
||||
<channel lang="fr" xmltv_id="beINSports2France.fr" site_id="384">BEIN SPORTS 2</channel>
|
||||
<channel lang="fr" xmltv_id="beINSports3France.fr" site_id="516">BEIN SPORTS 3</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax10France.fr" site_id="605">BEIN SPORTS MAX 10</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax4France.fr" site_id="596">BEIN SPORTS MAX 4</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax5France.fr" site_id="597">BEIN SPORTS MAX 5</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax6France.fr" site_id="598">BEIN SPORTS MAX 6</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax7France.fr" site_id="599">BEIN SPORTS MAX 7</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax8France.fr" site_id="603">BEIN SPORTS MAX 8</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax9France.fr" site_id="604">BEIN SPORTS MAX 9</channel>
|
||||
<channel lang="fr" xmltv_id="BETFrance.fr" site_id="628">BET</channel>
|
||||
<channel lang="fr" xmltv_id="BFMBusiness.fr" site_id="645">BFM BUSINESS</channel>
|
||||
<channel lang="fr" xmltv_id="BFMTV.fr" site_id="633">BFM TV</channel>
|
||||
<channel lang="fr" xmltv_id="BloombergTVEurope.uk" site_id="47">BLOOMBERG TV</channel>
|
||||
<channel lang="fr" xmltv_id="BlueZoomD.ch" site_id="893">BLUE ZOOM</channel>
|
||||
<channel lang="fr" xmltv_id="BoingFrance.fr" site_id="529">BOING</channel>
|
||||
<channel lang="fr" xmltv_id="BoomerangFrance.fr" site_id="530">BOOMERANG</channel>
|
||||
<channel lang="fr" xmltv_id="BSmartTV.fr" site_id="849">BSMART TV</channel>
|
||||
<channel lang="fr" xmltv_id="C8.fr" site_id="450">C8</channel>
|
||||
<channel lang="fr" xmltv_id="CanalAlphaNE.ch" site_id="772">CANAL ALPHA NE</channel>
|
||||
<channel lang="fr" xmltv_id="CanalJ.fr" site_id="525">CANAL J</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusCinemaFrance.fr" site_id="198">CANAL+CINEMA</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusDocs.fr" site_id="899">CANAL+DOCS</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="19">CANAL+FOOT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFormula1.fr" site_id="824">CANAL+FORMULA1</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="301">CANAL+</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusGrandEcran.fr" site_id="900">CANAL+GRAND ECRAN</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusKids.fr" site_id="259">CANAL+KIDS</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusMotoGP.fr" site_id="823">CANAL+MOTOGP</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusPremierLeague.fr" site_id="815">CANAL+PREMIER LEAGUE</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSeriesFrance.fr" site_id="481">CANAL+SERIES</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSport2.fr" site_id="861">CANAL+ SPORT 2 (CH)</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSport360.fr" site_id="83">CANAL+SPORT360</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSportFrance.fr" site_id="177">CANAL+SPORT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusTop14.fr" site_id="816">CANAL+TOP14</channel>
|
||||
<channel lang="fr" xmltv_id="CartoonNetworkFrance.fr" site_id="502">CARTOON NETWORK</channel>
|
||||
<channel lang="fr" xmltv_id="ChassePeche.fr" site_id="681">CHASSE ET PECHE</channel>
|
||||
<channel lang="fr" xmltv_id="Cherie25.fr" site_id="440">CHERIE 25</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusClassic.fr" site_id="531">CINE+ CLASSIC</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusClub.fr" site_id="532">CINE+ CLUB</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusEmotion.fr" site_id="396">CINE+ EMOTION</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusFamiz.fr" site_id="533">CINE+ FAMIZ</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusFrisson.fr" site_id="398">CINE+ FRISSON</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusPremier.fr" site_id="322">CINE+ PREMIER</channel>
|
||||
<channel lang="fr" xmltv_id="CliqueTV.fr" site_id="665">CLIQUE TV</channel>
|
||||
<channel lang="fr" xmltv_id="CNBCEurope.uk" site_id="64">CNBC</channel>
|
||||
<channel lang="fr" xmltv_id="CNews.fr" site_id="480">CNEWS</channel>
|
||||
<channel lang="en" xmltv_id="CNNInternationalEurope.us" site_id="30">CNN INT.</channel>
|
||||
<channel lang="fr" xmltv_id="ColmaxTV.fr" site_id="643">COLMAX TV</channel>
|
||||
<channel lang="fr" xmltv_id="ComediePlus.fr" site_id="534">COMEDIE+</channel>
|
||||
<channel lang="fr" xmltv_id="ComedyCentralFrance.fr" site_id="806">COMEDY CENTRAL</channel>
|
||||
<channel lang="fr" xmltv_id="CStar.fr" site_id="513">CSTAR</channel>
|
||||
<channel lang="fr" xmltv_id="CStarHitsFrance.fr" site_id="723">CSTAR HITS FRANCE</channel>
|
||||
<channel lang="fr" xmltv_id="DasErste.de" site_id="781">ARD DAS ERSTE</channel>
|
||||
<channel lang="fr" xmltv_id="DisneyChannelFrance.fr" site_id="282">DISNEY CHANNEL</channel>
|
||||
<channel lang="fr" xmltv_id="DisneyChannelFrancePlus1.fr" site_id="535">DISNEY CHANNEL+1</channel>
|
||||
<channel lang="fr" xmltv_id="DisneyJuniorFrance.fr" site_id="274">DISNEY JUNIOR</channel>
|
||||
<channel lang="fr" xmltv_id="DorcelTV.nl" site_id="536">DORCEL TV</channel>
|
||||
<channel lang="fr" xmltv_id="DorcelXXX.nl" site_id="537">DORCEL XXX</channel>
|
||||
<channel lang="fr" xmltv_id="Equidia.fr" site_id="540">EQUIDIA</channel>
|
||||
<channel lang="fr" xmltv_id="EuronewsFrench.fr" site_id="324">EURONEWS</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport1.fr" site_id="101">EUROSPORT 1</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport2.fr" site_id="436">EUROSPORT 2</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport3.fr" site_id="985">EUROSPORT 3</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD1.fr" site_id="635">EUROSPORT 360 1</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD2.fr" site_id="636">EUROSPORT 360 2</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD3.fr" site_id="637">EUROSPORT 360 3</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD4.fr" site_id="638">EUROSPORT 360 4</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD5.fr" site_id="650">EUROSPORT 360 5</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD6.fr" site_id="651">EUROSPORT 360 6</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD7.fr" site_id="652">EUROSPORT 360 7</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD8.fr" site_id="653">EUROSPORT 360 8</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport4.fr" site_id="986">EUROSPORT 4</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport5.fr" site_id="987">EUROSPORT 5</channel>
|
||||
<channel lang="fr" xmltv_id="FootPlus.fr" site_id="542">FOOT+ 24/24</channel>
|
||||
<channel lang="fr" xmltv_id="France2.fr" site_id="26">FRANCE 2</channel>
|
||||
<channel lang="en" xmltv_id="France24English.fr" site_id="311">FRANCE 24 ENG</channel>
|
||||
<channel lang="fr" xmltv_id="France24French.fr" site_id="310">FRANCE 24</channel>
|
||||
<channel lang="fr" xmltv_id="France3.fr" site_id="543">FRANCE 3</channel>
|
||||
<channel lang="fr" xmltv_id="France3Alpes.fr" site_id="926">F3 ALPES</channel>
|
||||
<channel lang="fr" xmltv_id="France3Alsace.fr" site_id="941">F3 ALSACE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Aquitaine.fr" site_id="922">F3 AQUITAINE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Auvergne.fr" site_id="924">F3 AUVERGNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3BasseNormandie.fr" site_id="923">F3 BNORMANDIE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Bourgogne.fr" site_id="925">F3 BOURGOGNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Bretagne.fr" site_id="939">F3 BRETAGNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3CentreValdeLoire.fr" site_id="935">F3 CENTRE</channel>
|
||||
<channel lang="fr" xmltv_id="France3ChampagneArdenne.fr" site_id="938">F3 CHAMP ARDENNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3CorseViaStella.fr" site_id="943">F3 CORSEVIASTELLA</channel>
|
||||
<channel lang="fr" xmltv_id="France3CotedAzur.fr" site_id="934">F3 COTE D'AZUR</channel>
|
||||
<channel lang="fr" xmltv_id="France3FrancheComte.fr" site_id="921">F3 FRANCHE COMTE</channel>
|
||||
<channel lang="fr" xmltv_id="France3HauteNormandie.fr" site_id="940">F3 HNORMANDIE</channel>
|
||||
<channel lang="fr" xmltv_id="France3LanguedocRoussillon.fr" site_id="931">F3 LANGUEDOCROU</channel>
|
||||
<channel lang="fr" xmltv_id="France3Limousin.fr" site_id="928">F3 LIMOUSIN</channel>
|
||||
<channel lang="fr" xmltv_id="France3Lorraine.fr" site_id="932">F3 LORRAINE</channel>
|
||||
<channel lang="fr" xmltv_id="France3MidiPyrenees.fr" site_id="942">F3 MIDI PYRENEES</channel>
|
||||
<channel lang="fr" xmltv_id="France3NordPasdeCalais.fr" site_id="927">F3 NORD PDC</channel>
|
||||
<channel lang="fr" xmltv_id="France3NouvelleAquitaine.fr" site_id="998">F3 NOUVELLE AQUITAINE</channel>
|
||||
<channel lang="fr" xmltv_id="France3ParisIledeFrance.fr" site_id="936">F3 PARIS IDF</channel>
|
||||
<channel lang="fr" xmltv_id="France3PaysdelaLoire.fr" site_id="933">F3 PAYS DE LA LOIRE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Picardie.fr" site_id="920">F3 PICARDIE</channel>
|
||||
<channel lang="fr" xmltv_id="France3PoitouCharentes.fr" site_id="937">F3 POITOUCHAR</channel>
|
||||
<channel lang="fr" xmltv_id="France3ProvenceAlpes.fr" site_id="930">F3 PROV ALPES</channel>
|
||||
<channel lang="fr" xmltv_id="France3RhoneAlpes.fr" site_id="929">F3 RHONE ALPES</channel>
|
||||
<channel lang="fr" xmltv_id="France4.fr" site_id="544">FRANCE 4</channel>
|
||||
<channel lang="fr" xmltv_id="France5.fr" site_id="545">FRANCE 5</channel>
|
||||
<channel lang="fr" xmltv_id="Franceinfo.fr" site_id="670">FRANCEINFO:</channel>
|
||||
<channel lang="fr" xmltv_id="GameOne.fr" site_id="592">GAME ONE</channel>
|
||||
<channel lang="fr" xmltv_id="GolfPlus.fr" site_id="378">GOLF+</channel>
|
||||
<channel lang="fr" xmltv_id="Gulli.fr" site_id="549">GULLI</channel>
|
||||
<channel lang="fr" xmltv_id="HistoireTV.fr" site_id="550">HISTOIRE TV</channel>
|
||||
<channel lang="fr" xmltv_id="I24NewsFrench.il" site_id="362">I24 NEWS</channel>
|
||||
<channel lang="fr" xmltv_id="InfosportPlus.fr" site_id="551">INFOSPORT+</channel>
|
||||
<channel lang="fr" xmltv_id="JacquieMichelTV.fr" site_id="850">JACQUIE & MICHEL TV</channel>
|
||||
<channel lang="fr" xmltv_id="JOne.fr" site_id="484">J-ONE</channel>
|
||||
<channel lang="fr" xmltv_id="LaChaineMeteo.fr" site_id="552">LA CHAINE METEO</channel>
|
||||
<channel lang="fr" xmltv_id="LCI.fr" site_id="553">LCI</channel>
|
||||
<channel lang="fr" xmltv_id="LCP.fr" site_id="554">LCP</channel>
|
||||
<channel lang="fr" xmltv_id="LEquipe.fr" site_id="451">L'EQUIPE</channel>
|
||||
<channel lang="fr" xmltv_id="LFMTV.ch" site_id="879">LFM TV</channel>
|
||||
<channel lang="fr" xmltv_id="M6.fr" site_id="313">M6</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="en" 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="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="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="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'HISTOIRE</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>
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#100">TEST03</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1049">CANAL+SPORT 360 (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1051">MULTISPORTS 7</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1053">CANAL+GRAND ECRAN (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1067">CHAINE: 1067</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1068">CHAINE: 1068</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1069">CHAINE: 1069</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1070">CHAINE: 1070</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#1071">CHAINE: 1071</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#184">DIEGO TV</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#196">BOB TV</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#202">TEST04</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#21120">ARTE ALLEMAND</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#289">CHAINE EVENEMENT</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#477">VOYAGE</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#546">EVENEMENT SPORT 4K HDR UHD</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#589">BBC WORLD NEWS</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#639">LL EVENT UHD</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#696">EURONEWS ALL</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#700">CANAL+ FINALE UEFA CHAMPIONS LEAGUE</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#702">CANAL+ (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#726">EVENEMENT SPORT 4K UHD</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#728">CANAL+ UHD</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#737">RELIN PIWI</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#738">RELIN CINE+ CLASSIC</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#739">TEST CSTAR</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#740">RELIN SEASONS</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#76">TEST05</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#766">RMC SPORT LIVE 3</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#767">RMC SPORT LIVE 4</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#768">CANAL 9</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#77">TEST06</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#770">RTS 1</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#771">RTS 2</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#776">RSI 1</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#777">RSI 2</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#779">SRF 2</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#78">TEST07</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#780">3 SAT</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#787">OCS MAX (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#788">OCS PULP (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#789">OCS GEANTS (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#79">TEST08</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#80">TEST09</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#82">TEST10</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#825">CANAL+ (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#827">CANAL+ CINEMA (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#829">CINE+ PREMIER (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#830">CINE+ FRISSON (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#831">C8 (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#832">CSTAR (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#85">TEST11</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#872">EVENEMENT SPORT 4K HLG UHD</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#873">CANAL+ SPORT (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#874">CANAL+ UHD (CH)</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#876">TEST01</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#877">TEST02</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#882">EVENEMENT A LA CARTE</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#89">TEST12</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#894">CANAL+ LIGUE1</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#90">TEST13</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#970">CHAINE : 970</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#971">CHAINE : 971</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#972">CHAINE : 972</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#973">CHAINE : 973</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#974">CHAINE : 974</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#975">CHAINE : 975</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#977">BEIN SPORTS 1</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#978">BEIN SPORTS 2</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#979">BEIN SPORTS 3</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#980">BEIN SPORTS MAX 4</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#981">BEIN SPORTS MAX 5</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#982">BEIN SPORTS MAX 6</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#983">BEIN SPORTS MAX 7</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#984">CANAL+</channel> -->
|
||||
<!-- <channel lang="fr" xmltv_id="" site_id="#993">CANAL+ UHD</channel> -->
|
||||
<channel lang="en" xmltv_id="AlJazeeraEnglish.qa" site_id="#675">AL JAZEERA ENG</channel>
|
||||
<channel lang="en" xmltv_id="BBCWorldNewsEurope.uk" site_id="#589">BBC WORLD NEWS</channel>
|
||||
<channel lang="en" xmltv_id="CNNInternationalEurope.us" site_id="#30">CNN INT.</channel>
|
||||
<channel lang="en" xmltv_id="France24English.fr" site_id="#311">FRANCE 24 ENG</channel>
|
||||
<channel lang="en" xmltv_id="NHKWorldJapan.jp" site_id="#654">NHK WORLD-JAPAN</channel>
|
||||
<channel lang="fr" xmltv_id="2STV.sn" site_id="sn#180122">2STV</channel>
|
||||
<channel lang="fr" xmltv_id="6ter.fr" site_id="#521">6TER</channel>
|
||||
<channel lang="fr" xmltv_id="AB1.fr" site_id="#611">AB1</channel>
|
||||
<channel lang="fr" xmltv_id="Action.fr" site_id="#504">ACTION</channel>
|
||||
<channel lang="fr" xmltv_id="AlJazeeraEnglish.qa" site_id="#675">AL JAZEERA ENG</channel>
|
||||
<channel lang="fr" xmltv_id="AlticeStudio.fr" site_id="#820">ALTICE STUDIO</channel>
|
||||
<channel lang="fr" xmltv_id="Animaux.fr" site_id="#503">ANIMAUX</channel>
|
||||
<channel lang="fr" xmltv_id="ArirangWorld.kr" site_id="#252">ARIRANG TV</channel>
|
||||
<channel lang="fr" xmltv_id="ARTEFrance.fr" site_id="#154">ARTE</channel>
|
||||
<channel lang="fr" xmltv_id="AstrocenterTV.fr" site_id="#632">ASTROCENTER TV</channel>
|
||||
<channel lang="fr" xmltv_id="Automotolachaine.fr" site_id="#612">AUTOMOTO LA CHAINE</channel>
|
||||
<channel lang="fr" xmltv_id="beINSports1France.fr" site_id="#381">BEIN SPORTS 1</channel>
|
||||
<channel lang="fr" xmltv_id="beINSports2France.fr" site_id="#384">BEIN SPORTS 2</channel>
|
||||
<channel lang="fr" xmltv_id="beINSports3France.fr" site_id="#516">BEIN SPORTS 3</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax10France.fr" site_id="#605">BEIN SPORTS MAX 10</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax4France.fr" site_id="#596">BEIN SPORTS MAX 4</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax5France.fr" site_id="#597">BEIN SPORTS MAX 5</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax6France.fr" site_id="#598">BEIN SPORTS MAX 6</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax7France.fr" site_id="#599">BEIN SPORTS MAX 7</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax8France.fr" site_id="#603">BEIN SPORTS MAX 8</channel>
|
||||
<channel lang="fr" xmltv_id="beINSportsMax9France.fr" site_id="#604">BEIN SPORTS MAX 9</channel>
|
||||
<channel lang="fr" xmltv_id="BETFrance.fr" site_id="#628">BET</channel>
|
||||
<channel lang="fr" xmltv_id="BFMBusiness.fr" site_id="#645">BFM BUSINESS</channel>
|
||||
<channel lang="fr" xmltv_id="BFMTV.fr" site_id="#633">BFM TV</channel>
|
||||
<channel lang="fr" xmltv_id="BloombergTVEurope.uk" site_id="#47">BLOOMBERG TV</channel>
|
||||
<channel lang="fr" xmltv_id="BlueZoomD.ch" site_id="#893">BLUE ZOOM</channel>
|
||||
<channel lang="fr" xmltv_id="BoingFrance.fr" site_id="#529">BOING</channel>
|
||||
<channel lang="fr" xmltv_id="BoomerangFrance.fr" site_id="#530">BOOMERANG</channel>
|
||||
<channel lang="fr" xmltv_id="BSmartTV.fr" site_id="#849">BSMART TV</channel>
|
||||
<channel lang="fr" xmltv_id="C8.fr" site_id="#450">C8</channel>
|
||||
<channel lang="fr" xmltv_id="CanalAlphaNE.ch" site_id="#772">CANAL ALPHA NE</channel>
|
||||
<channel lang="fr" xmltv_id="CanalJ.fr" site_id="#525">CANAL J</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusCinemaFrance.fr" site_id="#198">CANAL+CINEMA</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusDocs.fr" site_id="#899">CANAL+DOCS</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="#1045">CANAL+FOOT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="#19">CANAL+FOOT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFoot.fr" site_id="#992">CANAL+FOOT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFormula1.fr" site_id="#824">CANAL+FORMULA1</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="#301">CANAL+</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="#573">CANAL+</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusFrance.fr" site_id="#601">CANAL+</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusGrandEcran.fr" site_id="#900">CANAL+GRAND ECRAN</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusKids.fr" site_id="#259">CANAL+KIDS</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusMotoGP.fr" site_id="#823">CANAL+MOTOGP</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusPremierLeague.fr" site_id="#815">CANAL+PREMIER LEAGUE</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSeriesFrance.fr" site_id="#481">CANAL+SERIES</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSport2.fr" site_id="#861">CANAL+ SPORT 2 (CH)</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSport360.fr" site_id="#1048">CANAL+SPORT360</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSport360.fr" site_id="#83">CANAL+SPORT360</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSportFrance.fr" site_id="#177">CANAL+SPORT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusSportFrance.fr" site_id="#574">CANAL+SPORT</channel>
|
||||
<channel lang="fr" xmltv_id="CanalPlusTop14.fr" site_id="#816">CANAL+TOP14</channel>
|
||||
<channel lang="fr" xmltv_id="CartoonNetworkFrance.fr" site_id="#502">CARTOON NETWORK</channel>
|
||||
<channel lang="fr" xmltv_id="ChassePeche.fr" site_id="#681">CHASSE ET PECHE</channel>
|
||||
<channel lang="fr" xmltv_id="Cherie25.fr" site_id="#440">CHERIE 25</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusClassic.fr" site_id="#531">CINE+ CLASSIC</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusClub.fr" site_id="#532">CINE+ CLUB</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusEmotion.fr" site_id="#396">CINE+ EMOTION</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusFamiz.fr" site_id="#533">CINE+ FAMIZ</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusFrisson.fr" site_id="#398">CINE+ FRISSON</channel>
|
||||
<channel lang="fr" xmltv_id="CinePlusPremier.fr" site_id="#322">CINE+ PREMIER</channel>
|
||||
<channel lang="fr" xmltv_id="CliqueTV.fr" site_id="#665">CLIQUE TV</channel>
|
||||
<channel lang="fr" xmltv_id="CNBCEurope.uk" site_id="#64">CNBC</channel>
|
||||
<channel lang="fr" xmltv_id="CNews.fr" site_id="#480">CNEWS</channel>
|
||||
<channel lang="fr" xmltv_id="ColmaxTV.fr" site_id="#643">COLMAX TV</channel>
|
||||
<channel lang="fr" xmltv_id="ComediePlus.fr" site_id="#534">COMEDIE+</channel>
|
||||
<channel lang="fr" xmltv_id="ComedyCentralFrance.fr" site_id="#806">COMEDY CENTRAL</channel>
|
||||
<channel lang="fr" xmltv_id="CStar.fr" site_id="#513">CSTAR</channel>
|
||||
<channel lang="fr" xmltv_id="CStarHitsFrance.fr" site_id="#723">CSTAR HITS FRANCE</channel>
|
||||
<channel lang="fr" xmltv_id="DasErste.de" site_id="#781">ARD DAS ERSTE</channel>
|
||||
<channel lang="fr" xmltv_id="DisneyChannelFrance.fr" site_id="#282">DISNEY CHANNEL</channel>
|
||||
<channel lang="fr" xmltv_id="DisneyChannelFrancePlus1.fr" site_id="#535">DISNEY CHANNEL+1</channel>
|
||||
<channel lang="fr" xmltv_id="DisneyJuniorFrance.fr" site_id="#274">DISNEY JUNIOR</channel>
|
||||
<channel lang="fr" xmltv_id="DoraTVFrance.fr" site_id="#185">DORA TV</channel>
|
||||
<channel lang="fr" xmltv_id="DorcelTV.nl" site_id="#536">DORCEL TV</channel>
|
||||
<channel lang="fr" xmltv_id="DorcelXXX.nl" site_id="#537">DORCEL XXX</channel>
|
||||
<channel lang="fr" xmltv_id="Equidia.fr" site_id="#540">EQUIDIA</channel>
|
||||
<channel lang="fr" xmltv_id="EuronewsFrench.fr" site_id="#324">EURONEWS</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport1.fr" site_id="#101">EUROSPORT 1</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport2.fr" site_id="#436">EUROSPORT 2</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport3.fr" site_id="#985">EUROSPORT 3</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD1.fr" site_id="#635">EUROSPORT 360 1</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD2.fr" site_id="#636">EUROSPORT 360 2</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD3.fr" site_id="#637">EUROSPORT 360 3</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD4.fr" site_id="#638">EUROSPORT 360 4</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD5.fr" site_id="#650">EUROSPORT 360 5</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD6.fr" site_id="#651">EUROSPORT 360 6</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD7.fr" site_id="#652">EUROSPORT 360 7</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport360HD8.fr" site_id="#653">EUROSPORT 360 8</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport4.fr" site_id="#986">EUROSPORT 4</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport5.fr" site_id="#987">EUROSPORT 5</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport6.fr" site_id="#988">EUROSPORT 6</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport7.fr" site_id="#989">EUROSPORT 7</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport8.fr" site_id="#990">EUROSPORT 8</channel>
|
||||
<channel lang="fr" xmltv_id="Eurosport9.fr" site_id="#991">EUROSPORT 9</channel>
|
||||
<channel lang="fr" xmltv_id="FootPlus.fr" site_id="#542">FOOT+ 24/24</channel>
|
||||
<channel lang="fr" xmltv_id="France2.fr" site_id="#26">FRANCE 2</channel>
|
||||
<channel lang="fr" xmltv_id="France24English.fr" site_id="#311">FRANCE 24 ENG</channel>
|
||||
<channel lang="fr" xmltv_id="France24French.fr" site_id="#310">FRANCE 24</channel>
|
||||
<channel lang="fr" xmltv_id="France3.fr" site_id="#543">FRANCE 3</channel>
|
||||
<channel lang="fr" xmltv_id="France3Alpes.fr" site_id="#926">F3 ALPES</channel>
|
||||
<channel lang="fr" xmltv_id="France3Alsace.fr" site_id="#941">F3 ALSACE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Aquitaine.fr" site_id="#922">F3 AQUITAINE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Auvergne.fr" site_id="#924">F3 AUVERGNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3BasseNormandie.fr" site_id="#923">F3 BNORMANDIE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Bourgogne.fr" site_id="#925">F3 BOURGOGNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Bretagne.fr" site_id="#939">F3 BRETAGNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3CentreValdeLoire.fr" site_id="#935">F3 CENTRE</channel>
|
||||
<channel lang="fr" xmltv_id="France3ChampagneArdenne.fr" site_id="#938">F3 CHAMP ARDENNE</channel>
|
||||
<channel lang="fr" xmltv_id="France3CorseViaStella.fr" site_id="#943">F3 CORSEVIASTELLA</channel>
|
||||
<channel lang="fr" xmltv_id="France3CotedAzur.fr" site_id="#934">F3 COTE D'AZUR</channel>
|
||||
<channel lang="fr" xmltv_id="France3FrancheComte.fr" site_id="#921">F3 FRANCHE COMTE</channel>
|
||||
<channel lang="fr" xmltv_id="France3HauteNormandie.fr" site_id="#940">F3 HNORMANDIE</channel>
|
||||
<channel lang="fr" xmltv_id="France3LanguedocRoussillon.fr" site_id="#931">F3 LANGUEDOCROU</channel>
|
||||
<channel lang="fr" xmltv_id="France3Limousin.fr" site_id="#928">F3 LIMOUSIN</channel>
|
||||
<channel lang="fr" xmltv_id="France3Lorraine.fr" site_id="#932">F3 LORRAINE</channel>
|
||||
<channel lang="fr" xmltv_id="France3MidiPyrenees.fr" site_id="#942">F3 MIDI PYRENEES</channel>
|
||||
<channel lang="fr" xmltv_id="France3NordPasdeCalais.fr" site_id="#927">F3 NORD PDC</channel>
|
||||
<channel lang="fr" xmltv_id="France3NouvelleAquitaine.fr" site_id="#998">F3 NOUVELLE AQUITAINE</channel>
|
||||
<channel lang="fr" xmltv_id="France3ParisIledeFrance.fr" site_id="#936">F3 PARIS IDF</channel>
|
||||
<channel lang="fr" xmltv_id="France3PaysdelaLoire.fr" site_id="#933">F3 PAYS DE LA LOIRE</channel>
|
||||
<channel lang="fr" xmltv_id="France3Picardie.fr" site_id="#920">F3 PICARDIE</channel>
|
||||
<channel lang="fr" xmltv_id="France3PoitouCharentes.fr" site_id="#937">F3 POITOUCHAR</channel>
|
||||
<channel lang="fr" xmltv_id="France3ProvenceAlpes.fr" site_id="#930">F3 PROV ALPES</channel>
|
||||
<channel lang="fr" xmltv_id="France3RhoneAlpes.fr" site_id="#929">F3 RHONE ALPES</channel>
|
||||
<channel lang="fr" xmltv_id="France4.fr" site_id="#544">FRANCE 4</channel>
|
||||
<channel lang="fr" xmltv_id="France5.fr" site_id="#545">FRANCE 5</channel>
|
||||
<channel lang="fr" xmltv_id="Franceinfo.fr" site_id="#670">FRANCEINFO:</channel>
|
||||
<channel lang="fr" xmltv_id="GameOne.fr" site_id="#592">GAME ONE</channel>
|
||||
<channel lang="fr" xmltv_id="GolfPlus.fr" site_id="#378">GOLF+</channel>
|
||||
<channel lang="fr" xmltv_id="Gulli.fr" site_id="#549">GULLI</channel>
|
||||
<channel lang="fr" xmltv_id="HistoireTV.fr" site_id="#550">HISTOIRE TV</channel>
|
||||
<channel lang="fr" xmltv_id="I24NewsFrench.il" site_id="#362">I24 NEWS</channel>
|
||||
<channel lang="fr" xmltv_id="InfosportPlus.fr" site_id="#551">INFOSPORT+</channel>
|
||||
<channel lang="fr" xmltv_id="JacquieMichelTV.fr" site_id="#850">JACQUIE & MICHEL TV</channel>
|
||||
<channel lang="fr" xmltv_id="JOne.fr" site_id="#484">J-ONE</channel>
|
||||
<channel lang="fr" xmltv_id="LaChaineMeteo.fr" site_id="#552">LA CHAINE METEO</channel>
|
||||
<channel lang="fr" xmltv_id="LaTele.ch" site_id="#773">LA TELE</channel>
|
||||
<channel lang="fr" xmltv_id="LCI.fr" site_id="#553">LCI</channel>
|
||||
<channel lang="fr" xmltv_id="LCP.fr" site_id="#554">LCP</channel>
|
||||
<channel lang="fr" xmltv_id="LemanBleu.ch" site_id="#774">LEMAN BLEU</channel>
|
||||
<channel lang="fr" xmltv_id="LEquipe.fr" site_id="#451">L'EQUIPE</channel>
|
||||
<channel lang="fr" xmltv_id="LFMTV.ch" site_id="#879">LFM TV</channel>
|
||||
<channel lang="fr" xmltv_id="M6.fr" site_id="#313">M6</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'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>
|
||||
</site>
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
const dayjs = require('dayjs')
|
||||
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 = {
|
||||
site: 'canalplus.com',
|
||||
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')
|
||||
|
||||
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 }) {
|
||||
let programs = []
|
||||
|
@ -29,11 +30,11 @@ module.exports = {
|
|||
title: item.title,
|
||||
description: parseDescription(info),
|
||||
icon: parseIcon(info),
|
||||
actors: parseCast(info,"Avec :"),
|
||||
director: parseCast(info,"De :"),
|
||||
writer: parseCast(info,"Scénario :"),
|
||||
composer: parseCast(info,"Musique :"),
|
||||
presenter: parseCast(info,"Présenté par :"),
|
||||
actors: parseCast(info, 'Avec :'),
|
||||
director: parseCast(info, 'De :'),
|
||||
writer: parseCast(info, 'Scénario :'),
|
||||
composer: parseCast(info, 'Musique :'),
|
||||
presenter: parseCast(info, 'Présenté par :'),
|
||||
date: parseDate(info),
|
||||
rating: parseRating(info),
|
||||
start,
|
||||
|
@ -44,21 +45,78 @@ module.exports = {
|
|||
return programs
|
||||
},
|
||||
async channels() {
|
||||
const data = await axios
|
||||
.get(`https://secure-webtv-static.canal-plus.com/metadata/cpfra/all/v2.2/globalchannels.json`)
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
const endpoints = {
|
||||
ad: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/ad/all/v2.2/globalchannels.json',
|
||||
bf: 'https://secure-webtv-static.canal-plus.com/metadata/cpafr/bf/all/v2.2/globalchannels.json',
|
||||
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 => {
|
||||
return {
|
||||
lang: 'fr',
|
||||
site_id: item.id,
|
||||
name: item.name
|
||||
}
|
||||
})
|
||||
let channels = []
|
||||
for (let [region, url] of Object.entries(endpoints)) {
|
||||
const data = await axios
|
||||
.get(url)
|
||||
.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) {
|
||||
return item && item.startTime ? dayjs(item.startTime) : null
|
||||
}
|
||||
|
@ -101,7 +159,7 @@ function parseCast(info, type) {
|
|||
if (info && info.personnalities) {
|
||||
const personnalities = info.personnalities.find(i => i.prefix == type)
|
||||
if (!personnalities) return people
|
||||
for(let person of personnalities.personnalitiesList) {
|
||||
for (let person of personnalities.personnalitiesList) {
|
||||
people.push(person.title)
|
||||
}
|
||||
}
|
||||
|
@ -109,20 +167,20 @@ function parseCast(info, type) {
|
|||
}
|
||||
|
||||
function parseDate(info) {
|
||||
return (info && info.productionYear) ? info.productionYear : null
|
||||
return info && info.productionYear ? info.productionYear : null
|
||||
}
|
||||
|
||||
function parseRating(info) {
|
||||
if (!info || !info.parentalRatings) return null
|
||||
let rating = info.parentalRatings.find(i => i.authority === 'CSA')
|
||||
if (!rating || Array.isArray(rating)) return null
|
||||
if (rating.value === '1') return null
|
||||
if (rating.value === '2') rating.value = '-10'
|
||||
if (rating.value === '3') rating.value = '-12'
|
||||
if (rating.value === '4') rating.value = '-16'
|
||||
if (rating.value === '5') rating.value = '-18'
|
||||
return {
|
||||
system: rating.authority,
|
||||
value: rating.value
|
||||
}
|
||||
if (!info || !info.parentalRatings) return null
|
||||
let rating = info.parentalRatings.find(i => i.authority === 'CSA')
|
||||
if (!rating || Array.isArray(rating)) return null
|
||||
if (rating.value === '1') return null
|
||||
if (rating.value === '2') rating.value = '-10'
|
||||
if (rating.value === '3') rating.value = '-12'
|
||||
if (rating.value === '4') rating.value = '-16'
|
||||
if (rating.value === '5') rating.value = '-18'
|
||||
return {
|
||||
system: rating.authority,
|
||||
value: rating.value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// 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 fs = require('fs')
|
||||
|
@ -13,39 +13,68 @@ dayjs.extend(utc)
|
|||
jest.mock('axios')
|
||||
|
||||
const channel = {
|
||||
site_id: '198',
|
||||
site_id: 'bi#198',
|
||||
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')
|
||||
expect(url({ channel, date: today })).toBe(
|
||||
'https://hodor.canalplus.pro/api/v2/mycanal/channels/da2291af3b10e9900d1c55e1a65d3388/198/broadcasts/day/0'
|
||||
)
|
||||
url({ channel, date: today })
|
||||
.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')
|
||||
expect(url({ channel, date: tomorrow })).toBe(
|
||||
'https://hodor.canalplus.pro/api/v2/mycanal/channels/da2291af3b10e9900d1c55e1a65d3388/198/broadcasts/day/1'
|
||||
)
|
||||
url({ channel, date: tomorrow })
|
||||
.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 => {
|
||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
|
||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
|
||||
|
||||
axios.get.mockImplementation(url => {
|
||||
if (
|
||||
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({
|
||||
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program1.json')))
|
||||
})
|
||||
} else if (
|
||||
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({
|
||||
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 () => {
|
||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/no_content.json'))
|
||||
const result = await parser({ content })
|
||||
expect(result).toMatchObject([])
|
||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/no_content.json'))
|
||||
const result = await parser({ content })
|
||||
expect(result).toMatchObject([])
|
||||
})
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?><tv date="20221020">
|
||||
<channel id="6eren.dk"><display-name>6'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.
4
tests/__data__/expected/guides/en/example.com.xml
Normal file
4
tests/__data__/expected/guides/en/example.com.xml
Normal file
|
@ -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>
|
Binary file not shown.
4
tests/__data__/expected/guides/fr/example.com.xml
Normal file
4
tests/__data__/expected/guides/fr/example.com.xml
Normal file
|
@ -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>
|
16
tests/__data__/input/sites/epg-grab/epg-grab.config.js
Normal file
16
tests/__data__/input/sites/epg-grab/epg-grab.config.js
Normal file
|
@ -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
tests/commands/epg/grab.test.js
Normal file
39
tests/commands/epg/grab.test.js
Normal 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'
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue