-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloader.ts
164 lines (128 loc) · 4.2 KB
/
loader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// tslint:disable-next-line
var console = require("better-console") as Console;
import * as config from "config";
import * as fs from "fs";
import * as http from "http";
import * as jsdom from "jsdom";
const months: string[] = [
"january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december",
];
// Provide teams with a best-guessed colour (from their logo) for graph lines.
const teamColors = config.get("teamColors") as { [teamName: string]: string };
// The end format of the downloaded data.
const data: Rankings = JSON.parse(fs.readFileSync("loader/output.json", "utf8"));
const jquery = fs.readFileSync("./node_modules/jquery/dist/jquery.js", "utf-8");
function loadPageLoop(files) {
const file = files.pop();
const monthName = months[file.month - 1];
let path = "http://www.hltv.org/ranking/teams/";
path += file.year + "/";
path += monthName + "/";
path += file.day + "/";
const dateString = monthName + " " + file.day + ", " + file.year;
const date = new Date(dateString);
console.log("Rankings for " + date.toISOString());
const alreadyLoaded = data.rankings.some((ranking) => {
return ranking.date === dateString;
});
function loadNext() {
if (files.length > 0) {
loadPageLoop(files);
} else {
writeData();
}
}
if (alreadyLoaded) {
console.info("Already loaded");
loadNext();
return;
}
jsdom.env({
done: (err, window) => {
console.log("page loaded");
const ranking = {
date: dateString,
link: path,
ranks: [],
};
data.rankings.push(ranking);
const $ = (window as any).$ as JQueryStatic;
$(".ranking-box .ranking-logo").each((index: number, element: Element) => {
const thisElement = $(element);
const rankNumber = thisElement.find(".ranking-number").text().substring(1);
const teamName = thisElement.find(".ranking-teamName > a").text().trim();
const points = thisElement.find(".ranking-teamName > span").text().match(/([\d]+)/g)[0];
const details = "http://www.hltv.org" + thisElement.find(".ranking-teamName > span > a").attr("href");
const rank = {
link: details,
players: [],
points,
position: rankNumber,
team: teamName,
};
ranking.ranks.push(rank);
thisElement.find(".ranking-lineup .ranking-playerNick > a").each(
(playerIndex: number, playerElement: Element) => {
let playerName = $(playerElement).text().trim();
const playerUrl = "http://www.hltv.org" + $(playerElement).attr("href");
const playerNationality = $(playerElement).find("img").attr("src").match(/\/([a-zA-Z]+).gif$/)[1];
// Some player names (seang@res specifically) break the parsing
if (playerName.length > 30) {
playerName = "Broken_player_name";
}
rank.players.push({
link: playerUrl,
nationality: playerNationality,
player: playerName,
});
},
);
if (!data.teams.some((team) => {
return team.name === teamName;
})) {
const color = teamColors[teamName] || "white";
data.teams.push({
color,
name: teamName,
safeTeamName: teamName.replace(new RegExp("[\. ?!,()/\\\|<>&$%^#*;@+-]", "g"), "_"),
});
}
const numberOfPlayers = rank.players.length;
if (rank.players.length !== 5) {
console.warn(`Team ${teamName} had an unexpected number of players: ${numberOfPlayers}`);
}
});
loadNext();
},
src: [jquery],
url: path,
});
}
function writeData() {
const outputFile = "loader/output.json";
fs.writeFile(
outputFile,
JSON.stringify(data, null, 2),
(error) => {
if (error) {
return console.log(error);
}
console.log("Output written to " + outputFile);
},
);
}
// Dates for which rankings will be downloaded.
type RatingDate = { year: number, month: number, day: number };
const rankingDates = config.get("dates") as RatingDate[];
loadPageLoop(rankingDates);