Skip to content

Commit bf885af

Browse files
authored
Fix bug with votes count (#1585)
* Script up to down or down to up improperly counts script votes and messes up good/bad bar. Shouldn't affect Rating in Script or Group but will recheck a few. * At the same time move to MVC *(Currently isolated to Script e.g. parallel change)*... Fixes TODO in routes.js * Some styleguide.md conformance * Simplify some views. e.g. turn some things off when they aren't able to be used. Save b/w and possibly improve understanding for most * Still would prefer returning `err` *(aErr)* with libs but that's probably a separate PR since there are still inconsistent return callback parms * Some filling in for #1548 * Some additions for #430. e.g. we want to know if a DB action fails currently NOTES: * Structure mirrored and altered from `flagsLib` Applies to #262 and Active Maintainer override (Sorry sizzle but needed to be done so it doesn't mess up other areas down the line) * Will run through scripts and mitigate any script `votes` counts. Auto-merge
1 parent 36d39c4 commit bf885af

File tree

10 files changed

+390
-163
lines changed

10 files changed

+390
-163
lines changed

controllers/flag.js

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var formidable = require('formidable');
1313

1414
//--- Model inclusions
1515
var Flag = require('../models/flag').Flag;
16+
1617
var User = require('../models/user').User;
1718
var Script = require('../models/script').Script;
1819

@@ -109,6 +110,7 @@ exports.flag = function (aReq, aRes, aNext) {
109110
});
110111

111112
});
113+
112114
break;
113115
case 'users':
114116
username = aReq.params[1];

controllers/script.js

+10-150
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ var SPDX = require('spdx-license-ids');
1616
var Discussion = require('../models/discussion').Discussion;
1717
var Group = require('../models/group').Group;
1818
var Script = require('../models/script').Script;
19-
var Vote = require('../models/vote').Vote;
2019

2120
//--- Controller inclusions
2221
var scriptStorage = require('./scriptStorage');
@@ -29,6 +28,7 @@ var getFlaggedListForContent = require('./flag').getFlaggedListForContent;
2928

3029
var isSameOrigin = require('../libs/helpers').isSameOrigin;
3130

31+
var voteLib = require('../libs/vote');
3232
var flagLib = require('../libs/flag');
3333
var removeLib = require('../libs/remove');
3434

@@ -233,35 +233,17 @@ var getScriptPageTasks = function (aOptions) {
233233
aOptions.voteDownUrl = voteUrl + '/down';
234234
aOptions.unvoteUrl = voteUrl + '/unvote';
235235

236-
aOptions.voteable = false;
237-
aOptions.votedUp = false;
238-
aOptions.votedDown = false;
239-
240-
// Can't vote when not logged in or when user owns the script.
241-
if (!authedUser || aOptions.isOwner) {
242-
aCallback();
243-
return;
244-
}
245-
246-
Vote.findOne({
247-
_scriptId: script._id,
248-
_userId: authedUser._id
249-
}, function (aErr, aVoteModel) {
250-
// WARNING: No err handling
251-
252-
aOptions.voteable = !script.isOwner;
253-
254-
if (aVoteModel) {
255-
if (aVoteModel.vote) {
256-
aOptions.votedUp = true;
236+
voteLib.voteable(script, authedUser,
237+
function (aCanVote, aAuthor, aVote) {
238+
if (aVote) {
239+
aOptions.votedUp = aVote.vote === true;
240+
aOptions.votedDown = aVote.vote === false;
241+
aOptions.canVote = true;
257242
} else {
258-
aOptions.votedDown = true;
243+
aOptions.canVote = aCanVote;
259244
}
260-
}
261-
262-
aCallback();
263-
});
264-
245+
aCallback();
246+
});
265247
});
266248

