|
|
|
var serve = require("koa-static");
|
|
|
|
const Koa = require("koa");
|
|
|
|
const Router = require("@koa/router");
|
|
|
|
const mount = require("koa-mount");
|
|
|
|
|
|
|
|
const { getCard, getEmoji } = require("./number-to-emoji");
|
|
|
|
const getISP = require("./get-isp");
|
|
|
|
const mainView = require("./index.html.js");
|
|
|
|
const cardView = require("./card.html.js");
|
|
|
|
|
|
|
|
const router = new Router();
|
|
|
|
|
|
|
|
// response
|
|
|
|
const app = new Koa();
|
|
|
|
const static = new Koa();
|
|
|
|
static.use(serve("./static"));
|
|
|
|
|
|
|
|
app.use(mount("/static", static));
|
|
|
|
|
|
|
|
function* idgen() {
|
|
|
|
let i = 1;
|
|
|
|
while (true) {
|
|
|
|
yield i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const id = idgen();
|
|
|
|
const id_to_card = {};
|
|
|
|
|
|
|
|
router.get("/", async (ctx) => {
|
|
|
|
// stream data
|
|
|
|
ctx.set("content-type", "text/html");
|
|
|
|
const _id = id.next().value;
|
|
|
|
const _card = getCard();
|
|
|
|
id_to_card[_id] = _card;
|
|
|
|
ctx.body = mainView(_id, _card);
|
|
|
|
});
|
|
|
|
|
|
|
|
router.get("/card", async (ctx) => {
|
|
|
|
// stream data
|
|
|
|
ctx.set("content-type", "text/html");
|
|
|
|
const _id = id.next().value;
|
|
|
|
const _card = getCard();
|
|
|
|
id_to_card[_id] = _card;
|
|
|
|
ctx.body = cardView(_id, _card);
|
|
|
|
});
|
|
|
|
|
|
|
|
const tracks = [];
|
|
|
|
|
|
|
|
router.get("/track", async (ctx) => {
|
|
|
|
const ISP = await getISP(ctx.request.ip);
|
|
|
|
tracks.push({ ...ctx.query, ip: ctx.request.ip, ISP });
|
|
|
|
});
|
|
|
|
|
|
|
|
router.get("/stats", async (ctx) => {
|
|
|
|
ctx.set("content-type", "text/html");
|
|
|
|
console.log(tracks);
|
|
|
|
if (tracks.length === 0) {
|
|
|
|
ctx.body = /* HTML */ `<!DOCTYPE html>No tracks so far`;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ctx.body = /* HTML */ `<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Results</title>
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
<style>
|
|
|
|
tr:hover {
|
|
|
|
background-color: #ddd;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<table>
|
|
|
|
<tr>
|
|
|
|
<th>Mark</th>
|
|
|
|
<th>Card</th>
|
|
|
|
${Object.keys(tracks[0])
|
|
|
|
.map((key) => `<th>${key}</th>`)
|
|
|
|
.join("")}
|
|
|
|
</tr>
|
|
|
|
${tracks
|
|
|
|
.map(
|
|
|
|
(track) => /* HTML */ `<tr>
|
|
|
|
<td><input type="checkbox" /></td>
|
|
|
|
<td>${getEmoji(id_to_card[track.id])}</td>
|
|
|
|
${Object.values(track)
|
|
|
|
.map((value) => `<td>${value}</td>`)
|
|
|
|
.join("")}
|
|
|
|
</tr>`
|
|
|
|
)
|
|
|
|
.join("")}
|
|
|
|
</table>
|
|
|
|
</body>
|
|
|
|
</html>`;
|
|
|
|
});
|
|
|
|
|
|
|
|
app.use(router.routes()).use(router.allowedMethods());
|
|
|
|
app.listen(3000);
|