Skip to content

Commit 89e2321

Browse files
committed
Merge pull request #770 from Martii/Issue-643
Issue 643 Auto-merge
2 parents 349f8d0 + 15c7c54 commit 89e2321

14 files changed

Lines changed: 298 additions & 24 deletions

File tree

controllers/_template.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ var isDev = require('../libs/debug').isDev;
66
var isDbg = require('../libs/debug').isDbg;
77

88
//
9+
10+
//--- Dependency inclusions
911
var async = require('async');
1012
var _ = require('underscore');
11-
var pageMetadata = require('../libs/templateHelpers').pageMetadata;
1213

13-
//--- Models
14+
//--- Model inclusions
1415
var Group = require('../models/group').Group;
1516

17+
//--- Library inclusions
18+
var pageMetadata = require('../libs/templateHelpers').pageMetadata;
19+
20+
//--- Configuration inclusions
21+
1622
//--- Local
1723

1824
// Parse a mongoose model and add generated fields (eg: urls, formatted dates)

controllers/flag.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
'use strict';
2+
3+
// Define some pseudo module globals
4+
var isPro = require('../libs/debug').isPro;
5+
var isDev = require('../libs/debug').isDev;
6+
var isDbg = require('../libs/debug').isDbg;
7+
8+
//
9+
10+
//--- Dependency inclusions
11+
var async = require('async');
12+
13+
//--- Model inclusions
14+
var Flag = require('../models/flag').Flag;
15+
var User = require('../models/user').User;
16+
17+
//--- Library inclusions
18+
var flagLib = require('../libs/flag');
19+
20+
//--- Configuration inclusions
21+
22+
//---
23+
exports.getFlaggedListForContent = function (aModelName, aOptions, aCallback) {
24+
25+
var content = aModelName.toLowerCase();
26+
var contentList = aOptions[content + 'List'] || [aOptions[content]];
27+
28+
async.forEachOf(contentList, function (aContent, aContentKey, aEachOuterCallback) {
29+
30+
// NOTE: Directly use indexed parent identifier allowing set of the dynamic, virtual, field
31+
// So basically do not use `aContent` anywhere in this function
32+
33+
// Always ensure a snapshot copy!
34+
if (contentList[aContentKey].toObject) {
35+
contentList[aContentKey] = contentList[aContentKey].toObject({
36+
virtuals: true
37+
});
38+
}
39+
40+
// Ensure reset
41+
contentList[aContentKey].flaggedList = [];
42+
43+
// Find any flags
44+
Flag.find({
45+
model: aModelName,
46+
_contentId: contentList[aContentKey]._id
47+
48+
}, function (aErr, aFlagList) {
49+
if (aErr || !aFlagList || aFlagList.length === 0) {
50+
aEachOuterCallback();
51+
return;
52+
}
53+
54+
aOptions.hasFlagged = true;
55+
56+
async.forEachOfSeries(aFlagList, function (aFlag, aFlagKey, aEachInnerCallback) {
57+
User.findOne({ _id: aFlag._userId }, function (aErr, aUser) {
58+
contentList[aContentKey].flaggedList.push({
59+
name: aUser.name,
60+
reason: aFlagList[aFlagKey].reason,
61+
since: aFlagList[aFlagKey]._since
62+
});
63+
aEachInnerCallback();
64+
});
65+
}, aEachOuterCallback);
66+
});
67+
68+
}, aCallback);
69+
}

controllers/index.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var Strategy = require('../models/strategy').Strategy;
1818

1919
var strategies = require('./strategies.json');
2020
var discussionLib = require('./discussion');
21+
var getFlaggedListForContent = require('./flag').getFlaggedListForContent;
2122
var modelParser = require('../libs/modelParser');
2223
var modelQuery = require('../libs/modelQuery');
2324
var execQueryTask = require('../libs/tasks').execQueryTask;
@@ -147,8 +148,25 @@ exports.home = function (aReq, aRes) {
147148
}
148149
}
149150
}
150-
function render() { aRes.render('pages/scriptListPage', options); }
151-
function asyncComplete() { preRender(); render(); }
151+
function render() {
152+
aRes.render('pages/scriptListPage', options);
153+
}
154+
function asyncComplete() {
155+
156+
async.parallel([
157+
function (aCallback) {
158+
if (!options.isFlagged || !options.isAdmin) { // NOTE: Watchpoint
159+
aCallback();
160+
return;
161+
}
162+
getFlaggedListForContent('Script', options, aCallback);
163+
}
164+
], function (aErr) {
165+
preRender();
166+
render();
167+
});
168+
169+
}
152170
async.parallel(tasks, asyncComplete);
153171
};
154172

