Replace LF endings with CRLF

This commit is contained in:
freearhey
2025-07-31 22:29:01 +03:00
parent 17e3b4ddda
commit 29aa427923
379 changed files with 29332 additions and 29332 deletions

View File

@@ -1,115 +1,115 @@
const cheerio = require('cheerio')
const axios = require('axios')
const { DateTime } = require('luxon')
const API_ENDPOINT = 'https://tv-programme.telecablesat.fr/chaine'
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'
}
module.exports = {
site: 'tv-programme.telecablesat.fr',
days: 2,
delay: 5000,
request: {
headers
},
url: function ({ channel, date }) {
return `${API_ENDPOINT}/${channel.site_id}/index.html?date=${date.format(
'YYYY-MM-DD'
)}&period=morning`
},
async parser({ content, date, channel }) {
let programs = []
let items = parseItems(content)
if (!items.length) return programs
const url = `${API_ENDPOINT}/${channel.site_id}/index.html`
const promises = [
axios.get(`${url}?date=${date.format('YYYY-MM-DD')}&period=noon`, { headers }),
axios.get(`${url}?date=${date.format('YYYY-MM-DD')}&period=afternoon`, { headers })
]
await Promise.allSettled(promises).then(results => {
results.forEach(r => {
if (r.status === 'fulfilled') {
items = items.concat(parseItems(r.value.data))
}
})
})
for (let item of items) {
const prev = programs[programs.length - 1]
const $item = cheerio.load(item)
let start = parseStart($item, date)
if (prev) {
if (start < prev.start) {
start = start.plus({ days: 1 })
date = date.add(1, 'd')
}
prev.stop = start
}
const stop = start.plus({ hours: 1 })
programs.push({
title: parseTitle($item),
description: parseDescription($item),
image: parseImage($item),
start,
stop
})
}
return programs
},
async channels() {
const data = await axios
.get('https://tv-programme.telecablesat.fr/', { headers })
.then(r => r.data)
.catch(console.log)
const $ = cheerio.load(data)
const items = $(
'#ptgv_left > section.main > div > div > div:nth-child(1) > div > div > div.linker.with_search > div.inside > div.scroller > a'
).toArray()
return items.map(item => {
const $item = cheerio.load(item)
const link = $item('*').attr('href')
const [, site_id] = link.match(/\/chaine\/(\d+)\//) || [null, null]
const name = $item('*').text().trim()
return {
lang: 'fr',
site_id,
name
}
})
}
}
function parseStart($item, date) {
const timeString = $item('.schedule-hour').text()
if (!timeString) return null
return DateTime.fromFormat(`${date.format('YYYY-MM-DD')} ${timeString}`, 'yyyy-MM-dd HH:mm', {
zone: 'Europe/Paris'
}).toUTC()
}
function parseImage($item) {
const imgSrc = $item('img').attr('src')
return imgSrc ? `https:${imgSrc}` : null
}
function parseTitle($item) {
return $item('div.item-content > div.title-left').text().trim()
}
function parseDescription($item) {
return $item('div.item-content > p').text()
}
function parseItems(content) {
const $ = cheerio.load(content)
return $(
'#ptgv_left > div.container > div.row.no-gutter > div.col-md-8 > div > div > div > div > div > div > div.news'
).toArray()
}
const cheerio = require('cheerio')
const axios = require('axios')
const { DateTime } = require('luxon')
const API_ENDPOINT = 'https://tv-programme.telecablesat.fr/chaine'
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'
}
module.exports = {
site: 'tv-programme.telecablesat.fr',
days: 2,
delay: 5000,
request: {
headers
},
url: function ({ channel, date }) {
return `${API_ENDPOINT}/${channel.site_id}/index.html?date=${date.format(
'YYYY-MM-DD'
)}&period=morning`
},
async parser({ content, date, channel }) {
let programs = []
let items = parseItems(content)
if (!items.length) return programs
const url = `${API_ENDPOINT}/${channel.site_id}/index.html`
const promises = [
axios.get(`${url}?date=${date.format('YYYY-MM-DD')}&period=noon`, { headers }),
axios.get(`${url}?date=${date.format('YYYY-MM-DD')}&period=afternoon`, { headers })
]
await Promise.allSettled(promises).then(results => {
results.forEach(r => {
if (r.status === 'fulfilled') {
items = items.concat(parseItems(r.value.data))
}
})
})
for (let item of items) {
const prev = programs[programs.length - 1]
const $item = cheerio.load(item)
let start = parseStart($item, date)
if (prev) {
if (start < prev.start) {
start = start.plus({ days: 1 })
date = date.add(1, 'd')
}
prev.stop = start
}
const stop = start.plus({ hours: 1 })
programs.push({
title: parseTitle($item),
description: parseDescription($item),
image: parseImage($item),
start,
stop
})
}
return programs
},
async channels() {
const data = await axios
.get('https://tv-programme.telecablesat.fr/', { headers })
.then(r => r.data)
.catch(console.log)
const $ = cheerio.load(data)
const items = $(
'#ptgv_left > section.main > div > div > div:nth-child(1) > div > div > div.linker.with_search > div.inside > div.scroller > a'
).toArray()
return items.map(item => {
const $item = cheerio.load(item)
const link = $item('*').attr('href')
const [, site_id] = link.match(/\/chaine\/(\d+)\//) || [null, null]
const name = $item('*').text().trim()
return {
lang: 'fr',
site_id,
name
}
})
}
}
function parseStart($item, date) {
const timeString = $item('.schedule-hour').text()
if (!timeString) return null
return DateTime.fromFormat(`${date.format('YYYY-MM-DD')} ${timeString}`, 'yyyy-MM-dd HH:mm', {
zone: 'Europe/Paris'
}).toUTC()
}
function parseImage($item) {
const imgSrc = $item('img').attr('src')
return imgSrc ? `https:${imgSrc}` : null
}
function parseTitle($item) {
return $item('div.item-content > div.title-left').text().trim()
}
function parseDescription($item) {
return $item('div.item-content > p').text()
}
function parseItems(content) {
const $ = cheerio.load(content)
return $(
'#ptgv_left > div.container > div.row.no-gutter > div.col-md-8 > div > div > div > div > div > div > div.news'
).toArray()
}

View File

@@ -1,96 +1,96 @@
const { parser, url, request } = require('./tv-programme.telecablesat.fr.config.js')
const axios = require('axios')
const fs = require('fs')
const path = require('path')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
dayjs.extend(utc)
const date = dayjs.utc('2023-11-30', 'YYYY-MM-DD').startOf('d')
const channel = {
site_id: '13',
xmltv_id: 'DasErste.de'
}
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'
}
jest.mock('axios')
it('can generate valid url', () => {
expect(url({ channel, date })).toBe(
'https://tv-programme.telecablesat.fr/chaine/13/index.html?date=2023-11-30&period=morning'
)
})
it('can generate valid request headers', () => {
expect(request.headers).toMatchObject(headers)
})
it('can parse response', async () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content_morning.html'))
axios.get.mockImplementation((url, config) => {
if (
url ===
'https://tv-programme.telecablesat.fr/chaine/13/index.html?date=2023-11-30&period=noon' &&
JSON.stringify(config.headers) === JSON.stringify(headers)
) {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_noon.html'))
})
} else if (
url ===
'https://tv-programme.telecablesat.fr/chaine/13/index.html?date=2023-11-30&period=afternoon' &&
JSON.stringify(config.headers) === JSON.stringify(headers)
) {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_afternoon.html'))
})
} else {
return Promise.resolve({ data: '' })
}
})
let results = await parser({ content, channel, date })
results = results.map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
})
expect(results[0]).toMatchObject({
start: '2023-11-30T08:00:00.000Z',
stop: '2023-11-30T08:05:00.000Z',
title: 'Tagesschau',
description:
'Die Tagesschau ist eine Institution in der deutschen Fernsehlandschaft. Seit 1952 wird kurz und bündig von aktuellen Geschehnissen in Deutschland und der Welt berichtet. Bis heute ist die Redaktion der sachlichen Berichterstattung treu geblieben und...',
image:
'https://tv.cdnartwhere.eu/cache/i2/Dc5BDoMgEADAv3Cuwoqy4Fu4LLho24hEaNK06d_rcW7zFYEqi1lsrZU6e-nlXrqyHe2oXVxyT5_Xybys3GduXsYjN7pnPqdkI0CkJbk4gnKWMQFAQLQUtHZesuEwOgWa7DCkKV4cGFEBG0eQrCJSwY3YP8oqbmKn-rwexuBb20n8_g.jpg'
})
expect(results[36]).toMatchObject({
start: '2023-12-01T04:30:00.000Z',
stop: '2023-12-01T05:30:00.000Z',
title: 'ZDF-Morgenmagazin',
description: 'Für einen guten Start in den Tag',
image:
'https://tv.cdnartwhere.eu/cache/i2/Dc5BDoMgEADAv3CuIiIu-BYuu7Bo24hEaNK06d_rbY7zFYSVxSK21kpdvPRyL13ZjnbULsTc4-d1MseV-8zNy3DkhvfMp0k2KBUwJhcmNTjLkJRSBGCRtHZe2gQTYXRhJNCoL1NyyiTiSI6IhtHADOT6R1nFTexYn9djnuGtrRG_Pw.jpg'
})
})
it('can handle empty guide', done => {
parser({
content:
'<!DOCTYPE html><html lang="fr" dir="ltr" prefix=""> <head></head> <body></body></html>',
date,
channel
})
.then(result => {
expect(result).toMatchObject([])
done()
})
.catch(done)
})
const { parser, url, request } = require('./tv-programme.telecablesat.fr.config.js')
const axios = require('axios')
const fs = require('fs')
const path = require('path')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)
dayjs.extend(utc)
const date = dayjs.utc('2023-11-30', 'YYYY-MM-DD').startOf('d')
const channel = {
site_id: '13',
xmltv_id: 'DasErste.de'
}
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'
}
jest.mock('axios')
it('can generate valid url', () => {
expect(url({ channel, date })).toBe(
'https://tv-programme.telecablesat.fr/chaine/13/index.html?date=2023-11-30&period=morning'
)
})
it('can generate valid request headers', () => {
expect(request.headers).toMatchObject(headers)
})
it('can parse response', async () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content_morning.html'))
axios.get.mockImplementation((url, config) => {
if (
url ===
'https://tv-programme.telecablesat.fr/chaine/13/index.html?date=2023-11-30&period=noon' &&
JSON.stringify(config.headers) === JSON.stringify(headers)
) {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_noon.html'))
})
} else if (
url ===
'https://tv-programme.telecablesat.fr/chaine/13/index.html?date=2023-11-30&period=afternoon' &&
JSON.stringify(config.headers) === JSON.stringify(headers)
) {
return Promise.resolve({
data: fs.readFileSync(path.resolve(__dirname, '__data__/content_afternoon.html'))
})
} else {
return Promise.resolve({ data: '' })
}
})
let results = await parser({ content, channel, date })
results = results.map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
})
expect(results[0]).toMatchObject({
start: '2023-11-30T08:00:00.000Z',
stop: '2023-11-30T08:05:00.000Z',
title: 'Tagesschau',
description:
'Die Tagesschau ist eine Institution in der deutschen Fernsehlandschaft. Seit 1952 wird kurz und bündig von aktuellen Geschehnissen in Deutschland und der Welt berichtet. Bis heute ist die Redaktion der sachlichen Berichterstattung treu geblieben und...',
image:
'https://tv.cdnartwhere.eu/cache/i2/Dc5BDoMgEADAv3Cuwoqy4Fu4LLho24hEaNK06d_rcW7zFYEqi1lsrZU6e-nlXrqyHe2oXVxyT5_Xybys3GduXsYjN7pnPqdkI0CkJbk4gnKWMQFAQLQUtHZesuEwOgWa7DCkKV4cGFEBG0eQrCJSwY3YP8oqbmKn-rwexuBb20n8_g.jpg'
})
expect(results[36]).toMatchObject({
start: '2023-12-01T04:30:00.000Z',
stop: '2023-12-01T05:30:00.000Z',
title: 'ZDF-Morgenmagazin',
description: 'Für einen guten Start in den Tag',
image:
'https://tv.cdnartwhere.eu/cache/i2/Dc5BDoMgEADAv3CuIiIu-BYuu7Bo24hEaNK06d_rbY7zFYSVxSK21kpdvPRyL13ZjnbULsTc4-d1MseV-8zNy3DkhvfMp0k2KBUwJhcmNTjLkJRSBGCRtHZe2gQTYXRhJNCoL1NyyiTiSI6IhtHADOT6R1nFTexYn9djnuGtrRG_Pw.jpg'
})
})
it('can handle empty guide', done => {
parser({
content:
'<!DOCTYPE html><html lang="fr" dir="ltr" prefix=""> <head></head> <body></body></html>',
date,
channel
})
.then(result => {
expect(result).toMatchObject([])
done()
})
.catch(done)
})