-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrab.js
83 lines (77 loc) · 2.37 KB
/
grab.js
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
import {
cutData,
endOfDay,
preciseTokens,
startOfDay,
subDays,
} from "./core.js";
import tokensObj from "./tokens.json" with { type: "json" };
const tokens = Object.values(tokensObj).flat(Infinity);
const baseUrl = "https://mof.sora.org/qty/";
grab().then((grabbed) => {
const now = Date.now();
const append = (value) => (parsed) => (
parsed.length > 1 &&
value[1] === parsed[parsed.length - 2][1] &&
value[1] === parsed[parsed.length - 1][1]
? parsed.splice(-1, 1, value)
: parsed.push(value), parsed
);
const write = (token) => (data) => {
Deno.writeTextFile("./data/" + token + ".json", JSON.stringify(data));
const yearAgo = startOfDay(subDays(now, 366)).valueOf();
const yearData = cutData(data, yearAgo);
const monthAgo = startOfDay(subDays(now, 32)).valueOf();
const monthData = cutData(yearData, monthAgo);
const prepared = compressDaily(
yearData.filter(([timestamp]) => timestamp < monthAgo),
).concat(monthData);
Deno.writeTextFile(
"./data/prepared/" + token + ".json",
JSON.stringify(prepared),
);
};
grabbed.forEach(([token, qty]) => {
Deno.readTextFile("./data/" + token + ".json")
.then(JSON.parse)
.catch(() => [])
.then(append([now, qty]))
.then(write(token));
});
});
function grab() {
return Promise.allSettled(
tokens.map((token) =>
fetch(baseUrl + token)
.then((response) => response.text())
.then((text) => [token, formatValue(text, token)])
),
).then((result) =>
result
.filter(({ status }) => status === "fulfilled")
.map(({ value }) => value)
.filter(([_, value]) => value >= 0)
);
}
function compressDaily(data) {
const dailyData = new Map();
data.forEach(([timestamp, value]) => {
const start = startOfDay(timestamp).valueOf();
if (!dailyData.has(start)) {
dailyData.set(start, value);
}
const end = endOfDay(timestamp).valueOf();
dailyData.set(end, value);
});
return Array.from(dailyData);
}
function formatValue(value, token) {
const float = typeof value === "string" ? parseFloat(value) : value;
if (Number.isNaN(float)) return NaN;
if (preciseTokens.includes(token)) {
const round = Math.round(100_000 * float) / 100_000;
return round;
}
const round = Math.round(1000 * float) / 1000;
return round < 100 ? round : Math.trunc(round);
}