diff options
| author | こぴなたみぽ <Syuilotan@yahoo.co.jp> | 2017-11-06 19:11:23 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-06 19:11:23 +0900 |
| commit | cb7e70dee3aa47807d33757d4ecd07e2793540d0 (patch) | |
| tree | c6795a6c0aa200195748c364d4ab990c6a160150 /src/api/serializers | |
| parent | chore(package): update @types/rimraf to version 2.0.2 (diff) | |
| parent | Merge pull request #871 from syuilo/greenkeeper/@types/elasticsearch-5.0.17 (diff) | |
| download | misskey-cb7e70dee3aa47807d33757d4ecd07e2793540d0.tar.gz misskey-cb7e70dee3aa47807d33757d4ecd07e2793540d0.tar.bz2 misskey-cb7e70dee3aa47807d33757d4ecd07e2793540d0.zip | |
Merge branch 'master' into greenkeeper/@types/rimraf-2.0.2
Diffstat (limited to 'src/api/serializers')
| -rw-r--r-- | src/api/serializers/channel.ts | 66 | ||||
| -rw-r--r-- | src/api/serializers/drive-file.ts | 36 | ||||
| -rw-r--r-- | src/api/serializers/drive-folder.ts | 2 | ||||
| -rw-r--r-- | src/api/serializers/post.ts | 166 | ||||
| -rw-r--r-- | src/api/serializers/user.ts | 111 |
5 files changed, 268 insertions, 113 deletions
diff --git a/src/api/serializers/channel.ts b/src/api/serializers/channel.ts new file mode 100644 index 0000000000..3cba39aa16 --- /dev/null +++ b/src/api/serializers/channel.ts @@ -0,0 +1,66 @@ +/** + * Module dependencies + */ +import * as mongo from 'mongodb'; +import deepcopy = require('deepcopy'); +import { IUser } from '../models/user'; +import { default as Channel, IChannel } from '../models/channel'; +import Watching from '../models/channel-watching'; + +/** + * Serialize a channel + * + * @param channel target + * @param me? serializee + * @return response + */ +export default ( + channel: string | mongo.ObjectID | IChannel, + me?: string | mongo.ObjectID | IUser +) => new Promise<any>(async (resolve, reject) => { + + let _channel: any; + + // Populate the channel if 'channel' is ID + if (mongo.ObjectID.prototype.isPrototypeOf(channel)) { + _channel = await Channel.findOne({ + _id: channel + }); + } else if (typeof channel === 'string') { + _channel = await Channel.findOne({ + _id: new mongo.ObjectID(channel) + }); + } else { + _channel = deepcopy(channel); + } + + // Rename _id to id + _channel.id = _channel._id; + delete _channel._id; + + // Remove needless properties + delete _channel.user_id; + + // Me + const meId: mongo.ObjectID = me + ? mongo.ObjectID.prototype.isPrototypeOf(me) + ? me as mongo.ObjectID + : typeof me === 'string' + ? new mongo.ObjectID(me) + : (me as IUser)._id + : null; + + if (me) { + //#region Watchしているかどうか + const watch = await Watching.findOne({ + user_id: meId, + channel_id: _channel.id, + deleted_at: { $exists: false } + }); + + _channel.is_watching = watch !== null; + //#endregion + } + + resolve(_channel); +}); diff --git a/src/api/serializers/drive-file.ts b/src/api/serializers/drive-file.ts index b4e2ab064a..2af7db5726 100644 --- a/src/api/serializers/drive-file.ts +++ b/src/api/serializers/drive-file.ts @@ -31,44 +31,40 @@ export default ( if (mongo.ObjectID.prototype.isPrototypeOf(file)) { _file = await DriveFile.findOne({ _id: file - }, { - fields: { - data: false - } - }); + }); } else if (typeof file === 'string') { _file = await DriveFile.findOne({ _id: new mongo.ObjectID(file) - }, { - fields: { - data: false - } - }); + }); } else { _file = deepcopy(file); } - // Rename _id to id - _file.id = _file._id; - delete _file._id; + if (!_file) return reject('invalid file arg.'); + + // rendered target + let _target: any = {}; + + _target.id = _file._id; + _target.created_at = _file.uploadDate; - delete _file.data; + _target = Object.assign(_target, _file.metadata); - _file.url = `${config.drive_url}/${_file.id}/${encodeURIComponent(_file.name)}`; + _target.url = `${config.drive_url}/${_target.id}/${encodeURIComponent(_target.name)}`; - if (opts.detail && _file.folder_id) { + if (opts.detail && _target.folder_id) { // Populate folder - _file.folder = await serializeDriveFolder(_file.folder_id, { + _target.folder = await serializeDriveFolder(_target.folder_id, { detail: true }); } - if (opts.detail && _file.tags) { + if (opts.detail && _target.tags) { // Populate tags - _file.tags = await _file.tags.map(async (tag: any) => + _target.tags = await _target.tags.map(async (tag: any) => await serializeDriveTag(tag) ); } - resolve(_file); + resolve(_target); }); diff --git a/src/api/serializers/drive-folder.ts b/src/api/serializers/drive-folder.ts index a428464108..6ebf454a28 100644 --- a/src/api/serializers/drive-folder.ts +++ b/src/api/serializers/drive-folder.ts @@ -44,7 +44,7 @@ const self = ( }); const childFilesCount = await DriveFile.count({ - folder_id: _folder.id + 'metadata.folder_id': _folder.id }); _folder.folders_count = childFoldersCount; diff --git a/src/api/serializers/post.ts b/src/api/serializers/post.ts index 3c96884dd1..03fd120772 100644 --- a/src/api/serializers/post.ts +++ b/src/api/serializers/post.ts @@ -3,33 +3,45 @@ */ import * as mongo from 'mongodb'; import deepcopy = require('deepcopy'); -import Post from '../models/post'; +import { default as Post, IPost } from '../models/post'; import Reaction from '../models/post-reaction'; +import { IUser } from '../models/user'; import Vote from '../models/poll-vote'; import serializeApp from './app'; +import serializeChannel from './channel'; import serializeUser from './user'; import serializeDriveFile from './drive-file'; import parse from '../common/text'; +import rap from '@prezzemolo/rap'; /** * Serialize a post * - * @param {any} post - * @param {any} me? - * @param {any} options? - * @return {Promise<any>} + * @param post target + * @param me? serializee + * @param options? serialize options + * @return response */ -const self = ( - post: any, - me?: any, +const self = async ( + post: string | mongo.ObjectID | IPost, + me?: string | mongo.ObjectID | IUser, options?: { detail: boolean } -) => new Promise<any>(async (resolve, reject) => { +) => { const opts = options || { detail: true, }; + // Me + const meId: mongo.ObjectID = me + ? mongo.ObjectID.prototype.isPrototypeOf(me) + ? me as mongo.ObjectID + : typeof me === 'string' + ? new mongo.ObjectID(me) + : (me as IUser)._id + : null; + let _post: any; // Populate the post if 'post' is ID @@ -45,6 +57,8 @@ const self = ( _post = deepcopy(post); } + if (!_post) throw 'invalid post arg.'; + const id = _post._id; // Rename _id to id @@ -59,62 +73,120 @@ const self = ( } // Populate user - _post.user = await serializeUser(_post.user_id, me); + _post.user = serializeUser(_post.user_id, meId); // Populate app if (_post.app_id) { - _post.app = await serializeApp(_post.app_id); + _post.app = serializeApp(_post.app_id); } - if (_post.media_ids) { - // Populate media - _post.media = await Promise.all(_post.media_ids.map(async fileId => - await serializeDriveFile(fileId) - )); + // Populate channel + if (_post.channel_id) { + _post.channel = serializeChannel(_post.channel_id); } - if (_post.reply_to_id && opts.detail) { - // Populate reply to post - _post.reply_to = await self(_post.reply_to_id, me, { - detail: false - }); + // Populate media + if (_post.media_ids) { + _post.media = Promise.all(_post.media_ids.map(fileId => + serializeDriveFile(fileId) + )); } - if (_post.repost_id && opts.detail) { - // Populate repost - _post.repost = await self(_post.repost_id, me, { - detail: _post.text == null - }); - } + // When requested a detailed post data + if (opts.detail) { + // Get previous post info + _post.prev = (async () => { + const prev = await Post.findOne({ + user_id: _post.user_id, + _id: { + $lt: id + } + }, { + fields: { + _id: true + }, + sort: { + _id: -1 + } + }); + return prev ? prev._id : null; + })(); - // Poll - if (me && _post.poll && opts.detail) { - const vote = await Vote - .findOne({ - user_id: me._id, - post_id: id + // Get next post info + _post.next = (async () => { + const next = await Post.findOne({ + user_id: _post.user_id, + _id: { + $gt: id + } + }, { + fields: { + _id: true + }, + sort: { + _id: 1 + } }); + return next ? next._id : null; + })(); - if (vote != null) { - _post.poll.choices.filter(c => c.id == vote.choice)[0].is_voted = true; + if (_post.reply_id) { + // Populate reply to post + _post.reply = self(_post.reply_id, meId, { + detail: false + }); } - } - // Fetch my reaction - if (me && opts.detail) { - const reaction = await Reaction - .findOne({ - user_id: me._id, - post_id: id, - deleted_at: { $exists: false } + if (_post.repost_id) { + // Populate repost + _post.repost = self(_post.repost_id, meId, { + detail: _post.text == null }); + } + + // Poll + if (meId && _post.poll) { + _post.poll = (async (poll) => { + const vote = await Vote + .findOne({ + user_id: meId, + post_id: id + }); + + if (vote != null) { + const myChoice = poll.choices + .filter(c => c.id == vote.choice)[0]; + + myChoice.is_voted = true; + } - if (reaction) { - _post.my_reaction = reaction.reaction; + return poll; + })(_post.poll); + } + + // Fetch my reaction + if (meId) { + _post.my_reaction = (async () => { + const reaction = await Reaction + .findOne({ + user_id: meId, + post_id: id, + deleted_at: { $exists: false } + }); + + if (reaction) { + return reaction.reaction; + } + + return null; + })(); } } - resolve(_post); -}); + // resolve promises in _post object + _post = await rap(_post); + + return _post; +}; export default self; diff --git a/src/api/serializers/user.ts b/src/api/serializers/user.ts index bdbc749589..0d24d6cc04 100644 --- a/src/api/serializers/user.ts +++ b/src/api/serializers/user.ts @@ -3,22 +3,24 @@ */ import * as mongo from 'mongodb'; import deepcopy = require('deepcopy'); -import User from '../models/user'; +import { default as User, IUser } from '../models/user'; +import serializePost from './post'; import Following from '../models/following'; import getFriends from '../common/get-friends'; import config from '../../conf'; +import rap from '@prezzemolo/rap'; /** * Serialize a user * - * @param {any} user - * @param {any} me? - * @param {any} options? - * @return {Promise<any>} + * @param user target + * @param me? serializee + * @param options? serialize options + * @return response */ export default ( - user: any, - me?: any, + user: string | mongo.ObjectID | IUser, + me?: string | mongo.ObjectID | IUser, options?: { detail?: boolean, includeSecrets?: boolean @@ -36,7 +38,9 @@ export default ( data: false } : { data: false, - profile: false + profile: false, + keywords: false, + domains: false }; // Populate the user if 'user' is ID @@ -52,14 +56,16 @@ export default ( _user = deepcopy(user); } + if (!_user) return reject('invalid user arg.'); + // Me - if (me && !mongo.ObjectID.prototype.isPrototypeOf(me)) { - if (typeof me === 'string') { - me = new mongo.ObjectID(me); - } else { - me = me._id; - } - } + const meId: mongo.ObjectID = me + ? mongo.ObjectID.prototype.isPrototypeOf(me) + ? me as mongo.ObjectID + : typeof me === 'string' + ? new mongo.ObjectID(me) + : (me as IUser)._id + : null; // Rename _id to id _user.id = _user._id; @@ -76,6 +82,7 @@ export default ( delete _user.twitter.access_token; delete _user.twitter.access_token_secret; } + delete _user.line; // Visible via only the official client if (!opts.includeSecrets) { @@ -91,51 +98,65 @@ export default ( ? `${config.drive_url}/${_user.banner_id}` : null; - if (!me || !me.equals(_user.id) || !opts.detail) { + if (!meId || !meId.equals(_user.id) || !opts.detail) { delete _user.avatar_id; delete _user.banner_id; delete _user.drive_capacity; } - if (me && !me.equals(_user.id)) { + if (meId && !meId.equals(_user.id)) { // If the user is following - const follow = await Following.findOne({ - follower_id: me, - followee_id: _user.id, - deleted_at: { $exists: false } - }); - _user.is_following = follow !== null; + _user.is_following = (async () => { + const follow = await Following.findOne({ + follower_id: meId, + followee_id: _user.id, + deleted_at: { $exists: false } + }); + return follow !== null; + })(); // If the user is followed - const follow2 = await Following.findOne({ - follower_id: _user.id, - followee_id: me, - deleted_at: { $exists: false } - }); - _user.is_followed = follow2 !== null; + _user.is_followed = (async () => { + const follow2 = await Following.findOne({ + follower_id: _user.id, + followee_id: meId, + deleted_at: { $exists: false } + }); + return follow2 !== null; + })(); } - if (me && !me.equals(_user.id) && opts.detail) { - const myFollowingIds = await getFriends(me); + if (opts.detail) { + if (_user.pinned_post_id) { + // Populate pinned post + _user.pinned_post = serializePost(_user.pinned_post_id, meId, { + detail: true + }); + } + + if (meId && !meId.equals(_user.id)) { + const myFollowingIds = await getFriends(meId); - // Get following you know count - const followingYouKnowCount = await Following.count({ - followee_id: { $in: myFollowingIds }, - follower_id: _user.id, - deleted_at: { $exists: false } - }); - _user.following_you_know_count = followingYouKnowCount; + // Get following you know count + _user.following_you_know_count = Following.count({ + followee_id: { $in: myFollowingIds }, + follower_id: _user.id, + deleted_at: { $exists: false } + }); - // Get followers you know count - const followersYouKnowCount = await Following.count({ - followee_id: _user.id, - follower_id: { $in: myFollowingIds }, - deleted_at: { $exists: false } - }); - _user.followers_you_know_count = followersYouKnowCount; + // Get followers you know count + _user.followers_you_know_count = Following.count({ + followee_id: _user.id, + follower_id: { $in: myFollowingIds }, + deleted_at: { $exists: false } + }); + } } + // resolve promises in _user object + _user = await rap(_user); + resolve(_user); }); /* |