mirror of
https://github.com/iptv-org/epg.git
synced 2025-05-10 17:10:07 -04:00
Merge pull request #1229 from iptv-org/add-telsu.fi
Add guide from telsu.fi
This commit is contained in:
commit
5417a56c40
5 changed files with 539 additions and 0 deletions
236
sites/telsu.fi/__data__/content.html
Normal file
236
sites/telsu.fi/__data__/content.html
Normal file
File diff suppressed because one or more lines are too long
139
sites/telsu.fi/__data__/no_content.html
Normal file
139
sites/telsu.fi/__data__/no_content.html
Normal file
|
@ -0,0 +1,139 @@
|
|||
<!doctype html>
|
||||
<html lang="fi">
|
||||
<head>
|
||||
<title>YLE TV1 TV-ohjelmat sunnuntaina 29.10.2023 - Telsu.fi</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta name="description" content="Katso kanavan Yle TV1 ohjelmatiedot Suomen monipuolisimmasta TV-oppaasta.">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="referrer" content="origin">
|
||||
<meta name="theme-color" content="#d0d0d0">
|
||||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
|
||||
|
||||
<link rel="stylesheet" href="/css/t.css?v=321" type="text/css">
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="/icon.png">
|
||||
<link rel="icon" href="/icon.png">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
|
||||
<link rel="preload" as="font" type="font/woff2" href="/fonts/open-sans-v34-latin-regular.woff2" crossorigin>
|
||||
<link rel="preload" as="font" type="font/woff2" href="/fonts/open-sans-v34-latin-600.woff2" crossorigin>
|
||||
|
||||
<link rel="preconnect" href="https://fundingchoicesmessages.google.com" crossorigin>
|
||||
|
||||
<link rel="dns-prefetch" href="//www.googletagmanager.com">
|
||||
<link rel="dns-prefetch" href="//ajax.googleapis.com">
|
||||
<link rel="dns-prefetch" href="//apps-cdn.relevant-digital.com">
|
||||
<link rel="dns-prefetch" href="//cdn.jsdelivr.net">
|
||||
<link rel="dns-prefetch" href="//prg.smartadserver.com">
|
||||
<link rel="dns-prefetch" href="//ads.pubmatic.com">
|
||||
<link rel="dns-prefetch" href="//adx.adform.net">
|
||||
|
||||
|
||||
<meta property="og:image" content="https://www.telsu.fi/img/fblogo.png">
|
||||
<meta property="fb:app_id" content="259818434100858">
|
||||
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
window.googlefc = window.googlefc || {};
|
||||
window.googlefc.callbackQueue = window.googlefc.callbackQueue || [];
|
||||
</script>
|
||||
<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
|
||||
<script async src="/js/init.js?v=192"></script>
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="hat"><div>
|
||||
<a href="https://www.suomi24.fi/reseptit" target="_blank" rel="noopener">Reseptit</a><a href="https://www.auto1.fi" target="_blank" rel="noopener">Vaihtoautot</a><a href="https://www.suomi24.fi/horoskooppi" target="_blank" rel="noopener">Horoskooppi</a><a href="https://www.testeri.fi" target="_blank" rel="noopener">Tietovisat</a><a href="https://www.suomi24.fi/viihde" target="_blank" rel="noopener">Viihde</a><a href="https://www.blogit.fi" target="_blank" rel="noopener">Blogit</a><a href="https://ilmainensanakirja.fi" target="_blank" rel="noopener">Sanakirja</a></div></div>
|
||||
|
||||
|
||||
<div id="head" data-nosnippet>
|
||||
<a href="/" class="logo" title="Telsu on Suomen monipuolisin tv-opas! Klikkaa tästä etusivulle."><h1>TV-ohjelmat tänään</h1></a>
|
||||
|
||||
<a href="/20231028/yle1" class="cal_prev" title="Edellinen päivä"></a><a href="#" class="cal_open"><i>29</i>Su 29.10.</a><a href="/20231030/yle1" class="cal_next" title="Seuraava päivä"></a>
|
||||
<a class="chns" href="#">Kanavat</a>
|
||||
|
||||
<a class="time" href="#">Koko päivä</a>
|
||||
|
||||
<a class="prgs" href="#">Korostukset</a>
|
||||
|
||||
<a class="tops" href="/ohjelmat">Suosikit</a>
|
||||
|
||||
<div class="space"></div>
|
||||
|
||||
<div class="search">
|
||||
<input type="text" name="haku" placeholder="Hae ohjelmia" />
|
||||
<a href="#" class="do" title="Hae tulevia tai menneitä TV-ohjelmia"></a>
|
||||
</div>
|
||||
|
||||
<a class="sets" href="#"></a>
|
||||
|
||||
<a class="login" href="#"></a>
|
||||
|
||||
<a href="#" class="ft-search" title="haku"></a>
|
||||
<a href="#" class="ft-menu" title="valikko"></a>
|
||||
|
||||
<div class="calbox" rel="20231029"><div></div></div>
|
||||
<div class="loginbox"><div></div></div>
|
||||
<div class="ft-box">
|
||||
<div class="mobox">
|
||||
<a href="#" class="ft-login">Kirjaudu</a> <a href="#" class="ft-close lazy">Sulje</a>
|
||||
</div>
|
||||
<div class="chnsbox" rel="yle1"><div>
|
||||
<div class="d_mob">Valitse ohjelmataulun kanavat</div>
|
||||
<a href="/tanaan/suosikit" rel="suosikit">Omat kanavat</a><a href="/tanaan/kaikki" rel="kaikki">Kaikki</a><a href="/tanaan/ilmaiskanavat" rel="ilmaiskanavat">Ilmaiset</a><a href="/tanaan/antenni" rel="antenni">Antenni</a><a href="/tanaan/suoratoisto" rel="suoratoisto">Suoratoisto</a><a href="/tanaan/elokuvat" rel="elokuvat">Elokuvat</a><a href="/tanaan/urheilu" rel="urheilu">Urheilu</a><a href="/tanaan/lapset" rel="lapset">Lapset</a><a href="/tanaan/cmore_kanavat" rel="cmore_kanavat">C More</a><a href="/tanaan/viasat" rel="viasat">Viasat</a> <a href="#" class="ft-chns">Muokkaa omia kanavia</a>
|
||||
<div class="chnsbox2"></div>
|
||||
</div></div>
|
||||
<div class="timebox"><div>
|
||||
<div class="d_desk">Valitse, mitä ohjelmia tämän päivän ohjelmalistalla näytetään.</div>
|
||||
<div class="d_mob">Mitä ohjelmalistalla näytetään?</div>
|
||||
<a href="#" class="tmode" rel="1">Vain tulevat</a><a href="#" class="tmode a" rel="2">Koko päivä</a><a href="#" class="tmode" rel="3">Seuraavat 3h</a><a href="#" class="tmode" rel="4">Ilta</a> </div></div>
|
||||
<div class="prgsbox"><div>
|
||||
<div class="d_desk">Voit korostaa tv-listauksen ohjelmia aihepiirin mukaan. Valitse alta aihepiiri ja sen jälkeen haluamasi korostusväri.<div class="c h10"></div>
|
||||
Ohjelman lisätietoikkunan kautta pääset korostamaan myös yksittäisiä ohjelmia.<div class="c"></div>
|
||||
</div>
|
||||
<div class="d_mob">Korosta ohjelmia aihepiirin mukaan</div>
|
||||
<a href="#" class="favs fbb" rel="1">Elokuvat<u></u></a><a href="#" class="favs fb0" rel="2">Urheilu<u></u></a><a href="#" class="favs fb0" rel="3">Uutiset<u></u></a><a href="#" class="favs fb0" rel="8">Fakta<u></u></a><a href="#" class="favs fb0" rel="5">Kotim. fiktio<u></u></a><a href="#" class="favs fb0" rel="6">Ulkom. sarjat<u></u></a><a href="#" class="favs fb0" rel="7">Viihde<u></u></a><a href="#" class="favs fb0" rel="4">Lapsille<u></u></a><a href="#" class="favs fb0" rel="9">Muut<u></u></a> </div></div>
|
||||
<div class="topsbox"><div>
|
||||
<div class="d_desk">Katso lista korostamistasi ohjelmista. Tai kurkkaa, mitä muut Telsun käyttäjät katsovat.</div>
|
||||
<div class="d_mob">Suosikkeja ja listoja</div>
|
||||
<a href="/ohjelmat">Omat korostukset</a>
|
||||
<a href="/suosikit">Käyttäjien suosikit</a>
|
||||
<a href="/elokuvat">Elokuvat</a>
|
||||
<a href="/urheilu">Urheilu</a>
|
||||
<a href="/sarjat">Sarjat</a>
|
||||
</div></div>
|
||||
<div class="setsbox"><div>
|
||||
<div class="d_desk">Valitse ohjelmaoppaan tyyli:</div>
|
||||
<div class="d_mob">Tuunaa Telsusta näköisesi</div>
|
||||
<a href="#" class="vmode a" title="Ohjelmataulun suunta">Pystynäkymä</a>
|
||||
<a href="#" class="vmode" title="Ohjelmataulun suunta">Vaakanäkymä</a>
|
||||
<div class="c h20 d_desk"></div>
|
||||
<div class="d_desk">Valitse Telsun ulkoasu fiiliksen mukaan:</div>
|
||||
<a href="#" class="cmode a" title="Väriteema">Vaalea ulkoasu</a>
|
||||
<a href="#" class="cmode" title="Väriteema">Tumma ulkoasu</a>
|
||||
</div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="headph"></div>
|
||||
|
||||
<div class="c"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="res1"><a href="/" class="goback">TV-ohjelmat tänään</a><h2>Kanavan <b>Yle TV1</b> ohjelmatiedot sunnuntaina 29.10.2023</h2><div class="filt"><a href="#" rel="co">Näytä tiivistettynä</a></div><div class="c"></div></div><div id="pb_top"><div id="gpp-1539858836009-0"></div></div>
|
||||
<div id="res"><div class="rpos">
|
||||
<div id="pb_side" class="pb"><div id="gpp-1539858931234-0"></div></div>
|
||||
<div class="c h10"></div>
|
||||
<div class="stck"><div>
|
||||
<div id="pb_side2" class="pb"><div id="gpp-1539858931234-1"></div></div>
|
||||
|
||||
</div></div>
|
||||
</div><div class="info"><br /><br /><b>Oops, tältä ajankohdalta ei löydy ohjelmatietoja :(</b></div>
|
95
sites/telsu.fi/telsu.fi.config.js
Normal file
95
sites/telsu.fi/telsu.fi.config.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
const axios = require('axios')
|
||||
const cheerio = require('cheerio')
|
||||
const dayjs = require('dayjs')
|
||||
const utc = require('dayjs/plugin/utc')
|
||||
const timezone = require('dayjs/plugin/timezone')
|
||||
|
||||
dayjs.extend(utc)
|
||||
dayjs.extend(timezone)
|
||||
|
||||
module.exports = {
|
||||
site: 'telsu.fi',
|
||||
url: function ({ date, channel }) {
|
||||
return `https://www.telsu.fi/${date.format('YYYYMMDD')}/${channel.site_id}`
|
||||
},
|
||||
parser: function ({ content, date }) {
|
||||
let programs = []
|
||||
const items = parseItems(content)
|
||||
items.forEach(item => {
|
||||
const $item = cheerio.load(item)
|
||||
const prev = programs[programs.length - 1]
|
||||
let start = parseStart($item, date)
|
||||
let stop = parseStop($item, date)
|
||||
if (prev) {
|
||||
if (start.isBefore(prev.start)) {
|
||||
start = start.add(1, 'd')
|
||||
stop = stop.add(1, 'd')
|
||||
}
|
||||
prev.stop = start
|
||||
}
|
||||
programs.push({
|
||||
title: parseTitle($item),
|
||||
description: parseDescription($item),
|
||||
icon: parseIcon($item),
|
||||
start,
|
||||
stop
|
||||
})
|
||||
})
|
||||
|
||||
return programs
|
||||
},
|
||||
async channels() {
|
||||
const html = await axios
|
||||
.get(`https://www.telsu.fi/`)
|
||||
.then(r => r.data)
|
||||
.catch(console.log)
|
||||
const $ = cheerio.load(html)
|
||||
const items = $('.ch').toArray()
|
||||
return items.map(item => {
|
||||
const name = $(item).find('a').attr('title')
|
||||
const site_id = $(item).attr('rel')
|
||||
|
||||
return {
|
||||
lang: 'fi',
|
||||
site_id,
|
||||
name
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function parseTitle($item) {
|
||||
return $item('h1 > b').text().trim()
|
||||
}
|
||||
|
||||
function parseDescription($item) {
|
||||
return $item('.t > div').text().trim()
|
||||
}
|
||||
|
||||
function parseIcon($item) {
|
||||
const imgSrc = $item('.t > div > div.ps > a > img').attr('src')
|
||||
|
||||
return imgSrc ? `https://www.telsu.fi${imgSrc}` : null
|
||||
}
|
||||
|
||||
function parseStart($item, date) {
|
||||
const subtitle = $item('.h > h2').text().trim()
|
||||
const [_, HH, mm] = subtitle.match(/ (\d{2})\.(\d{2}) -/) || [null, null, null]
|
||||
if (!HH || !mm) return null
|
||||
|
||||
return dayjs.tz(`${date.format('YYYY-MM-DD')} ${HH}:${mm}`, 'YYYY-MM-DD HH:mm', 'Europe/Helsinki')
|
||||
}
|
||||
|
||||
function parseStop($item, date) {
|
||||
const subtitle = $item('.h > h2').text().trim()
|
||||
const [_, HH, mm] = subtitle.match(/ - (\d{2})\.(\d{2})/) || [null, null, null]
|
||||
if (!HH || !mm) return null
|
||||
|
||||
return dayjs.tz(`${date.format('YYYY-MM-DD')} ${HH}:${mm}`, 'YYYY-MM-DD HH:mm', 'Europe/Helsinki')
|
||||
}
|
||||
|
||||
function parseItems(content) {
|
||||
const $ = cheerio.load(content)
|
||||
|
||||
return $('#res > div.dets').toArray()
|
||||
}
|
47
sites/telsu.fi/telsu.fi.test.js
Normal file
47
sites/telsu.fi/telsu.fi.test.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
// npm run channels:parse -- --config=./sites/telsu.fi/telsu.fi.config.js --output=./sites/telsu.fi/telsu.fi_fi.channels.xml
|
||||
// npx epg-grabber --config=sites/telsu.fi/telsu.fi.config.js --channels=sites/telsu.fi/telsu.fi_fi.channels.xml --output=guide.xml --days=2
|
||||
|
||||
const { parser, url } = require('./telsu.fi.config.js')
|
||||
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('2022-10-29', 'YYYY-MM-DD').startOf('d')
|
||||
const channel = {
|
||||
site_id: 'yle1',
|
||||
xmltv_id: 'YleTV1.fi'
|
||||
}
|
||||
|
||||
it('can generate valid url', () => {
|
||||
expect(url({ date, channel })).toBe('https://www.telsu.fi/20221029/yle1')
|
||||
})
|
||||
|
||||
it('can parse response', () => {
|
||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
|
||||
const results = parser({ content, date }).map(p => {
|
||||
p.start = p.start.toJSON()
|
||||
p.stop = p.stop.toJSON()
|
||||
return p
|
||||
})
|
||||
|
||||
expect(results[0]).toMatchObject({
|
||||
start: '2022-10-29T04:00:00.000Z',
|
||||
stop: '2022-10-29T04:28:00.000Z',
|
||||
title: 'Antiikkikaksintaistelu',
|
||||
description:
|
||||
'Kausi 6, osa 5/12. Antiikkikaksintaistelu jatkuu Løkkenissä. Uusi taistelupari Rikke Fog ja Lasse Franck saavat kumpikin 10 000 kruunua ja viisi tuntia aikaa ostaa alueelta hyvää tavaraa halvalla.',
|
||||
icon: 'https://www.telsu.fi/s/antiikkikaksintaistelu_11713730.jpg'
|
||||
})
|
||||
})
|
||||
|
||||
it('can handle empty guide', () => {
|
||||
const result = parser({
|
||||
content: fs.readFileSync(path.resolve(__dirname, '__data__/no_content.html')),
|
||||
date
|
||||
})
|
||||
expect(result).toMatchObject([])
|
||||
})
|
22
sites/telsu.fi/telsu.fi_fi.channels.xml
Normal file
22
sites/telsu.fi/telsu.fi_fi.channels.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<site site="telsu.fi">
|
||||
<channels>
|
||||
<channel lang="fi" xmltv_id="AlfaTV.fi" site_id="alfatv">AlfaTV</channel>
|
||||
<channel lang="fi" xmltv_id="AVA.fi" site_id="mtv3ava">AVA</channel>
|
||||
<channel lang="fi" xmltv_id="FoxFinland.fi" site_id="fox">FOX</channel>
|
||||
<channel lang="fi" xmltv_id="Frii.fi" site_id="frii">Frii</channel>
|
||||
<channel lang="fi" xmltv_id="Hero.fi" site_id="hero">Hero</channel>
|
||||
<channel lang="fi" xmltv_id="Jim.fi" site_id="jim">Jim</channel>
|
||||
<channel lang="fi" xmltv_id="Kutonen.fi" site_id="kutonen">Kutonen</channel>
|
||||
<channel lang="fi" xmltv_id="Liv.fi" site_id="liv">Liv</channel>
|
||||
<channel lang="fi" xmltv_id="MTV3.fi" site_id="mtv3">MTV3</channel>
|
||||
<channel lang="fi" xmltv_id="NationalGeographicFinland.fi" site_id="nationalgeo">National Geographic Channel</channel>
|
||||
<channel lang="fi" xmltv_id="Nelonen.fi" site_id="nelonen">Nelonen</channel>
|
||||
<channel lang="fi" xmltv_id="Sub.fi" site_id="subtv">Sub</channel>
|
||||
<channel lang="fi" xmltv_id="TLCFinland.fi" site_id="tlc">TLC</channel>
|
||||
<channel lang="fi" xmltv_id="TV5.fi" site_id="viisi">TV5</channel>
|
||||
<channel lang="fi" xmltv_id="YleTeemaFem.fi" site_id="ylefem">Yle Teema & Fem</channel>
|
||||
<channel lang="fi" xmltv_id="YleTV1.fi" site_id="yle1">Yle TV1</channel>
|
||||
<channel lang="fi" xmltv_id="YleTV2.fi" site_id="yle2">Yle TV2</channel>
|
||||
</channels>
|
||||
</site>
|
Loading…
Add table
Add a link
Reference in a new issue