Replaced for clearer project structure & new ctrls.

These files where directly called from the api endpoints. Now all
functoins have been replaced with a controller interfacing to the
endpoint and a repository file for each of the functions.
This commit is contained in:
2021-01-26 23:01:49 +01:00
parent ba86bf3ada
commit ce480e790a
4 changed files with 0 additions and 777 deletions

View File

@@ -1,154 +0,0 @@
const path = require("path");
const Purchase = require(path.join(__dirname, "/schemas/Purchase"));
const Wine = require(path.join(__dirname, "/schemas/Wine"));
const Highscore = require(path.join(__dirname, "/schemas/Highscore"));
const PreLotteryWine = require(path.join(
__dirname, "/schemas/PreLotteryWine"
));
const prelotteryWines = async (req, res) => {
let wines = await PreLotteryWine.find();
return res.json(wines);
};
const allPurchase = async (req, res) => {
let purchases = await Purchase.find()
.populate("wines")
.sort({ date: 1 });
return res.json(purchases);
};
const purchaseByColor = async (req, res) => {
const countColor = await Purchase.find();
let red = 0;
let blue = 0;
let yellow = 0;
let green = 0;
let stolen = 0;
for (let i = 0; i < countColor.length; i++) {
let element = countColor[i];
red += element.red;
blue += element.blue;
yellow += element.yellow;
green += element.green;
if (element.stolen != undefined) {
stolen += element.stolen;
}
}
const highscore = await Highscore.find();
let redWin = 0;
let blueWin = 0;
let yellowWin = 0;
let greenWin = 0;
for (let i = 0; i < highscore.length; i++) {
let element = highscore[i];
for (let y = 0; y < element.wins.length; y++) {
let currentWin = element.wins[y];
switch (currentWin.color) {
case "blue":
blueWin += 1;
break;
case "red":
redWin += 1;
break;
case "yellow":
yellowWin += 1;
break;
case "green":
greenWin += 1;
break;
}
}
}
const total = red + yellow + blue + green;
return res.json({
red: {
total: red,
win: redWin
},
blue: {
total: blue,
win: blueWin
},
green: {
total: green,
win: greenWin
},
yellow: {
total: yellow,
win: yellowWin
},
stolen: stolen,
total: total
});
};
const highscore = async (req, res) => {
const highscore = await Highscore.find().populate("wins.wine");
return res.json(highscore);
};
const allWines = async (req, res) => {
const wines = await Wine.find();
return res.json(wines);
};
const allWinesSummary = async (req, res) => {
const highscore = await Highscore.find().populate("wins.wine");
let wines = {};
for (let i = 0; i < highscore.length; i++) {
let person = highscore[i];
for (let y = 0; y < person.wins.length; y++) {
let wine = person.wins[y].wine;
let date = person.wins[y].date;
let color = person.wins[y].color;
if (wines[wine._id] == undefined) {
wines[wine._id] = {
name: wine.name,
occurences: wine.occurences,
vivinoLink: wine.vivinoLink,
rating: wine.rating,
image: wine.image,
id: wine.id,
_id: wine._id,
dates: [date],
winners: [person.name],
red: 0,
blue: 0,
green: 0,
yellow: 0
};
wines[wine._id][color] += 1;
} else {
wines[wine._id].dates.push(date);
wines[wine._id].winners.push(person.name);
if (wines[wine._id][color] == undefined) {
wines[wine._id][color] = 1;
} else {
wines[wine._id][color] += 1;
}
}
}
}
wines = Object.values(wines).reverse()
return res.json(wines);
};
module.exports = {
prelotteryWines,
allPurchase,
purchaseByColor,
highscore,
allWines,
allWinesSummary
};

View File

