Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add epg.telemach.ba #2631

Merged
merged 5 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sites/epg.telemach.ba/__data__/content.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions sites/epg.telemach.ba/__data__/no_content.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"status":400,"error":"resource_not_found","errorMessage":"Resource not found","messageId":1674123545}
1 change: 1 addition & 0 deletions sites/epg.telemach.ba/__data__/no_session.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"error":"unsupported_grant_type","error_description":"Unsupported grant type"}
1 change: 1 addition & 0 deletions sites/epg.telemach.ba/__data__/session.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidWMtaW5mby1zZXJ2aWNlIl0sInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNzM3Mzc3NDUxLCJhdXRob3JpdGllcyI6WyJST0xFX1BVQkxJQ19FUEciXSwianRpIjoiUVBubHdRSDczS1EwSnU0WDZwRTc2Zm5mUmRnIiwiY2xpZW50X2lkIjoiMjdlMTFmNWUtODhlMi00OGU0LWJkNDItOGUxNWFiYmM2NmY1In0.LqJAZUWEqIOcLrRSMpxZxnF-f1arKbHgfweLMXt-MBjCDbVJD39OQEsh_b68mtePAoa3n8LRbf3IFT40Ys5Vbe-k_Btm4a9gdEGr6cNi_4HGk4Bto6RUDvCp59VRfoRZhWe145Q2b5TS6szmC4Ws2YWIcZU5vrJcYs2GZiCk6U11MOcd1i52WmZj8cLPq0ZPDB_bzmTgYkvkVa7zOzUOPSl4M8T6fPUa__vVKUt0jOgtFoHeue2mQVgISC2puEGsBN0jJwvJ8PzM6IVxXrQno3MBv0VJy_qILiFPcxRePGRAmKLuEqagvikO7P_XQgFjZgg-j8u8wX2WwO0Yxft0Pg","token_type":"bearer","expires_in":86399,"scope":"read","jti":"QPnlwQH73KQ0Ju4X6pE76fnfRdg"}
262 changes: 262 additions & 0 deletions sites/epg.telemach.ba/epg.telemach.ba.channels.xml

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions sites/epg.telemach.ba/epg.telemach.ba.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
const dayjs = require('dayjs')
const axios = require('axios')

const BASIC_TOKEN =
'MjdlMTFmNWUtODhlMi00OGU0LWJkNDItOGUxNWFiYmM2NmY1OjEyejJzMXJ3bXdhZmsxMGNkdzl0cjloOWFjYjZwdjJoZDhscXZ0aGc='

let session

module.exports = {
site: 'epg.telemach.ba',
days: 3,
url({ channel, date }) {
return `https://api-web.ug-be.cdn.united.cloud/v1/public/events/epg?fromTime=${date.format(
'YYYY-MM-DDTHH:mm:ss-00:00'
)}&toTime=${date
.add(1, 'days')
.subtract(1, 's')
.format('YYYY-MM-DDTHH:mm:ss-00:00')}&communityId=12&languageId=59&cid=${channel.site_id}`
},
request: {
async headers() {
if (!session) {
session = await loadSessionDetails()
if (!session || !session.access_token) return null
}

return {
Authorization: `Bearer ${session.access_token}`
}
}
},
parser({ content }) {
try {
const programs = []
const data = JSON.parse(content)
for (const channelId in data) {
if (Array.isArray(data[channelId])) {
data[channelId].forEach(item => {
programs.push({
title: item.title,
description: item.shortDescription,
image: parseImage(item),
season: item.seasonNumber,
episode: item.episodeNumber,
start: dayjs(item.startTime),
stop: dayjs(item.endTime)
})
})
}
}

return programs
} catch {
return []
}
},
async channels() {
const session = await loadSessionDetails()
if (!session || !session.access_token) return null

const data = await axios
.get(
'https://api-web.ug-be.cdn.united.cloud/v1/public/channels?channelType=TV&communityId=12&languageId=59&imageSize=L',
{
headers: {
Authorization: `Bearer ${session.access_token}`
}
}
)
.then(r => r.data)
.catch(console.error)

return data.map(item => ({
lang: 'hr',
site_id: item.id,
name: item.name
}))
}
}

function parseImage(item) {
const baseURL = 'https://images-web.ug-be.cdn.united.cloud'

return Array.isArray(item?.images) && item.images[0] ? `${baseURL}${item.images[0].path}` : null
}

function loadSessionDetails() {
return axios
.post(
'https://api-web.ug-be.cdn.united.cloud/oauth/token?grant_type=client_credentials',
{},
{
headers: {
Authorization: `Basic ${BASIC_TOKEN}`
}
}
)
.then(r => r.data)
.catch(console.log)
}
94 changes: 94 additions & 0 deletions sites/epg.telemach.ba/epg.telemach.ba.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const { parser, url, request } = require('./epg.telemach.ba.config.js')
const fs = require('fs')
const axios = require('axios')
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)

