const { TypeError, Error } = require("../errors");
const { URLs } = require("./Constants");
const cheerio = require("cheerio");
/**
* Parses raw HTML to readable objects
*/
class HTMLParser {
constructor(html, type) {
/**
* The HTML to be parsed
* @type {string}
*/
this.html = html;
/**
* The type to parse
* @type {string}
*/
this.type = type;
}
/**
* Parses the HTML to a readable object
* @return {PlayerData|SquadronData|NewsInfo[]|Wiki[]}
*/
parse() {
switch (this.type.toLowerCase()) {
case "user":
return this.parseUser();
case "clan":
return this.parseClan();
case "news":
return this.parseNews();
case "wiki":
return this.parseWiki();
}
throw new TypeError("INVALID_TYPE");
}
parseUser() { // eslint-disable-line complexity
const $ = cheerio.load(this.html);
if (!$(".user-profile__data-nick").length) throw new TypeError("USER_UNAVAILABLE");
// General profile information
const info = $(".user-profile__data-item"),
planes = $(".profile-score__list-col:nth-child(2) > .profile-score__list-item:not(:first-child)"),
elite = $(".profile-score__list-col:nth-child(3) > .profile-score__list-item:not(:first-child)"),
medals = $(".profile-score__list-col:nth-child(4) > .profile-score__list-item:not(:first-child)"),
avab = $(".profile-stat__list-row:nth-child(1) > .profile-stat__list-ab:nth-child(3) > li:not(:first-child)"),
avrb = $(".profile-stat__list-row:nth-child(1) > .profile-stat__list-rb:nth-child(4) > li:not(:first-child)"),
avsb = $(".profile-stat__list-row:nth-child(1) > .profile-stat__list-sb:nth-child(5) > li:not(:first-child)"),
grab = $(".profile-stat__list-row:nth-child(2) > .profile-stat__list-ab:nth-child(3) > li:not(:first-child)"),
grrb = $(".profile-stat__list-row:nth-child(2) > .profile-stat__list-rb:nth-child(4) > li:not(:first-child)"),
grsb = $(".profile-stat__list-row:nth-child(2) > .profile-stat__list-sb:nth-child(5) > li:not(:first-child)"),
flab = $(".profile-stat__list-row:nth-child(3) > .profile-stat__list-ab:nth-child(3) > li:not(:first-child)"),
flrb = $(".profile-stat__list-row:nth-child(3) > .profile-stat__list-rb:nth-child(4) > li:not(:first-child)"),
flsb = $(".profile-stat__list-row:nth-child(3) > .profile-stat__list-sb:nth-child(5) > li:not(:first-child)"),
abdata = $(".profile-stat__list-ab > .profile-stat__list-item"),
rbdata = $(".profile-stat__list-rb > .profile-stat__list-item"),
sbdata = $(".profile-stat__list-sb > .profile-stat__list-item");
const profile = {
name: $(".user-profile__data-nick").text().trim(),
title: info.eq(0).text().trim().length ? info.eq(0).text().trim() : null,
clan: info.eq(2).length ? { tag: info.eq(1).text().trim(), url: $(".user-profile__data-link").attr("href") } : null,
level: info.eq(2).length ? parseInt(info.eq(2).text().trim()
.split(" ")[1])
: parseInt(info.eq(1).text().trim()
.split(" ")[1]),
avatar: "http:".concat($(".user-profile__ava-img").attr("src")),
registered: $(".user-profile__data-regdate")
.text()
.trim()
.replace(/Registration date\s/, ""),
banned: Boolean($(".user-profile__data-nick--banned").length),
// Country information
usa: {
vehicles: parseInt(planes.eq(0).text().trim()),
elite: parseInt(elite.eq(0).text().trim()),
medals: parseInt(medals.eq(0).text().trim())
},
ussr: {
vehicles: parseInt(planes.eq(1).text().trim()),
elite: parseInt(elite.eq(1).text().trim()),
medals: parseInt(medals.eq(1).text().trim())
},
britain: {
vehicles: parseInt(planes.eq(2).text().trim()),
elite: parseInt(elite.eq(2).text().trim()),
medals: parseInt(medals.eq(2).text().trim())
},
germany: {
vehicles: parseInt(planes.eq(3).text().trim()),
elite: parseInt(elite.eq(3).text().trim()),
medals: parseInt(medals.eq(3).text().trim())
},
japan: {
vehicles: parseInt(planes.eq(4).text().trim()),
elite: parseInt(elite.eq(4).text().trim()),
medals: parseInt(medals.eq(4).text().trim())
},
italy: {
vehicles: parseInt(planes.eq(5).text().trim()),
elite: parseInt(elite.eq(5).text().trim()),
medals: parseInt(medals.eq(5).text().trim())
},
france: {
vehicles: parseInt(planes.eq(6).text().trim()),
elite: parseInt(elite.eq(6).text().trim()),
medals: parseInt(medals.eq(6).text().trim())
}
};
// Stat cards
const stats = {
arcade: {
victories: !isNaN(parseInt(abdata.eq(1).text().trim())) ? parseInt(abdata.eq(1).text().trim()) : null,
completed: !isNaN(
parseInt(abdata.eq(2)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(abdata.eq(2)
.text()
.trim()
.replace(/,/g, "")
) : null,
ratio: abdata.eq(3).text().trim(),
deaths: !isNaN(
parseInt(abdata.eq(4)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(abdata.eq(4)
.text()
.trim()
.replace(/,/g, "")
) : null,
lionsEarned: !isNaN(
parseInt(abdata.eq(5)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(abdata.eq(5)
.text()
.trim()
.replace(/,/g, "")
) : null,
playTime: abdata.eq(6).text().trim(),
airTargetsDestroyed: !isNaN(parseInt(abdata.eq(7).text().trim())) ? parseInt(abdata.eq(7).text().trim()) : null,
groundTargetsDestroyed: !isNaN(parseInt(abdata.eq(8).text().trim())) ? parseInt(abdata.eq(8).text().trim()) : null,
navalTargetsDestroyed: !isNaN(parseInt(abdata.eq(9).text().trim())) ? parseInt(abdata.eq(9).text().trim()) : null,
aviation: {
battles: {
total: !isNaN(avab.eq(0).text().trim()) ? parseInt(avab.eq(0).text().trim()) : null,
fighter: !isNaN(avab.eq(1).text().trim()) ? parseInt(avab.eq(1).text().trim()) : null,
bomber: !isNaN(avab.eq(2).text().trim()) ? parseInt(avab.eq(2).text().trim()) : null,
attacker: !isNaN(avab.eq(3).text().trim()) ? parseInt(avab.eq(3).text().trim()) : null
},
playTime: {
total: avab.eq(4).text().trim() !== "N/A" ? avab.eq(4).text().trim() : null,
fighter: avab.eq(5).text().trim() !== "N/A" ? avab.eq(5).text().trim() : null,
bomber: avab.eq(6).text().trim() !== "N/A" ? avab.eq(6).text().trim() : null,
attacker: avab.eq(7).text().trim() !== "N/A" ? avab.eq(7).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(avab.eq(8).text().trim()) ? parseInt(avab.eq(8).text().trim()) : null,
air: !isNaN(avab.eq(9).text().trim()) ? parseInt(avab.eq(9).text().trim()) : null,
ground: !isNaN(avab.eq(10).text().trim()) ? parseInt(avab.eq(10).text().trim()) : null,
naval: !isNaN(avab.eq(11).text().trim()) ? parseInt(avab.eq(11).text().trim()) : null
}
},
ground: {
battles: {
total: !isNaN(grab.eq(0).text().trim()) ? parseInt(grab.eq(0).text().trim()) : null,
tank: !isNaN(grab.eq(1).text().trim()) ? parseInt(grab.eq(1).text().trim()) : null,
spg: !isNaN(grab.eq(2).text().trim()) ? parseInt(grab.eq(2).text().trim()) : null,
heavy: !isNaN(grab.eq(3).text().trim()) ? parseInt(grab.eq(3).text().trim()) : null,
spaa: !isNaN(grab.eq(4).text().trim()) ? parseInt(grab.eq(4).text().trim()) : null
},
playTime: {
total: grab.eq(5).text().trim() !== "N/A" ? grab.eq(5).text().trim() : null,
tank: grab.eq(6).text().trim() !== "N/A" ? grab.eq(5).text().trim() : null,
spg: grab.eq(7).text().trim() !== "N/A" ? grab.eq(5).text().trim() : null,
heavy: grab.eq(8).text().trim() !== "N/A" ? grab.eq(5).text().trim() : null,
spaa: grab.eq(9).text().trim() !== "N/A" ? grab.eq(5).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(grab.eq(10).text().trim()) ? parseInt(grab.eq(10).text().trim()) : null,
air: !isNaN(grab.eq(11).text().trim()) ? parseInt(grab.eq(11).text().trim()) : null,
ground: !isNaN(grab.eq(12).text().trim()) ? parseInt(grab.eq(12).text().trim()) : null,
naval: !isNaN(grab.eq(13).text().trim()) ? parseInt(grab.eq(13).text().trim()) : null
}
},
fleet: {
battles: {
total: !isNaN(flab.eq(0).text().trim()) ? parseInt(flab.eq(0).text().trim()) : null,
ship: !isNaN(flab.eq(1).text().trim()) ? parseInt(flab.eq(1).text().trim()) : null,
torpedoBoat: !isNaN(flab.eq(2).text().trim()) ? parseInt(flab.eq(2).text().trim()) : null,
gunBoat: !isNaN(flab.eq(3).text().trim()) ? parseInt(flab.eq(3).text().trim()) : null,
torpedoGunBoat: !isNaN(flab.eq(4).text().trim()) ? parseInt(flab.eq(4).text().trim()) : null,
subChaser: !isNaN(flab.eq(5).text().trim()) ? parseInt(flab.eq(5).text().trim()) : null,
destroyer: !isNaN(flab.eq(6).text().trim()) ? parseInt(flab.eq(6).text().trim()) : null,
ferryBarge: !isNaN(flab.eq(7).text().trim()) ? parseInt(flab.eq(7).text().trim()) : null
},
playTime: {
total: flab.eq(8).text().trim() !== "N/A" ? flab.eq(8).text().trim() : null,
ship: flab.eq(9).text().trim() !== "N/A" ? flab.eq(9).text().trim() : null,
torpedoBoat: flab.eq(10).text().trim() !== "N/A" ? flab.eq(10).text().trim() : null,
gunBoat: flab.eq(11).text().trim() !== "N/A" ? flab.eq(11).text().trim() : null,
torpedoGunBoat: flab.eq(12).text().trim() !== "N/A" ? flab.eq(12).text().trim() : null,
subChaser: flab.eq(13).text().trim() !== "N/A" ? flab.eq(13).text().trim() : null,
destroyer: flab.eq(14).text().trim() !== "N/A" ? flab.eq(14).text().trim() : null,
ferryBarge: flab.eq(15).text().trim() !== "N/A" ? flab.eq(15).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(flab.eq(16).text().trim()) ? parseInt(flab.eq(16).text().trim()) : null,
air: !isNaN(flab.eq(17).text().trim()) ? parseInt(flab.eq(17).text().trim()) : null,
ground: !isNaN(flab.eq(18).text().trim()) ? parseInt(flab.eq(18).text().trim()) : null,
naval: !isNaN(flab.eq(19).text().trim()) ? parseInt(flab.eq(19).text().trim()) : null
}
}
},
realistic: {
victories: !isNaN(parseInt(rbdata.eq(1).text().trim())) ? parseInt(rbdata.eq(1).text().trim()) : null,
completed: !isNaN(
parseInt(rbdata.eq(2)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(rbdata.eq(2)
.text()
.trim()
.replace(/,/g, "")
) : null,
ratio: rbdata.eq(3).text().trim(),
deaths: !isNaN(
parseInt(rbdata.eq(4)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(rbdata.eq(4)
.text()
.trim()
.replace(/,/g, "")
) : null,
lionsEarned: !isNaN(
parseInt(rbdata.eq(5)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(rbdata.eq(5)
.text()
.trim()
.replace(/,/g, "")
) : null,
playTime: rbdata.eq(6).text().trim(),
airTargetsDestroyed: !isNaN(parseInt(rbdata.eq(7).text().trim())) ? parseInt(rbdata.eq(7).text().trim()) : null,
groundTargetsDestroyed: !isNaN(parseInt(rbdata.eq(8).text().trim())) ? parseInt(rbdata.eq(8).text().trim()) : null,
navalTargetsDestroyed: !isNaN(parseInt(rbdata.eq(9).text().trim())) ? parseInt(rbdata.eq(9).text().trim()) : null,
aviation: {
battles: {
total: !isNaN(avrb.eq(0).text().trim()) ? parseInt(avrb.eq(0).text().trim()) : null,
fighter: !isNaN(avrb.eq(1).text().trim()) ? parseInt(avrb.eq(1).text().trim()) : null,
bomber: !isNaN(avrb.eq(2).text().trim()) ? parseInt(avrb.eq(2).text().trim()) : null,
attacker: !isNaN(avrb.eq(3).text().trim()) ? parseInt(avrb.eq(3).text().trim()) : null
},
playTime: {
total: avrb.eq(4).text().trim() !== "N/A" ? avrb.eq(4).text().trim() : null,
fighter: avrb.eq(5).text().trim() !== "N/A" ? avrb.eq(5).text().trim() : null,
bomber: avrb.eq(6).text().trim() !== "N/A" ? avrb.eq(6).text().trim() : null,
attacker: avrb.eq(7).text().trim() !== "N/A" ? avrb.eq(7).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(avrb.eq(8).text().trim()) ? parseInt(avrb.eq(8).text().trim()) : null,
air: !isNaN(avrb.eq(9).text().trim()) ? parseInt(avrb.eq(9).text().trim()) : null,
ground: !isNaN(avrb.eq(10).text().trim()) ? parseInt(avrb.eq(10).text().trim()) : null,
naval: !isNaN(avrb.eq(11).text().trim()) ? parseInt(avrb.eq(11).text().trim()) : null
}
},
ground: {
battles: {
total: !isNaN(grrb.eq(0).text().trim()) ? parseInt(grrb.eq(0).text().trim()) : null,
tank: !isNaN(grrb.eq(1).text().trim()) ? parseInt(grrb.eq(1).text().trim()) : null,
spg: !isNaN(grrb.eq(2).text().trim()) ? parseInt(grrb.eq(2).text().trim()) : null,
heavy: !isNaN(grrb.eq(3).text().trim()) ? parseInt(grrb.eq(3).text().trim()) : null,
spaa: !isNaN(grrb.eq(4).text().trim()) ? parseInt(grrb.eq(4).text().trim()) : null
},
playTime: {
total: grrb.eq(5).text().trim() !== "N/A" ? grrb.eq(5).text().trim() : null,
tank: grrb.eq(6).text().trim() !== "N/A" ? grrb.eq(6).text().trim() : null,
spg: grrb.eq(7).text().trim() !== "N/A" ? grrb.eq(7).text().trim() : null,
heavy: grrb.eq(8).text().trim() !== "N/A" ? grrb.eq(8).text().trim() : null,
spaa: grrb.eq(9).text().trim() !== "N/A" ? grrb.eq(9).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(grrb.eq(10).text().trim()) ? parseInt(grrb.eq(10).text().trim()) : null,
air: !isNaN(grrb.eq(11).text().trim()) ? parseInt(grrb.eq(11).text().trim()) : null,
ground: !isNaN(grrb.eq(12).text().trim()) ? parseInt(grrb.eq(12).text().trim()) : null,
naval: !isNaN(grrb.eq(13).text().trim()) ? parseInt(grrb.eq(13).text().trim()) : null
}
},
fleet: {
battles: {
total: !isNaN(flrb.eq(0).text().trim()) ? parseInt(flrb.eq(0).text().trim()) : null,
ship: !isNaN(flrb.eq(1).text().trim()) ? parseInt(flrb.eq(1).text().trim()) : null,
torpedoBoat: !isNaN(flrb.eq(2).text().trim()) ? parseInt(flrb.eq(2).text().trim()) : null,
gunBoat: !isNaN(flrb.eq(3).text().trim()) ? parseInt(flrb.eq(3).text().trim()) : null,
torpedoGunBoat: !isNaN(flrb.eq(4).text().trim()) ? parseInt(flrb.eq(4).text().trim()) : null,
subChaser: !isNaN(flrb.eq(5).text().trim()) ? parseInt(flrb.eq(5).text().trim()) : null,
destroyer: !isNaN(flrb.eq(6).text().trim()) ? parseInt(flrb.eq(6).text().trim()) : null,
ferryBarge: !isNaN(flrb.eq(7).text().trim()) ? parseInt(flrb.eq(7).text().trim()) : null
},
playTime: {
total: flrb.eq(8).text().trim() !== "N/A" ? flrb.eq(8).text().trim() : null,
ship: flrb.eq(9).text().trim() !== "N/A" ? flrb.eq(9).text().trim() : null,
torpedoBoat: flrb.eq(10).text().trim() !== "N/A" ? flrb.eq(10).text().trim() : null,
gunBoat: flrb.eq(11).text().trim() !== "N/A" ? flrb.eq(11).text().trim() : null,
torpedoGunBoat: flrb.eq(12).text().trim() !== "N/A" ? flrb.eq(12).text().trim() : null,
subChaser: flrb.eq(13).text().trim() !== "N/A" ? flrb.eq(13).text().trim() : null,
destroyer: flrb.eq(14).text().trim() !== "N/A" ? flrb.eq(14).text().trim() : null,
ferryBarge: flrb.eq(15).text().trim() !== "N/A" ? flrb.eq(15).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(flrb.eq(16).text().trim()) ? parseInt(flrb.eq(16).text().trim()) : null,
air: !isNaN(flrb.eq(17).text().trim()) ? parseInt(flrb.eq(17).text().trim()) : null,
ground: !isNaN(flrb.eq(18).text().trim()) ? parseInt(flrb.eq(18).text().trim()) : null,
naval: !isNaN(flrb.eq(19).text().trim()) ? parseInt(flrb.eq(19).text().trim()) : null
}
}
},
simulator: {
victories: !isNaN(parseInt(sbdata.eq(1).text().trim())) ? parseInt(sbdata.eq(1).text().trim()) : null,
completed: !isNaN(
parseInt(sbdata.eq(2)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(sbdata.eq(2)
.text()
.trim()
.replace(/,/g, "")
) : null,
ratio: sbdata.eq(3).text().trim(),
deaths: !isNaN(
parseInt(sbdata.eq(4)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(sbdata.eq(4)
.text()
.trim()
.replace(/,/g, "")
) : null,
lionsEarned: !isNaN(
parseInt(sbdata.eq(5)
.text()
.trim()
.replace(/,/g, "")
)
) ? parseInt(sbdata.eq(5)
.text()
.trim()
.replace(/,/g, "")
) : null,
playTime: sbdata.eq(6).text().trim(),
airTargetsDestroyed: !isNaN(parseInt(sbdata.eq(7).text().trim())) ? parseInt(sbdata.eq(7).text().trim()) : null,
groundTargetsDestroyed: !isNaN(parseInt(sbdata.eq(8).text().trim())) ? parseInt(sbdata.eq(8).text().trim()) : null,
navalTargetsDestroyed: !isNaN(parseInt(sbdata.eq(9).text().trim())) ? parseInt(sbdata.eq(9).text().trim()) : null,
aviation: {
battles: {
total: !isNaN(avsb.eq(0).text().trim()) ? parseInt(avsb.eq(0).text().trim()) : null,
fighter: !isNaN(avsb.eq(1).text().trim()) ? parseInt(avsb.eq(1).text().trim()) : null,
bomber: !isNaN(avsb.eq(2).text().trim()) ? parseInt(avsb.eq(2).text().trim()) : null,
attacker: !isNaN(avsb.eq(3).text().trim()) ? parseInt(avsb.eq(3).text().trim()) : null
},
playTime: {
total: avsb.eq(4).text().trim() !== "N/A" ? avsb.eq(4).text().trim() : null,
fighter: avsb.eq(5).text().trim() !== "N/A" ? avsb.eq(5).text().trim() : null,
bomber: avsb.eq(6).text().trim() !== "N/A" ? avsb.eq(6).text().trim() : null,
attacker: avsb.eq(7).text().trim() !== "N/A" ? avsb.eq(7).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(avsb.eq(8).text().trim()) ? parseInt(avsb.eq(8).text().trim()) : null,
air: !isNaN(avsb.eq(9).text().trim()) ? parseInt(avsb.eq(9).text().trim()) : null,
ground: !isNaN(avsb.eq(10).text().trim()) ? parseInt(avsb.eq(10).text().trim()) : null,
naval: !isNaN(avsb.eq(11).text().trim()) ? parseInt(avsb.eq(11).text().trim()) : null
}
},
ground: {
battles: {
total: !isNaN(grsb.eq(0).text().trim()) ? parseInt(grsb.eq(0).text().trim()) : null,
tank: !isNaN(grsb.eq(1).text().trim()) ? parseInt(grsb.eq(1).text().trim()) : null,
spg: !isNaN(grsb.eq(2).text().trim()) ? parseInt(grsb.eq(2).text().trim()) : null,
heavy: !isNaN(grsb.eq(3).text().trim()) ? parseInt(grsb.eq(3).text().trim()) : null,
spaa: !isNaN(grsb.eq(4).text().trim()) ? parseInt(grsb.eq(4).text().trim()) : null
},
playTime: {
total: grsb.eq(5).text().trim() !== "N/A" ? grsb.eq(5).text().trim() : null,
tank: grsb.eq(6).text().trim() !== "N/A" ? grsb.eq(6).text().trim() : null,
spg: grsb.eq(7).text().trim() !== "N/A" ? grsb.eq(7).text().trim() : null,
heavy: grsb.eq(8).text().trim() !== "N/A" ? grsb.eq(8).text().trim() : null,
spaa: grsb.eq(9).text().trim() !== "N/A" ? grsb.eq(9).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(grsb.eq(10).text().trim()) ? parseInt(grsb.eq(10).text().trim()) : null,
air: !isNaN(grsb.eq(11).text().trim()) ? parseInt(grsb.eq(11).text().trim()) : null,
ground: !isNaN(grsb.eq(12).text().trim()) ? parseInt(grsb.eq(12).text().trim()) : null,
naval: !isNaN(grsb.eq(13).text().trim()) ? parseInt(grsb.eq(13).text().trim()) : null
}
},
fleet: {
battles: {
total: !isNaN(flsb.eq(0).text().trim()) ? parseInt(flsb.eq(0).text().trim()) : null,
ship: !isNaN(flsb.eq(1).text().trim()) ? parseInt(flsb.eq(1).text().trim()) : null,
torpedoBoat: !isNaN(flsb.eq(2).text().trim()) ? parseInt(flsb.eq(2).text().trim()) : null,
gunBoat: !isNaN(flsb.eq(3).text().trim()) ? parseInt(flsb.eq(3).text().trim()) : null,
torpedoGunBoat: !isNaN(flsb.eq(4).text().trim()) ? parseInt(flsb.eq(4).text().trim()) : null,
subChaser: !isNaN(flsb.eq(5).text().trim()) ? parseInt(flsb.eq(5).text().trim()) : null,
destroyer: !isNaN(flsb.eq(6).text().trim()) ? parseInt(flsb.eq(6).text().trim()) : null,
ferryBarge: !isNaN(flsb.eq(7).text().trim()) ? parseInt(flsb.eq(7).text().trim()) : null
},
playTime: {
total: flsb.eq(8).text().trim() !== "N/A" ? flsb.eq(8).text().trim() : null,
ship: flsb.eq(9).text().trim() !== "N/A" ? flsb.eq(9).text().trim() : null,
torpedoBoat: flsb.eq(10).text().trim() !== "N/A" ? flsb.eq(10).text().trim() : null,
gunBoat: flsb.eq(11).text().trim() !== "N/A" ? flsb.eq(11).text().trim() : null,
torpedoGunBoat: flsb.eq(12).text().trim() !== "N/A" ? flsb.eq(12).text().trim() : null,
subChaser: flsb.eq(13).text().trim() !== "N/A" ? flsb.eq(13).text().trim() : null,
destroyer: flsb.eq(14).text().trim() !== "N/A" ? flsb.eq(14).text().trim() : null,
ferryBarge: flsb.eq(15).text().trim() !== "N/A" ? flsb.eq(15).text().trim() : null
},
targetsDestroyed: {
total: !isNaN(flsb.eq(16).text().trim()) ? parseInt(flsb.eq(16).text().trim()) : null,
air: !isNaN(flsb.eq(17).text().trim()) ? parseInt(flsb.eq(17).text().trim()) : null,
ground: !isNaN(flsb.eq(18).text().trim()) ? parseInt(flsb.eq(18).text().trim()) : null,
naval: !isNaN(flsb.eq(19).text().trim()) ? parseInt(flsb.eq(19).text().trim()) : null
}
}
}
};
return {
profile,
stats
};
}
parseClan() {
const $ = cheerio.load(this.html);
const nameArr = $(".username").text().trim().split(" "),
tag = nameArr.shift().replace("[", "").replace("]", "").trim(),
name = nameArr.join(" ");
if (!name.length) throw new TypeError("NOT_FOUND", "clan");
const _info = $(".clan-info > tbody > tr:nth-child(1) > td > div").children();
const stats = $(".clan-info > tbody > tr:not(:first-child)").slice(2);
const members = $(".clan-members > tbody:nth-child(1) > tr").slice(2);
const arr = [];
members.each((index, element) => {
/**
* Represents info about a squadron member
* @typedef {Object} ClanMember
* @property {string} name The in-game name of the squadron member
* @property {ClanRating} rating The rating for the squadron member, per difficulty
* @property {string} role The squadron member's role
* @property {string} entry The date of entry for the squadron member
*/
const obj = {
name: $(element).children().eq(1).text().trim(),
/**
* Represents information about the member's personal squadron rating
* @typedef {Object} ClanRating
* @property {number} arcade The member's rating for Squadron Arcade Events
* @property {number} realistic The member's rating for Squadron Realistic Events
* @property {number} simulator The member's rating for Squadron Simulator Events
*/
rating: {
arcade: parseInt($(element)
.children()
.eq(2)
.text()
.trim()),
realistic: parseInt($(element)
.children()
.eq(3)
.text()
.trim()),
simulator: parseInt($(element)
.children()
.eq(4)
.text()
.trim())
},
role: $(element).children().eq(5).text().trim(),
entry: $(element).children().eq(6).text().trim()
};
arr.push(obj);
});
/**
* Represents raw squadron data
* @typedef {Object} ClanData
* @property {string} name The squadron name
* @property {string} image The URL to the squadron's in-game picture
* @property {number} players The amount of players in the squadron
* @property {string} description The squadron's description
* @property {string} created The date of creation for the squadron
* @property {ClanStats} stats The statistics for the squadron per difficulty for SQB
* @property {ClanMember[]} members Info for each squadron member
*/
const obj = {
name,
tag,
image: `http:${_info.eq(0).attr("src")}`,
players: parseInt(_info.eq(2).text().replace("Number of players:", "").trim()),
description: _info.eq(3).text().trim(),
created: _info.eq(4).text().replace("date of creation:", "").trim(),
/**
* Represents the statistics for the squadron per difficulty for SRE
* @typedef {Object} ClanStats
* @property {SQBStats} arcade The info for the Arcade gamemode
* @property {SQBStats} realistic The info for the Realistic gamemode
* @property {SQBStats} simulator The info for the Simulator gamemode
*/
stats: {
/**
* Represents statistics for a Squadron Event per difficulty
* @typedef {Object} SQBStats
* @property {number} airTargetsDestroyed The total amount of air targets destroyed
* @property {number} groundTargetsDestroyed The total amount of ground targets destroyed
* @property {number} deaths The total amount of deaths
* @property {string} battleTime The total amount of battle time
*/
arcade: {
airTargetsDestroyed: parseInt(stats.eq(0).children().eq(1).text().trim()),
groundTargetsDestroyed: parseInt(stats.eq(0).children().eq(2).text().trim()),
deaths: parseInt(stats.eq(0).children().eq(3).text().trim()),
battleTime: stats.eq(0).children().eq(4).text()
},
realistic: {
airTargetsDestroyed: parseInt(stats.eq(2).children().eq(1).text().trim()),
groundTargetsDestroyed: parseInt(stats.eq(2).children().eq(2).text().trim()),
deaths: parseInt(stats.eq(2).children().eq(3).text().trim()),
battleTime: stats.eq(2).children().eq(4).text()
},
simulator: {
airTargetsDestroyed: parseInt(stats.eq(4).children().eq(1).text().trim()),
groundTargetsDestroyed: parseInt(stats.eq(4).children().eq(2).text().trim()),
deaths: parseInt(stats.eq(4).children().eq(3).text().trim()),
battleTime: stats.eq(4).children().eq(4).text()
}
},
members: arr
};
return obj;
}
parseNews() {
const $ = cheerio.load(this.html);
const elements = $(".news_item");
const data = [];
elements.each((index, element) => {
const item_ = $(element);
/**
* Represents a War Thunder news item
* @typedef {Object} NewsInfo
* @property {string} url The URL to the news/changelog page
* @property {string} title The title of the news/update
* @property {string} date The date the news was announced/the update was released
*/
const item = {
url: item_.children().eq(1).children().eq(0).attr("href"),
title: item_.children().eq(1).children().eq(0).text()
.split(" ")
.join(" "),
// eslint-disable-next-line max-len
date: item_.children().eq(0).text()
};
data.push(item);
});
return data;
}
parseWiki() {
const $ = cheerio.load(this.html);
if ($(".mw-search-nonefound").length) throw new Error("NOT_FOUND", "wiki");
const results = $(".mw-search-results").eq(0);
const data = [];
results.children().each((index, element) => { // eslint-disable-line consistent-return
const result = $(element);
const child = result.children().eq(0);
/**
* Represents a War Thunder Wiki search result
* @typedef {Object} wiki
* @property {string} title The title of the search result's page
* @property {string} url The URL to the search result's page
* @property {Boolean} main If there is a page named as the search query on the Wiki
*/
const obj = {
title: child.text().trim(),
url: `${URLs.wiki}${child.children().eq(0).attr("href")}`,
main: false
};
if (data[0] && data[0].title === obj.title) return true;
data.push(obj);
});
return data;
}
}
module.exports = HTMLParser;