@@ -1,142 +0,0 @@
const express = require("express");
const path = require("path");
const sub = require(path.join(__dirname, "/subscriptions"));
const _wineFunctions = require(path.join(__dirname, "/wine"));
const _personFunctions = require(path.join(__dirname, "/person"));
const Subscription = require(path.join(__dirname, "/schemas/Subscription"));
const Lottery = require(path.join(__dirname, "/schemas/Purchase"));
const PreLotteryWine = require(path.join(
__dirname, "/schemas/PreLotteryWine"
));
const submitWines = async (req, res) => {
const wines = req.body;
for (let i = 0; i < wines.length; i++) {
let wine = wines[i];
let newWonWine = new PreLotteryWine({
name: wine.name,
vivinoLink: wine.vivinoLink,
rating: wine.rating,
image: wine.image,
price: wine.price,
country: wine.country,
id: wine.id
});
await newWonWine.save();
}
let subs = await Subscription.find();
console.log("Sending new wines w/ push notification to all subscribers.")
for (let i = 0; i < subs.length; i++) {
let subscription = subs[i]; //get subscription from your databse here.
const message = JSON.stringify({
message: "Dagens vin er lagt til, se den på lottis.vin/dagens!",
title: "Ny vin!",
link: "/#/dagens"
});
try {
sub.sendNotification(subscription, message);
} catch (error) {
console.error("Error when trying to send push notification to subscriber.");
console.error(error);
}
}
return res.send({
message: "Submitted and notified push subscribers of new wines!",
success: true
});
};
const schema = async (req, res) => {
let schema = { ...PreLotteryWine.schema.obj };
let nulledSchema = Object.keys(schema).reduce((accumulator, current) => {
accumulator[current] = "";
return accumulator
}, {});
return res.send(nulledSchema);
}
// TODO IMPLEMENT WITH FRONTEND (unused)
const submitWinesToLottery = async (req, res) => {
const { lottery } = req.body;
const { date, wines } = lottery;
const wineObjects = await Promise.all(wines.map(async (wine) => await _wineFunctions.findSaveWine(wine)))
return Lottery.findOneAndUpdate({ date: date }, {
date: date,
wines: wineObjects
}, {
upsert: true
}).then(_ => res.send(true))
.catch(err => res.status(500).send({ message: 'Unexpected error while updating/saving wine to lottery.',
success: false,
exception: err.message }));
}
/**
* @apiParam (Request body) {Array} winners List of winners
*/
const submitWinnersToLottery = async (req, res) => {
const { lottery } = req.body;
const { winners, date } = lottery;
for (let i = 0; i < winners.length; i++) {
let currentWinner = winners[i];
let wonWine = await _wineFunctions.findSaveWine(currentWinner.wine); // TODO rename to findAndSaveWineToLottery
await _personFunctions.findSavePerson(currentWinner, wonWine, date); // TODO rename to findAndSaveWineToPerson
}
return res.json(true);
}
/**
* @apiParam (Request body) {Date} date Date of lottery
* @apiParam (Request body) {Number} blue Number of blue tickets
* @apiParam (Request body) {Number} red Number of red tickets
* @apiParam (Request body) {Number} green Number of green tickets
* @apiParam (Request body) {Number} yellow Number of yellow tickets
* @apiParam (Request body) {Number} bought Number of tickets bought
* @apiParam (Request body) {Number} stolen Number of tickets stolen
*/
const submitLottery = async (req, res) => {
const { lottery } = req.body
const { date,
blue,
red,
yellow,
green,
bought,
stolen } = lottery;
return Lottery.findOneAndUpdate({ date: date }, {
date: date,
blue: blue,
yellow: yellow,
red: red,
green: green,
bought: bought,
stolen: stolen
}, {
upsert: true
}).then(_ => res.send(true))
.catch(err => res.status(500).send({ message: 'Unexpected error while updating/saving lottery.',
success: false,
exception: err.message }));
return res.send(true);
};
module.exports = {
submitWines,
schema,
submitLottery,
submitWinnersToLottery,
submitWinesToLottery
};

View File

