Add getSkillPage

This commit is contained in:
Max
2019-06-14 17:02:52 -04:00
parent 9ea736e3ff
commit 6e0bb2aebc
4 changed files with 184 additions and 60 deletions

View File

@@ -1,4 +1,5 @@
import { parseStats, getRSNFormat } from '../src/index'; import { parseStats, getRSNFormat, getSkillPage } from '../src/index';
import { PlayerSkillRow } from '../src/types';
test('Parse CSV to json', () => { test('Parse CSV to json', () => {
const csv = `40258,2063,218035714 const csv = `40258,2063,218035714
@@ -88,3 +89,122 @@ test('Get rsn format', async done => {
getRSNFormat('lYnX tiTaN').then(callback); getRSNFormat('lYnX tiTaN').then(callback);
}); });
test('Get attack top page', async done => {
const callback = (data: PlayerSkillRow[]) => {
expect(data).toStrictEqual([
{ rsn: 'Heur', rank: 1, level: 99, xp: 200000000, dead: false },
{
rsn: 'Unohdettu2',
rank: 2,
level: 99,
xp: 200000000,
dead: false,
},
{ rsn: 'Drakon', rank: 3, level: 99, xp: 200000000, dead: false },
{
rsn: 'Ame Umehara',
rank: 4,
level: 99,
xp: 200000000,
dead: false,
},
{ rsn: 'Jakee', rank: 5, level: 99, xp: 200000000, dead: false },
{ rsn: 'Hitsuji', rank: 6, level: 99, xp: 200000000, dead: false },
{ rsn: 'Howson', rank: 7, level: 99, xp: 200000000, dead: false },
{ rsn: 'Dr PFAFF', rank: 8, level: 99, xp: 200000000, dead: false },
{
rsn: 'Malt Lickeys',
rank: 9,
level: 99,
xp: 200000000,
dead: false,
},
{ rsn: 'Burned', rank: 10, level: 99, xp: 200000000, dead: false },
{
rsn: 'Blue Limes',
rank: 11,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'Mini Finbarr',
rank: 12,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'Unohdettu3',
rank: 13,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'Eslihero',
rank: 14,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'Lynx Titan',
rank: 15,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'AndrewWigins',
rank: 16,
level: 99,
xp: 200000000,
dead: false,
},
{ rsn: 'iMelee', rank: 17, level: 99, xp: 200000000, dead: false },
{
rsn: 'Portuguese',
rank: 18,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'MarkoOSRS',
rank: 19,
level: 99,
xp: 200000000,
dead: false,
},
{ rsn: 'Cairo', rank: 20, level: 99, xp: 200000000, dead: false },
{
rsn: 'Hey Jase',
rank: 21,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'Sleighur',
rank: 22,
level: 99,
xp: 200000000,
dead: false,
},
{
rsn: 'KMSat200mALL',
rank: 23,
level: 99,
xp: 200000000,
dead: false,
},
{ rsn: 'Yumemi', rank: 24, level: 99, xp: 200000000, dead: false },
{ rsn: 'Fiiggy', rank: 25, level: 99, xp: 200000000, dead: false },
]);
done();
};
getSkillPage('main', 'attack', 1).then(callback);
});

View File

@@ -11,6 +11,8 @@ import {
Clues, Clues,
Gamemode, Gamemode,
Category, Category,
SkillName,
PlayerSkillRow,
} from './types'; } from './types';
import { import {
getStatsURL, getStatsURL,
@@ -19,9 +21,11 @@ import {
CLUES, CLUES,
MODES, MODES,
getPlayerTableURL, getPlayerTableURL,
getHiscoresPageURL, getSkillPageURL,
GAMEMODES, GAMEMODES,
OTHER, OTHER,
numberFromElement,
rsnFromElement,
} from './utils'; } from './utils';
export async function getStats( export async function getStats(
@@ -111,59 +115,42 @@ export async function getStats(
} }
} }
// export async function getHiscores( export const getSkillPage = async (
// mode: Gamemode, mode: Gamemode,
// category: Category, skill: SkillName,
// page: number page: number
// ) { ): Promise<PlayerSkillRow[]> => {
// if (GAMEMODES.includes(mode) || mode.toLowerCase() === 'full') { if (!GAMEMODES.includes(mode)) {
// throw Error('Invalid game mode'); throw Error('Invalid game mode');
// } else if (!Number.isInteger(page) || page < 1) { } else if (!Number.isInteger(page) || page < 1) {
// throw Error('Page must be an integer greater than 0'); throw Error('Page must be an integer greater than 0');
// } else if ([...SKILLS, ...OTHER].includes(category)) { } else if (!SKILLS.includes(skill)) {
// throw Error('Invalid category'); throw Error('Invalid skill');
// } }
// const url = getHiscoresPageURL(mode, category, page); const url = getSkillPageURL(mode, skill, page);
// const players = []; const response = await axios(url);
// const response = await axios(url); const $ = cheerio.load(response.data);
// const $ = cheerio.load(response.data); const playersHTML = $('.personal-hiscores__row').toArray();
// const playersHTML = $('.personal-hiscores__row').toArray();
// for (const player of playersHTML) { const players: PlayerSkillRow[] = playersHTML.map(row => {
// const attributes = player.children.filter(node => node.name === 'td'); const cells = row.children.filter(el => el.name === 'td');
const [rankEl, nameCell, levelEl, xpEl] = cells;
const [nameEl] = nameCell.children.filter(el => el.name === 'a');
// let playerInfo = { return {
// mode, rsn: rsnFromElement(nameEl),
// category, rank: numberFromElement(rankEl),
// rank: (attributes[0].children[0].data || '').slice(1, -1), level: numberFromElement(levelEl),
// rsn: (attributes[1].children[1].children[0].data || '').replace( xp: numberFromElement(xpEl),
// /\uFFFD/g, dead: nameCell.children.length === 4,
// ' ' };
// ), });
// };
// SKILLS.includes(category) return players;
// ? (playerInfo = Object.assign( };
// {
// level: attributes[2].children[0].data.slice(1, -1),
// xp: attributes[3].children[0].data.slice(1, -1),
// },
// playerInfo
// ))
// : (playerInfo.score = attributes[2].children[0].data.slice(1, -1));
// if (mode === 'hc') { export const getRSNFormat = async (rsn: string): Promise<string> => {
// playerInfo.dead = attributes[1].children.length > 1;
// }
// players.push(playerInfo);
// }
// return players;
// }
export const getRSNFormat = async (rsn: string) => {
const url = getPlayerTableURL('main', rsn); const url = getPlayerTableURL('main', rsn);
try { try {

View File

@@ -85,3 +85,13 @@ export interface Player extends Modes {
deulted: boolean; deulted: boolean;
deironed: boolean; deironed: boolean;
} }
export interface PlayerSkillRow extends Skill {
rsn: string;
dead: boolean;
}
export interface PlayerActivityRow extends Activity {
rsn: string;
dead: boolean;
}

View File

@@ -1,4 +1,4 @@
import { Gamemode, Category } from '../types'; import { Gamemode, Category, SkillName } from '../types';
import { import {
BASE_URL, BASE_URL,
GAMEMODE_URL, GAMEMODE_URL,
@@ -16,15 +16,22 @@ export const getPlayerTableURL = (gamemode: Gamemode, rsn: string) =>
GAMEMODE_URL[gamemode] GAMEMODE_URL[gamemode]
}${SCORES_URL}table=0&user=${encodeURIComponent(rsn)}`; }${SCORES_URL}table=0&user=${encodeURIComponent(rsn)}`;
export const getHiscoresPageURL = ( export const getSkillPageURL = (
gamemode: Gamemode, gamemode: Gamemode,
category: Category, skill: SkillName,
page: number page: number
) => { ) =>
const table = [...SKILLS, ...OTHER]; `${BASE_URL}${GAMEMODE_URL[gamemode]}${SCORES_URL}table=${SKILLS.indexOf(
return `${BASE_URL}${GAMEMODE_URL[gamemode]}${SCORES_URL}${ skill
table.includes(category) )}&page=${page}`;
? `table=${table.indexOf(category)}`
: `category_type=1&table=${OTHER.indexOf(category)}` export const numberFromElement = (el: CheerioElement) => {
}&page=${page}`; const innerText = el.firstChild.data;
const number = innerText ? innerText.replace(/[\n|,]/g, '') : '-1';
return parseInt(number, 10);
};
export const rsnFromElement = (el: CheerioElement) => {
const innerText = el.firstChild.data;
return innerText ? innerText.replace(/\uFFFD/g, ' ') : '';
}; };