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

feat: include liveMatches in matches response #94

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"printWidth": 100,
"semi": false,
"singleQuote": true,
"trailingComma": "es5"
"trailingComma": "es5",
"endOfLine":"auto"
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getMatchById } from './match'
import { getMatches } from './matches'
import { getLiveMatchById } from './liveMatch'
import { getResults } from './results'
import { getTopPlayers } from './players'
import { getPlayerById, getPlayersByName } from './player'
Expand All @@ -12,6 +13,7 @@ export default {
getResults,
getMatchById,
getMatches,
getLiveMatchById,
getTopPlayers,
getPlayerById,
getPlayersByName,
Expand Down
158 changes: 158 additions & 0 deletions src/liveMatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import cheerio from 'cheerio'
import fetch from 'node-fetch'
import { CONFIG, USER_AGENT } from './config'

interface IHalfResult {
side: 't' | 'ct'
rounds: number
}

interface IResult {
first: IHalfResult
second: IHalfResult
ext?: number
}

interface IMapTeam {
logo?: string
name: string
result: IResult
}

interface IMap {
name: string
pick: string
teams: IMapTeam[]
}

interface IStats {
name: string
nickname: string
id: number
kills: number
deaths: number
adr: number
kast: number
rating: number
}

interface IEvent {
name: string
logo: string
}

interface ITeam {
name: string
logo: string
result: number
players: IStats[]
}

interface IMatch {
id: number
time: string
event: IEvent
teams: ITeam[]
maps: IMap[]
}

export async function getLiveMatchById(matchId: number): Promise<IMatch> {
const url = `${CONFIG.BASE}/${CONFIG.MATCHES}/${matchId}/_`

try {
const body = await (
await fetch(url, {
headers: { 'User-Agent': USER_AGENT },
})
).text()

const $ = cheerio.load(body, {
normalizeWhitespace: true,
})

const stats1: IStats[] = []
const stats2: IStats[] = []

const mapsEl = $('.mapholder')

const maps: IMap[] = []

mapsEl.each((_, element) => {
const el = $(element)

const mapTeam1: IMapTeam = {
name: el.find('.results-left').find('.results-teamname').text(),
result: {
first: {
side: el.find('.results-center-half-score').children().eq(1).attr('class') as any,
rounds: Number(el.find('.results-center-half-score').children().eq(1).text()),
},
second: {
side: el.find('.results-center-half-score').children().eq(5).attr('class') as any,
rounds: Number(el.find('.results-center-half-score').children().eq(5).text()),
},
ext: Number(el.find('.results-center-half-score').children().eq(11).text()),
},
}

const mapTeam2: IMapTeam = {
name: el.find('.results-right').find('.results-teamname').text(),
result: {
first: {
side: el.find('.results-center-half-score').children().eq(3).attr('class') as any,
rounds: Number(el.find('.results-center-half-score').children().eq(3).text()),
},
second: {
side: el.find('.results-center-half-score').children().eq(7).attr('class') as any,
rounds: Number(el.find('.results-center-half-score').children().eq(7).text()),
},
ext: Number(el.find('.results-center-half-score').children().eq(13).text()),
},
}

maps.push({
name: el.find('.mapname').text(),
pick: el.find('.pick').find('.results-teamname').text(),
teams: [mapTeam1, mapTeam2],
})
})

const timeAndEvent = $('.timeAndEvent')
const time = new Date(timeAndEvent.find('.time').data('unix')).toISOString()
const event = {
name: timeAndEvent.find('.event').find('a').text(),
logo: '',
}

const team1El = $('.teamsBox').children('.team').eq(0)
const team2El = $('.teamsBox').children('.team').eq(1)

const team1: ITeam = {
name: team1El.find('.teamName').text(),
logo: /* istanbul ignore next */ team1El.find('.logo').attr('src')?.includes('https')
? (team1El.find('.logo').attr('src') as string)
: `${CONFIG.BASE}${team1El.find('.logo').attr('src')}`,
result: Number(team1El.find('.team1-gradient').children().last().text()),
players: stats1,
}

const team2: ITeam = {
name: team2El.find('.teamName').text(),
logo: /* istanbul ignore next */ team2El.find('.logo').attr('src')?.includes('https')
? (team2El.find('.logo').attr('src') as string)
: `${CONFIG.BASE}${team2El.find('.logo').attr('src')}`,
result: Number(team2El.find('.team2-gradient').children().last().text()),
players: stats2,
}

return {
id: Number(matchId),
time,
event,
teams: [team1, team2],
maps,
}
} catch (error) {
throw new Error(error as any)
}
}
39 changes: 31 additions & 8 deletions src/matches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ interface IMatch {
stars: number
maps: string
teams: ITeam[]
isLive: boolean
}

export async function getMatches(eventId?: number) {
export async function getMatches(eventId?: number, includeLiveMatches?: boolean) {
const url =
eventId !== undefined
? `${CONFIG.BASE}/events/${eventId}/${CONFIG.MATCHES}`
Expand All @@ -38,20 +39,33 @@ export async function getMatches(eventId?: number) {
normalizeWhitespace: true,
})

const allContent = $('.upcomingMatch')
const selectors = ['.upcomingMatch']
if (includeLiveMatches) {
selectors.push('.liveMatch')
}
const allContent = $(selectors.join(','))
const matches: IMatch[] = []

allContent.map((_i, element) => {
const el = $(element)

const isLive = el.hasClass('liveMatch')
const link = el.children('a').attr('href') as string
const id = Number(link.split('/')[2])
const time = new Date(parseInt(el.find('.matchTime').attr('data-unix')!, 10)).toISOString()

let time
try {
time = new Date(parseInt(el.find('.matchTime').attr('data-unix')!, 10)).toISOString()
} catch (err) {
time = new Date().toISOString()
}
const event: IEvent = {
name: el.find('.matchEventName').text(),
logo: el.find('.matchEventLogo').attr('src') as string,
}
const stars = Number(el.attr('stars'))
const stars = Number(
isLive ? el.find('.matchRating .fa-star:not(.fa-star-faded)').length : el.attr('stars')
)
const map: keyof typeof MAPS = el.find('.matchMeta').text() as any

const teamsEl = el.find('.matchTeams')
Expand All @@ -61,17 +75,25 @@ export async function getMatches(eventId?: number) {
return
}

const team1El = teamsEl.find('.matchTeam.team1')
const team2El = teamsEl.find('.matchTeam.team2')
let team1El
let team2El

if (isLive) {
team1El = teamsEl.find('.matchTeam:first-child')
team2El = teamsEl.find('.matchTeam:last-child')
} else {
team1El = teamsEl.find('.matchTeam.team1')
team2El = teamsEl.find('.matchTeam.team2')
}

const team1 = {
id: Number(el.attr('team1')),
id: Number(isLive ? el.parent().attr('team1') : el.attr('team1')),
name: team1El.find('.matchTeamName').text() || /* istanbul ignore next */ 'n/a',
logo: team1El.find('.matchTeamLogo').attr('src') as string,
}

const team2 = {
id: Number(el.attr('team2')),
id: Number(isLive ? el.parent().attr('team2') : el.attr('team2')),
name: team2El.find('.matchTeamName').text() || 'n/a',
logo: team2El.find('.matchTeamLogo').attr('src') as string,
}
Expand All @@ -83,6 +105,7 @@ export async function getMatches(eventId?: number) {
stars,
maps: MAPS[map] || map,
teams: [team1, team2],
isLive,
}

matches[matches.length] = response
Expand Down
7 changes: 7 additions & 0 deletions website/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 100,
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"endOfLine":"auto"
}
5 changes: 5 additions & 0 deletions website/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export default function Home() {
<a>Stats (by match id)</a>
</Link>
</li>
<li>
<Link href="/api/liveMatch.json">
<a>Live match (by match id)</a>
</Link>
</li>
<li>
<Link href="/api/players.json">
<a>Players</a>
Expand Down
Loading