dota-wiki-api
Advanced tools
Comparing version 0.2.0 to 1.0.0
@@ -8,3 +8,3 @@ "use strict"; | ||
const myDotaWikiApi = new index_1.DotaWikiApi(myConfig); | ||
myDotaWikiApi.getTeam('VGJ.Storm') | ||
myDotaWikiApi.getPlayer('Arteezy') | ||
.then((res) => { | ||
@@ -11,0 +11,0 @@ console.log(res); |
import { IRank, IRankKey } from './modules/dpc-rankings'; | ||
import { IPlayer } from './modules/players'; | ||
import { ITeam } from './modules/teams'; | ||
import { ITeam, ITeamMember } from './modules/teams'; | ||
import { IDotaWikiConfig } from './utils/base'; | ||
export { IDotaWikiConfig, IPlayer, IRank, IRankKey, ITeam }; | ||
export { IDotaWikiConfig, IPlayer, IRank, IRankKey, ITeam, ITeamMember }; | ||
export declare class DotaWikiApi { | ||
private dpc; | ||
private dPlayer; | ||
private dTeam; | ||
@@ -14,2 +15,3 @@ constructor(config: IDotaWikiConfig); | ||
getTeam(teamName: string): Promise<ITeam>; | ||
getPlayer(playerName: string): Promise<IPlayer>; | ||
} |
@@ -12,2 +12,3 @@ "use strict"; | ||
const dpc_rankings_1 = require("./modules/dpc-rankings"); | ||
const players_1 = require("./modules/players"); | ||
const teams_1 = require("./modules/teams"); | ||
@@ -17,2 +18,3 @@ class DotaWikiApi { | ||
this.dpc = new dpc_rankings_1.DPCRankings(config); | ||
this.dPlayer = new players_1.DotaPlayers(config); | ||
this.dTeam = new teams_1.DotaTeams(config); | ||
@@ -40,3 +42,8 @@ } | ||
} | ||
getPlayer(playerName) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.dPlayer.getPlayerInfo(playerName); | ||
}); | ||
} | ||
} | ||
exports.DotaWikiApi = DotaWikiApi; |
import { Request, RequestInit } from 'node-fetch'; | ||
export declare class CacheFetch { | ||
urlStub: string; | ||
private apiCache; | ||
private lastFetch; | ||
constructor(useHttps?: boolean); | ||
cacheFetch(url: string | Request, init?: RequestInit): Promise<any>; | ||
checkRedirect(response: any, requestInfo: any): Promise<any>; | ||
fakeFetch(url: string | Request, init?: RequestInit): Promise<any>; | ||
private _canFetchNew(currentTime); | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -6,19 +14,25 @@ const node_fetch_1 = require("node-fetch"); | ||
class CacheFetch { | ||
constructor() { | ||
constructor(useHttps = true) { | ||
this.urlStub = 'https://liquipedia.net/dota2/api.php'; | ||
this.apiCache = {}; | ||
this.lastFetch = new Date('1-1-1970'); | ||
this.urlStub = useHttps | ||
? 'https://liquipedia.net/dota2/api.php' | ||
: 'http://liquipedia.net/dota2/api.php'; | ||
} | ||
cacheFetch(url, init) { | ||
return new Promise((resolve, reject) => { | ||
this._canFetchNew(new Date()) | ||
.then(() => { | ||
node_fetch_1.default(url, init) | ||
.then((res) => { | ||
this.lastFetch = new Date(); | ||
const json = res.json(); | ||
this.apiCache[url.toString()] = json; | ||
resolve(json); | ||
}) | ||
.catch((err) => { | ||
reject(err); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
this._canFetchNew(new Date()) | ||
.then(() => { | ||
node_fetch_1.default(url, init) | ||
.then((res) => { | ||
this.lastFetch = new Date(); | ||
const json = res.json(); | ||
this.apiCache[url.toString()] = json; | ||
resolve(json); | ||
}) | ||
.catch((err) => { | ||
reject(err); | ||
}); | ||
}); | ||
@@ -28,2 +42,34 @@ }); | ||
} | ||
checkRedirect(response, requestInfo) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
if (response.parse.text['*'].indexOf('Redirect to:') !== -1) { | ||
const redirectMatch = /\/dota2\/(.+)(" title)/.exec(response.parse.text['*']); | ||
if (redirectMatch) { | ||
const redirectURL = (redirectMatch[1].indexOf('.') !== -1) | ||
? `${this.urlStub}?action=parse&origin=*&format=json&page=${redirectMatch[1]}&*` | ||
: `${this.urlStub}?action=parse&origin=*&format=json&page=${redirectMatch[1]}`; | ||
this.cacheFetch(redirectURL, requestInfo) | ||
.then((rdJson) => { | ||
resolve(rdJson); | ||
}) | ||
.catch((err) => { | ||
reject(err); | ||
}); | ||
} | ||
else { | ||
reject('Invalid URL. This likely means your page query value is incorrect or has no match'); | ||
} | ||
} | ||
else { | ||
resolve(response); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
}); | ||
} | ||
fakeFetch(url, init) { | ||
@@ -30,0 +76,0 @@ return new Promise((resolve, reject) => { |
@@ -84,3 +84,3 @@ "use strict"; | ||
}; | ||
this.cacheFetch.cacheFetch('http://liquipedia.net/dota2/api.php?action=parse&format=json&page=Dota_Pro_Circuit/Rankings/Teams', requestInfo) | ||
this.cacheFetch.cacheFetch(`${this.cacheFetch.urlStub}?action=parse&format=json&page=Dota_Pro_Circuit/Rankings/Teams`, requestInfo) | ||
.then((json) => { | ||
@@ -87,0 +87,0 @@ resolve(this._parseRanks(json.parse.text['*'])); |
import { Base, IDotaWikiConfig } from '../utils/base'; | ||
export interface IPlayer { | ||
handle: string; | ||
isCaptain: boolean; | ||
joinDate?: string; | ||
name?: string; | ||
photo?: string; | ||
position?: string; | ||
region?: string; | ||
name: string; | ||
photo: string; | ||
position: string[]; | ||
region?: string[]; | ||
birthday?: string; | ||
earnings?: string; | ||
team?: string; | ||
} | ||
export declare class DotaPlayers extends Base { | ||
constructor(config: IDotaWikiConfig); | ||
getPlayerInfo(playerName: string): Promise<any>; | ||
private _parsePlayer(teamHtml, displayTitle); | ||
private _parseBirthday(birthdayText); | ||
private _parseRegions(regionHtml); | ||
private _parseRoles(rolesHtml); | ||
private _trimDate(dateStr); | ||
private _trimName(name); | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const cheerio = require("cheerio"); | ||
const base_1 = require("../utils/base"); | ||
@@ -8,3 +17,113 @@ class DotaPlayers extends base_1.Base { | ||
} | ||
getPlayerInfo(playerName) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
const requestInfo = { | ||
headers: { | ||
'Accept-Encoding': 'gzip', | ||
'User-Agent': this.userAgentValue, | ||
}, | ||
method: 'GET', | ||
}; | ||
const playerNameEncoded = playerName.replace(/ /g, '_'); | ||
const playerUrl = (playerNameEncoded.indexOf('.') !== -1) | ||
? `${this.cacheFetch.urlStub}?action=parse&origin=*&format=json&page=${playerNameEncoded}&*` | ||
: `${this.cacheFetch.urlStub}?action=parse&origin=*&format=json&page=${playerNameEncoded}`; | ||
this.cacheFetch.cacheFetch(playerUrl, requestInfo) | ||
.then((json) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const playerJson = yield this.cacheFetch.checkRedirect(json, requestInfo); | ||
resolve(this._parsePlayer(playerJson.parse.text['*'], playerJson.parse.displaytitle)); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
})) | ||
.catch((err) => { | ||
reject(`Error fetching team list: ${err}`); | ||
}); | ||
}); | ||
}); | ||
} | ||
_parsePlayer(teamHtml, displayTitle) { | ||
const $ = cheerio.load(teamHtml); | ||
const handle = displayTitle; | ||
const playerLogo = `https://liquipedia.net${$('.infobox-image').eq(0).find('img').attr('src')}`; | ||
const potentialTeamBoxes = $('.fo-nttax-infobox-wrapper.infobox-dota2'); | ||
let $playerBox; | ||
for (let i = 0, len = potentialTeamBoxes.length; i < len; i++) { | ||
const teamBoxString = potentialTeamBoxes.eq(i).html(); | ||
if (teamBoxString.indexOf('Player Information') !== -1) { | ||
$playerBox = cheerio.load(teamBoxString); | ||
break; | ||
} | ||
} | ||
const playerInfoBlock = $playerBox('.infobox-cell-2.infobox-description'); | ||
const playerInfoObj = {}; | ||
for (let i = 0, len = playerInfoBlock.length; i < len; i++) { | ||
const block = playerInfoBlock.eq(i); | ||
const blockLabel = block.text(); | ||
switch (blockLabel) { | ||
case 'Name:': | ||
playerInfoObj.name = block.siblings().eq(0).text(); | ||
break; | ||
case 'Country:': | ||
playerInfoObj.region = this._parseRegions(block.siblings().eq(0).html()); | ||
break; | ||
case 'Birth:': | ||
playerInfoObj.birthday = this._parseBirthday(block.siblings().eq(0).text()); | ||
break; | ||
case 'Team:': | ||
playerInfoObj.team = block.siblings().eq(0).text(); | ||
break; | ||
case 'Role(s):': | ||
playerInfoObj.position = this._parseRoles(block.siblings().eq(0).html()); | ||
break; | ||
case 'Approx. Total Earnings:': | ||
playerInfoObj.earnings = block.siblings().eq(0).text(); | ||
break; | ||
} | ||
} | ||
return Object.assign({ handle, photo: playerLogo }, playerInfoObj); | ||
} | ||
_parseBirthday(birthdayText) { | ||
const match = birthdayText.match(/\d{4}(-\d{2}){2}/); | ||
if (match) { | ||
return match[0]; | ||
} | ||
return ''; | ||
} | ||
_parseRegions(regionHtml) { | ||
const regions = []; | ||
const matches = regionHtml.match(/<\/a> <a href="\/dota2\/Category:(\w+)/gm); | ||
for (const match of matches) { | ||
if (match) { | ||
const countryMatch = match.match(/<\/a> <a href="\/dota2\/Category:(\w+)/)[1]; | ||
if (countryMatch) { | ||
regions.push(countryMatch); | ||
} | ||
} | ||
} | ||
return regions; | ||
} | ||
_parseRoles(rolesHtml) { | ||
const roles = []; | ||
const matches = rolesHtml.match(/>(\w+|\w+ \w+)</gm); | ||
for (const match of matches) { | ||
if (match) { | ||
const roleMatch = match.match(/>(\w+|\w+ \w+)</)[1]; | ||
if (roleMatch && roleMatch !== 'Captain') { | ||
roles.push(roleMatch); | ||
} | ||
} | ||
} | ||
return roles; | ||
} | ||
_trimDate(dateStr) { | ||
return dateStr.substr(0, 10); | ||
} | ||
_trimName(name) { | ||
return /\((.+)\)/.exec(name)[1]; | ||
} | ||
} | ||
exports.DotaPlayers = DotaPlayers; |
import { Base, IDotaWikiConfig } from '../utils/base'; | ||
import { IPlayer } from './players'; | ||
export interface ITeam { | ||
name: string; | ||
roster: IPlayer[]; | ||
roster: ITeamMember[]; | ||
teamLogo?: string; | ||
@@ -14,6 +13,13 @@ location?: string; | ||
} | ||
export interface ITeamMember { | ||
handle: string; | ||
isCaptain: boolean; | ||
joinDate: string; | ||
name: string; | ||
position: string; | ||
region: string; | ||
} | ||
export declare class DotaTeams extends Base { | ||
constructor(config: IDotaWikiConfig); | ||
getTeamInfo(teamName: string): Promise<ITeam>; | ||
private _checkRedirect(teamJson, requestInfo); | ||
private _parseTeam(teamHtml, displayTitle); | ||
@@ -20,0 +26,0 @@ private _trimDate(dateStr); |
@@ -29,8 +29,8 @@ "use strict"; | ||
const teamURL = (teamNameEncode.indexOf('.') !== -1) | ||
? `http://liquipedia.net/dota2/api.php?action=parse&origin=*&format=json&page=${teamNameEncode}&*` | ||
: `http://liquipedia.net/dota2/api.php?action=parse&origin=*&format=json&page=${teamNameEncode}`; | ||
? `${this.cacheFetch.urlStub}?action=parse&origin=*&format=json&page=${teamNameEncode}&*` | ||
: `${this.cacheFetch.urlStub}?action=parse&origin=*&format=json&page=${teamNameEncode}`; | ||
this.cacheFetch.cacheFetch(teamURL, requestInfo) | ||
.then((json) => __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
const teamJson = yield this._checkRedirect(json, requestInfo); | ||
const teamJson = yield this.cacheFetch.checkRedirect(json, requestInfo); | ||
resolve(this._parseTeam(teamJson.parse.text['*'], teamJson.parse.displaytitle)); | ||
@@ -48,34 +48,2 @@ } | ||
} | ||
_checkRedirect(teamJson, requestInfo) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
if (teamJson.parse.text['*'].indexOf('Redirect to:') !== -1) { | ||
const redirectMatch = /\/dota2\/(.+)(" title)/.exec(teamJson.parse.text['*']); | ||
if (redirectMatch) { | ||
const redirectURL = (redirectMatch[1].indexOf('.') !== -1) | ||
? `http://liquipedia.net/dota2/api.php?action=parse&origin=*&format=json&page=${redirectMatch[1]}&*` | ||
: `http://liquipedia.net/dota2/api.php?action=parse&origin=*&format=json&page=${redirectMatch[1]}`; | ||
this.cacheFetch.cacheFetch(redirectURL, requestInfo) | ||
.then((rdJson) => { | ||
resolve(rdJson); | ||
}) | ||
.catch((err) => { | ||
reject(err); | ||
}); | ||
} | ||
else { | ||
reject('Invalid URL. This likely means your page query value is incorrect or has no match'); | ||
} | ||
} | ||
else { | ||
resolve(teamJson); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
}); | ||
} | ||
_parseTeam(teamHtml, displayTitle) { | ||
@@ -123,13 +91,15 @@ const $ = cheerio.load(teamHtml); | ||
const roster = []; | ||
for (let i = ROSTER_TABLE_OFFSET, len = rosterTableRows.length; i < len; i++) { | ||
const playerRow = rosterTableRows.eq(i); | ||
const playerObject = { | ||
handle: playerRow.find('.ID').eq(0).find('b a').eq(1).attr('title'), | ||
isCaptain: !!(playerRow.find('.ID > a').eq(0).html()), | ||
joinDate: this._trimDate(playerRow.find('.Date .Date').eq(0).text()), | ||
name: this._trimName(playerRow.find('.Name').eq(0).text()), | ||
position: playerRow.find('.PositionWoTeam2').eq(0).text(), | ||
region: playerRow.find('.ID').eq(0).find('b a').eq(0).attr('title'), | ||
}; | ||
roster.push(playerObject); | ||
if (rosterTableRows.eq(0).text().indexOf('Active Squad') !== -1) { | ||
for (let i = ROSTER_TABLE_OFFSET, len = rosterTableRows.length; i < len; i++) { | ||
const playerRow = rosterTableRows.eq(i); | ||
const playerObject = { | ||
handle: playerRow.find('.ID').eq(0).find('b a').eq(1).attr('title'), | ||
isCaptain: !!(playerRow.find('.ID > a').eq(0).html()), | ||
joinDate: this._trimDate(playerRow.find('.Date .Date').eq(0).text()), | ||
name: this._trimName(playerRow.find('.Name').eq(0).text()), | ||
position: playerRow.find('.PositionWoTeam2').eq(0).text(), | ||
region: playerRow.find('.ID').eq(0).find('b a').eq(0).attr('title'), | ||
}; | ||
roster.push(playerObject); | ||
} | ||
} | ||
@@ -136,0 +106,0 @@ return Object.assign({ name, |
import { CacheFetch } from '../modules/cachefetch'; | ||
export interface IDotaWikiConfig { | ||
userAgentValue: string; | ||
useHttps?: boolean; | ||
} | ||
@@ -5,0 +6,0 @@ export declare class Base { |
@@ -6,6 +6,6 @@ "use strict"; | ||
constructor(config) { | ||
this.cacheFetch = new cachefetch_1.CacheFetch(); | ||
this.userAgentValue = config.userAgentValue; | ||
this.cacheFetch = new cachefetch_1.CacheFetch(!!config.useHttps); | ||
} | ||
} | ||
exports.Base = Base; |
{ | ||
"name": "dota-wiki-api", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "A module to communicate with Liquipedia's Dota 2 Wiki to fetch Team Info, DPC Rankings, Dota Game Schedules, and more!", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
503348
5450
1