aboutsummaryrefslogtreecommitdiff
path: root/src/api/structures
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/structures')
-rw-r--r--src/api/structures/Database.js48
-rw-r--r--src/api/structures/Route.js36
-rw-r--r--src/api/structures/Server.js13
3 files changed, 62 insertions, 35 deletions
diff --git a/src/api/structures/Database.js b/src/api/structures/Database.js
new file mode 100644
index 0000000..5818452
--- /dev/null
+++ b/src/api/structures/Database.js
@@ -0,0 +1,48 @@
+const nodePath = require('path');
+const Knex = require('knex');
+
+// eslint-disable-next-line func-names
+Knex.QueryBuilder.extend('wasMutated', function() {
+ this.client.config.userParams.lastMutationTime = Date.now();
+ return this;
+});
+
+const db = Knex({
+ client: process.env.DB_CLIENT,
+ connection: {
+ host: process.env.DB_HOST,
+ user: process.env.DB_USER,
+ password: process.env.DB_PASSWORD,
+ database: process.env.DB_DATABASE,
+ filename: nodePath.join(__dirname, '../../../database/database.sqlite')
+ },
+ postProcessResponse: result => {
+ /*
+ Fun fact: Depending on the database used by the user and given that I don't want
+ to force a specific database for everyone because of the nature of this project,
+ some things like different data types for booleans need to be considered like in
+ the implementation below where sqlite returns 1 and 0 instead of true and false.
+ */
+ const booleanFields = ['enabled', 'enableDownload', 'isAdmin', 'nsfw'];
+
+ const processResponse = row => {
+ Object.keys(row).forEach(key => {
+ if (booleanFields.includes(key)) {
+ if (row[key] === 0) row[key] = false;
+ else if (row[key] === 1) row[key] = true;
+ }
+ });
+ return row;
+ };
+
+ if (Array.isArray(result)) return result.map(row => processResponse(row));
+ if (typeof result === 'object') return processResponse(result);
+ return result;
+ },
+ useNullAsDefault: process.env.DB_CLIENT === 'sqlite3',
+ userParams: {
+ lastMutationTime: null
+ }
+});
+
+module.exports = db;
diff --git a/src/api/structures/Route.js b/src/api/structures/Route.js
index bb7ba87..24d45b2 100644
--- a/src/api/structures/Route.js
+++ b/src/api/structures/Route.js
@@ -1,39 +1,5 @@
-const nodePath = require('path');
const JWT = require('jsonwebtoken');
-const db = require('knex')({
- client: process.env.DB_CLIENT,
- connection: {
- host: process.env.DB_HOST,
- user: process.env.DB_USER,
- password: process.env.DB_PASSWORD,
- database: process.env.DB_DATABASE,
- filename: nodePath.join(__dirname, '../../../database/database.sqlite')
- },
- postProcessResponse: result => {
- /*
- Fun fact: Depending on the database used by the user and given that I don't want
- to force a specific database for everyone because of the nature of this project,
- some things like different data types for booleans need to be considered like in
- the implementation below where sqlite returns 1 and 0 instead of true and false.
- */
- const booleanFields = ['enabled', 'enableDownload', 'isAdmin', 'nsfw'];
-
- const processResponse = row => {
- Object.keys(row).forEach(key => {
- if (booleanFields.includes(key)) {
- if (row[key] === 0) row[key] = false;
- else if (row[key] === 1) row[key] = true;
- }
- });
- return row;
- };
-
- if (Array.isArray(result)) return result.map(row => processResponse(row));
- if (typeof result === 'object') return processResponse(result);
- return result;
- },
- useNullAsDefault: process.env.DB_CLIENT === 'sqlite3'
-});
+const db = require('./Database');
const moment = require('moment');
const log = require('../utils/Log');
diff --git a/src/api/structures/Server.js b/src/api/structures/Server.js
index 0dec72a..cb97dd1 100644
--- a/src/api/structures/Server.js
+++ b/src/api/structures/Server.js
@@ -14,8 +14,11 @@ const jetpack = require('fs-jetpack');
const path = require('path');
const morgan = require('morgan');
const rfs = require('rotating-file-stream');
+const CronJob = require('cron').CronJob;
const log = require('../utils/Log');
+const Util = require('../utils/Util');
+
// eslint-disable-next-line no-unused-vars
const rateLimiter = new RateLimit({
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW, 10),
@@ -55,6 +58,9 @@ class Server {
// Serve the uploads
this.server.use(express.static(path.join(__dirname, '../../../uploads')));
this.routesFolder = path.join(__dirname, '../routes');
+
+ // Save the cron job instances in case we want to stop them later
+ this.jobs = {};
}
registerAllTheRoutes() {
@@ -95,6 +101,11 @@ class Server {
});
}
+ createJobs() {
+ // TODO: move into the database config. (we can just show the crontab line for start, later on we can add dropdowns and stuff)
+ this.jobs.stats = new CronJob('* 0 * * * *', Util.saveStatsToDb, null, true);
+ }
+
start() {
jetpack.dir('uploads/chunks');
jetpack.dir('uploads/thumbs/square');
@@ -105,6 +116,8 @@ class Server {
log.success(`Backend ready and listening on port ${this.port}`);
});
server.setTimeout(600000);
+
+ this.createJobs();
}
}