From 08d6d22fb3999f16b733cbf9f6870dec63258410 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 14 Jun 2019 18:26:26 -0400 Subject: [PATCH] Add getActivityPage --- src/hiscores.ts | 65 ++++++++++++++++++++++++++++++++++---------- src/types.ts | 3 +- src/utils/helpers.ts | 15 ++++++++-- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/hiscores.ts b/src/hiscores.ts index 88c0e64..e5eea68 100644 --- a/src/hiscores.ts +++ b/src/hiscores.ts @@ -10,22 +10,24 @@ import { BH as BHStats, Clues, Gamemode, - Category, SkillName, PlayerSkillRow, + ActivityName, + PlayerActivityRow, } from './types'; import { getStatsURL, SKILLS, - BH, + BH_MODES, CLUES, MODES, getPlayerTableURL, getSkillPageURL, GAMEMODES, - OTHER, + ACTIVITIES, numberFromElement, rsnFromElement, + getActivityPageURL, } from './utils'; export async function getStats( @@ -115,11 +117,11 @@ export async function getStats( } } -export const getSkillPage = async ( - mode: Gamemode, +export async function getSkillPage( skill: SkillName, - page: number -): Promise => { + mode: Gamemode = 'main', + page: number = 1 +): Promise { if (!GAMEMODES.includes(mode)) { throw Error('Invalid game mode'); } else if (!Number.isInteger(page) || page < 1) { @@ -148,11 +150,44 @@ export const getSkillPage = async ( }); return players; -}; +} -export const getRSNFormat = async (rsn: string): Promise => { +export async function getActivityPage( + activity: ActivityName, + mode: Gamemode = 'main', + page: number = 1 +): Promise { + if (!GAMEMODES.includes(mode)) { + throw Error('Invalid game mode'); + } else if (!Number.isInteger(page) || page < 1) { + throw Error('Page must be an integer greater than 0'); + } else if (!ACTIVITIES.includes(activity)) { + throw Error('Invalid activity'); + } + const url = getActivityPageURL(mode, activity, page); + + const response = await axios(url); + const $ = cheerio.load(response.data); + const playersHTML = $('.personal-hiscores__row').toArray(); + + const players: PlayerActivityRow[] = playersHTML.map(row => { + const cells = row.children.filter(el => el.name === 'td'); + const [rankEl, nameCell, scoreEl] = cells; + const [nameEl] = nameCell.children.filter(el => el.name === 'a'); + + return { + rsn: rsnFromElement(nameEl), + rank: numberFromElement(rankEl), + score: numberFromElement(scoreEl), + dead: nameCell.children.length === 4, + }; + }); + + return players; +} + +export async function getRSNFormat(rsn: string): Promise { const url = getPlayerTableURL('main', rsn); - try { const response = await axios(url); const $ = cheerio.load(response.data); @@ -164,9 +199,9 @@ export const getRSNFormat = async (rsn: string): Promise => { } catch { throw Error('Player not found'); } -}; +} -export const parseStats = (csv: string): Stats => { +export function parseStats(csv: string): Stats { const splitCSV = csv .split('\n') .filter(entry => !!entry) @@ -193,7 +228,7 @@ export const parseStats = (csv: string): Stats => { return activity; }); - const bhObjects = activityObjects.splice(0, BH.length); + const bhObjects = activityObjects.splice(0, BH_MODES.length); const [lms] = activityObjects.splice(0, 1); const clueObjects = activityObjects.splice(0, CLUES.length); @@ -209,7 +244,7 @@ export const parseStats = (csv: string): Stats => { const bh: BHStats = bhObjects.reduce( (prev, curr, index) => { const newBH = { ...prev }; - newBH[BH[index]] = curr; + newBH[BH_MODES[index]] = curr; return newBH; }, {} as BHStats @@ -232,4 +267,4 @@ export const parseStats = (csv: string): Stats => { }; return stats; -}; +} diff --git a/src/types.ts b/src/types.ts index 26db078..f55676d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -56,8 +56,7 @@ export type BHType = 'rogue' | 'hunter'; export type BH = { [Type in BHType]: Activity }; -export type Category = - | SkillName +export type ActivityName = | 'hunterbh' | 'roguebh' | 'lms' diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 498dbe9..b211995 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -1,11 +1,11 @@ -import { Gamemode, Category, SkillName } from '../types'; +import { Gamemode, SkillName, ActivityName } from '../types'; import { BASE_URL, GAMEMODE_URL, STATS_URL, SCORES_URL, SKILLS, - OTHER, + ACTIVITIES, } from './constants'; export const getStatsURL = (gamemode: Gamemode, rsn: string) => @@ -25,6 +25,17 @@ export const getSkillPageURL = ( skill )}&page=${page}`; +export const getActivityPageURL = ( + gamemode: Gamemode, + activity: ActivityName, + page: number +) => + `${BASE_URL}${ + GAMEMODE_URL[gamemode] + }${SCORES_URL}category_type=1&table=${ACTIVITIES.indexOf( + activity + )}&page=${page}`; + export const numberFromElement = (el: CheerioElement) => { const innerText = el.firstChild.data; const number = innerText ? innerText.replace(/[\n|,]/g, '') : '-1';