diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-04-08 02:30:37 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-04-08 02:30:37 +0900 |
| commit | a1b490afa756a71b9cef4afa424575bc223bc612 (patch) | |
| tree | 06de4d839e17b1e08e0891542af7360c701a154a /src/server/api/endpoints/posts | |
| parent | Merge pull request #1392 from syuilo/greenkeeper/element-ui-2.3.3 (diff) | |
| download | sharkey-a1b490afa756a71b9cef4afa424575bc223bc612.tar.gz sharkey-a1b490afa756a71b9cef4afa424575bc223bc612.tar.bz2 sharkey-a1b490afa756a71b9cef4afa424575bc223bc612.zip | |
Post --> Note
Closes #1411
Diffstat (limited to 'src/server/api/endpoints/posts')
| -rw-r--r-- | src/server/api/endpoints/posts/context.ts | 63 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/create.ts | 108 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/favorites/create.ts | 48 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/favorites/delete.ts | 46 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/mentions.ts | 78 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/polls/recommendation.ts | 59 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/polls/vote.ts | 115 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/reactions.ts | 57 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/reactions/create.ts | 47 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/reactions/delete.ts | 60 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/replies.ts | 53 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/reposts.ts | 73 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/search.ts | 364 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/show.ts | 32 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/timeline.ts | 132 | ||||
| -rw-r--r-- | src/server/api/endpoints/posts/trend.ts | 79 |
16 files changed, 54 insertions, 1360 deletions
diff --git a/src/server/api/endpoints/posts/context.ts b/src/server/api/endpoints/posts/context.ts deleted file mode 100644 index 7abb045a49..0000000000 --- a/src/server/api/endpoints/posts/context.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Post, { pack } from '../../../../models/post'; - -/** - * Show a context of a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; - if (offsetErr) return rej('invalid offset param'); - - // Lookup post - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - const context = []; - let i = 0; - - async function get(id) { - i++; - const p = await Post.findOne({ _id: id }); - - if (i > offset) { - context.push(p); - } - - if (context.length == limit) { - return; - } - - if (p.replyId) { - await get(p.replyId); - } - } - - if (post.replyId) { - await get(post.replyId); - } - - // Serialize - res(await Promise.all(context.map(async post => - await pack(post, user)))); -}); diff --git a/src/server/api/endpoints/posts/create.ts b/src/server/api/endpoints/posts/create.ts index 003a892bc0..7e79912b1b 100644 --- a/src/server/api/endpoints/posts/create.ts +++ b/src/server/api/endpoints/posts/create.ts @@ -3,15 +3,15 @@ */ import $ from 'cafy'; import deepEqual = require('deep-equal'); -import Post, { IPost, isValidText, isValidCw, pack } from '../../../../models/post'; +import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note'; import { ILocalUser } from '../../../../models/user'; import Channel, { IChannel } from '../../../../models/channel'; import DriveFile from '../../../../models/drive-file'; -import create from '../../../../services/post/create'; +import create from '../../../../services/note/create'; import { IApp } from '../../../../models/app'; /** - * Create a post + * Create a note * * @param {any} params * @param {any} user @@ -79,26 +79,26 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res files = null; } - // Get 'repostId' parameter - const [repostId, repostIdErr] = $(params.repostId).optional.id().$; - if (repostIdErr) return rej('invalid repostId'); + // Get 'renoteId' parameter + const [renoteId, renoteIdErr] = $(params.renoteId).optional.id().$; + if (renoteIdErr) return rej('invalid renoteId'); - let repost: IPost = null; + let renote: INote = null; let isQuote = false; - if (repostId !== undefined) { - // Fetch repost to post - repost = await Post.findOne({ - _id: repostId + if (renoteId !== undefined) { + // Fetch renote to note + renote = await Note.findOne({ + _id: renoteId }); - if (repost == null) { - return rej('repostee is not found'); - } else if (repost.repostId && !repost.text && !repost.mediaIds) { - return rej('cannot repost to repost'); + if (renote == null) { + return rej('renoteee is not found'); + } else if (renote.renoteId && !renote.text && !renote.mediaIds) { + return rej('cannot renote to renote'); } - // Fetch recently post - const latestPost = await Post.findOne({ + // Fetch recently note + const latestNote = await Note.findOne({ userId: user._id }, { sort: { @@ -108,19 +108,19 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res isQuote = text != null || files != null; - // 直近と同じRepost対象かつ引用じゃなかったらエラー - if (latestPost && - latestPost.repostId && - latestPost.repostId.equals(repost._id) && + // 直近と同じRenote対象かつ引用じゃなかったらエラー + if (latestNote && + latestNote.renoteId && + latestNote.renoteId.equals(renote._id) && !isQuote) { - return rej('cannot repost same post that already reposted in your latest post'); + return rej('cannot renote same note that already reposted in your latest note'); } - // 直近がRepost対象かつ引用じゃなかったらエラー - if (latestPost && - latestPost._id.equals(repost._id) && + // 直近がRenote対象かつ引用じゃなかったらエラー + if (latestNote && + latestNote._id.equals(renote._id) && !isQuote) { - return rej('cannot repost your latest post'); + return rej('cannot renote your latest note'); } } @@ -128,20 +128,20 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res const [replyId, replyIdErr] = $(params.replyId).optional.id().$; if (replyIdErr) return rej('invalid replyId'); - let reply: IPost = null; + let reply: INote = null; if (replyId !== undefined) { // Fetch reply - reply = await Post.findOne({ + reply = await Note.findOne({ _id: replyId }); if (reply === null) { - return rej('in reply to post is not found'); + return rej('in reply to note is not found'); } - // 返信対象が引用でないRepostだったらエラー - if (reply.repostId && !reply.text && !reply.mediaIds) { - return rej('cannot reply to repost'); + // 返信対象が引用でないRenoteだったらエラー + if (reply.renoteId && !reply.text && !reply.mediaIds) { + return rej('cannot reply to renote'); } } @@ -165,14 +165,14 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res return rej('チャンネル内部からチャンネル外部の投稿に返信することはできません'); } - // Repost対象の投稿がこのチャンネルじゃなかったらダメ - if (repost && !channelId.equals(repost.channelId)) { - return rej('チャンネル内部からチャンネル外部の投稿をRepostすることはできません'); + // Renote対象の投稿がこのチャンネルじゃなかったらダメ + if (renote && !channelId.equals(renote.channelId)) { + return rej('チャンネル内部からチャンネル外部の投稿をRenoteすることはできません'); } - // 引用ではないRepostはダメ - if (repost && !isQuote) { - return rej('チャンネル内部では引用ではないRepostをすることはできません'); + // 引用ではないRenoteはダメ + if (renote && !isQuote) { + return rej('チャンネル内部では引用ではないRenoteをすることはできません'); } } else { // 返信対象の投稿がチャンネルへの投稿だったらダメ @@ -180,9 +180,9 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res return rej('チャンネル外部からチャンネル内部の投稿に返信することはできません'); } - // Repost対象の投稿がチャンネルへの投稿だったらダメ - if (repost && repost.channelId != null) { - return rej('チャンネル外部からチャンネル内部の投稿をRepostすることはできません'); + // Renote対象の投稿がチャンネルへの投稿だったらダメ + if (renote && renote.channelId != null) { + return rej('チャンネル外部からチャンネル内部の投稿をRenoteすることはできません'); } } @@ -203,23 +203,23 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res })); } - // テキストが無いかつ添付ファイルが無いかつRepostも無いかつ投票も無かったらエラー - if (text === undefined && files === null && repost === null && poll === undefined) { - return rej('text, mediaIds, repostId or poll is required'); + // テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー + if (text === undefined && files === null && renote === null && poll === undefined) { + return rej('text, mediaIds, renoteId or poll is required'); } // 直近の投稿と重複してたらエラー // TODO: 直近の投稿が一日前くらいなら重複とは見なさない - if (user.latestPost) { + if (user.latestNote) { if (deepEqual({ - text: user.latestPost.text, - reply: user.latestPost.replyId ? user.latestPost.replyId.toString() : null, - repost: user.latestPost.repostId ? user.latestPost.repostId.toString() : null, - mediaIds: (user.latestPost.mediaIds || []).map(id => id.toString()) + text: user.latestNote.text, + reply: user.latestNote.replyId ? user.latestNote.replyId.toString() : null, + renote: user.latestNote.renoteId ? user.latestNote.renoteId.toString() : null, + mediaIds: (user.latestNote.mediaIds || []).map(id => id.toString()) }, { text: text, reply: reply ? reply._id.toString() : null, - repost: repost ? repost._id.toString() : null, + renote: renote ? renote._id.toString() : null, mediaIds: (files || []).map(file => file._id.toString()) })) { return rej('duplicate'); @@ -227,13 +227,13 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res } // 投稿を作成 - const post = await create(user, { + const note = await create(user, { createdAt: new Date(), media: files, poll: poll, text: text, reply, - repost, + renote, cw: cw, tags: tags, app: app, @@ -242,10 +242,10 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res geo }); - const postObj = await pack(post, user); + const noteObj = await pack(note, user); // Reponse res({ - createdPost: postObj + createdNote: noteObj }); }); diff --git a/src/server/api/endpoints/posts/favorites/create.ts b/src/server/api/endpoints/posts/favorites/create.ts deleted file mode 100644 index f537fb7ddf..0000000000 --- a/src/server/api/endpoints/posts/favorites/create.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Favorite from '../../../../../models/favorite'; -import Post from '../../../../../models/post'; - -/** - * Favorite a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get favoritee - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // if already favorited - const exist = await Favorite.findOne({ - postId: post._id, - userId: user._id - }); - - if (exist !== null) { - return rej('already favorited'); - } - - // Create favorite - await Favorite.insert({ - createdAt: new Date(), - postId: post._id, - userId: user._id - }); - - // Send response - res(); -}); diff --git a/src/server/api/endpoints/posts/favorites/delete.ts b/src/server/api/endpoints/posts/favorites/delete.ts deleted file mode 100644 index 28930337a3..0000000000 --- a/src/server/api/endpoints/posts/favorites/delete.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Favorite from '../../../../../models/favorite'; -import Post from '../../../../../models/post'; - -/** - * Unfavorite a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get favoritee - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // if already favorited - const exist = await Favorite.findOne({ - postId: post._id, - userId: user._id - }); - - if (exist === null) { - return rej('already not favorited'); - } - - // Delete favorite - await Favorite.remove({ - _id: exist._id - }); - - // Send response - res(); -}); diff --git a/src/server/api/endpoints/posts/mentions.ts b/src/server/api/endpoints/posts/mentions.ts deleted file mode 100644 index d7302c0620..0000000000 --- a/src/server/api/endpoints/posts/mentions.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Post from '../../../../models/post'; -import getFriends from '../../common/get-friends'; -import { pack } from '../../../../models/post'; - -/** - * Get mentions of myself - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'following' parameter - const [following = false, followingError] = - $(params.following).optional.boolean().$; - if (followingError) return rej('invalid following param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$; - if (sinceIdErr) return rej('invalid sinceId param'); - - // Get 'untilId' parameter - const [untilId, untilIdErr] = $(params.untilId).optional.id().$; - if (untilIdErr) return rej('invalid untilId param'); - - // Check if both of sinceId and untilId is specified - if (sinceId && untilId) { - return rej('cannot set sinceId and untilId'); - } - - // Construct query - const query = { - mentions: user._id - } as any; - - const sort = { - _id: -1 - }; - - if (following) { - const followingIds = await getFriends(user._id); - - query.userId = { - $in: followingIds - }; - } - - if (sinceId) { - sort._id = 1; - query._id = { - $gt: sinceId - }; - } else if (untilId) { - query._id = { - $lt: untilId - }; - } - - // Issue query - const mentions = await Post - .find(query, { - limit: limit, - sort: sort - }); - - // Serialize - res(await Promise.all(mentions.map(async mention => - await pack(mention, user) - ))); -}); diff --git a/src/server/api/endpoints/posts/polls/recommendation.ts b/src/server/api/endpoints/posts/polls/recommendation.ts deleted file mode 100644 index d706742618..0000000000 --- a/src/server/api/endpoints/posts/polls/recommendation.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Vote from '../../../../../models/poll-vote'; -import Post, { pack } from '../../../../../models/post'; - -/** - * Get recommended polls - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; - if (offsetErr) return rej('invalid offset param'); - - // Get votes - const votes = await Vote.find({ - userId: user._id - }, { - fields: { - _id: false, - postId: true - } - }); - - const nin = votes && votes.length != 0 ? votes.map(v => v.postId) : []; - - const posts = await Post - .find({ - _id: { - $nin: nin - }, - userId: { - $ne: user._id - }, - poll: { - $exists: true, - $ne: null - } - }, { - limit: limit, - skip: offset, - sort: { - _id: -1 - } - }); - - // Serialize - res(await Promise.all(posts.map(async post => - await pack(post, user, { detail: true })))); -}); diff --git a/src/server/api/endpoints/posts/polls/vote.ts b/src/server/api/endpoints/posts/polls/vote.ts deleted file mode 100644 index c270cd09ab..0000000000 --- a/src/server/api/endpoints/posts/polls/vote.ts +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Vote from '../../../../../models/poll-vote'; -import Post from '../../../../../models/post'; -import Watching from '../../../../../models/post-watching'; -import watch from '../../../../../post/watch'; -import { publishPostStream } from '../../../../../publishers/stream'; -import notify from '../../../../../publishers/notify'; - -/** - * Vote poll of a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get votee - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - if (post.poll == null) { - return rej('poll not found'); - } - - // Get 'choice' parameter - const [choice, choiceError] = - $(params.choice).number() - .pipe(c => post.poll.choices.some(x => x.id == c)) - .$; - if (choiceError) return rej('invalid choice param'); - - // if already voted - const exist = await Vote.findOne({ - postId: post._id, - userId: user._id - }); - - if (exist !== null) { - return rej('already voted'); - } - - // Create vote - await Vote.insert({ - createdAt: new Date(), - postId: post._id, - userId: user._id, - choice: choice - }); - - // Send response - res(); - - const inc = {}; - inc[`poll.choices.${findWithAttr(post.poll.choices, 'id', choice)}.votes`] = 1; - - // Increment votes count - await Post.update({ _id: post._id }, { - $inc: inc - }); - - publishPostStream(post._id, 'poll_voted'); - - // Notify - notify(post.userId, user._id, 'poll_vote', { - postId: post._id, - choice: choice - }); - - // Fetch watchers - Watching - .find({ - postId: post._id, - userId: { $ne: user._id }, - // 削除されたドキュメントは除く - deletedAt: { $exists: false } - }, { - fields: { - userId: true - } - }) - .then(watchers => { - watchers.forEach(watcher => { - notify(watcher.userId, user._id, 'poll_vote', { - postId: post._id, - choice: choice - }); - }); - }); - - // この投稿をWatchする - if (user.account.settings.autoWatch !== false) { - watch(user._id, post); - } -}); - -function findWithAttr(array, attr, value) { - for (let i = 0; i < array.length; i += 1) { - if (array[i][attr] === value) { - return i; - } - } - return -1; -} diff --git a/src/server/api/endpoints/posts/reactions.ts b/src/server/api/endpoints/posts/reactions.ts deleted file mode 100644 index da733f5337..0000000000 --- a/src/server/api/endpoints/posts/reactions.ts +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Post from '../../../../models/post'; -import Reaction, { pack } from '../../../../models/post-reaction'; - -/** - * Show reactions of a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; - if (offsetErr) return rej('invalid offset param'); - - // Get 'sort' parameter - const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$; - if (sortError) return rej('invalid sort param'); - - // Lookup post - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // Issue query - const reactions = await Reaction - .find({ - postId: post._id, - deletedAt: { $exists: false } - }, { - limit: limit, - skip: offset, - sort: { - _id: sort == 'asc' ? 1 : -1 - } - }); - - // Serialize - res(await Promise.all(reactions.map(async reaction => - await pack(reaction, user)))); -}); diff --git a/src/server/api/endpoints/posts/reactions/create.ts b/src/server/api/endpoints/posts/reactions/create.ts deleted file mode 100644 index 71fa6a2955..0000000000 --- a/src/server/api/endpoints/posts/reactions/create.ts +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Reaction from '../../../../../models/post-reaction'; -import Post from '../../../../../models/post'; -import create from '../../../../../services/post/reaction/create'; - -/** - * React to a post - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get 'reaction' parameter - const [reaction, reactionErr] = $(params.reaction).string().or([ - 'like', - 'love', - 'laugh', - 'hmm', - 'surprise', - 'congrats', - 'angry', - 'confused', - 'pudding' - ]).$; - if (reactionErr) return rej('invalid reaction param'); - - // Fetch reactee - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - try { - await create(user, post, reaction); - } catch (e) { - rej(e); - } - - res(); -}); diff --git a/src/server/api/endpoints/posts/reactions/delete.ts b/src/server/api/endpoints/posts/reactions/delete.ts deleted file mode 100644 index 3a88bbd7ca..0000000000 --- a/src/server/api/endpoints/posts/reactions/delete.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Reaction from '../../../../../models/post-reaction'; -import Post from '../../../../../models/post'; -// import event from '../../../publishers/stream'; - -/** - * Unreact to a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Fetch unreactee - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // if already unreacted - const exist = await Reaction.findOne({ - postId: post._id, - userId: user._id, - deletedAt: { $exists: false } - }); - - if (exist === null) { - return rej('never reacted'); - } - - // Delete reaction - await Reaction.update({ - _id: exist._id - }, { - $set: { - deletedAt: new Date() - } - }); - - // Send response - res(); - - const dec = {}; - dec[`reactionCounts.${exist.reaction}`] = -1; - - // Decrement reactions count - Post.update({ _id: post._id }, { - $inc: dec - }); -}); diff --git a/src/server/api/endpoints/posts/replies.ts b/src/server/api/endpoints/posts/replies.ts deleted file mode 100644 index dd5a95c173..0000000000 --- a/src/server/api/endpoints/posts/replies.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Post, { pack } from '../../../../models/post'; - -/** - * Show a replies of a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; - if (offsetErr) return rej('invalid offset param'); - - // Get 'sort' parameter - const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$; - if (sortError) return rej('invalid sort param'); - - // Lookup post - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // Issue query - const replies = await Post - .find({ replyId: post._id }, { - limit: limit, - skip: offset, - sort: { - _id: sort == 'asc' ? 1 : -1 - } - }); - - // Serialize - res(await Promise.all(replies.map(async post => - await pack(post, user)))); -}); diff --git a/src/server/api/endpoints/posts/reposts.ts b/src/server/api/endpoints/posts/reposts.ts deleted file mode 100644 index ec6218ca38..0000000000 --- a/src/server/api/endpoints/posts/reposts.ts +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Post, { pack } from '../../../../models/post'; - -/** - * Show a reposts of a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$; - if (sinceIdErr) return rej('invalid sinceId param'); - - // Get 'untilId' parameter - const [untilId, untilIdErr] = $(params.untilId).optional.id().$; - if (untilIdErr) return rej('invalid untilId param'); - - // Check if both of sinceId and untilId is specified - if (sinceId && untilId) { - return rej('cannot set sinceId and untilId'); - } - - // Lookup post - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // Construct query - const sort = { - _id: -1 - }; - const query = { - repostId: post._id - } as any; - if (sinceId) { - sort._id = 1; - query._id = { - $gt: sinceId - }; - } else if (untilId) { - query._id = { - $lt: untilId - }; - } - - // Issue query - const reposts = await Post - .find(query, { - limit: limit, - sort: sort - }); - - // Serialize - res(await Promise.all(reposts.map(async post => - await pack(post, user)))); -}); diff --git a/src/server/api/endpoints/posts/search.ts b/src/server/api/endpoints/posts/search.ts deleted file mode 100644 index 21c4e77fdd..0000000000 --- a/src/server/api/endpoints/posts/search.ts +++ /dev/null @@ -1,364 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -const escapeRegexp = require('escape-regexp'); -import Post from '../../../../models/post'; -import User from '../../../../models/user'; -import Mute from '../../../../models/mute'; -import getFriends from '../../common/get-friends'; -import { pack } from '../../../../models/post'; - -/** - * Search a post - * - * @param {any} params - * @param {any} me - * @return {Promise<any>} - */ -module.exports = (params, me) => new Promise(async (res, rej) => { - // Get 'text' parameter - const [text, textError] = $(params.text).optional.string().$; - if (textError) return rej('invalid text param'); - - // Get 'includeUserIds' parameter - const [includeUserIds = [], includeUserIdsErr] = $(params.includeUserIds).optional.array('id').$; - if (includeUserIdsErr) return rej('invalid includeUserIds param'); - - // Get 'excludeUserIds' parameter - const [excludeUserIds = [], excludeUserIdsErr] = $(params.excludeUserIds).optional.array('id').$; - if (excludeUserIdsErr) return rej('invalid excludeUserIds param'); - - // Get 'includeUserUsernames' parameter - const [includeUserUsernames = [], includeUserUsernamesErr] = $(params.includeUserUsernames).optional.array('string').$; - if (includeUserUsernamesErr) return rej('invalid includeUserUsernames param'); - - // Get 'excludeUserUsernames' parameter - const [excludeUserUsernames = [], excludeUserUsernamesErr] = $(params.excludeUserUsernames).optional.array('string').$; - if (excludeUserUsernamesErr) return rej('invalid excludeUserUsernames param'); - - // Get 'following' parameter - const [following = null, followingErr] = $(params.following).optional.nullable.boolean().$; - if (followingErr) return rej('invalid following param'); - - // Get 'mute' parameter - const [mute = 'mute_all', muteErr] = $(params.mute).optional.string().$; - if (muteErr) return rej('invalid mute param'); - - // Get 'reply' parameter - const [reply = null, replyErr] = $(params.reply).optional.nullable.boolean().$; - if (replyErr) return rej('invalid reply param'); - - // Get 'repost' parameter - const [repost = null, repostErr] = $(params.repost).optional.nullable.boolean().$; - if (repostErr) return rej('invalid repost param'); - - // Get 'media' parameter - const [media = null, mediaErr] = $(params.media).optional.nullable.boolean().$; - if (mediaErr) return rej('invalid media param'); - - // Get 'poll' parameter - const [poll = null, pollErr] = $(params.poll).optional.nullable.boolean().$; - if (pollErr) return rej('invalid poll param'); - - // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $(params.sinceDate).optional.number().$; - if (sinceDateErr) throw 'invalid sinceDate param'; - - // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $(params.untilDate).optional.number().$; - if (untilDateErr) throw 'invalid untilDate param'; - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; - if (offsetErr) return rej('invalid offset param'); - - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 30).$; - if (limitErr) return rej('invalid limit param'); - - let includeUsers = includeUserIds; - if (includeUserUsernames != null) { - const ids = (await Promise.all(includeUserUsernames.map(async (username) => { - const _user = await User.findOne({ - usernameLower: username.toLowerCase() - }); - return _user ? _user._id : null; - }))).filter(id => id != null); - includeUsers = includeUsers.concat(ids); - } - - let excludeUsers = excludeUserIds; - if (excludeUserUsernames != null) { - const ids = (await Promise.all(excludeUserUsernames.map(async (username) => { - const _user = await User.findOne({ - usernameLower: username.toLowerCase() - }); - return _user ? _user._id : null; - }))).filter(id => id != null); - excludeUsers = excludeUsers.concat(ids); - } - - search(res, rej, me, text, includeUsers, excludeUsers, following, - mute, reply, repost, media, poll, sinceDate, untilDate, offset, limit); -}); - -async function search( - res, rej, me, text, includeUserIds, excludeUserIds, following, - mute, reply, repost, media, poll, sinceDate, untilDate, offset, max) { - - let q: any = { - $and: [] - }; - - const push = x => q.$and.push(x); - - if (text) { - // 完全一致検索 - if (/"""(.+?)"""/.test(text)) { - const x = text.match(/"""(.+?)"""/)[1]; - push({ - text: x - }); - } else { - const tags = text.split(' ').filter(x => x[0] == '#'); - if (tags) { - push({ - $and: tags.map(x => ({ - tags: x - })) - }); - } - - push({ - $and: text.split(' ').map(x => ({ - // キーワードが-で始まる場合そのキーワードを除外する - text: x[0] == '-' ? { - $not: new RegExp(escapeRegexp(x.substr(1))) - } : new RegExp(escapeRegexp(x)) - })) - }); - } - } - - if (includeUserIds && includeUserIds.length != 0) { - push({ - userId: { - $in: includeUserIds - } - }); - } else if (excludeUserIds && excludeUserIds.length != 0) { - push({ - userId: { - $nin: excludeUserIds - } - }); - } - - if (following != null && me != null) { - const ids = await getFriends(me._id, false); - push({ - userId: following ? { - $in: ids - } : { - $nin: ids.concat(me._id) - } - }); - } - - if (me != null) { - const mutes = await Mute.find({ - muterId: me._id, - deletedAt: { $exists: false } - }); - const mutedUserIds = mutes.map(m => m.muteeId); - - switch (mute) { - case 'mute_all': - push({ - userId: { - $nin: mutedUserIds - }, - '_reply.userId': { - $nin: mutedUserIds - }, - '_repost.userId': { - $nin: mutedUserIds - } - }); - break; - case 'mute_related': - push({ - '_reply.userId': { - $nin: mutedUserIds - }, - '_repost.userId': { - $nin: mutedUserIds - } - }); - break; - case 'mute_direct': - push({ - userId: { - $nin: mutedUserIds - } - }); - break; - case 'direct_only': - push({ - userId: { - $in: mutedUserIds - } - }); - break; - case 'related_only': - push({ - $or: [{ - '_reply.userId': { - $in: mutedUserIds - } - }, { - '_repost.userId': { - $in: mutedUserIds - } - }] - }); - break; - case 'all_only': - push({ - $or: [{ - userId: { - $in: mutedUserIds - } - }, { - '_reply.userId': { - $in: mutedUserIds - } - }, { - '_repost.userId': { - $in: mutedUserIds - } - }] - }); - break; - } - } - - if (reply != null) { - if (reply) { - push({ - replyId: { - $exists: true, - $ne: null - } - }); - } else { - push({ - $or: [{ - replyId: { - $exists: false - } - }, { - replyId: null - }] - }); - } - } - - if (repost != null) { - if (repost) { - push({ - repostId: { - $exists: true, - $ne: null - } - }); - } else { - push({ - $or: [{ - repostId: { - $exists: false - } - }, { - repostId: null - }] - }); - } - } - - if (media != null) { - if (media) { - push({ - mediaIds: { - $exists: true, - $ne: null - } - }); - } else { - push({ - $or: [{ - mediaIds: { - $exists: false - } - }, { - mediaIds: null - }] - }); - } - } - - if (poll != null) { - if (poll) { - push({ - poll: { - $exists: true, - $ne: null - } - }); - } else { - push({ - $or: [{ - poll: { - $exists: false - } - }, { - poll: null - }] - }); - } - } - - if (sinceDate) { - push({ - createdAt: { - $gt: new Date(sinceDate) - } - }); - } - - if (untilDate) { - push({ - createdAt: { - $lt: new Date(untilDate) - } - }); - } - - if (q.$and.length == 0) { - q = {}; - } - - // Search posts - const posts = await Post - .find(q, { - sort: { - _id: -1 - }, - limit: max, - skip: offset - }); - - // Serialize - res(await Promise.all(posts.map(async post => - await pack(post, me)))); -} diff --git a/src/server/api/endpoints/posts/show.ts b/src/server/api/endpoints/posts/show.ts deleted file mode 100644 index e1781b545c..0000000000 --- a/src/server/api/endpoints/posts/show.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import Post, { pack } from '../../../../models/post'; - -/** - * Show a post - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'postId' parameter - const [postId, postIdErr] = $(params.postId).id().$; - if (postIdErr) return rej('invalid postId param'); - - // Get post - const post = await Post.findOne({ - _id: postId - }); - - if (post === null) { - return rej('post not found'); - } - - // Serialize - res(await pack(post, user, { - detail: true - })); -}); diff --git a/src/server/api/endpoints/posts/timeline.ts b/src/server/api/endpoints/posts/timeline.ts deleted file mode 100644 index b58d25fa80..0000000000 --- a/src/server/api/endpoints/posts/timeline.ts +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import rap from '@prezzemolo/rap'; -import Post from '../../../../models/post'; -import Mute from '../../../../models/mute'; -import ChannelWatching from '../../../../models/channel-watching'; -import getFriends from '../../common/get-friends'; -import { pack } from '../../../../models/post'; - -/** - * Get timeline of myself - * - * @param {any} params - * @param {any} user - * @param {any} app - * @return {Promise<any>} - */ -module.exports = async (params, user, app) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) throw 'invalid limit param'; - - // Get 'sinceId' parameter - const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$; - if (sinceIdErr) throw 'invalid sinceId param'; - - // Get 'untilId' parameter - const [untilId, untilIdErr] = $(params.untilId).optional.id().$; - if (untilIdErr) throw 'invalid untilId param'; - - // Get 'sinceDate' parameter - const [sinceDate, sinceDateErr] = $(params.sinceDate).optional.number().$; - if (sinceDateErr) throw 'invalid sinceDate param'; - - // Get 'untilDate' parameter - const [untilDate, untilDateErr] = $(params.untilDate).optional.number().$; - if (untilDateErr) throw 'invalid untilDate param'; - - // Check if only one of sinceId, untilId, sinceDate, untilDate specified - if ([sinceId, untilId, sinceDate, untilDate].filter(x => x != null).length > 1) { - throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified'; - } - - const { followingIds, watchingChannelIds, mutedUserIds } = await rap({ - // ID list of the user itself and other users who the user follows - followingIds: getFriends(user._id), - - // Watchしているチャンネルを取得 - watchingChannelIds: ChannelWatching.find({ - userId: user._id, - // 削除されたドキュメントは除く - deletedAt: { $exists: false } - }).then(watches => watches.map(w => w.channelId)), - - // ミュートしているユーザーを取得 - mutedUserIds: Mute.find({ - muterId: user._id, - // 削除されたドキュメントは除く - deletedAt: { $exists: false } - }).then(ms => ms.map(m => m.muteeId)) - }); - - //#region Construct query - const sort = { - _id: -1 - }; - - const query = { - $or: [{ - // フォローしている人のタイムラインへの投稿 - userId: { - $in: followingIds - }, - // 「タイムラインへの」投稿に限定するためにチャンネルが指定されていないもののみに限る - $or: [{ - channelId: { - $exists: false - } - }, { - channelId: null - }] - }, { - // Watchしているチャンネルへの投稿 - channelId: { - $in: watchingChannelIds - } - }], - // mute - userId: { - $nin: mutedUserIds - }, - '_reply.userId': { - $nin: mutedUserIds - }, - '_repost.userId': { - $nin: mutedUserIds - }, - } as any; - - if (sinceId) { - sort._id = 1; - query._id = { - $gt: sinceId - }; - } else if (untilId) { - query._id = { - $lt: untilId - }; - } else if (sinceDate) { - sort._id = 1; - query.createdAt = { - $gt: new Date(sinceDate) - }; - } else if (untilDate) { - query.createdAt = { - $lt: new Date(untilDate) - }; - } - //#endregion - - // Issue query - const timeline = await Post - .find(query, { - limit: limit, - sort: sort - }); - - // Serialize - return await Promise.all(timeline.map(post => pack(post, user))); -}; diff --git a/src/server/api/endpoints/posts/trend.ts b/src/server/api/endpoints/posts/trend.ts deleted file mode 100644 index dbee169138..0000000000 --- a/src/server/api/endpoints/posts/trend.ts +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Module dependencies - */ -const ms = require('ms'); -import $ from 'cafy'; -import Post, { pack } from '../../../../models/post'; - -/** - * Get trend posts - * - * @param {any} params - * @param {any} user - * @return {Promise<any>} - */ -module.exports = (params, user) => new Promise(async (res, rej) => { - // Get 'limit' parameter - const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; - if (limitErr) return rej('invalid limit param'); - - // Get 'offset' parameter - const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; - if (offsetErr) return rej('invalid offset param'); - - // Get 'reply' parameter - const [reply, replyErr] = $(params.reply).optional.boolean().$; - if (replyErr) return rej('invalid reply param'); - - // Get 'repost' parameter - const [repost, repostErr] = $(params.repost).optional.boolean().$; - if (repostErr) return rej('invalid repost param'); - - // Get 'media' parameter - const [media, mediaErr] = $(params.media).optional.boolean().$; - if (mediaErr) return rej('invalid media param'); - - // Get 'poll' parameter - const [poll, pollErr] = $(params.poll).optional.boolean().$; - if (pollErr) return rej('invalid poll param'); - - const query = { - createdAt: { - $gte: new Date(Date.now() - ms('1days')) - }, - repostCount: { - $gt: 0 - } - } as any; - - if (reply != undefined) { - query.replyId = reply ? { $exists: true, $ne: null } : null; - } - - if (repost != undefined) { - query.repostId = repost ? { $exists: true, $ne: null } : null; - } - - if (media != undefined) { - query.mediaIds = media ? { $exists: true, $ne: null } : null; - } - - if (poll != undefined) { - query.poll = poll ? { $exists: true, $ne: null } : null; - } - - // Issue query - const posts = await Post - .find(query, { - limit: limit, - skip: offset, - sort: { - repostCount: -1, - _id: -1 - } - }); - - // Serialize - res(await Promise.all(posts.map(async post => - await pack(post, user, { detail: true })))); -}); |