jest.mock('axios')

axios.post.mockImplementation((url, data, opts) => {
if (
url === 'https://api-web.ug-be.cdn.united.cloud/oauth/token?grant_type=client_credentials' &&
JSON.stringify(opts.headers) ===
JSON.stringify({
Authorization:
'Basic MjdlMTFmNWUtODhlMi00OGU0LWJkNDItOGUxNWFiYmM2NmY1OjEyejJzMXJ3bXdhZmsxMGNkdzl0cjloOWFjYjZwdjJoZDhscXZ0aGc='
})
) {
return Promise.resolve({
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/session.json')))
})
} else {
return Promise.resolve({
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/no_session.json')))
})
}
})

const date = dayjs.utc('2025-01-20', 'YYYY-MM-DD').startOf('d')
const channel = {
site_id: '1607',
xmltv_id: 'N1HD.hr'
}

it('can generate valid url', async () => {
const result = url({ date, channel })

expect(result).toBe(
'https://api-web.ug-be.cdn.united.cloud/v1/public/events/epg?fromTime=2025-01-20T00:00:00-00:00&toTime=2025-01-20T23:59:59-00:00&communityId=12&languageId=59&cid=1607'
)
})

it('can generate valid request headers', async () => {
const result = await request.headers()

expect(result).toMatchObject({
Authorization:
'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidWMtaW5mby1zZXJ2aWNlIl0sInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNzM3Mzc3NDUxLCJhdXRob3JpdGllcyI6WyJST0xFX1BVQkxJQ19FUEciXSwianRpIjoiUVBubHdRSDczS1EwSnU0WDZwRTc2Zm5mUmRnIiwiY2xpZW50X2lkIjoiMjdlMTFmNWUtODhlMi00OGU0LWJkNDItOGUxNWFiYmM2NmY1In0.LqJAZUWEqIOcLrRSMpxZxnF-f1arKbHgfweLMXt-MBjCDbVJD39OQEsh_b68mtePAoa3n8LRbf3IFT40Ys5Vbe-k_Btm4a9gdEGr6cNi_4HGk4Bto6RUDvCp59VRfoRZhWe145Q2b5TS6szmC4Ws2YWIcZU5vrJcYs2GZiCk6U11MOcd1i52WmZj8cLPq0ZPDB_bzmTgYkvkVa7zOzUOPSl4M8T6fPUa__vVKUt0jOgtFoHeue2mQVgISC2puEGsBN0jJwvJ8PzM6IVxXrQno3MBv0VJy_qILiFPcxRePGRAmKLuEqagvikO7P_XQgFjZgg-j8u8wX2WwO0Yxft0Pg'
})
})

it('can parse response', () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'), 'utf8')
let results = parser({ content })
results = results.map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
})

expect(results.length).toBe(35)
expect(results[0]).toMatchObject({
start: '2025-01-20T00:00:00.000Z',
stop: '2025-01-20T00:30:00.000Z',
title: 'DW Euromaxx',
description:
'Euromaxx je lifestyle Europe magazine, koji nam donosi zanimljivosti iz evropskih gradova, priče o načinu života ljudi i upoznaje nas sa njihovim kulturama.',
image:
'https://images-web.ug-be.cdn.united.cloud/2021/02/18/06/05/21/stb_xl_cd4f72e01d308ecce782e29b69af7de6707b9e85.jpg',
season: null,
episode: null
})
expect(results[34]).toMatchObject({
start: '2025-01-20T23:50:00.000Z',
stop: '2025-01-21T00:00:00.000Z',
title: 'DW Shift',
description: 'Tjedni magazin koji nam donosi najnovije vijesti vezane za Internet.',
image:
'https://images-web.ug-be.cdn.united.cloud/2023/06/09/13/07/53/stb_xl_0849d5d70c1337651b85b6335e340e15bd5d6a73_340fc454bc73019d052cf936ebee5da3.jpg',
season: null,
episode: null
})
})

it('can handle empty guide', () => {
const results = parser({
content: fs.readFileSync(path.resolve(__dirname, '__data__/no_content.json'), 'utf8')
})

expect(results).toMatchObject([])
})
21 changes: 21 additions & 0 deletions sites/epg.telemach.ba/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# epg.telemach.ba

https://epg.telemach.ba/

### Download the guide

```sh
npm run grab --- --site=epg.telemach.ba
```

### Update channel list

```sh
npm run channels:parse --- --config=./sites/epg.telemach.ba/epg.telemach.ba.config.js --output=./sites/epg.telemach.ba/epg.telemach.ba.channels.xml
```

### Test

```sh
npm test --- epg.telemach.ba
```
Loading