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
|
#!/usr/bin/env node
/* jshint esnext: true */
"use strict";
const Promise = require("bluebird"),
request = require("request-promise"),
sleep = require("sleep-promise"),
jsonapi = require("./jsonapi");
const MADGLORY_TOKEN = process.env.MADGLORY_TOKEN;
if (MADGLORY_TOKEN == undefined) throw "Need an API token";
const api = module.exports;
// send a request to url with options, log data about it
// return [jsonapi parsed data, jsonapi links]
module.exports.request = async (url, options, logger) => {
let response;
while (true) {
try {
const opts = {
uri: url,
headers: {
"X-Title-Id": "semc-vainglory",
"Authorization": MADGLORY_TOKEN
},
qs: options,
json: true,
gzip: true,
time: true,
forever: true,
strictSSL: true,
resolveWithFullResponse: true
};
logger.info("API request", {
uri: opts.uri,
qs: opts.qs
});
response = await request(opts);
return [jsonapi.parse(response.body), response.body.links];
} catch (err) {
response = err.response;
if (err.statusCode == 429) {
logger.warn("rate limited, sleeping");
await sleep(100); // no return, no break => retry
continue;
} else if (err.statusCode != 404) {
logger.error("API error, retrying", err);
await sleep(100);
continue;
}
logger.warn("not found", {
uri: err.options.uri,
qs: err.options.qs,
error: err.response.body
});
return [undefined, undefined];
} finally {
logger.info("API response", {
status: response.statusCode,
connection_start: response.timings.connect,
connection_end: response.timings.end,
ratelimit_remaining: parseInt(response.headers["x-ratelimit-remaining"])
});
}
}
}
// loop over all pages, yield jsonapi parsed data results
// TODO make it an async generator? coroutine?
module.exports.requests = async (endpoint, region, options, logger) => {
let url = api.url(endpoint, region),
result = [];
do {
const [data, links] = await api.request(url, options, logger);
if (data == undefined) break; // 404
if (links == undefined) break; // 404
url = links.next;
result.push(...data);
if (links.next == undefined) break; // last page
} while (true);
return result;
}
module.exports.url = (endpoint, region) =>
"https://api.dc01.gamelockerapp.com/shards/" + region + "/" + endpoint;
|