267249
// Setup the flagging UI
@@ -506,125 +488,3 @@ exports.edit = function (aReq, aRes, aNext) {
506488
}
507489
});
508490
};
509-
510-
// Script voting
511-
exports.vote = function (aReq, aRes, aNext) {
512-
//
513-
var uri = aReq._parsedUrl.pathname.split('/');
514-
var vote = aReq.params.vote;
515-
var unvote = false;
516-
517-
var isLib = aReq.params.isLib;
518-
var installNameBase = scriptStorage.getInstallNameBase(aReq);
519-
520-
// ---
521-
if (uri.length > 5) {
522-
uri.pop();
523-
}
524-
uri.shift();
525-
uri.shift();
526-
uri = '/' + uri.join('/');
527-
528-
if (vote === 'up') {
529-
vote = true;
530-
} else if (vote === 'down') {
531-
vote = false;
532-
} else if (vote === 'unvote') {
533-
unvote = true;
534-
} else {
535-
aRes.redirect(uri);
536-
return;
537-
}
538-
539-
Script.findOne({
540-
installName: scriptStorage.caseSensitive(installNameBase +
541-
(isLib ? '.js' : '.user.js'))
542-
}, function (aErr, aScript) {
543-
//
544-
var authedUser = aReq.session.user;
545-
546-
// ---
547-
if (aErr || !aScript) {
548-
aRes.redirect(uri);
549-
return;
550-
}
551-
552-
Vote.findOne({ _scriptId: aScript._id, _userId: authedUser._id },
553-
function (aErr, aVoteModel) {
554-
// WARNING: No err handling
555-
556-
var votes = aScript.votes || 0;
557-
var flags = 0;
558-
var oldVote = null;
559-
560-
function saveScript() {
561-
if (!flags) {
562-
aScript.save(function (aErr, aScript) {
563-
// WARNING: No err handling
564-
565-
var script = null;
566-
567-
if (vote === false) {
568-
script = modelParser.parseScript(aScript);
569-
570-
// Gently encourage browsing/creating an issue with a down vote
571-
aRes.redirect(script.scriptIssuesPageUri);
572-
} else {
573-
aRes.redirect(uri);
574-
}
575-
});
576-
return;
577-
}
578-
579-
flagLib.getAuthor(aScript, function (aAuthor) {
580-
flagLib.saveContent(Script, aScript, aAuthor, flags, false,
581-
function (aFlagged) {
582-
aRes.redirect(uri);
583-
});
584-
});
585-
}
586-
587-
if (!aScript.rating) {
588-
aScript.rating = 0;
589-
}
590-
591-
if (!aScript.votes) {
592-
aScript.votes = 0;
593-
}
594-
595-
if (authedUser._id == aScript._authorId || (!aVoteModel && unvote)) {
596-
aRes.redirect(uri);
597-
return;
598-
} else if (!aVoteModel) {
599-
aVoteModel = new Vote({
600-
vote: vote,
601-
_scriptId: aScript._id,
602-
_userId: authedUser._id
603-
});
604-
aScript.rating += vote ? 1 : -1;
605-
aScript.votes = votes + 1;
606-
if (vote) {
607-
flags = -1;
608-
}
609-
} else if (unvote) {
610-
oldVote = aVoteModel.vote;
611-
aVoteModel.remove(function () {
612-
aScript.rating += oldVote ? -1 : 1;
613-
aScript.votes = votes <= 0 ? 0 : votes - 1;
614-
if (oldVote) {
615-
flags = 1;
616-
}
617-
saveScript();
618-
});
619-
return;
620-
} else if (aVoteModel.vote !== vote) {
621-
aVoteModel.vote = vote;
622-
aScript.rating += vote ? 2 : -2;
623-
flags = vote ? -1 : 1;
624-
}
625-
626-
aVoteModel.save(saveScript);
627-
}
628-
);
629-
});
630-
};

controllers/vote.js

+97
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,111 @@ var isDbg = require('../libs/debug').isDbg;
88
//
99

1010
//--- Dependency inclusions
11+
var formidable = require('formidable');
1112

1213
//--- Model inclusions
14+
var Script = require('../models/script').Script;
1315

1416
//--- Controller inclusions
17+
var scriptStorage = require('./scriptStorage');
18+
1519

1620
//--- Library inclusions
1721
var voteLib = require('../libs/vote');
1822

23+
var modelParser = require('../libs/modelParser');
24+
25+
var statusCodePage = require('../libs/templateHelpers').statusCodePage;
26+
1927
//--- Configuration inclusions
2028

