feat: nhl.com site

I was having trouble with the extant sites for this channel so I decided to add a source for the league's own guide. Unfortunately it's missing images since I don't know where they need to be hosted :(
This commit is contained in:
shay committed 2024-11-21 18:30:57 -06:00
1 parent 7610f7b9f5
commit 5d33db08b8
6 files changed
+116

No files matched your search

+1
View File
@@ -91,6 +91,7 @@
| [mytvsuper.com](sites/mytvsuper.com) | 🟢 | |
| [nhk.or.jp](sites/nhk.or.jp) | 🟢 | |
| [nhkworldpremium.com](sites/nhkworldpremium.com) | 🟢 | |
| [nhl.com](sites/nhl.com) | 🟢 | |
| [nostv.pt](sites/nostv.pt) | 🟢 | |
| [novacyprus.com](sites/novacyprus.com) | 🟢 | |
| [novasports.gr](sites/novasports.gr) | 🟢 | |
+1
View File
@@ -0,0 +1 @@
{"date":"2024-11-22","startDate":"2024-11-08","endDate":"2024-12-05","broadcasts":[{"startTime":"2024-11-22T00:00:00","endTime":"2024-11-22T01:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124SOR","broadcastType":"HD","broadcastStatus":"LIVE","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T01:00:00","endTime":"2024-11-22T02:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T02:00:00","endTime":"2024-11-22T03:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T03:00:00","endTime":"2024-11-22T04:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T04:00:00","endTime":"2024-11-22T05:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T05:00:00","endTime":"2024-11-22T06:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T06:00:00","endTime":"2024-11-22T07:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T07:00:00","endTime":"2024-11-22T08:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T08:00:00","endTime":"2024-11-22T09:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T09:00:00","endTime":"2024-11-22T10:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T10:00:00","endTime":"2024-11-22T11:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T11:00:00","endTime":"2024-11-22T12:00:00","durationSeconds":3600,"title":"On The Fly","description":"On The Fly","houseNumber":"HOTF25R112124CC","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"onthefly.png"},{"startTime":"2024-11-22T12:00:00","endTime":"2024-11-22T14:00:00","durationSeconds":7200,"title":"NHL Game","description":"New York Rangers at Calgary Flames on 11/21/2024 From Scotiabank Saddledome","houseNumber":"H120NYRCGY11212024","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"nhl.png"},{"startTime":"2024-11-22T14:00:00","endTime":"2024-11-22T16:00:00","durationSeconds":7200,"title":"NHL Game","description":"Carolina Hurricanes at New Jersey Devils on 11/21/2024 From Prudential Center","houseNumber":"H120CARNJD11212024","broadcastType":"HD","broadcastStatus":"","broadcastImageUrl":"nhl.png"},{"startTime":"2024-11-22T16:00:00","endTime":"2024-11-22T17:00:00","durationSeconds":3600,"title":"NHL Tonight: First Shift","description":"NHL Tonight: First Shift","houseNumber":"HNHLTFS25112224LV","broadcastType":"HD","broadcastStatus":"LIVE","broadcastImageUrl":""},{"startTime":"2024-11-22T17:00:00","endTime":"2024-11-22T19:00:00","durationSeconds":7200,"title":"NHL Now","description":"NHL Now","houseNumber":"HNOW25R112224LV","broadcastType":"HD","broadcastStatus":"LIVE","broadcastImageUrl":"nhlnow.png"},{"startTime":"2024-11-22T19:00:00","endTime":"2024-11-22T22:00:00","durationSeconds":10800,"title":"Regular Season Hockey on NHL Network","description":"Winnipeg Jets at Pittsburgh Penguins on 11/22/2024 From PPG Paints Arena","houseNumber":"H180WPGPIT11222024","broadcastType":"HD","broadcastStatus":"LIVE","broadcastImageUrl":"nhl.png"},{"startTime":"2024-11-22T22:00:00","endTime":"2024-11-22T22:30:00","durationSeconds":1800,"title":"NHL Tonight","description":"NHL Tonight","houseNumber":"HNHLT25RS112224LV","broadcastType":"HD","broadcastStatus":"LIVE","broadcastImageUrl":"nhltonight.png"},{"startTime":"2024-11-22T22:30:00","endTime":"2024-11-22T23:00:00","durationSeconds":1800,"title":"NHL Tonight","description":"NHL Tonight","houseNumber":"HNHLT25RS112224CC","broadcastType":"HD","broadcasLine truncated
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<channels>
<!--
`site_id` is not relevant for this configuration as nhl.com only has a guide for one channel.
nonetheless I elected to use "network" here because:
1) a blank value causes the record to be skipped
2) "network" is a keyword in the API endpoint
-->
<channel site="nhl.com" lang="en" xmltv_id="NHLNetwork.us" site_id="network">NHL Network</channel>
</channels>
+45
View File
@@ -0,0 +1,45 @@
const dayjs = require('dayjs')
module.exports = {
site: 'nhl.com',
// I'm not sure what `endDate` represents but they only return 1 day of
// results, with `endTime`s ocassionally in the following day.
days: 1,
url: ({ date }) => `https://api-web.nhle.com/v1/network/tv-schedule/${date.toJSON().split("T")[0]}`,
parser({ content }) {
const programs = []
const items = parseItems(content)
for (const item of items) {
programs.push({
title: item.title,
description: item.description === item.title ? undefined : item.description,
category: item.title === "NHL Game" ? "Sports event" : "Sports non-event",
// image: parseImage(item),
start: parseStart(item),
stop: parseStop(item)
})
}
return programs
}
}
// Unfortunately I couldn't determine how these are
// supposed to be formatted. Pointers appreciated!
// function parseImage(item) {
// const uri = item.broadcastImageUrl
// return uri ? `https://???/${uri}` : null
// }
function parseStart(item) {
return dayjs(item.startTime)
}
function parseStop(item) {
return dayjs(item.endTime)
}
function parseItems(content) {
return JSON.parse(content).broadcasts
}
+44
View File
@@ -0,0 +1,44 @@
const { parser, url } = require('./nhl.com.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('2024-11-21', 'YYYY-MM-DD').startOf('d')
it('can generate valid url', () => {
expect(url({ date })).toBe(
'https://api-web.nhle.com/v1/network/tv-schedule/2024-11-21'
)
})
it('can parse response', () => {
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.json'))
let results = parser({ content, date })
results = results.map(p => {
p.start = p.start.toJSON()
p.stop = p.stop.toJSON()
return p
})
expect(results[0]).toMatchObject({
start: '2024-11-21T12:00:00.000Z',
stop: '2024-11-21T13:00:00.000Z',
title: 'On The Fly',
category: 'Sports non-event',
})
})
it('can handle empty guide', () => {
const results = parser({ content: JSON.stringify({
// extra props not necessary but they form a valid response
date: "2024-11-21",
startDate: "2024-11-07",
endDate: "2024-12-05",
broadcasts: [],
}) })
expect(results).toMatchObject([])
})
+15
View File
@@ -0,0 +1,15 @@
# nhl.com
https://www.nhl.com/nhl-network/programming-schedule
### Download the guide
```sh
npm run grab -- --site=nhl.com
```
### Test
```sh
npm test -- nhl.com
```