summaryrefslogtreecommitdiff
path: root/src/api/endpoints
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2017-09-08 23:29:33 +0900
committersyuilo <syuilotan@yahoo.co.jp>2017-09-08 23:29:33 +0900
commit13a568889cabd36539b6205acbb0f9ce42b6419b (patch)
treeb8c54306634d84434c3358290155daf492d76594 /src/api/endpoints
parentImplement #771 (diff)
downloadsharkey-13a568889cabd36539b6205acbb0f9ce42b6419b.tar.gz
sharkey-13a568889cabd36539b6205acbb0f9ce42b6419b.tar.bz2
sharkey-13a568889cabd36539b6205acbb0f9ce42b6419b.zip
Implement #770
Diffstat (limited to 'src/api/endpoints')
-rw-r--r--src/api/endpoints/users/get_frequently_replied_users.ts96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/api/endpoints/users/get_frequently_replied_users.ts b/src/api/endpoints/users/get_frequently_replied_users.ts
new file mode 100644
index 0000000000..2e0e2e40a7
--- /dev/null
+++ b/src/api/endpoints/users/get_frequently_replied_users.ts
@@ -0,0 +1,96 @@
+/**
+ * Module dependencies
+ */
+import $ from 'cafy';
+import Post from '../../models/post';
+import User from '../../models/user';
+import serialize from '../../serializers/user';
+
+module.exports = (params, me) => new Promise(async (res, rej) => {
+ // Get 'user_id' parameter
+ const [userId, userIdErr] = $(params.user_id).id().$;
+ if (userIdErr) return rej('invalid user_id param');
+
+ // Lookup user
+ const user = await User.findOne({
+ _id: userId
+ }, {
+ fields: {
+ _id: true
+ }
+ });
+
+ if (user === null) {
+ return rej('user not found');
+ }
+
+ // Fetch recent posts
+ const recentPosts = await Post.find({
+ user_id: user._id,
+ reply_to_id: {
+ $exists: true,
+ $ne: null
+ }
+ }, {
+ sort: {
+ _id: -1
+ },
+ limit: 1000,
+ fields: {
+ _id: false,
+ reply_to_id: true
+ }
+ });
+
+ // 投稿が少なかったら中断
+ if (recentPosts.length === 0) {
+ return res([]);
+ }
+
+ const replyTargetPosts = await Post.find({
+ _id: {
+ $in: recentPosts.map(p => p.reply_to_id)
+ },
+ user_id: {
+ $ne: user._id
+ }
+ }, {
+ fields: {
+ _id: false,
+ user_id: true
+ }
+ });
+
+ const repliedUsers = {};
+
+ // Extract replies from recent posts
+ replyTargetPosts.forEach(post => {
+ const userId = post.user_id.toString();
+ if (repliedUsers[userId]) {
+ repliedUsers[userId]++;
+ } else {
+ repliedUsers[userId] = 1;
+ }
+ });
+
+ // Calc peak
+ let peak = 0;
+ Object.keys(repliedUsers).forEach(user => {
+ if (repliedUsers[user] > peak) peak = repliedUsers[user];
+ });
+
+ // Sort replies by frequency
+ const repliedUsersSorted = Object.keys(repliedUsers).sort((a, b) => repliedUsers[b] - repliedUsers[a]);
+
+ // Lookup top 10 replies
+ const topRepliedUsers = repliedUsersSorted.slice(0, 10);
+
+ // Make replies object (includes weights)
+ const repliesObj = await Promise.all(topRepliedUsers.map(async (user) => ({
+ user: await serialize(user, me, { detail: true }),
+ weight: repliedUsers[user] / peak
+ })));
+
+ // Response
+ res(repliesObj);
+});