2129
//---
30+
31+
// Controller for Script voting
32+
exports.vote = function (aReq, aRes, aNext) {
33+
var form = null;
34+
35+
// Check to make sure multipart form data submission header is present
36+
if (!/multipart\/form-data/.test(aReq.headers['content-type'])) {
37+
statusCodePage(aReq, aRes, aNext, {
38+
statusCode: 400,
39+
statusMessage: 'Missing required header.'
40+
});
41+
return;
42+
}
43+
44+
form = new formidable.IncomingForm();
45+
form.parse(aReq, function (aErr, aFields) {
46+
// WARNING: No err handling
47+
48+
var vote = aFields.vote;
49+
var unvote = false;
50+
51+
var type = aReq.params[0];
52+
var isLib = null;
53+
54+
var installNameBase = null;
55+
var authedUser = aReq.session.user;
56+
57+
switch (vote) {
58+
case 'up':
59+
// fallthrough
60+
case 'down':
61+
// fallthrough
62+
case 'un':
63+
break;
64+
default:
65+
statusCodePage(aReq, aRes, aNext, {
66+
statusCode: 400,
67+
statusMessage: 'Missing required field value.'
68+
});
69+
return;
70+
}
71+
72+
switch (type) {
73+
case 'libs':
74+
isLib = true;
75+
// fallthrough
76+
case 'scripts':
77+
aReq.params.username = aReq.params[2];
78+
aReq.params.scriptname = aReq.params[3]
79+
80+
installNameBase = scriptStorage.getInstallNameBase(aReq);
81+
82+
Script.findOne({
83+
installName: scriptStorage.caseSensitive(installNameBase +
84+
(isLib ? '.js' : '.user.js'))
85+
}, function (aErr, aScript) {
86+
var fn = voteLib[vote + 'vote'];
87+
88+
// ---
89+
if (aErr || !aScript) {
90+
aRes.redirect((isLib ? '/libs/' : '/scripts/') + scriptStorage.getInstallNameBase(
91+
aReq, { encoding: 'uri' }));
92+
return;
93+
}
94+
95+
fn(aScript, authedUser, function (aErr) {
96+
var script = null;
97+
98+
if (vote === 'down') {
99+
script = modelParser.parseScript(aScript);
100+
101+
// Gently encourage browsing/creating an issue with a down vote
102+
aRes.redirect(script.scriptIssuesPageUri);
103+
104+
} else {
105+
aRes.redirect((isLib ? '/libs/' : '/scripts/') + scriptStorage.getInstallNameBase(
106+
aReq, { encoding: 'uri' }));
107+
}
108+
});
109+
110+
});
111+
112+
break;
113+
default:
114+
aNext();
115+
return;
116+
}
117+
});
118+
};

libs/flag.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ function getFlag(aModel, aContent, aUser, aCallback) {
7070
function getAuthor(aContent, aCallback) {
7171
User.findOne({ _id: aContent._authorId }, function (aErr, aAuthor) {
7272
// Content without an author shouldn't exist
73-
if (aErr || !aAuthor) { return aCallback(null); }
73+
if (aErr || !aAuthor) {
74+
aCallback(null);
75+
return;
76+
}
7477

7578
aCallback(aAuthor);
7679
});
@@ -152,6 +155,8 @@ function flag(aModel, aContent, aUser, aAuthor, aReason, aCallback) {
152155
});
153156

154157
flag.save(function (aErr, aFlag) {
158+
// WARNING: No err handling
159+
155160
if (!aContent.flags) {
156161
aContent.flags = {};
157162
}

libs/modelParser.js

+4
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ var parseScript = function (aScript) {
380380
// Urls: Moderation
381381
script.scriptRemovePageUrl = '/remove' + (script.isLib ? '/libs/' : '/scripts/') +
382382
script.installNameSlugUrl;
383+
384+
script.scriptVotePageUrl = '/vote' + (script.isLib ? '/libs/' : '/scripts/') +
385+
script.installNameSlugUrl;
386+
383387
script.scriptFlagPageUrl = '/flag' + (script.isLib ? '/libs/' : '/scripts/') +
384388
script.installNameSlugUrl;
385389

0 commit comments

Comments
 (0)