controllers/script.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ var Group = require('../models/group').Group;
1616
var Script = require('../models/script').Script;
1717
var Vote = require('../models/vote').Vote;
1818

19+
1920
var scriptStorage = require('./scriptStorage');
2021
var addScriptToGroups = require('./group').addScriptToGroups;
22+
var getFlaggedListForContent = require('./flag').getFlaggedListForContent;
2123
var flagLib = require('../libs/flag');
2224
var removeLib = require('../libs/remove');
2325
var modelQuery = require('../libs/modelQuery');
@@ -319,8 +321,25 @@ exports.view = function (aReq, aRes, aNext) {
319321
script.description, _.pluck(script.groups, 'name'));
320322
}
321323
}
322-
function render() { aRes.render('pages/scriptPage', options); }
323-
function asyncComplete() { preRender(); render(); }
324+
function render() {
325+
aRes.render('pages/scriptPage', options);
326+
}
327+
function asyncComplete() {
328+
329+
async.parallel([
330+
function (aCallback) {
331+
if (!options.isAdmin) { // NOTE: Watchpoint
332+
aCallback();
333+
return;
334+
}
335+
getFlaggedListForContent('Script', options, aCallback);
336+
}
337+
], function (aErr) {
338+
preRender();
339+
render();
340+
});
341+
342+
}
324343

325344
//---
326345
if (aErr || !aScriptData) {

controllers/user.js

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ var Strategy = require('../models/strategy').Strategy;
1818
var User = require('../models/user').User;
1919
var Discussion = require('../models/discussion').Discussion;
2020

21+
// TODO: Possible unneccessary directory traversal
2122
var categories = require('../controllers/discussion').categories;
2223

24+
var getFlaggedListForContent = require('./flag').getFlaggedListForContent;
25+
2326
var userRoles = require('../models/userRoles.json');
2427
var scriptStorage = require('./scriptStorage');
2528
var modelParser = require('../libs/modelParser');
@@ -234,8 +237,29 @@ exports.userListPage = function (aReq, aRes, aNext) {
234237
pageMetadata(options, ['Flagged Users', 'Moderation']);
235238
}
236239
}
237-
function render() { aRes.render('pages/userListPage', options); }
238-
function asyncComplete(err) { if (err) { return aNext(); } else { preRender(); render(); } }
240+
function render() {
241+
aRes.render('pages/userListPage', options);
242+
}
243+
function asyncComplete(aErr) {
244+
if (aErr) {
245+
aNext();
246+
return;
247+
}
248+
249+
async.parallel([
250+
function (aCallback) {
251+
if (!options.isFlagged || !options.isAdmin) { // NOTE: Watchpoint
252+
aCallback();
253+
return;
254+
}
255+
getFlaggedListForContent('User', options, aCallback);
256+
}
257+
], function (aErr) {
258+
preRender();
259+
render();
260+
});
261+
262+
}
239263
async.parallel(tasks, asyncComplete);
240264
};
241265

