seems better - aggregate on dlete, increment on new post

merge-requests/208/head
fatchan 5 years ago
parent 2adb6dfa11
commit 620d873c88
  1. 48
      controllers/forms.js
  2. 51
      db/posts.js
  3. 12
      models/forms/deletepostsfiles.js
  4. 9
      models/forms/make-post.js
  5. 2
      views/mixins/catalogtile.pug

@ -312,7 +312,7 @@ router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, a
if (req.body.ban_reason && req.body.ban_reason.length > 50) { if (req.body.ban_reason && req.body.ban_reason.length > 50) {
errors.push('Ban reason must be 50 characters or less'); errors.push('Ban reason must be 50 characters or less');
} }
if (req.body.report && (!req.body.report_reason || req.body.report_reason.length === 0)) { if ((req.body.report || req.body.global_report) && (!req.body.report_reason || req.body.report_reason.length === 0)) {
errors.push('Reports must have a reason') errors.push('Reports must have a reason')
} }
@ -362,6 +362,7 @@ router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, a
const messages = []; const messages = [];
const combinedQuery = {}; const combinedQuery = {};
const passwordCombinedQuery = {}; const passwordCombinedQuery = {};
let aggregateNeeded = false;
try { try {
if (hasPerms) { if (hasPerms) {
// if getting global banned, board ban doesnt matter // if getting global banned, board ban doesnt matter
@ -376,11 +377,13 @@ router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, a
if (req.body.delete) { if (req.body.delete) {
const { message } = await deletePosts(req, res, next, passwordPosts); const { message } = await deletePosts(req, res, next, passwordPosts);
messages.push(message); messages.push(message);
aggregateNeeded = true;
} else { } else {
// if it was getting deleted, we cant do any of these // if it was getting deleted, we cant do any of these
if (req.body.delete_file) { if (req.body.delete_file) {
const { message, action, query } = await deletePostsFiles(passwordPosts); const { message, action, query } = await deletePostsFiles(passwordPosts);
if (action) { if (action) {
aggregateNeeded = true;
passwordCombinedQuery[action] = { ...passwordCombinedQuery[action], ...query} passwordCombinedQuery[action] = { ...passwordCombinedQuery[action], ...query}
} }
messages.push(message); messages.push(message);
@ -464,6 +467,20 @@ router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, a
) )
} }
await Promise.all(dbPromises); await Promise.all(dbPromises);
if (aggregateNeeded) {
const threadsToUpdate = [...new Set(posts.filter(post => post.thread !== null))];
//recalculate and set correct aggregation numbers again
await Promise.all(threadsToUpdate.map(async (post) => {
const replyCounts = await Posts.getReplyCounts(post.board, post.thread);
let replyposts = 0;
let replyfiles = 0;
if (replyCounts[0]) {
replyposts = replyCounts[0].replyposts;
replyfiles = replyCounts[0].replyfiles;
}
Posts.setReplyCounts(post.board, post.thread, replyposts, replyfiles);
}));
}
} catch (err) { } catch (err) {
return next(err); return next(err);
} }
@ -562,6 +579,7 @@ router.post('/global/actions', checkPermsMiddleware, numberConverter, async(req,
const postMongoIds = posts.map(post => Mongo.ObjectId(post._id)); const postMongoIds = posts.map(post => Mongo.ObjectId(post._id));
const messages = []; const messages = [];
const combinedQuery = {}; const combinedQuery = {};
let aggregateNeeded = false;
try { try {
if (req.body.global_ban) { if (req.body.global_ban) {
const { message } = await banPoster(req, res, next, null, posts); const { message } = await banPoster(req, res, next, null, posts);
@ -570,11 +588,13 @@ router.post('/global/actions', checkPermsMiddleware, numberConverter, async(req,
if (req.body.delete) { if (req.body.delete) {
const { message } = await deletePosts(req, res, next, posts); const { message } = await deletePosts(req, res, next, posts);
messages.push(message); messages.push(message);
aggregateNeeded = true;
} else { } else {
// if it was getting deleted, we cant do any of these // if it was getting deleted, we cant do any of these
if (req.body.delete_file) { if (req.body.delete_file) {
const { message, action, query } = await deletePostsFiles(posts); const { message, action, query } = await deletePostsFiles(posts);
if (action) { if (action) {
aggregateNeeded = true;
combinedQuery[action] = { ...combinedQuery[action], ...query} combinedQuery[action] = { ...combinedQuery[action], ...query}
} }
messages.push(message); messages.push(message);
@ -587,11 +607,27 @@ router.post('/global/actions', checkPermsMiddleware, numberConverter, async(req,
messages.push(message); messages.push(message);
} }
} }
await Posts.db.updateMany({ if (Object.keys(combinedQuery).length > 0) {
'_id': { await Posts.db.updateMany({
'$in': postMongoIds '_id': {
} '$in': postMongoIds
}, combinedQuery) }
}, combinedQuery);
}
if (aggregateNeeded) {
const threadsToUpdate = [...new Set(posts.filter(post => post.thread !== null))];
//recalculate and set correct aggregation numbers again
await Promise.all(threadsToUpdate.map(async (post) => {
const replyCounts = await Posts.getReplyCounts(post.board, post.thread);
let replyposts = 0;
let replyfiles = 0;
if (replyCounts[0]) {
replyposts = replyCounts[0].replyposts;
replyfiles = replyCounts[0].replyfiles;
}
Posts.setReplyCounts(post.board, post.thread, replyposts, replyfiles);
}));
}
} catch (err) { } catch (err) {
return next(err); return next(err);
} }

@ -49,18 +49,17 @@ module.exports = {
//temporary mitigation for deletion issue //temporary mitigation for deletion issue
if (replies.length >= 5) { if (replies.length >= 5) {
//count omitted image and posts //cout omitted image and posts
const counts = await module.exports.getOmitted(board, thread.postId);
const numPreviewImages = replies.reduce((acc, post) => { return acc + post.files.length }, 0); const numPreviewImages = replies.reduce((acc, post) => { return acc + post.files.length }, 0);
thread.omittedimages = counts[0].images - numPreviewImages; thread.omittedimages = thread.replyfiles - numPreviewImages;
thread.omittedposts = counts[0].posts - replies.length; thread.omittedposts = thread.replyposts - replies.length;
} }
})); }));
return threads; return threads;
}, },
getOmitted: (board, thread) => { getReplyCounts: (board, thread) => {
return db.aggregate([ return db.aggregate([
{ {
'$match': { '$match': {
@ -70,12 +69,10 @@ module.exports = {
}, { }, {
'$group': { '$group': {
'_id': null, '_id': null,
// omitted posts is number of documents returned 'replyposts': {
'posts': {
'$sum': 1 '$sum': 1
}, },
//files is sum of all length of files arrays 'replyfiles': {
'images': {
'$sum': { '$sum': {
'$size': '$files' '$size': '$files'
} }
@ -85,6 +82,18 @@ module.exports = {
]).toArray(); ]).toArray();
}, },
setReplyCounts: (board, thread, replyposts, replyfiles) => {
return db.updateOne({
'postId': thread,
'board': board
}, {
'$set': {
'replyposts': replyposts,
'replyfiles': replyfiles,
}
})
},
getPages: (board) => { getPages: (board) => {
return db.countDocuments({ return db.countDocuments({
'board': board, 'board': board,
@ -93,7 +102,6 @@ module.exports = {
}, },
getThread: async (board, id) => { getThread: async (board, id) => {
// get thread post and potential replies concurrently // get thread post and potential replies concurrently
const data = await Promise.all([ const data = await Promise.all([
db.findOne({ db.findOne({
@ -111,13 +119,11 @@ module.exports = {
}), }),
module.exports.getThreadPosts(board, id) module.exports.getThreadPosts(board, id)
]) ])
// attach the replies to the thread post // attach the replies to the thread post
const thread = data[0]; const thread = data[0];
if (thread) { if (thread) {
thread.replies = data[1]; thread.replies = data[1];
} }
return thread; return thread;
}, },
@ -225,18 +231,25 @@ module.exports = {
insertOne: async (board, data, thread) => { insertOne: async (board, data, thread) => {
//if a reply to thread, bump if not sage
if (data.thread !== null && data.email !== 'sage' && !thread.saged) { if (data.thread !== null && data.email !== 'sage' && !thread.saged) {
await db.updateOne({ const filter = {
'postId': data.thread, 'postId': data.thread,
'board': board 'board': board
}, { }
'$set': { const query = {
'bumped':Date.now() '$inc': {
'replyposts': 1,
'replyfiles': data.files.length
} }
}); }
if (data.email !== 'sage' && !thread.saged) {
query['$set'] = {
'bumped': Date.now()
}
}
await db.updateOne(filter, query);
} else { } else {
//this is a new thread, so set the bump date instead //this is a new thread, so set the bump date
data.bumped = Date.now() data.bumped = Date.now()
} }

@ -14,6 +14,12 @@ module.exports = async (posts) => {
fileNames = fileNames.concat(post.files.map(x => x.filename)) fileNames = fileNames.concat(post.files.map(x => x.filename))
}) })
if (fileNames.length === 0) {
return {
message: 'No files to delete'
}
}
//delete all the files using the filenames //delete all the files using the filenames
await Promise.all(fileNames.map(async filename => { await Promise.all(fileNames.map(async filename => {
//dont question it. //dont question it.
@ -23,12 +29,6 @@ module.exports = async (posts) => {
]) ])
})); }));
if (fileNames.length === 0) {
return {
message: 'No files to delete'
}
}
return { return {
message:`Deleted ${fileNames.length} file(s) across ${posts.length} post(s)`, message:`Deleted ${fileNames.length} file(s) across ${posts.length} post(s)`,
action:'$set', action:'$set',

@ -55,6 +55,13 @@ module.exports = async (req, res, next, numFiles) => {
'redirect': redirect 'redirect': redirect
}); });
} }
if (thread.replyposts >= 100) { //reply limit
return res.status(400).render('message', {
'title': 'Bad request',
'message': 'Thread reached reply limit',
'redirect': redirect
});
}
salt = thread.salt; salt = thread.salt;
redirect += `/thread/${req.body.thread}` redirect += `/thread/${req.body.thread}`
} }
@ -193,6 +200,8 @@ module.exports = async (req, res, next, numFiles) => {
'files': files, 'files': files,
'reports': [], 'reports': [],
'globalreports': [], 'globalreports': [],
'replyposts': 0,
'replyfiles': 0,
'sticky': false, 'sticky': false,
'locked': false, 'locked': false,
'saged': false, 'saged': false,

@ -15,7 +15,7 @@ mixin catalogtile(board, post, truncate)
header.post-info header.post-info
span: a(href=postURL) ##{post.postId} span: a(href=postURL) ##{post.postId}
span Replies: #{post.replyposts} span Replies: #{post.replyposts}
span Images: #{post.replyimages} span Images: #{post.replyfiles}
br br
if post.message if post.message
blockquote.no-m-p.post-message !{post.message} blockquote.no-m-p.post-message !{post.message}

Loading…
Cancel
Save