nodebb-plugin-poll 3.1.7 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/config.js +42 -39
- package/lib/hooks.js +93 -111
- package/lib/poll.js +216 -304
- package/lib/scheduler.js +45 -56
- package/lib/sockets.js +158 -249
- package/lib/vote.js +65 -120
- package/library.js +8 -11
- package/package.json +4 -4
- package/plugin.json +1 -7
- package/public/js/poll/creator.js +5 -29
- package/public/js/poll/serializer.js +1 -1
- package/templates/poll/creator.tpl +2 -3
- package/vendor/dayjs.min.js +0 -1
- package/vendor/flatpickr.l10n.js +0 -1
- package/vendor/flatpickr.min.css +0 -13
- package/vendor/flatpickr.min.js +0 -2
package/lib/poll.js
CHANGED
|
@@ -1,312 +1,224 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const async = require('async');
|
|
4
|
-
|
|
5
3
|
const NodeBB = require('./nodebb');
|
|
6
4
|
|
|
7
5
|
const Vote = require('./vote');
|
|
8
6
|
const Scheduler = require('./scheduler');
|
|
9
7
|
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
Poll.delete = function (pollId) {
|
|
227
|
-
Poll.setField(pollId, 'deleted', 1);
|
|
228
|
-
};
|
|
8
|
+
const Poll = exports;
|
|
9
|
+
|
|
10
|
+
const POLL_DATA_VERSION = 2;
|
|
11
|
+
|
|
12
|
+
Poll.add = async function (pollData, postData) {
|
|
13
|
+
const pollId = await NodeBB.db.incrObjectField('global', 'nextPollId');
|
|
14
|
+
|
|
15
|
+
const poll = {
|
|
16
|
+
pollId: pollId,
|
|
17
|
+
uid: postData.editor || postData.uid,
|
|
18
|
+
tid: postData.tid,
|
|
19
|
+
pid: postData.pid,
|
|
20
|
+
deleted: 0,
|
|
21
|
+
ended: 0,
|
|
22
|
+
timestamp: postData.edited || postData.timestamp,
|
|
23
|
+
version: POLL_DATA_VERSION,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
pollData.options = pollData.options.map((val, i) => ({
|
|
27
|
+
id: i,
|
|
28
|
+
title: val,
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
await Promise.all([
|
|
32
|
+
NodeBB.db.setObject(`poll:${pollId}`, poll),
|
|
33
|
+
NodeBB.db.setObject(`poll:${pollId}:settings`, pollData.settings),
|
|
34
|
+
NodeBB.db.listAppend('polls', pollId),
|
|
35
|
+
NodeBB.db.setObjectField(`topic:${poll.tid}`, 'pollId', pollId),
|
|
36
|
+
NodeBB.db.setAdd(`poll:${pollId}:options`, pollData.options.map(option => option.id)),
|
|
37
|
+
NodeBB.db.setObjectBulk(pollData.options.map(
|
|
38
|
+
option => ([`poll:${pollId}:options:${option.id}`, option])
|
|
39
|
+
)),
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
// Check if this poll is scheduled to end
|
|
43
|
+
if (parseInt(pollData.settings.end, 10) > 0) {
|
|
44
|
+
Poll.schedule(pollId);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return pollId;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
Poll.get = async function (pollId, uid, withVotes) {
|
|
51
|
+
const [info, options, settings, hasVoted, vote] = await Promise.all([
|
|
52
|
+
Poll.getInfo(pollId),
|
|
53
|
+
Poll.getOptions(pollId, withVotes),
|
|
54
|
+
Poll.getSettings(pollId),
|
|
55
|
+
uid ? Vote.hasUidVoted(uid, pollId) : false,
|
|
56
|
+
uid ? Vote.getUidVote(uid, pollId) : null,
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
options.forEach((option) => {
|
|
60
|
+
const percentage = ((option.voteCount / info.voteCount) * 100).toFixed(0);
|
|
61
|
+
option.percentage = isNaN(percentage) ? 0 : percentage;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
settings.disallowVoteUpdate = parseInt(settings.disallowVoteUpdate, 10);
|
|
65
|
+
return {
|
|
66
|
+
info,
|
|
67
|
+
options,
|
|
68
|
+
settings,
|
|
69
|
+
hasVoted,
|
|
70
|
+
vote,
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
Poll.getPollIdByTid = async function (tid) {
|
|
75
|
+
return await NodeBB.db.getObjectField(`topic:${tid}`, 'pollId');
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
Poll.getPollIdByPid = async function (pid) {
|
|
79
|
+
return await NodeBB.db.getObjectField(`post:${pid}`, 'pollId');
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
Poll.getInfo = async function (pollId) {
|
|
83
|
+
const [poll, voteCount] = await Promise.all([
|
|
84
|
+
NodeBB.db.getObject(`poll:${pollId}`),
|
|
85
|
+
Poll.getVoteCount(pollId),
|
|
86
|
+
]);
|
|
87
|
+
poll.voteCount = parseInt(voteCount, 10) || 0;
|
|
88
|
+
return poll;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
Poll.getOptions = async function (pollId, withVotes = false) {
|
|
92
|
+
const options = await NodeBB.db.getSetMembers(`poll:${pollId}:options`);
|
|
93
|
+
// sort options according to option id. option id are supposed to preseve the order as in Poll.add(),
|
|
94
|
+
// when the user create the poll
|
|
95
|
+
options.sort((a, b) => a - b);
|
|
96
|
+
return await Promise.all(
|
|
97
|
+
options.map(option => Poll.getOption(pollId, option, withVotes))
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
Poll.getOption = async function (pollId, option, withVotes = false) {
|
|
102
|
+
const [optionData, votes, voteCount] = await Promise.all([
|
|
103
|
+
NodeBB.db.getObject(`poll:${pollId}:options:${option}`),
|
|
104
|
+
withVotes ? NodeBB.db.getSortedSetRange(`poll:${pollId}:options:${option}:votes`, 0, -1) : null,
|
|
105
|
+
Poll.getOptionVoteCount(pollId, option),
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
if (votes) {
|
|
109
|
+
optionData.votes = votes;
|
|
110
|
+
}
|
|
111
|
+
optionData.voteCount = parseInt(voteCount, 10) || 0;
|
|
112
|
+
return optionData;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
Poll.getVotersCount = async function (pollId) {
|
|
116
|
+
return await NodeBB.db.sortedSetCard(`poll:${pollId}:voters`);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
Poll.getVoteCount = async function (pollId) {
|
|
120
|
+
const options = await NodeBB.db.getSetMembers(`poll:${pollId}:options`);
|
|
121
|
+
return await NodeBB.db.sortedSetsCardSum(
|
|
122
|
+
options.map(option => `poll:${pollId}:options:${option}:votes`)
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
Poll.getOptionVoteCount = async function (pollId, option) {
|
|
127
|
+
return await NodeBB.db.sortedSetCard(`poll:${pollId}:options:${option}:votes`);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
Poll.hasOption = async function (pollId, option) {
|
|
131
|
+
return await NodeBB.db.isSetMember(`poll:${pollId}:options`, option);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
Poll.hasOptions = async function (pollId, options) {
|
|
135
|
+
return await NodeBB.db.isSetMembers(`poll:${pollId}:options`, options);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
Poll.getSettings = async function (pollId) {
|
|
139
|
+
return await NodeBB.db.getObject(`poll:${pollId}:settings`);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
Poll.isDeleted = async function (pollId) {
|
|
143
|
+
const result = await Poll.getField(pollId, 'deleted');
|
|
144
|
+
return parseInt(result, 10) === 1;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
Poll.delete = async function (pollId) {
|
|
148
|
+
await Poll.setField(pollId, 'deleted', 1);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
Poll.restore = async function (pollId) {
|
|
152
|
+
await Poll.setFields(pollId, {
|
|
153
|
+
edited: 0,
|
|
154
|
+
deleted: 0,
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
Poll.schedule = async function (pollId) {
|
|
159
|
+
await NodeBB.db.setAdd('polls:scheduled', pollId);
|
|
160
|
+
Scheduler.add(pollId);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
Poll.getScheduled = async function () {
|
|
164
|
+
return await NodeBB.db.getSetMembers('polls:scheduled');
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
Poll.hasEnded = async function (pollId) {
|
|
168
|
+
const result = await Poll.getField(pollId, 'ended');
|
|
169
|
+
return parseInt(result, 10) === 1;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
Poll.doesDisallowVoteUpdate = async function (pollId) {
|
|
173
|
+
const result = await Poll.getSettingsField(pollId, 'disallowVoteUpdate');
|
|
174
|
+
return parseInt(result, 10) === 1;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
Poll.doesAllowVoteUpdate = async function (pollId) {
|
|
178
|
+
const result = await Poll.getSettingsField(pollId, 'disallowVoteUpdate');
|
|
179
|
+
return parseInt(result, 10) !== 1;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
Poll.end = async function (pollId) {
|
|
183
|
+
await NodeBB.db.setRemove('polls:scheduled', pollId);
|
|
184
|
+
await Poll.setField(pollId, 'ended', 1);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
Poll.changePid = async function (pollId, pid) {
|
|
188
|
+
await Promise.all([
|
|
189
|
+
Poll.setField(pollId, 'pid', pid),
|
|
190
|
+
NodeBB.db.setObjectField(`post:${pid}`, 'pollId', pollId),
|
|
191
|
+
]);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
Poll.changeTid = async function (pollId, tid) {
|
|
195
|
+
await Promise.all([
|
|
196
|
+
Poll.setField(pollId, 'tid', tid),
|
|
197
|
+
NodeBB.db.setObjectField(`topic:${tid}`, 'pollId', pollId),
|
|
198
|
+
]);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
Poll.setField = async function (pollId, field, value) {
|
|
202
|
+
await NodeBB.db.setObjectField(`poll:${pollId}`, field, value);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
Poll.setFields = async function (pollId, data) {
|
|
206
|
+
await NodeBB.db.setObject(`poll:${pollId}`, data);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
Poll.getField = async function (pollId, field) {
|
|
210
|
+
return await NodeBB.db.getObjectField(`poll:${pollId}`, field);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
Poll.getFields = async function (pollId, fields) {
|
|
214
|
+
return await NodeBB.db.getObjectFields(`poll:${pollId}`, fields);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
Poll.getSettingsField = async function (pollId, field) {
|
|
218
|
+
return await NodeBB.db.getObjectField(`poll:${pollId}:settings`, field);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
Poll.setSettingsField = async function (pollId, field, value) {
|
|
222
|
+
await NodeBB.db.setObjectField(`poll:${pollId}:settings`, field, value);
|
|
223
|
+
};
|
|
229
224
|
|
|
230
|
-
Poll.restore = function (pollId) {
|
|
231
|
-
Poll.setField(pollId, 'edited', 0);
|
|
232
|
-
Poll.setField(pollId, 'deleted', 0);
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
Poll.schedule = function (pollId) {
|
|
236
|
-
NodeBB.db.setAdd('polls:scheduled', pollId);
|
|
237
|
-
Scheduler.add(pollId);
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
Poll.getScheduled = function (callback) {
|
|
241
|
-
NodeBB.db.getSetMembers('polls:scheduled', callback);
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
Poll.hasEnded = function (pollId, callback) {
|
|
245
|
-
Poll.getField(pollId, 'ended', (err, result) => {
|
|
246
|
-
callback(err, parseInt(result, 10) === 1);
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
Poll.doesDisallowVoteUpdate = function (pollId, callback) {
|
|
251
|
-
Poll.getSettingsField(pollId, 'disallowVoteUpdate', (err, result) => {
|
|
252
|
-
callback(err, parseInt(result, 10) === 1);
|
|
253
|
-
});
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
Poll.doesAllowVoteUpdate = function (pollId, callback) {
|
|
257
|
-
Poll.getSettingsField(pollId, 'disallowVoteUpdate', (err, result) => {
|
|
258
|
-
callback(err, parseInt(result, 10) !== 1);
|
|
259
|
-
});
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
Poll.end = function (pollId) {
|
|
263
|
-
NodeBB.db.setRemove('polls:scheduled', pollId);
|
|
264
|
-
Poll.setField(pollId, 'ended', 1);
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
Poll.changePid = function (pollId, pid, callback) {
|
|
268
|
-
async.parallel([
|
|
269
|
-
function (next) {
|
|
270
|
-
Poll.setField(pollId, 'pid', pid, next);
|
|
271
|
-
},
|
|
272
|
-
function (next) {
|
|
273
|
-
NodeBB.db.setObjectField(`post:${pid}`, 'pollId', pollId, next);
|
|
274
|
-
},
|
|
275
|
-
], callback);
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
Poll.changeTid = function (pollId, tid, callback) {
|
|
279
|
-
async.parallel([
|
|
280
|
-
function (next) {
|
|
281
|
-
Poll.setField(pollId, 'tid', tid, next);
|
|
282
|
-
},
|
|
283
|
-
function (next) {
|
|
284
|
-
NodeBB.db.setObjectField(`topic:${tid}`, 'pollId', pollId, next);
|
|
285
|
-
},
|
|
286
|
-
], callback);
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
Poll.setField = function (pollId, field, value, callback) {
|
|
290
|
-
NodeBB.db.setObjectField(`poll:${pollId}`, field, value, callback);
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
Poll.setFields = function (pollId, fields, values, callback) {
|
|
294
|
-
NodeBB.db.setObjectFields(`poll:${pollId}`, fields, values, callback);
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
Poll.getField = function (pollId, field, callback) {
|
|
298
|
-
NodeBB.db.getObjectField(`poll:${pollId}`, field, callback);
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
Poll.getFields = function (pollId, fields, callback) {
|
|
302
|
-
NodeBB.db.getObjectFields(`poll:${pollId}`, fields, callback);
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
Poll.getSettingsField = function (pollId, field, callback) {
|
|
306
|
-
NodeBB.db.getObjectField(`poll:${pollId}:settings`, field, callback);
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
Poll.setSettingsField = function (pollId, field, value, callback) {
|
|
310
|
-
NodeBB.db.setObjectField(`poll:${pollId}:settings`, field, callback);
|
|
311
|
-
};
|
|
312
|
-
}(exports));
|
package/lib/scheduler.js
CHANGED
|
@@ -5,59 +5,48 @@ const NodeBB = require('./nodebb');
|
|
|
5
5
|
|
|
6
6
|
const Poll = require('./poll');
|
|
7
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
|
-
const index = Object.keys(jobs).indexOf(pollId.toString());
|
|
55
|
-
|
|
56
|
-
if (index !== -1 && jobs[pollId] !== undefined) {
|
|
57
|
-
jobs[pollId].stop();
|
|
58
|
-
delete jobs[pollId];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
Poll.end(pollId);
|
|
62
|
-
};
|
|
63
|
-
}(exports));
|
|
8
|
+
const Scheduler = exports;
|
|
9
|
+
const jobs = {};
|
|
10
|
+
|
|
11
|
+
Scheduler.start = async function () {
|
|
12
|
+
const pollIds = await Poll.getScheduled();
|
|
13
|
+
await Promise.all(pollIds.map(Scheduler.add));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
Scheduler.add = async function (pollId) {
|
|
17
|
+
if (Object.keys(jobs).indexOf(pollId.toString()) !== -1) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const settings = await Poll.getSettings(pollId);
|
|
22
|
+
if (!settings) {
|
|
23
|
+
return NodeBB.winston.error(`[nodebb-plugin-poll/scheduler] Poll ID ${pollId} has no settings!`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const end = parseInt(settings.end, 10);
|
|
28
|
+
|
|
29
|
+
if (end < now) {
|
|
30
|
+
Scheduler.end(pollId);
|
|
31
|
+
} else {
|
|
32
|
+
const date = new Date(end);
|
|
33
|
+
NodeBB.winston.verbose(`[nodebb-plugin-poll/scheduler] Starting scheduler for poll with ID ${pollId} to end on ${date}`);
|
|
34
|
+
jobs[pollId] = new cron(date, (() => {
|
|
35
|
+
Scheduler.end(pollId);
|
|
36
|
+
}), null, true);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
Scheduler.end = async function (pollId) {
|
|
41
|
+
NodeBB.winston.verbose(`[nodebb-plugin-poll/scheduler] Ending poll with ID ${pollId}`);
|
|
42
|
+
|
|
43
|
+
const index = Object.keys(jobs).indexOf(pollId.toString());
|
|
44
|
+
|
|
45
|
+
if (index !== -1 && jobs[pollId] !== undefined) {
|
|
46
|
+
jobs[pollId].stop();
|
|
47
|
+
delete jobs[pollId];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
await Poll.end(pollId);
|
|
51
|
+
};
|
|
52
|
+
|