You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nodebb/src/posts/summary.js

98 lines
3.3 KiB
JavaScript

'use strict';
const validator = require('validator');
const _ = require('lodash');
const topics = require('../topics');
const user = require('../user');
const plugins = require('../plugins');
const categories = require('../categories');
const utils = require('../utils');
module.exports = function (Posts) {
Posts.getPostSummaryByPids = async function (pids, uid, options) {
if (!Array.isArray(pids) || !pids.length) {
return [];
}
options.stripTags = options.hasOwnProperty('stripTags') ? options.stripTags : false;
options.parse = options.hasOwnProperty('parse') ? options.parse : true;
options.extraFields = options.hasOwnProperty('extraFields') ? options.extraFields : [];
const fields = ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted', 'upvotes', 'downvotes'].concat(options.extraFields);
let posts = await Posts.getPostsFields(pids, fields);
posts = posts.filter(Boolean);
posts = await user.blocks.filter(uid, posts);
const uids = _.uniq(posts.map(p => p && p.uid));
const tids = _.uniq(posts.map(p => p && p.tid));
const [users, topicsAndCategories] = await Promise.all([
user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'status']),
getTopicAndCategories(tids),
]);
const uidToUser = toObject('uid', users);
const tidToTopic = toObject('tid', topicsAndCategories.topics);
const cidToCategory = toObject('cid', topicsAndCategories.categories);
posts.forEach(function (post) {
// If the post author isn't represented in the retrieved users' data, then it means they were deleted, assume guest.
if (!uidToUser.hasOwnProperty(post.uid)) {
post.uid = 0;
}
post.user = uidToUser[post.uid];
post.topic = tidToTopic[post.tid];
post.category = post.topic && cidToCategory[post.topic.cid];
post.isMainPost = post.topic && post.pid === post.topic.mainPid;
post.deleted = post.deleted === 1;
post.timestampISO = utils.toISOString(post.timestamp);
});
posts = posts.filter(post => tidToTopic[post.tid]);
posts = await parsePosts(posts, options);
const result = await plugins.fireHook('filter:post.getPostSummaryByPids', { posts: posts, uid: uid });
return result.posts;
};
async function parsePosts(posts, options) {
async function parse(post) {
if (!post.content || !options.parse) {
post.content = post.content ? validator.escape(String(post.content)) : post.content;
return post;
}
post = await Posts.parsePost(post);
if (options.stripTags) {
post.content = stripTags(post.content);
}
return post;
}
return await Promise.all(posts.map(p => parse(p)));
}
async function getTopicAndCategories(tids) {
const topicsData = await topics.getTopicsFields(tids, ['uid', 'tid', 'title', 'cid', 'slug', 'deleted', 'postcount', 'mainPid']);
const cids = _.uniq(topicsData.map(topic => topic && topic.cid));
const categoriesData = await categories.getCategoriesFields(cids, ['cid', 'name', 'icon', 'slug', 'parentCid', 'bgColor', 'color', 'image', 'imageClass']);
return { topics: topicsData, categories: categoriesData };
}
function toObject(key, data) {
var obj = {};
for (var i = 0; i < data.length; i += 1) {
obj[data[i][key]] = data[i];
}
return obj;
}
function stripTags(content) {
if (content) {
return utils.stripHTMLTags(content, utils.stripTags);
}
return content;
}
};