From 6e181ee0f1ca2ecd0fdf3a78654607ef112f2a6a Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 3 Mar 2017 06:48:26 +0900 Subject: wip --- src/api/endpoints/posts/context.ts | 6 +- src/api/endpoints/posts/likes.ts | 8 +-- src/api/endpoints/posts/replies.js | 72 ------------------- src/api/endpoints/posts/replies.ts | 58 +++++++++++++++ src/api/endpoints/posts/reposts.js | 84 ---------------------- src/api/endpoints/posts/reposts.ts | 78 ++++++++++++++++++++ src/api/endpoints/posts/search.js | 137 ------------------------------------ src/api/endpoints/posts/search.ts | 123 ++++++++++++++++++++++++++++++++ src/api/endpoints/posts/show.js | 44 ------------ src/api/endpoints/posts/show.ts | 37 ++++++++++ src/api/endpoints/posts/timeline.js | 77 -------------------- src/api/endpoints/posts/timeline.ts | 73 +++++++++++++++++++ 12 files changed, 376 insertions(+), 421 deletions(-) delete mode 100644 src/api/endpoints/posts/replies.js create mode 100644 src/api/endpoints/posts/replies.ts delete mode 100644 src/api/endpoints/posts/reposts.js create mode 100644 src/api/endpoints/posts/reposts.ts delete mode 100644 src/api/endpoints/posts/search.js create mode 100644 src/api/endpoints/posts/search.ts delete mode 100644 src/api/endpoints/posts/show.js create mode 100644 src/api/endpoints/posts/show.ts delete mode 100644 src/api/endpoints/posts/timeline.js create mode 100644 src/api/endpoints/posts/timeline.ts diff --git a/src/api/endpoints/posts/context.ts b/src/api/endpoints/posts/context.ts index 53fc4737e5..5b0a56f356 100644 --- a/src/api/endpoints/posts/context.ts +++ b/src/api/endpoints/posts/context.ts @@ -19,15 +19,15 @@ module.exports = (params, user) => { // Get 'post_id' parameter const [postId, postIdErr] = it(params.post_id, 'id', true); - if (postIdErr) return rej('invalid post_id'); + if (postIdErr) return rej('invalid post_id param'); // Get 'limit' parameter const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); - if (limitErr) return rej('invalid limit'); + if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter const [offset, offsetErr] = it(params.offset).expect.number().min(0).default(0).qed(); - if (offsetErr) return rej('invalid offset'); + if (offsetErr) return rej('invalid offset param'); // Lookup post const post = await Post.findOne({ diff --git a/src/api/endpoints/posts/likes.ts b/src/api/endpoints/posts/likes.ts index e44013c246..f299de7492 100644 --- a/src/api/endpoints/posts/likes.ts +++ b/src/api/endpoints/posts/likes.ts @@ -20,19 +20,19 @@ module.exports = (params, user) => { // Get 'post_id' parameter const [postId, postIdErr] = it(params.post_id, 'id', true); - if (postIdErr) return rej('invalid post_id'); + if (postIdErr) return rej('invalid post_id param'); // Get 'limit' parameter const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); - if (limitErr) return rej('invalid limit'); + if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter const [offset, offsetErr] = it(params.offset).expect.number().min(0).default(0).qed(); - if (offsetErr) return rej('invalid offset'); + if (offsetErr) return rej('invalid offset param'); // Get 'sort' parameter const [sort, sortError] = it(params.sort).expect.string().or('desc asc').default('desc').qed(); - if (sortError) return rej('invalid sort'); + if (sortError) return rej('invalid sort param'); // Lookup post const post = await Post.findOne({ diff --git a/src/api/endpoints/posts/replies.js b/src/api/endpoints/posts/replies.js deleted file mode 100644 index cbbb5dc312..0000000000 --- a/src/api/endpoints/posts/replies.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import * as mongo from 'mongodb'; -import Post from '../../models/post'; -import serialize from '../../serializers/post'; - -/** - * Show a replies of a post - * - * @param {any} params - * @param {any} user - * @return {Promise} - */ -module.exports = (params, user) => - new Promise(async (res, rej) => -{ - // Get 'post_id' parameter - const postId = params.post_id; - if (postId === undefined || postId === null) { - return rej('post_id is required'); - } - - // Get 'limit' parameter - let limit = params.limit; - if (limit !== undefined && limit !== null) { - limit = parseInt(limit, 10); - - // From 1 to 100 - if (!(1 <= limit && limit <= 100)) { - return rej('invalid limit range'); - } - } else { - limit = 10; - } - - // Get 'offset' parameter - let offset = params.offset; - if (offset !== undefined && offset !== null) { - offset = parseInt(offset, 10); - } else { - offset = 0; - } - - // Get 'sort' parameter - let sort = params.sort || 'desc'; - - // Lookup post - const post = await Post.findOne({ - _id: new mongo.ObjectID(postId) - }); - - if (post === null) { - return rej('post not found', 'POST_NOT_FOUND'); - } - - // Issue query - const replies = await Post - .find({ reply_to_id: post._id }, { - limit: limit, - skip: offset, - sort: { - _id: sort == 'asc' ? 1 : -1 - } - }); - - // Serialize - res(await Promise.all(replies.map(async post => - await serialize(post, user)))); -}); diff --git a/src/api/endpoints/posts/replies.ts b/src/api/endpoints/posts/replies.ts new file mode 100644 index 0000000000..3f448d1632 --- /dev/null +++ b/src/api/endpoints/posts/replies.ts @@ -0,0 +1,58 @@ +'use strict'; + +/** + * Module dependencies + */ +import it from '../../it'; +import Post from '../../models/post'; +import serialize from '../../serializers/post'; + +/** + * Show a replies of a post + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = (params, user) => + new Promise(async (res, rej) => +{ + // Get 'post_id' parameter + const [postId, postIdErr] = it(params.post_id, 'id', true); + if (postIdErr) return rej('invalid post_id param'); + + // Get 'limit' parameter + const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); + if (limitErr) return rej('invalid limit param'); + + // Get 'offset' parameter + const [offset, offsetErr] = it(params.offset).expect.number().min(0).default(0).qed(); + if (offsetErr) return rej('invalid offset param'); + + // Get 'sort' parameter + const [sort, sortError] = it(params.sort).expect.string().or('desc asc').default('desc').qed(); + 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({ reply_to_id: post._id }, { + limit: limit, + skip: offset, + sort: { + _id: sort == 'asc' ? 1 : -1 + } + }); + + // Serialize + res(await Promise.all(replies.map(async post => + await serialize(post, user)))); +}); diff --git a/src/api/endpoints/posts/reposts.js b/src/api/endpoints/posts/reposts.js deleted file mode 100644 index 0ffe44cb16..0000000000 --- a/src/api/endpoints/posts/reposts.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import * as mongo from 'mongodb'; -import Post from '../../models/post'; -import serialize from '../../serializers/post'; - -/** - * Show a reposts of a post - * - * @param {any} params - * @param {any} user - * @return {Promise} - */ -module.exports = (params, user) => - new Promise(async (res, rej) => -{ - // Get 'post_id' parameter - const postId = params.post_id; - if (postId === undefined || postId === null) { - return rej('post_id is required'); - } - - // Get 'limit' parameter - let limit = params.limit; - if (limit !== undefined && limit !== null) { - limit = parseInt(limit, 10); - - // From 1 to 100 - if (!(1 <= limit && limit <= 100)) { - return rej('invalid limit range'); - } - } else { - limit = 10; - } - - const since = params.since_id || null; - const max = params.max_id || null; - - // Check if both of since_id and max_id is specified - if (since !== null && max !== null) { - return rej('cannot set since_id and max_id'); - } - - // Lookup post - const post = await Post.findOne({ - _id: new mongo.ObjectID(postId) - }); - - if (post === null) { - return rej('post not found', 'POST_NOT_FOUND'); - } - - // Construct query - const sort = { - _id: -1 - }; - const query = { - repost_id: post._id - }; - if (since !== null) { - sort._id = 1; - query._id = { - $gt: new mongo.ObjectID(since) - }; - } else if (max !== null) { - query._id = { - $lt: new mongo.ObjectID(max) - }; - } - - // Issue query - const reposts = await Post - .find(query, { - limit: limit, - sort: sort - }); - - // Serialize - res(await Promise.all(reposts.map(async post => - await serialize(post, user)))); -}); diff --git a/src/api/endpoints/posts/reposts.ts b/src/api/endpoints/posts/reposts.ts new file mode 100644 index 0000000000..d8410b322b --- /dev/null +++ b/src/api/endpoints/posts/reposts.ts @@ -0,0 +1,78 @@ +'use strict'; + +/** + * Module dependencies + */ +import it from '../../it'; +import Post from '../../models/post'; +import serialize from '../../serializers/post'; + +/** + * Show a reposts of a post + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = (params, user) => + new Promise(async (res, rej) => +{ + // Get 'post_id' parameter + const [postId, postIdErr] = it(params.post_id, 'id', true); + if (postIdErr) return rej('invalid post_id param'); + + // Get 'limit' parameter + const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); + if (limitErr) return rej('invalid limit param'); + + // Get 'since_id' parameter + const [sinceId, sinceIdErr] = it(params.since_id).expect.id().qed(); + if (sinceIdErr) return rej('invalid since_id param'); + + // Get 'max_id' parameter + const [maxId, maxIdErr] = it(params.max_id).expect.id().qed(); + if (maxIdErr) return rej('invalid max_id param'); + + // Check if both of since_id and max_id is specified + if (sinceId !== null && maxId !== null) { + return rej('cannot set since_id and max_id'); + } + + // 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 = { + repost_id: post._id + } as any; + if (sinceId) { + sort._id = 1; + query._id = { + $gt: sinceId + }; + } else if (maxId) { + query._id = { + $lt: maxId + }; + } + + // Issue query + const reposts = await Post + .find(query, { + limit: limit, + sort: sort + }); + + // Serialize + res(await Promise.all(reposts.map(async post => + await serialize(post, user)))); +}); diff --git a/src/api/endpoints/posts/search.js b/src/api/endpoints/posts/search.js deleted file mode 100644 index bc06340fda..0000000000 --- a/src/api/endpoints/posts/search.js +++ /dev/null @@ -1,137 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import * as mongo from 'mongodb'; -const escapeRegexp = require('escape-regexp'); -import Post from '../../models/post'; -import serialize from '../../serializers/post'; -import config from '../../../conf'; - -/** - * Search a post - * - * @param {any} params - * @param {any} me - * @return {Promise} - */ -module.exports = (params, me) => - new Promise(async (res, rej) => -{ - // Get 'query' parameter - let query = params.query; - if (query === undefined || query === null || query.trim() === '') { - return rej('query is required'); - } - - // Get 'offset' parameter - let offset = params.offset; - if (offset !== undefined && offset !== null) { - offset = parseInt(offset, 10); - } else { - offset = 0; - } - - // Get 'max' parameter - let max = params.max; - if (max !== undefined && max !== null) { - max = parseInt(max, 10); - - // From 1 to 30 - if (!(1 <= max && max <= 30)) { - return rej('invalid max range'); - } - } else { - max = 10; - } - - // If Elasticsearch is available, search by it - // If not, search by MongoDB - (config.elasticsearch.enable ? byElasticsearch : byNative) - (res, rej, me, query, offset, max); -}); - -// Search by MongoDB -async function byNative(res, rej, me, query, offset, max) { - const escapedQuery = escapeRegexp(query); - - // Search posts - const posts = await Post - .find({ - text: new RegExp(escapedQuery) - }, { - sort: { - _id: -1 - }, - limit: max, - skip: offset - }); - - // Serialize - res(await Promise.all(posts.map(async post => - await serialize(post, me)))); -} - -// Search by Elasticsearch -async function byElasticsearch(res, rej, me, query, offset, max) { - const es = require('../../db/elasticsearch'); - - es.search({ - index: 'misskey', - type: 'post', - body: { - size: max, - from: offset, - query: { - simple_query_string: { - fields: ['text'], - query: query, - default_operator: 'and' - } - }, - sort: [ - { _doc: 'desc' } - ], - highlight: { - pre_tags: [''], - post_tags: [''], - encoder: 'html', - fields: { - text: {} - } - } - } - }, async (error, response) => { - if (error) { - console.error(error); - return res(500); - } - - if (response.hits.total === 0) { - return res([]); - } - - const hits = response.hits.hits.map(hit => new mongo.ObjectID(hit._id)); - - // Fetch found posts - const posts = await Post - .find({ - _id: { - $in: hits - } - }, { - sort: { - _id: -1 - } - }); - - posts.map(post => { - post._highlight = response.hits.hits.filter(hit => post._id.equals(hit._id))[0].highlight.text[0]; - }); - - // Serialize - res(await Promise.all(posts.map(async post => - await serialize(post, me)))); - }); -} diff --git a/src/api/endpoints/posts/search.ts b/src/api/endpoints/posts/search.ts new file mode 100644 index 0000000000..1d02f6775d --- /dev/null +++ b/src/api/endpoints/posts/search.ts @@ -0,0 +1,123 @@ +'use strict'; + +/** + * Module dependencies + */ +import * as mongo from 'mongodb'; +import it from '../../it'; +const escapeRegexp = require('escape-regexp'); +import Post from '../../models/post'; +import serialize from '../../serializers/post'; +import config from '../../../conf'; + +/** + * Search a post + * + * @param {any} params + * @param {any} me + * @return {Promise} + */ +module.exports = (params, me) => + new Promise(async (res, rej) => +{ + // Get 'query' parameter + const [query, queryError] = it(params.query).expect.string().required().trim().validate(x => x != '').qed(); + if (queryError) return rej('invalid query param'); + + // Get 'offset' parameter + const [offset, offsetErr] = it(params.offset).expect.number().min(0).default(0).qed(); + if (offsetErr) return rej('invalid offset param'); + + // Get 'max' parameter + const [max, maxErr] = it(params.max).expect.number().range(1, 30).default(10).qed(); + if (maxErr) return rej('invalid max param'); + + // If Elasticsearch is available, search by it + // If not, search by MongoDB + (config.elasticsearch.enable ? byElasticsearch : byNative) + (res, rej, me, query, offset, max); +}); + +// Search by MongoDB +async function byNative(res, rej, me, query, offset, max) { + const escapedQuery = escapeRegexp(query); + + // Search posts + const posts = await Post + .find({ + text: new RegExp(escapedQuery) + }, { + sort: { + _id: -1 + }, + limit: max, + skip: offset + }); + + // Serialize + res(await Promise.all(posts.map(async post => + await serialize(post, me)))); +} + +// Search by Elasticsearch +async function byElasticsearch(res, rej, me, query, offset, max) { + const es = require('../../db/elasticsearch'); + + es.search({ + index: 'misskey', + type: 'post', + body: { + size: max, + from: offset, + query: { + simple_query_string: { + fields: ['text'], + query: query, + default_operator: 'and' + } + }, + sort: [ + { _doc: 'desc' } + ], + highlight: { + pre_tags: [''], + post_tags: [''], + encoder: 'html', + fields: { + text: {} + } + } + } + }, async (error, response) => { + if (error) { + console.error(error); + return res(500); + } + + if (response.hits.total === 0) { + return res([]); + } + + const hits = response.hits.hits.map(hit => new mongo.ObjectID(hit._id)); + + // Fetch found posts + const posts = await Post + .find({ + _id: { + $in: hits + } + }, { + sort: { + _id: -1 + } + }); + + posts.map(post => { + post._highlight = response.hits.hits.filter(hit => post._id.equals(hit._id))[0].highlight.text[0]; + }); + + // Serialize + res(await Promise.all(posts.map(async post => + await serialize(post, me)))); + }); +} diff --git a/src/api/endpoints/posts/show.js b/src/api/endpoints/posts/show.js deleted file mode 100644 index 4938199cdb..0000000000 --- a/src/api/endpoints/posts/show.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import * as mongo from 'mongodb'; -import Post from '../../models/post'; -import serialize from '../../serializers/post'; - -/** - * Show a post - * - * @param {any} params - * @param {any} user - * @return {Promise} - */ -module.exports = (params, user) => - new Promise(async (res, rej) => -{ - // Get 'post_id' parameter - const postId = params.post_id; - if (postId === undefined || postId === null) { - return rej('post_id is required'); - } - - // Validate id - if (!mongo.ObjectID.isValid(postId)) { - return rej('incorrect post_id'); - } - - // Get post - const post = await Post.findOne({ - _id: new mongo.ObjectID(postId) - }); - - if (post === null) { - return rej('post not found'); - } - - // Serialize - res(await serialize(post, user, { - detail: true - })); -}); diff --git a/src/api/endpoints/posts/show.ts b/src/api/endpoints/posts/show.ts new file mode 100644 index 0000000000..712ef1e160 --- /dev/null +++ b/src/api/endpoints/posts/show.ts @@ -0,0 +1,37 @@ +'use strict'; + +/** + * Module dependencies + */ +import it from '../../it'; +import Post from '../../models/post'; +import serialize from '../../serializers/post'; + +/** + * Show a post + * + * @param {any} params + * @param {any} user + * @return {Promise} + */ +module.exports = (params, user) => + new Promise(async (res, rej) => +{ + // Get 'post_id' parameter + const [postId, postIdErr] = it(params.post_id, 'id', true); + if (postIdErr) return rej('invalid post_id param'); + + // Get post + const post = await Post.findOne({ + _id: postId + }); + + if (post === null) { + return rej('post not found'); + } + + // Serialize + res(await serialize(post, user, { + detail: true + })); +}); diff --git a/src/api/endpoints/posts/timeline.js b/src/api/endpoints/posts/timeline.js deleted file mode 100644 index 48f7c26940..0000000000 --- a/src/api/endpoints/posts/timeline.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ -import * as mongo from 'mongodb'; -import Post from '../../models/post'; -import getFriends from '../../common/get-friends'; -import serialize from '../../serializers/post'; - -/** - * Get timeline of myself - * - * @param {any} params - * @param {any} user - * @param {any} app - * @return {Promise} - */ -module.exports = (params, user, app) => - new Promise(async (res, rej) => -{ - // Get 'limit' parameter - let limit = params.limit; - if (limit !== undefined && limit !== null) { - limit = parseInt(limit, 10); - - // From 1 to 100 - if (!(1 <= limit && limit <= 100)) { - return rej('invalid limit range'); - } - } else { - limit = 10; - } - - const since = params.since_id || null; - const max = params.max_id || null; - - // Check if both of since_id and max_id is specified - if (since !== null && max !== null) { - return rej('cannot set since_id and max_id'); - } - - // ID list of the user itself and other users who the user follows - const followingIds = await getFriends(user._id); - - // Construct query - const sort = { - _id: -1 - }; - const query = { - user_id: { - $in: followingIds - } - }; - if (since !== null) { - sort._id = 1; - query._id = { - $gt: new mongo.ObjectID(since) - }; - } else if (max !== null) { - query._id = { - $lt: new mongo.ObjectID(max) - }; - } - - // Issue query - const timeline = await Post - .find(query, { - limit: limit, - sort: sort - }); - - // Serialize - res(await Promise.all(timeline.map(async post => - await serialize(post, user) - ))); -}); diff --git a/src/api/endpoints/posts/timeline.ts b/src/api/endpoints/posts/timeline.ts new file mode 100644 index 0000000000..5744084932 --- /dev/null +++ b/src/api/endpoints/posts/timeline.ts @@ -0,0 +1,73 @@ +'use strict'; + +/** + * Module dependencies + */ +import it from '../../it'; +import Post from '../../models/post'; +import getFriends from '../../common/get-friends'; +import serialize from '../../serializers/post'; + +/** + * Get timeline of myself + * + * @param {any} params + * @param {any} user + * @param {any} app + * @return {Promise} + */ +module.exports = (params, user, app) => + new Promise(async (res, rej) => +{ + // Get 'limit' parameter + const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); + if (limitErr) return rej('invalid limit param'); + + // Get 'since_id' parameter + const [sinceId, sinceIdErr] = it(params.since_id).expect.id().qed(); + if (sinceIdErr) return rej('invalid since_id param'); + + // Get 'max_id' parameter + const [maxId, maxIdErr] = it(params.max_id).expect.id().qed(); + if (maxIdErr) return rej('invalid max_id param'); + + // Check if both of since_id and max_id is specified + if (sinceId !== null && maxId !== null) { + return rej('cannot set since_id and max_id'); + } + + // ID list of the user itself and other users who the user follows + const followingIds = await getFriends(user._id); + + // Construct query + const sort = { + _id: -1 + }; + const query = { + user_id: { + $in: followingIds + } + } as any; + if (sinceId) { + sort._id = 1; + query._id = { + $gt: sinceId + }; + } else if (maxId) { + query._id = { + $lt: maxId + }; + } + + // Issue query + const timeline = await Post + .find(query, { + limit: limit, + sort: sort + }); + + // Serialize + res(await Promise.all(timeline.map(async post => + await serialize(post, user) + ))); +}); -- cgit v1.2.3-freya