-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.js
158 lines (133 loc) · 4.2 KB
/
utils.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
'use strict';
const fs = require('fs'),
http = require('http'),
config = require('./config');
// Handler function to make running asynchronous functions in an express context easier
exports.asyncHandler = (func) => {
return (req, res, next) => {
return func(req, res, next).catch(next);
};
}
// Log string to appropriate logfile (specified in config)
exports.logToFile = string => {
fs.appendFile(config.logFile, string + '\n', err => {
if (err) console.log("\x1b[31m[ERROR]\x1b[0m Error writing to logfile: " + err.message);
});
}
exports.logError = string => {
console.log("\x1b[31m[ERROR]\x1b[0m " + string); // Red formatted text
exports.logToFile("[ERROR] " + string);
}
exports.logSuccess = string => {
console.log("\x1b[32m[SUCCESS]\x1b[0m " + string); // Green formatted text
exports.logToFile("[SUCCESS] " + string);
}
// Function to make getting all the data (user, book) for a loan easy
exports.getLoanData = async (loans, db) => {
// error is used to unify the error handling asynchronously
let error = false;
const loanData = await Promise.all(loans.map(async loan => {
const withdraw = await db.collection('history').findOne({_id: loan.withdrawID});
if (!withdraw) {
exports.logError("Withdrawal '" + loan.withdrawID + "' not found");
error = true;
}
const book = await db.collection('books').findOne({_id: withdraw.book});
if (!book) {
exports.logError("Book '" + withdraw.book + "' not found");
error = true;
}
const user = await db.collection('users').findOne({_id: withdraw.user});
if (!user) {
exports.logError("User '" + withdraw.user + "' not found");
error = true;
}
return {
loan: loan,
book: book,
user: user
}
}));
return (error) ? undefined : loanData;
}
// Get all the loan data from a list of IDs
exports.getLoansForIDs = async (loanIDs, db) => {
// error allows there to be a single error check over the whole map
let error = false;
const loans = await Promise.all(loanIDs.map(async loanID => {
const loan = await db.collection('loans').findOne({_id: loanID});
if (!loan) {
exports.logError("Loan '" + loanID + "' not found");
error = true;
}
return loan;
}));
const allData = await exports.getLoanData(loans, db);
// Check if the loan data was found
if (!allData) error = true;
else allData.forEach(loan => delete loan.user);
return (error) ? undefined : allData;
}
// Calculate fine for a loan
exports.calculateFine = (loans) => {
let fine = 0;
let now = new Date();
now.setHours(0,0,0,0);
loans.map(loan => {
let due = loan.loan.dueDate;
due.setHours(0,0,0,0);
if (loan.loan.dueDate < now) fine += (now.getTime() - due.getTime()) / 4320000 // Fine accumulates at 20p per day
});
return fine;
}
// Check is a date string is valid
exports.validDate = (dateString) => {
console.log("Checking date '" + dateString + "'");
// Test if the format is yyyy-mm-dd
if (!/^\d{4}([./-])\d{2}\1\d{2}$/.test(dateString)) {
exports.logError("Date is not yyyy-mm-dd");
return false;
}
console.log("...Date is yyyy-mm-dd");
// Check if the date can be converted to a Date object
const newDate = new Date(dateString);
if (isNaN(newDate)) {
exports.logError("Date does not convert to valid object");
return false;
}
console.log("...Date converted to valid object");
// Check the date is in the future
var now = new Date();
now.setHours(0,0,0,0);
if (newDate > now) {
console.log("...Date is in future");
exports.logSuccess("Date is vaild")
return true;
} else {
exports.logError("Date is not in future");
return false;
}
};
// Connect to the API via GET or POST
exports.connectAPI = (url, body) => {
return new Promise((resolve, reject) => {
var req = http.request({
host: 'localhost',
port: config.port,
method: body ? 'POST' : 'GET', // If a body is specified, POST
path: url,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}, res => {
// Read the data into a string and resolve it when the data transfer is finished
let str = '';
res.on('data', chunk => str += chunk);
res.on('end', () => resolve(str));
}).on('error', err => {
exports.logError(err);
});
if (body) req.write(JSON.stringify(body)); // Add JSON data to req if it exists
req.end();
});
}