@@ -292,9 +316,27 @@ exports.view = function (aReq, aRes, aNext) {
292316
tasks = tasks.concat(stats.getSummaryTasks(options));
293317

294318
//---
295-
function preRender() { }
296-
function render() { aRes.render('pages/userPage', options); }
297-
function asyncComplete() { preRender(); render(); }
319+
function preRender() {
320+
}
321+
function render() {
322+
aRes.render('pages/userPage', options);
323+
}
324+
function asyncComplete() {
325+
326+
async.parallel([
327+
function (aCallback) {
328+
if (!options.isAdmin) { // NOTE: Watchpoint
329+
aCallback();
330+
return;
331+
}
332+
getFlaggedListForContent('User', options, aCallback);
333+
}
334+
], function (aErr) {
335+
preRender();
336+
render();
337+
});
338+
339+
}
298340
async.parallel(tasks, asyncComplete);
299341
});
300342
};
@@ -410,13 +452,14 @@ exports.userCommentListPage = function (aReq, aRes, aNext) {
410452

411453
exports.userScriptListPage = function (aReq, aRes, aNext) {
412454
var authedUser = aReq.session.user;
413-
414455
var username = aReq.params.username;
415456

416457
User.findOne({
417458
name: caseInsensitive(username)
418459
}, function (aErr, aUserData) {
419-
if (aErr || !aUserData) { return aNext(); }
460+
if (aErr || !aUserData) {
461+
return aNext();
462+
}
420463

421464
//
422465
var options = {};
@@ -497,8 +540,25 @@ exports.userScriptListPage = function (aReq, aRes, aNext) {
497540
options.scriptListIsEmptyMessage = 'This user hasn\'t added any scripts yet.';
498541
}
499542
}
500-
function render() { aRes.render('pages/userScriptListPage', options); }
501-
function asyncComplete() { preRender(); render(); }
543+
function render() {
544+
aRes.render('pages/userScriptListPage', options);
545+
}
546+
function asyncComplete() {
547+
548+
async.parallel([
549+
function (aCallback) {
550+
if (!options.isFlagged || !options.isAdmin) { // NOTE: Watchpoint
551+
aCallback();
552+
return;
553+
}
554+
getFlaggedListForContent('Script', options, aCallback);
555+
}
556+
], function (aErr) {
557+
preRender();
558+
render();
559+
});
560+
561+
}
502562
async.parallel(tasks, asyncComplete);
503563
});
504564
};

controllers/vote.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
// Define some pseudo module globals
4+
var isPro = require('../libs/debug').isPro;
5+
var isDev = require('../libs/debug').isDev;
6+
var isDbg = require('../libs/debug').isDbg;
7+
8+
//
9+
10+
//--- Dependency inclusions
11+
12+
//--- Model inclusions
13+
14+
//--- Library inclusions
15+
var voteLib = require('../libs/vote');
16+
17+
//--- Configuration inclusions
18+
19+
//---

libs/modelParser.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,12 @@ moment.locale('en-tiny', {
6363
});
6464

6565
var parseDateProperty = function (aObj, aKey) {
66-
var date = aObj[aKey];
67-
if (date) {
68-
aObj[aKey + 'ISOFormat'] = date.toISOString();
69-
aObj[aKey + 'Humanized'] = moment(date).locale('en-tiny').calendar();
66+
if (aObj[aKey]) {
67+
var date = new Date(aObj[aKey]);
68+
if (date) {
69+
aObj[aKey + 'ISOFormat'] = date.toISOString();
70+
aObj[aKey + 'Humanized'] = moment(date).locale('en-tiny').calendar();
71+
}
7072
}
7173
};
7274

@@ -243,10 +245,9 @@ var parseUser = function (aUserData) {
243245
if (!aUserData) {
244246
return;
245247
}
246-
// var user = aUserData.toObject ? aUserData.toObject() : aUserData;
247248

248249
// Intermediates
249-
var user = aUserData;
250+
var user = aUserData.toObject ? aUserData.toObject({ virtuals: true }) : aUserData;
250251

251252
// Role
252253
user.isMod = user.role < 4;

libs/vote.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
// Define some pseudo module globals
4+
var isPro = require('../libs/debug').isPro;
5+
var isDev = require('../libs/debug').isDev;
6+
var isDbg = require('../libs/debug').isDbg;
7+
8+
//

models/flag.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ var Schema = mongoose.Schema;
1111

1212
var flagSchema = new Schema({
1313
model: String,
14+
reason: String,
1415
_contentId: Schema.Types.ObjectId,
1516
_userId: Schema.Types.ObjectId
1617
});
1718

19+
flagSchema.virtual('_since').get(function () {
20+
return this._id.getTimestamp();
21+
});
22+
1823
var Flag = mongoose.model('Flag', flagSchema);
1924

2025
exports.Flag = Flag;

public/css/common.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,8 @@ a.panel-heading {
302302
.reason-automated {
303303
opacity: 0.25;
304304
}
305+
306+
ul.flaggedList {
307+
list-style-type: none;
308+
padding-left: 0;
309+
}

0 commit comments

Comments
 (0)