https://webapplog.com/http2-node/
https://www.npmjs.com/package/spdy
Express 5?
-
-Finish :
- - models
- - routes
- - sockets
var server = http.createServer(app);
+/*
+ * CRON tasks
+ */
+
+var cron = require('node-cron');
+var UserModel = require("../models/User");
+var ChallengeModel = require("../models/Challenge");
+var GameModel = require("../models/Game");
+cron.schedule('0 0 0 * * *', function() {
+ // Remove some old users, challenges and games every 24h
+ UserModel.cleanUsersDb(); //TODO: write this
+ ChallengeModel.removeOld(); //TODO: this too
+ GameModel.cleanGamesDb();
+});
+
/**
* Listen on provided port, on all network interfaces.
*/
notify boolean
);
-create table Problems (
- id integer primary key,
- added datetime,
- uid integer,
- vid integer,
- fen varchar,
- instructions text,
- solution text,
- foreign key (uid) references Users(id),
- foreign key (vid) references Variants(id)
-);
-
-- All the following tables are for correspondance play only
-- (Live games are stored in browser)
fen varchar, --current state
score varchar,
timeControl varchar,
+ created datetime, --used only for DB cleaning
foreign key (vid) references Variants(id)
);
},
}
+// TODO: adapt
+// Remove challenges older than 1 month, and 1to1 older than 36h
+//exports.removeOld = function()
+//{
+// var tsNow = new Date().getTime();
+// // 86400000 = 24 hours in milliseconds
+// var day = 86400000;
+// db.challenges.find({}, (err,challengeArray) => {
+// challengeArray.forEach( c => {
+// if (c._id.getTimestamp() + 30*day < tsNow //automatch
+// || (!!c.to && c._id.getTimestamp() + 1.5*day < tsNow)) //1 to 1
+// {
+// db.challenges.remove({"_id": c._id});
+// }
+// });
+// });
+//}
+
module.exports = ChallengeModel;
{
db.serialize(function() {
let query =
- "INSERT INTO Games (vid, fenStart, fen, score, timeControl) VALUES " +
- "(" + vid + ",'" + fen + "','" + fen + "','*','" + timeControl + "')";
+ "INSERT INTO Games (vid, fenStart, fen, score, timeControl, created)"
+ + " VALUES (" + vid + ",'" + fen + "','" + fen + "','*','"
+ + timeControl + "'," + Date.now() + ")";
db.run(query, function(err) {
if (!!err)
return cb(err);
db.run(query);
});
},
+
+ cleanGamesDb: function()
+ {
+ const tsNow = Date.now();
+ // 86400000 = 24 hours in milliseconds
+ const day = 86400000;
+ db.serialize(function() {
+ let query =
+ "SELECT id,score " +
+ "FROM Games ";
+ db.all(query, (err,games) => {
+ games.forEach(g => {
+ query =
+ "SELECT max(played) AS lastMaj " +
+ "FROM Moves " +
+ "WHERE gid = " + g.id;
+ db.get(query, (err2,updated) {
+ if (!updated && tsNow - g.created > 7*day)
+ return GameModel.remove(g.id);
+ const lastMaj = updated.lastMaj;
+ if (g.score != "*" && tsNow - lastMaj > 7*day ||
+ g.score == "*" && tsNow - lastMaj > 91*day)
+ {
+ GameModel.remove(g.id);
+ }
+ });
+ });
+ });
+ });
+ },
}
module.exports = GameModel;
+++ /dev/null
-var db = require("../utils/database");
-
-/*
- * Structure:
- * id: problem number (int)
- * uid: user id (int)
- * vid: variant id (int)
- * added: timestamp
- * instructions: text
- * solution: text
- */
-
-const ProblemModel =
-{
- create: function(uid, vid, fen, instructions, solution, cb)
- {
- db.serialize(function() {
- const insertQuery =
- "INSERT INTO Problems (added, uid, vid, fen, instructions, solution) " +
- "VALUES (" + Date.now() + "," + uid + "," + vid + ",'" + fen + "',?,?)";
- db.run(insertQuery, [instructions, solution], err => {
- if (!!err)
- return cb(err);
- db.get("SELECT last_insert_rowid() AS rowid", cb);
- });
- });
- },
-
- getOne: function(id, callback)
- {
- db.serialize(function() {
- const query =
- "SELECT * " +
- "FROM Problems " +
- "WHERE id = " + id;
- db.get(query, callback);
- });
- },
-
- fetchN: function(vid, uid, type, directionStr, lastDt, MaxNbProblems, callback)
- {
- db.serialize(function() {
- let typeLine = "";
- if (uid > 0)
- typeLine = "AND uid " + (type=="others" ? "!=" : "=") + " " + uid;
- const query =
- "SELECT * FROM Problems " +
- "WHERE vid = " + vid +
- " AND added " + directionStr + " " + lastDt + " " + typeLine + " " +
- "ORDER BY added " + (directionStr=="<" ? "DESC " : "") +
- "LIMIT " + MaxNbProblems;
- db.all(query, callback);
- });
- },
-
- // TODO: update fails (but insert is OK)
- update: function(id, uid, fen, instructions, solution, cb)
- {
- db.serialize(function() {
- const query =
- "UPDATE Problems SET " +
- "fen = '" + fen + "', " +
- "instructions = ?, " +
- "solution = ? " +
- "WHERE id = " + id + " AND uid = " + uid;
- db.run(query, [instructions,solution], cb);
- });
- },
-
- remove: function(id, uid)
- {
- db.serialize(function() {
- const query =
- "DELETE FROM Problems " +
- "WHERE id = " + id + " AND uid = " + uid;
- db.run(query);
- });
- },
-}
-
-module.exports = ProblemModel;
}
}
+// TODO: adapt
+//exports.cleanUsersDb = function()
+//{
+// var tsNow = new Date().getTime();
+// // 86400000 = 24 hours in milliseconds
+// var day = 86400000;
+//
+// db.users.find({}, (err,userArray) => {
+// userArray.forEach( u => {
+// if ((u.sessionTokens.length==0 &&
+// u._id.getTimestamp().getTime() + day < tsNow) //unlogged
+// || u.updated + 365*day < tsNow) //inactive for one year
+// {
+// db.users.remove({"_id": u._id});
+// }
+// });
+// });
+//}
+
module.exports = UserModel;
router.use("/", require("./challenges"));
router.use("/", require("./games"));
router.use("/", require("./messages"));
-router.use("/", require("./problems"));
router.use("/", require("./users"));
router.use("/", require("./variants"));
+++ /dev/null
-// AJAX methods to get, create, update or delete a problem
-
-let router = require("express").Router();
-const access = require("../utils/access");
-const ProblemModel = require("../models/Problem");
-const sanitizeHtml = require('sanitize-html');
-const MaxNbProblems = 20;
-
-function sanitizeUserInput(fen, instructions, solution)
-{
- if (!fen.match(/^[a-zA-Z0-9, /-]*$/))
- return "Bad characters in FEN string";
- instructions = sanitizeHtml(instructions);
- solution = sanitizeHtml(solution);
- if (instructions.length == 0)
- return "Empty instructions";
- if (solution.length == 0)
- return "Empty solution";
- return {
- fen: fen,
- instructions: instructions,
- solution: solution
- };
-}
-
-// Get one problem (TODO: vid unused, here for URL de-ambiguification)
-router.get("/problems/:vid([0-9]+)/:id([0-9]+)", access.ajax, (req,res) => {
- const pid = req.params["id"];
- ProblemModel.getOne(pid, (err,problem) => {
- if (!!err)
- return res.json(err);
- return res.json({problem: problem});
- });
-});
-
-// Fetch N previous or next problems
-router.get("/problems/:vid([0-9]+)", access.ajax, (req,res) => {
- const vid = req.params["vid"];
- const directionStr = (req.query.direction == "forward" ? ">" : "<");
- const lastDt = req.query.last_dt;
- const type = req.query.type;
- if (!lastDt.match(/[0-9]+/))
- return res.json({errmsg: "Bad timestamp"});
- if (!["others","mine"].includes(type))
- return res.json({errmsg: "Bad type"});
- ProblemModel.fetchN(vid, req.userId, type, directionStr, lastDt, MaxNbProblems,
- (err,problems) => {
- if (!!err)
- return res.json(err);
- return res.json({problems: problems});
- }
- );
-});
-
-// Upload a problem (sanitize inputs)
-router.post("/problems/:vid([0-9]+)", access.logged, access.ajax, (req,res) => {
- const vid = req.params["vid"];
- const s = sanitizeUserInput(
- req.body["fen"], req.body["instructions"], req.body["solution"]);
- if (typeof s === "string")
- return res.json({errmsg: s});
- ProblemModel.create(req.userId, vid, s.fen, s.instructions, s.solution,
- (err,pid) => {
- if (!!err)
- return res.json(err);
- res.json({id: pid["rowid"]});
- }
- );
-});
-
-// Update a problem (also sanitize inputs)
-router.put("/problems/:id([0-9]+)", access.logged, access.ajax, (req,res) => {
- const pid = req.params["id"]; //problem ID
- const s = sanitizeUserInput(
- req.body["fen"], req.body["instructions"], req.body["solution"]);
- if (typeof s === "string")
- return res.json({errmsg: s});
- ProblemModel.update(pid, req.userId, s.fen, s.instructions, s.solution,
- err => {
- if (!!err)
- return res.json(err);
- res.json({});
- }
- );
-});
-
-// Delete a problem
-router.delete("/problems/:id([0-9]+)", access.logged, access.ajax, (req,res) => {
- const pid = req.params["id"]; //problem ID
- ProblemModel.remove(pid, req.userId);
- res.json({});
-});
-
-module.exports = router;