-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSupportFunctions.js
More file actions
140 lines (122 loc) · 4.4 KB
/
SupportFunctions.js
File metadata and controls
140 lines (122 loc) · 4.4 KB
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
// TODO: Add restaurants to ignore
// TODO: Add daily specials
// TODO: Add ability to save config
// TODO: Add ability to overrule LunchBot
// TODO: Restaurants shouldn't be saved to config
// TODO: Might be better to have channel ID as an environment variable too
"use strict";
const chalk = require("chalk");
chalk.enabled = true;
const CONFIG = require("./config.json");
/**
* list of possible valid poll options. Can have up to nine restaurants in a poll.
*/
const POSSIBLE_REACTIONS = ["a1", "a2", "a3", "a4", "a5", "a6", "seven", "eight", "nine"];
/**
* Determine the intersection of two arrays.
*
* @param {any} array1 The first array.
* @param {any} array2 The second array.
* @returns The elements where the two arrays intersect.
*/
function intersect(array1, array2) {
if (array2.length > array1.length) {
const temp = array2;
array2 = array1;
array1 = temp;
}
// indexOf to loop over shorter
const intersection = array1.filter(e => array2.indexOf(e) > -1);
return intersection;
}
/**
* Filters the restaurants down to whose categories have not been selected.
*
* @param {any} restaurants The list of restaurants from which to select.
* @param {any} selectedRestaurants This of already selected restaurants.
*/
function filterRestaurants(restaurants, selectedRestaurants) {
// Get list of selected categories.
const selectedCategories = [];
selectedRestaurants.forEach(selectedRestaurant => {
selectedRestaurant.categories.forEach(category => {
if (selectedCategories.indexOf(category) < 0) {
selectedCategories.push(category);
}
});
});
// Get restaurants whose categories have not already been selected
const filteredRestaurants = restaurants.filter(restaurant => {
// Find the categories where there is overlap
const categories = restaurant.categories;
const categoryIntersection = intersect(selectedCategories, categories);
if (categoryIntersection.length === 0) {
return true;
}
// Keep if there is no overlap.
return false;
});
return filteredRestaurants;
}
/**
* Select a set of restaurants.
*
* @param restaurants The list of restaurants from which to select.
* @param previouslySelectedRestaurants The list of restaurants that have previously been selected.
*/
function selectRestaurants(restaurants, previouslySelectedRestaurants) {
if (!previouslySelectedRestaurants) {
previouslySelectedRestaurants = [];
}
// TODO: This should be done on start up and saved to the config file.
let restaurantsPerPoll = CONFIG.restaurantsPerPoll;
if (typeof (restaurantsPerPoll) === "undefined") {
// Default to five restaurants per poll
restaurantsPerPoll = 5;
}
if (restaurantsPerPoll < 2) {
// Minimum of two restaurants in a poll
restaurantsPerPoll = 2;
} else if (restaurantsPerPoll > 9) {
// Maximum of 9 restaurants in a poll
restaurantsPerPoll = 9;
}
// Dump anything we've already selected this week.
restaurants = restaurants.filter(restaurant => !previouslySelectedRestaurants.join("").includes(restaurant.name));
// Select reactions for the number of restaurants
const reactions = POSSIBLE_REACTIONS.slice(0, restaurantsPerPoll);
const selectedRestaurants = [];
// Select the number of restaurants as the number of reactions.
for (let i = 0; i < reactions.length; ++i) {
// Don't select restaurants that match the categories of the already selected restaurants.
restaurants = filterRestaurants(restaurants, selectedRestaurants);
if (restaurants.length > 0) {
// Select random restaurant from remaining restaurant list.
const restaurantIndex = Math.floor(Math.random() * restaurants.length);
const selectedRestaurant = restaurants[restaurantIndex];
selectedRestaurant.reaction = reactions[i];
// Added selected restaurant to the list.
selectedRestaurants.push(selectedRestaurant);
} else {
console.error("Not enough restaurants to provide the full list");
}
}
return selectedRestaurants;
}
function outputToTerminal() {
for (let i = 0; i < arguments.length; i++) {
const arg = arguments[i];
console.log(chalk.cyan(arg));
}
}
function outputErrorToTerminal() {
for (let i = 0; i < arguments.length; i++) {
const arg = arguments[i];
console.log(chalk.red(arg));
}
}
module.exports.outputErrorToTerminal = outputErrorToTerminal;
module.exports.outputToTerminal = outputToTerminal;
module.exports.selectRestaurants = selectRestaurants;
module.exports.filterRestaurants = filterRestaurants;
module.exports.intersect = intersect;