@@ -1,281 +0,0 @@
const path = require("path");
const crypto = require("crypto");
const config = require(path.join(__dirname, "/../config/defaults/lottery"));
const Message = require(path.join(__dirname, "/message"));
const { findAndNotifyNextWinner } = require(path.join(__dirname, "/virtualRegistration"));
const Attendee = require(path.join(__dirname, "/schemas/Attendee"));
const VirtualWinner = require(path.join(__dirname, "/schemas/VirtualWinner"));
const PreLotteryWine = require(path.join(__dirname, "/schemas/PreLotteryWine"));
const winners = async (req, res) => {
let winners = await VirtualWinner.find();
let winnersRedacted = [];
let winner;
for (let i = 0; i < winners.length; i++) {
winner = winners[i];
winnersRedacted.push({
name: winner.name,
color: winner.color
});
}
res.json(winnersRedacted);
};
const winnersSecure = async (req, res) => {
let winners = await VirtualWinner.find();
return res.json(winners);
};
const deleteWinners = async (req, res) => {
await VirtualWinner.deleteMany();
var io = req.app.get('socketio');
io.emit("refresh_data", {});
return res.json(true);
};
const attendees = async (req, res) => {
let attendees = await Attendee.find();
let attendeesRedacted = [];
let attendee;
for (let i = 0; i < attendees.length; i++) {
attendee = attendees[i];
attendeesRedacted.push({
name: attendee.name,
raffles: attendee.red + attendee.blue + attendee.yellow + attendee.green,
red: attendee.red,
blue: attendee.blue,
green: attendee.green,
yellow: attendee.yellow
});
}
return res.json(attendeesRedacted);
};
const attendeesSecure = async (req, res) => {
let attendees = await Attendee.find();
return res.json(attendees);
};
const addAttendee = async (req, res) => {
const attendee = req.body;
const { red, blue, yellow, green } = attendee;
let newAttendee = new Attendee({
name: attendee.name,
red,
blue,
green,
yellow,
phoneNumber: attendee.phoneNumber,
winner: false
});
await newAttendee.save();
var io = req.app.get('socketio');
io.emit("new_attendee", {});
return res.send(true);
};
const deleteAttendees = async (req, res) => {
await Attendee.deleteMany();
var io = req.app.get('socketio');
io.emit("refresh_data", {});
return res.json(true);
};
const drawWinner = async (req, res) => {
let allContestants = await Attendee.find({ winner: false });
if (allContestants.length == 0) {
return res.json({
success: false,
message: "No attendees left that have not won."
});
}
let raffleColors = [];
for (let i = 0; i < allContestants.length; i++) {
let currentContestant = allContestants[i];
for (let blue = 0; blue < currentContestant.blue; blue++) {
raffleColors.push("blue");
}
for (let red = 0; red < currentContestant.red; red++) {
raffleColors.push("red");
}
for (let green = 0; green < currentContestant.green; green++) {
raffleColors.push("green");
}
for (let yellow = 0; yellow < currentContestant.yellow; yellow++) {
raffleColors.push("yellow");
}
}
raffleColors = shuffle(raffleColors);
let colorToChooseFrom =
raffleColors[Math.floor(Math.random() * raffleColors.length)];
let findObject = { winner: false };
findObject[colorToChooseFrom] = { $gt: 0 };
let tries = 0;
const maxTries = 3;
let contestantsToChooseFrom = undefined;
while (contestantsToChooseFrom == undefined && tries < maxTries) {
const hit = await Attendee.find(findObject);
if (hit && hit.length) {
contestantsToChooseFrom = hit;
break;
}
tries++;
}
if (contestantsToChooseFrom == undefined) {
return res.status(404).send({
success: false,
message: `Klarte ikke trekke en vinner etter ${maxTries} forsøk.`
});
}
let attendeeListDemocratic = [];
let currentContestant;
for (let i = 0; i < contestantsToChooseFrom.length; i++) {
currentContestant = contestantsToChooseFrom[i];
for (let y = 0; y < currentContestant[colorToChooseFrom]; y++) {
attendeeListDemocratic.push({
name: currentContestant.name,
phoneNumber: currentContestant.phoneNumber,
red: currentContestant.red,
blue: currentContestant.blue,
green: currentContestant.green,
yellow: currentContestant.yellow
});
}
}
attendeeListDemocratic = shuffle(attendeeListDemocratic);
let winner =
attendeeListDemocratic[
Math.floor(Math.random() * attendeeListDemocratic.length)
];
let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({
timestamp_drawn: 1
});
var io = req.app.get('socketio');
io.emit("winner", {
color: colorToChooseFrom,
name: winner.name,
winner_count: winners.length + 1
});
let newWinnerElement = new VirtualWinner({
name: winner.name,
phoneNumber: winner.phoneNumber,
color: colorToChooseFrom,
red: winner.red,
blue: winner.blue,
green: winner.green,
yellow: winner.yellow,
id: sha512(winner.phoneNumber, genRandomString(10)),
timestamp_drawn: new Date().getTime()
});
await Attendee.update(
{ name: winner.name, phoneNumber: winner.phoneNumber },
{ $set: { winner: true } }
);
await newWinnerElement.save();
return res.json({
success: true,
winner
});
};
const finish = async (req, res) => {
if (!config.gatewayToken) {
return res.json({
message: "Missing api token for sms gateway.",
success: false
});
}
let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({
timestamp_drawn: 1
});
if (winners.length == 0) {
return res.json({
message: "No winners to draw from.",
success: false
});
}
Message.sendInitialMessageToWinners(winners.slice(1));
return findAndNotifyNextWinner()
.then(() => res.json({
success: true,
message: "Sent wine select message to first winner and update message to rest of winners."
}))
.catch(error => res.json({
message: error["message"] || "Unable to send message to first winner.",
success: false
}))
};
const genRandomString = function(length) {
return crypto
.randomBytes(Math.ceil(length / 2))
.toString("hex") /** convert to hexadecimal format */
.slice(0, length); /** return required number of characters */
};
const sha512 = function(password, salt) {
var hash = crypto.createHmac("md5", salt); /** Hashing algorithm sha512 */
hash.update(password);
var value = hash.digest("hex");
return value;
};
function shuffle(array) {
let currentIndex = array.length,
temporaryValue,
randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
module.exports = {
deleteWinners,
deleteAttendees,
winners,
winnersSecure,
drawWinner,
finish,
attendees,
attendeesSecure,
addAttendee
}

View File

@@ -1,200 +0,0 @@
const path = require("path");
const _wineFunctions = require(path.join(__dirname, "/wine"));
const _personFunctions = require(path.join(__dirname, "/person"));
const Message = require(path.join(__dirname, "/message"));
const VirtualWinner = require(path.join(
__dirname, "/schemas/VirtualWinner"
));
const PreLotteryWine = require(path.join(
__dirname, "/schemas/PreLotteryWine"
));
const getWinesToWinnerById = async (req, res) => {
let id = req.params.id;
let foundWinner = await VirtualWinner.findOne({ id: id });
if (!foundWinner) {
return res.json({
success: false,
message: "No winner with this id.",
existing: false,
turn: false
});
}
let allWinners = await VirtualWinner.find().sort({ timestamp_drawn: 1 });
if (
allWinners[0].id != foundWinner.id ||
foundWinner.timestamp_limit == undefined ||
foundWinner.timestamp_sent == undefined
) {
return res.json({
success: false,
message: "Not the winner next in line!",
existing: true,
turn: false
});
}
return res.json({
success: true,
existing: true,
turn: true,
name: foundWinner.name,
color: foundWinner.color
});
};
const registerWinnerSelection = async (req, res) => {
let id = req.params.id;
let wineName = req.body.wineName;
let foundWinner = await VirtualWinner.findOne({ id: id });
if (!foundWinner) {
return res.json({
success: false,
message: "No winner with this id."
})
} else if (foundWinner.timestamp_limit < new Date().getTime()) {
return res.json({
success: false,
message: "Timelimit expired, you will receive a wine after other users have chosen.",
limit: true
})
}
let date = new Date();
date.setHours(5, 0, 0, 0);
let prelotteryWine = await PreLotteryWine.findOne({ name: wineName });
if (!prelotteryWine) {
return res.json({
success: false,
message: "No wine with this name.",
wine: false
});
}
let wonWine = await _wineFunctions.findSaveWine(prelotteryWine);
await prelotteryWine.delete();
await _personFunctions.findSavePerson(foundWinner, wonWine, date);
await Message.sendWineConfirmation(foundWinner, wonWine, date);
await foundWinner.delete();
console.info("Saved winners choice.");
return findAndNotifyNextWinner()
.then(() => res.json({
message: "Choice saved and next in line notified.",
success: true
}))
.catch(error => res.json({
message: error["message"] || "Error when notifing next winner.",
success: false
}))
};
const chooseLastWineForUser = (winner, preLotteryWine) => {
let date = new Date();
date.setHours(5, 0, 0, 0);
return _wineFunctions.findSaveWine(preLotteryWine)
.then(wonWine => _personFunctions.findSavePerson(winner, wonWine, date))
.then(() => preLotteryWine.delete())
.then(() => Message.sendLastWinnerMessage(winner, preLotteryWine))
.then(() => winner.delete())
.catch(err => {
console.log("Error thrown from chooseLastWineForUser: " + err);
throw err;
})
}
const findAndNotifyNextWinner = async () => {
let nextWinner = undefined;
let winnersLeft = await VirtualWinner.find().sort({ timestamp_drawn: 1 });
let winesLeft = await PreLotteryWine.find();
if (winnersLeft.length > 1) {
console.log("multiple winners left, choose next in line")
nextWinner = winnersLeft[0]; // multiple winners left, choose next in line
} else if (winnersLeft.length == 1 && winesLeft.length > 1) {
console.log("one winner left, but multiple wines")
nextWinner = winnersLeft[0] // one winner left, but multiple wines
} else if (winnersLeft.length == 1 && winesLeft.length == 1) {
console.log("one winner and one wine left, choose for user")
nextWinner = winnersLeft[0] // one winner and one wine left, choose for user
wine = winesLeft[0]
return chooseLastWineForUser(nextWinner, wine);
}
if (nextWinner) {
return Message.sendWineSelectMessage(nextWinner)
.then(messageResponse => startTimeout(nextWinner.id))
} else {
console.info("All winners notified. Could start cleanup here.");
return Promise.resolve({
message: "All winners notified."
})
}
};
const sendNotificationToWinnerById = async (req, res) => {
const { id } = req.params;
let winner = await VirtualWinner.findOne({ id: id });
if (!winner) {
return res.json({
message: "No winner with this id.",
success: false
})
}
return Message.sendWineSelectMessage(winner)
.then(success => res.json({
success: success,
message: `Message sent to winner ${id} successfully!`
}))
.catch(err => res.json({
success: false,
message: "Error while trying to send sms.",
error: err
}))
}
function startTimeout(id) {
const minute = 60000;
const minutesForTimeout = 10;
console.log(`Starting timeout for user ${id}.`);
console.log(`Timeout duration: ${ minutesForTimeout * minute }`)
setTimeout(async () => {
let virtualWinner = await VirtualWinner.findOne({ id: id });
if (!virtualWinner) {
console.log(`Timeout done for user ${id}, but user has already sent data.`);
return;
}
console.log(`Timeout done for user ${id}, sending update to user.`);
Message.sendWineSelectMessageTooLate(virtualWinner);
virtualWinner.timestamp_drawn = new Date().getTime();
virtualWinner.timestamp_limit = null;
virtualWinner.timestamp_sent = null;
await virtualWinner.save();
findAndNotifyNextWinner();
}, minutesForTimeout * minute);
return Promise.resolve()
}
module.exports = {
getWinesToWinnerById,
registerWinnerSelection,
findAndNotifyNextWinner,
sendNotificationToWinnerById
};