import express from "express"; import ejs from "ejs"; import multer from "multer"; import { db } from "./database/db"; import { eq, sql } from "drizzle-orm"; import { personTable, pointsTable } from "./database/schema"; import calculateNewPoints from "./gambleMath"; const app = express(); const port = 8080; const upload = multer(); //app.use(express.urlencoded); app.use(express.static('www')); app.get("/", async (req, res) => { const people = await db.select({ personId: personTable.personId, name: personTable.name }).from(personTable) .leftJoin(pointsTable, eq(personTable.personId, pointsTable.personId)) .groupBy(personTable.personId) ejs.renderFile('src/templates/index.ejs', { people: people }, function (err, str) { if (err) { res.status(500).send(err); } res.send(str); }); }); function getNextGambleTime(time: Date): Date { return new Date(time.getTime() + 3 * 60 * 60 * 1000); } function isGambleAvailable(time: Date | null): boolean { if (time == null) { return true; } // 3 hour delay before showing if (getNextGambleTime(time) < new Date()) { return true; } return false; } function isDetailAvailable(time: Date | null): boolean { if (time == null) { return false; } // 2 minute delay before hiding if (new Date(time.getTime() + 2 * 60 * 1000) > new Date()) { return true; } return false; } function sendError(res: express.Response, code: number, error: string): void { ejs.renderFile('src/templates/error.ejs', { error: error }, function (err, str) { if (err) { res.status(500).send(err); } res.status(code).send(str); }); } app.get("/gamble/:id", async (req, res) => { let id = parseInt(req.params.id); if (id == undefined) { res.status(404).send("Invalid person id"); return; } let person = await db.query.personTable.findFirst({ where: eq(personTable.personId, id) }) if (!person) { res.status(404).send("Invalid person id"); return; } if (isDetailAvailable(person.gambleTime)) { res.redirect('/person/' + id); return; } if (!isGambleAvailable(person.gambleTime)) { if (person.gambleTime == null) { sendError(res, 423, "Gamble není dostupný"); } else { sendError(res, 423, "Gamble bude dostupný až ve " + getNextGambleTime(person.gambleTime).toLocaleString('cs', { hour: "2-digit", minute: "2-digit", })); } return; } ejs.renderFile('src/templates/gamble.ejs', { person: person }, function (err, str) { if (err) { res.status(500).send(err); } res.send(str); }); }); app.post("/gamble/:id", upload.none(), async (req, res) => { let id = parseInt(req.params.id); if (id == undefined) { res.status(404).send("Invalid person id"); return; } let person = (await db.select({ personId: personTable.personId, name: personTable.name, secret: personTable.secret, gambleTime: personTable.gambleTime, pointsTotal: sql`coalesce(sum(${pointsTable.points}), 0)` }).from(personTable) .leftJoin(pointsTable, eq(personTable.personId, pointsTable.personId)) .where(eq(personTable.personId, id)) .groupBy(personTable.personId))[0]; if (!person) { sendError(res, 404, "Osoba nenalezena"); return; } if (!isGambleAvailable(person.gambleTime)) { sendError(res, 423, "Nelze zadat další gamble"); return; } if (person.secret != req.body['secret']) { sendError(res, 423, "Nesprávé heslo"); return; } let currentPoints = parseInt(person.pointsTotal); let newTotalPoints = calculateNewPoints(currentPoints); let pointsDiff = newTotalPoints - currentPoints; await db.update(personTable) .set({ gambleTime: sql`NOW()` }) .where(eq(personTable.personId, person.personId)); await db.insert(pointsTable).values({ personId: id, points: pointsDiff }) res.redirect('/person/' + id); }); app.get("/person/:id", async (req, res) => { let id = parseInt(req.params.id); if (id == undefined) { sendError(res, 404, "Osoba nenalezena"); return; } let person = (await db.select({ personId: personTable.personId, name: personTable.name, gambleTime: personTable.gambleTime, pointsTotal: sql`coalesce(sum(${pointsTable.points}), 0)` }).from(personTable) .leftJoin(pointsTable, eq(personTable.personId, pointsTable.personId)) .where(eq(personTable.personId, id)) .groupBy(personTable.personId))[0]; if (!person) { sendError(res, 404, "Osoba nenalezena"); return; } if (!isDetailAvailable(person.gambleTime)) { sendError(res, 404, "Detail bude dostupný až po dalším gamblu"); } let points = await db.query.pointsTable.findMany({ where: eq(pointsTable.personId, id) }); ejs.renderFile('src/templates/person.ejs', { person: person, points: JSON.stringify(points) }, function (err, str) { if (err) { res.status(500).send(err); } res.send(str); }); }); app.listen(port, () => { console.log(`Listening on port ${port}...`); });