互換性のためのコードを追加 & #2623
This commit is contained in:
		
							parent
							
								
									229e85b2c5
								
							
						
					
					
						commit
						b5ff2abdb9
					
				|  | @ -1,51 +1,65 @@ | |||
| /** | ||||
|  * Module dependencies | ||||
|  */ | ||||
| import $ from 'cafy'; import ID from '../../../misc/cafy-id'; | ||||
| import Note, { pack } from '../../../models/note'; | ||||
| import getParams from '../get-params'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	desc: { | ||||
| 		'ja-JP': '投稿を取得します。' | ||||
| 	}, | ||||
| 
 | ||||
| 	params: { | ||||
| 		local: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ローカルの投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		reply: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': '返信に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		renote: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'Renoteに限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		media: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		poll: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'アンケートが添付された投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		limit: $.num.optional.range(1, 100).note({ | ||||
| 			default: 10 | ||||
| 		}), | ||||
| 
 | ||||
| 		sinceId: $.type(ID).optional.note({}), | ||||
| 
 | ||||
| 		untilId: $.type(ID).optional.note({}), | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Get all notes | ||||
|  */ | ||||
| export default (params: any) => new Promise(async (res, rej) => { | ||||
| 	// Get 'local' parameter
 | ||||
| 	const [local, localErr] = $.bool.optional.get(params.local); | ||||
| 	if (localErr) return rej('invalid local param'); | ||||
| 
 | ||||
| 	// Get 'reply' parameter
 | ||||
| 	const [reply, replyErr] = $.bool.optional.get(params.reply); | ||||
| 	if (replyErr) return rej('invalid reply param'); | ||||
| 
 | ||||
| 	// Get 'renote' parameter
 | ||||
| 	const [renote, renoteErr] = $.bool.optional.get(params.renote); | ||||
| 	if (renoteErr) return rej('invalid renote param'); | ||||
| 
 | ||||
| 	// Get 'files' parameter
 | ||||
| 	const [files, filesErr] = $.bool.optional.get(params.files); | ||||
| 	if (filesErr) return rej('invalid files param'); | ||||
| 
 | ||||
| 	// Get 'poll' parameter
 | ||||
| 	const [poll, pollErr] = $.bool.optional.get(params.poll); | ||||
| 	if (pollErr) return rej('invalid poll param'); | ||||
| 
 | ||||
| 	// Get 'bot' parameter
 | ||||
| 	//const [bot, botErr] = $.bool.optional.get(params.bot);
 | ||||
| 	//if (botErr) return rej('invalid bot param');
 | ||||
| 
 | ||||
| 	// Get 'limit' parameter
 | ||||
| 	const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); | ||||
| 	if (limitErr) return rej('invalid limit param'); | ||||
| 
 | ||||
| 	// Get 'sinceId' parameter
 | ||||
| 	const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); | ||||
| 	if (sinceIdErr) return rej('invalid sinceId param'); | ||||
| 
 | ||||
| 	// Get 'untilId' parameter
 | ||||
| 	const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); | ||||
| 	if (untilIdErr) return rej('invalid untilId param'); | ||||
| 	const [ps, psErr] = getParams(meta, params); | ||||
| 	if (psErr) throw psErr; | ||||
| 
 | ||||
| 	// Check if both of sinceId and untilId is specified
 | ||||
| 	if (sinceId && untilId) { | ||||
| 	if (ps.sinceId && ps.untilId) { | ||||
| 		return rej('cannot set sinceId and untilId'); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -56,35 +70,37 @@ export default (params: any) => new Promise(async (res, rej) => { | |||
| 	const query = { | ||||
| 		visibility: 'public' | ||||
| 	} as any; | ||||
| 	if (sinceId) { | ||||
| 	if (ps.sinceId) { | ||||
| 		sort._id = 1; | ||||
| 		query._id = { | ||||
| 			$gt: sinceId | ||||
| 			$gt: ps.sinceId | ||||
| 		}; | ||||
| 	} else if (untilId) { | ||||
| 	} else if (ps.untilId) { | ||||
| 		query._id = { | ||||
| 			$lt: untilId | ||||
| 			$lt: ps.untilId | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	if (local) { | ||||
| 	if (ps.local) { | ||||
| 		query['_user.host'] = null; | ||||
| 	} | ||||
| 
 | ||||
| 	if (reply != undefined) { | ||||
| 		query.replyId = reply ? { $exists: true, $ne: null } : null; | ||||
| 	if (ps.reply != undefined) { | ||||
| 		query.replyId = ps.reply ? { $exists: true, $ne: null } : null; | ||||
| 	} | ||||
| 
 | ||||
| 	if (renote != undefined) { | ||||
| 		query.renoteId = renote ? { $exists: true, $ne: null } : null; | ||||
| 	if (ps.renote != undefined) { | ||||
| 		query.renoteId = ps.renote ? { $exists: true, $ne: null } : null; | ||||
| 	} | ||||
| 
 | ||||
| 	if (files != undefined) { | ||||
| 		query.fileIds = files ? { $exists: true, $ne: null } : []; | ||||
| 	const withFiles = ps.withFiles != undefined ? ps.withFiles : ps.media; | ||||
| 
 | ||||
| 	if (withFiles) { | ||||
| 		query.fileIds = withFiles ? { $exists: true, $ne: null } : []; | ||||
| 	} | ||||
| 
 | ||||
| 	if (poll != undefined) { | ||||
| 		query.poll = poll ? { $exists: true, $ne: null } : null; | ||||
| 	if (ps.poll != undefined) { | ||||
| 		query.poll = ps.poll ? { $exists: true, $ne: null } : null; | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO
 | ||||
|  | @ -95,7 +111,7 @@ export default (params: any) => new Promise(async (res, rej) => { | |||
| 	// Issue query
 | ||||
| 	const notes = await Note | ||||
| 		.find(query, { | ||||
| 			limit: limit, | ||||
| 			limit: ps.limit, | ||||
| 			sort: sort | ||||
| 		}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,40 +3,49 @@ import Note from '../../../../models/note'; | |||
| import Mute from '../../../../models/mute'; | ||||
| import { pack } from '../../../../models/note'; | ||||
| import { ILocalUser } from '../../../../models/user'; | ||||
| import getParams from '../../get-params'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	desc: { | ||||
| 		'ja-JP': 'グローバルタイムラインを取得します。' | ||||
| 	}, | ||||
| 
 | ||||
| 	params: { | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		mediaOnly: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		limit: $.num.optional.range(1, 100).note({ | ||||
| 			default: 10 | ||||
| 		}), | ||||
| 
 | ||||
| 		sinceId: $.type(ID).optional.note({}), | ||||
| 
 | ||||
| 		untilId: $.type(ID).optional.note({}), | ||||
| 
 | ||||
| 		sinceDate: $.num.optional.note({}), | ||||
| 
 | ||||
| 		untilDate: $.num.optional.note({}), | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Get timeline of global | ||||
|  */ | ||||
| export default async (params: any, user: ILocalUser) => { | ||||
| 	// Get 'limit' parameter
 | ||||
| 	const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); | ||||
| 	if (limitErr) throw 'invalid limit param'; | ||||
| 
 | ||||
| 	// Get 'sinceId' parameter
 | ||||
| 	const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); | ||||
| 	if (sinceIdErr) throw 'invalid sinceId param'; | ||||
| 
 | ||||
| 	// Get 'untilId' parameter
 | ||||
| 	const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); | ||||
| 	if (untilIdErr) throw 'invalid untilId param'; | ||||
| 
 | ||||
| 	// Get 'sinceDate' parameter
 | ||||
| 	const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); | ||||
| 	if (sinceDateErr) throw 'invalid sinceDate param'; | ||||
| 
 | ||||
| 	// Get 'untilDate' parameter
 | ||||
| 	const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); | ||||
| 	if (untilDateErr) throw 'invalid untilDate param'; | ||||
| 	const [ps, psErr] = getParams(meta, params); | ||||
| 	if (psErr) throw psErr; | ||||
| 
 | ||||
| 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 | ||||
| 	if ([sinceId, untilId, sinceDate, untilDate].filter(x => x != null).length > 1) { | ||||
| 	if ([ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate].filter(x => x != null).length > 1) { | ||||
| 		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified'; | ||||
| 	} | ||||
| 
 | ||||
| 	// Get 'withFiles' parameter
 | ||||
| 	const [withFiles, withFilesErr] = $.bool.optional.get(params.withFiles); | ||||
| 	if (withFilesErr) throw 'invalid withFiles param'; | ||||
| 
 | ||||
| 	// ミュートしているユーザーを取得
 | ||||
| 	const mutedUserIds = user ? (await Mute.find({ | ||||
| 		muterId: user._id | ||||
|  | @ -68,27 +77,29 @@ export default async (params: any, user: ILocalUser) => { | |||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	const withFiles = ps.withFiles != null ? ps.withFiles : ps.mediaOnly; | ||||
| 
 | ||||
| 	if (withFiles) { | ||||
| 		query.fileIds = { $exists: true, $ne: [] }; | ||||
| 	} | ||||
| 
 | ||||
| 	if (sinceId) { | ||||
| 	if (ps.sinceId) { | ||||
| 		sort._id = 1; | ||||
| 		query._id = { | ||||
| 			$gt: sinceId | ||||
| 			$gt: ps.sinceId | ||||
| 		}; | ||||
| 	} else if (untilId) { | ||||
| 	} else if (ps.untilId) { | ||||
| 		query._id = { | ||||
| 			$lt: untilId | ||||
| 			$lt: ps.untilId | ||||
| 		}; | ||||
| 	} else if (sinceDate) { | ||||
| 	} else if (ps.sinceDate) { | ||||
| 		sort._id = 1; | ||||
| 		query.createdAt = { | ||||
| 			$gt: new Date(sinceDate) | ||||
| 			$gt: new Date(ps.sinceDate) | ||||
| 		}; | ||||
| 	} else if (untilDate) { | ||||
| 	} else if (ps.untilDate) { | ||||
| 		query.createdAt = { | ||||
| 			$lt: new Date(untilDate) | ||||
| 			$lt: new Date(ps.untilDate) | ||||
| 		}; | ||||
| 	} | ||||
| 	//#endregion
 | ||||
|  | @ -96,7 +107,7 @@ export default async (params: any, user: ILocalUser) => { | |||
| 	// Issue query
 | ||||
| 	const timeline = await Note | ||||
| 		.find(query, { | ||||
| 			limit: limit, | ||||
| 			limit: ps.limit, | ||||
| 			sort: sort | ||||
| 		}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,8 +7,6 @@ import { ILocalUser } from '../../../../models/user'; | |||
| import getParams from '../../get-params'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	name: 'notes/hybrid-timeline', | ||||
| 
 | ||||
| 	desc: { | ||||
| 		'ja-JP': 'ハイブリッドタイムラインを取得します。' | ||||
| 	}, | ||||
|  | @ -68,7 +66,13 @@ export const meta = { | |||
| 
 | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します' | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		mediaOnly: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 	} | ||||
|  | @ -203,7 +207,7 @@ export default async (params: any, user: ILocalUser) => { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ps.withFiles) { | ||||
| 	if (ps.withFiles || ps.mediaOnly) { | ||||
| 		query.$and.push({ | ||||
| 			fileIds: { $exists: true, $ne: [] } | ||||
| 		}); | ||||
|  |  | |||
|  | @ -3,40 +3,49 @@ import Note from '../../../../models/note'; | |||
| import Mute from '../../../../models/mute'; | ||||
| import { pack } from '../../../../models/note'; | ||||
| import { ILocalUser } from '../../../../models/user'; | ||||
| import getParams from '../../get-params'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	desc: { | ||||
| 		'ja-JP': 'ローカルタイムラインを取得します。' | ||||
| 	}, | ||||
| 
 | ||||
| 	params: { | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		mediaOnly: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		limit: $.num.optional.range(1, 100).note({ | ||||
| 			default: 10 | ||||
| 		}), | ||||
| 
 | ||||
| 		sinceId: $.type(ID).optional.note({}), | ||||
| 
 | ||||
| 		untilId: $.type(ID).optional.note({}), | ||||
| 
 | ||||
| 		sinceDate: $.num.optional.note({}), | ||||
| 
 | ||||
| 		untilDate: $.num.optional.note({}), | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Get timeline of local | ||||
|  */ | ||||
| export default async (params: any, user: ILocalUser) => { | ||||
| 	// Get 'limit' parameter
 | ||||
| 	const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); | ||||
| 	if (limitErr) throw 'invalid limit param'; | ||||
| 
 | ||||
| 	// Get 'sinceId' parameter
 | ||||
| 	const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); | ||||
| 	if (sinceIdErr) throw 'invalid sinceId param'; | ||||
| 
 | ||||
| 	// Get 'untilId' parameter
 | ||||
| 	const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); | ||||
| 	if (untilIdErr) throw 'invalid untilId param'; | ||||
| 
 | ||||
| 	// Get 'sinceDate' parameter
 | ||||
| 	const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); | ||||
| 	if (sinceDateErr) throw 'invalid sinceDate param'; | ||||
| 
 | ||||
| 	// Get 'untilDate' parameter
 | ||||
| 	const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); | ||||
| 	if (untilDateErr) throw 'invalid untilDate param'; | ||||
| 	const [ps, psErr] = getParams(meta, params); | ||||
| 	if (psErr) throw psErr; | ||||
| 
 | ||||
| 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 | ||||
| 	if ([sinceId, untilId, sinceDate, untilDate].filter(x => x != null).length > 1) { | ||||
| 	if ([ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate].filter(x => x != null).length > 1) { | ||||
| 		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified'; | ||||
| 	} | ||||
| 
 | ||||
| 	// Get 'withFiles' parameter
 | ||||
| 	const [withFiles, withFilesErr] = $.bool.optional.get(params.withFiles); | ||||
| 	if (withFilesErr) throw 'invalid withFiles param'; | ||||
| 
 | ||||
| 	// ミュートしているユーザーを取得
 | ||||
| 	const mutedUserIds = user ? (await Mute.find({ | ||||
| 		muterId: user._id | ||||
|  | @ -69,27 +78,29 @@ export default async (params: any, user: ILocalUser) => { | |||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	const withFiles = ps.withFiles != null ? ps.withFiles : ps.mediaOnly; | ||||
| 
 | ||||
| 	if (withFiles) { | ||||
| 		query.fileIds = { $exists: true, $ne: [] }; | ||||
| 	} | ||||
| 
 | ||||
| 	if (sinceId) { | ||||
| 	if (ps.sinceId) { | ||||
| 		sort._id = 1; | ||||
| 		query._id = { | ||||
| 			$gt: sinceId | ||||
| 			$gt: ps.sinceId | ||||
| 		}; | ||||
| 	} else if (untilId) { | ||||
| 	} else if (ps.untilId) { | ||||
| 		query._id = { | ||||
| 			$lt: untilId | ||||
| 			$lt: ps.untilId | ||||
| 		}; | ||||
| 	} else if (sinceDate) { | ||||
| 	} else if (ps.sinceDate) { | ||||
| 		sort._id = 1; | ||||
| 		query.createdAt = { | ||||
| 			$gt: new Date(sinceDate) | ||||
| 			$gt: new Date(ps.sinceDate) | ||||
| 		}; | ||||
| 	} else if (untilDate) { | ||||
| 	} else if (ps.untilDate) { | ||||
| 		query.createdAt = { | ||||
| 			$lt: new Date(untilDate) | ||||
| 			$lt: new Date(ps.untilDate) | ||||
| 		}; | ||||
| 	} | ||||
| 	//#endregion
 | ||||
|  | @ -97,7 +108,7 @@ export default async (params: any, user: ILocalUser) => { | |||
| 	// Issue query
 | ||||
| 	const timeline = await Note | ||||
| 		.find(query, { | ||||
| 			limit: limit, | ||||
| 			limit: ps.limit, | ||||
| 			sort: sort | ||||
| 		}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,119 +4,152 @@ import User, { ILocalUser } from '../../../../models/user'; | |||
| import Mute from '../../../../models/mute'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| import { pack } from '../../../../models/note'; | ||||
| import getParams from '../../get-params'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	desc: { | ||||
| 		'ja-JP': '指定されたタグが付けられた投稿を取得します。' | ||||
| 	}, | ||||
| 
 | ||||
| 	params: { | ||||
| 		tag: $.str.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'タグ' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		includeUserIds: $.arr($.type(ID)).optional.note({ | ||||
| 			default: [] | ||||
| 		}), | ||||
| 
 | ||||
| 		excludeUserIds: $.arr($.type(ID)).optional.note({ | ||||
| 			default: [] | ||||
| 		}), | ||||
| 
 | ||||
| 		includeUserUsernames: $.arr($.str).optional.note({ | ||||
| 			default: [] | ||||
| 		}), | ||||
| 
 | ||||
| 		excludeUserUsernames: $.arr($.str).optional.note({ | ||||
| 			default: [] | ||||
| 		}), | ||||
| 
 | ||||
| 		following: $.bool.optional.nullable.note({ | ||||
| 			default: null | ||||
| 		}), | ||||
| 
 | ||||
| 		mute: $.str.optional.note({ | ||||
| 			default: 'mute_all' | ||||
| 		}), | ||||
| 
 | ||||
| 		reply: $.bool.optional.nullable.note({ | ||||
| 			default: null, | ||||
| 
 | ||||
| 			desc: { | ||||
| 				'ja-JP': '返信に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		renote: $.bool.optional.nullable.note({ | ||||
| 			default: null, | ||||
| 
 | ||||
| 			desc: { | ||||
| 				'ja-JP': 'Renoteに限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		withFiles: $.bool.optional.nullable.note({ | ||||
| 			default: null, | ||||
| 
 | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		media: $.bool.optional.nullable.note({ | ||||
| 			default: null, | ||||
| 
 | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ファイルが添付された投稿に限定するか否か (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		poll: $.bool.optional.nullable.note({ | ||||
| 			default: null, | ||||
| 
 | ||||
| 			desc: { | ||||
| 				'ja-JP': 'アンケートが添付された投稿に限定するか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		sinceDate: $.num.optional.note({ | ||||
| 		}), | ||||
| 
 | ||||
| 		untilDate: $.num.optional.note({ | ||||
| 		}), | ||||
| 
 | ||||
| 		offset: $.num.optional.min(0).note({ | ||||
| 			default: 0 | ||||
| 		}), | ||||
| 
 | ||||
| 		limit: $.num.optional.range(1, 30).note({ | ||||
| 			default: 10 | ||||
| 		}), | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Search notes by tag | ||||
|  */ | ||||
| export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { | ||||
| 	// Get 'tag' parameter
 | ||||
| 	const [tag, tagError] = $.str.get(params.tag); | ||||
| 	if (tagError) return rej('invalid tag param'); | ||||
| 	const [ps, psErr] = getParams(meta, params); | ||||
| 	if (psErr) throw psErr; | ||||
| 
 | ||||
| 	// Get 'includeUserIds' parameter
 | ||||
| 	const [includeUserIds = [], includeUserIdsErr] = $.arr($.type(ID)).optional.get(params.includeUserIds); | ||||
| 	if (includeUserIdsErr) return rej('invalid includeUserIds param'); | ||||
| 
 | ||||
| 	// Get 'excludeUserIds' parameter
 | ||||
| 	const [excludeUserIds = [], excludeUserIdsErr] = $.arr($.type(ID)).optional.get(params.excludeUserIds); | ||||
| 	if (excludeUserIdsErr) return rej('invalid excludeUserIds param'); | ||||
| 
 | ||||
| 	// Get 'includeUserUsernames' parameter
 | ||||
| 	const [includeUserUsernames = [], includeUserUsernamesErr] = $.arr($.str).optional.get(params.includeUserUsernames); | ||||
| 	if (includeUserUsernamesErr) return rej('invalid includeUserUsernames param'); | ||||
| 
 | ||||
| 	// Get 'excludeUserUsernames' parameter
 | ||||
| 	const [excludeUserUsernames = [], excludeUserUsernamesErr] = $.arr($.str).optional.get(params.excludeUserUsernames); | ||||
| 	if (excludeUserUsernamesErr) return rej('invalid excludeUserUsernames param'); | ||||
| 
 | ||||
| 	// Get 'following' parameter
 | ||||
| 	const [following = null, followingErr] = $.bool.optional.nullable.get(params.following); | ||||
| 	if (followingErr) return rej('invalid following param'); | ||||
| 
 | ||||
| 	// Get 'mute' parameter
 | ||||
| 	const [mute = 'mute_all', muteErr] = $.str.optional.get(params.mute); | ||||
| 	if (muteErr) return rej('invalid mute param'); | ||||
| 
 | ||||
| 	// Get 'reply' parameter
 | ||||
| 	const [reply = null, replyErr] = $.bool.optional.nullable.get(params.reply); | ||||
| 	if (replyErr) return rej('invalid reply param'); | ||||
| 
 | ||||
| 	// Get 'renote' parameter
 | ||||
| 	const [renote = null, renoteErr] = $.bool.optional.nullable.get(params.renote); | ||||
| 	if (renoteErr) return rej('invalid renote param'); | ||||
| 
 | ||||
| 	// Get 'withFiles' parameter
 | ||||
| 	const [withFiles = null, withFilesErr] = $.bool.optional.nullable.get(params.withFiles); | ||||
| 	if (withFilesErr) return rej('invalid withFiles param'); | ||||
| 
 | ||||
| 	// Get 'poll' parameter
 | ||||
| 	const [poll = null, pollErr] = $.bool.optional.nullable.get(params.poll); | ||||
| 	if (pollErr) return rej('invalid poll param'); | ||||
| 
 | ||||
| 	// Get 'sinceDate' parameter
 | ||||
| 	const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); | ||||
| 	if (sinceDateErr) throw 'invalid sinceDate param'; | ||||
| 
 | ||||
| 	// Get 'untilDate' parameter
 | ||||
| 	const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); | ||||
| 	if (untilDateErr) throw 'invalid untilDate param'; | ||||
| 
 | ||||
| 	// Get 'offset' parameter
 | ||||
| 	const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset); | ||||
| 	if (offsetErr) return rej('invalid offset param'); | ||||
| 
 | ||||
| 	// Get 'limit' parameter
 | ||||
| 	const [limit = 10, limitErr] = $.num.optional.range(1, 30).get(params.limit); | ||||
| 	if (limitErr) return rej('invalid limit param'); | ||||
| 
 | ||||
| 	if (includeUserUsernames != null) { | ||||
| 		const ids = (await Promise.all(includeUserUsernames.map(async (username) => { | ||||
| 	if (ps.includeUserUsernames != null) { | ||||
| 		const ids = (await Promise.all(ps.includeUserUsernames.map(async (username) => { | ||||
| 			const _user = await User.findOne({ | ||||
| 				usernameLower: username.toLowerCase() | ||||
| 			}); | ||||
| 			return _user ? _user._id : null; | ||||
| 		}))).filter(id => id != null); | ||||
| 
 | ||||
| 		ids.forEach(id => includeUserIds.push(id)); | ||||
| 		ids.forEach(id => ps.includeUserIds.push(id)); | ||||
| 	} | ||||
| 
 | ||||
| 	if (excludeUserUsernames != null) { | ||||
| 		const ids = (await Promise.all(excludeUserUsernames.map(async (username) => { | ||||
| 	if (ps.excludeUserUsernames != null) { | ||||
| 		const ids = (await Promise.all(ps.excludeUserUsernames.map(async (username) => { | ||||
| 			const _user = await User.findOne({ | ||||
| 				usernameLower: username.toLowerCase() | ||||
| 			}); | ||||
| 			return _user ? _user._id : null; | ||||
| 		}))).filter(id => id != null); | ||||
| 
 | ||||
| 		ids.forEach(id => excludeUserIds.push(id)); | ||||
| 		ids.forEach(id => ps.excludeUserIds.push(id)); | ||||
| 	} | ||||
| 
 | ||||
| 	let q: any = { | ||||
| 		$and: [{ | ||||
| 			tagsLower: tag.toLowerCase() | ||||
| 			tagsLower: ps.tag.toLowerCase() | ||||
| 		}] | ||||
| 	}; | ||||
| 
 | ||||
| 	const push = (x: any) => q.$and.push(x); | ||||
| 
 | ||||
| 	if (includeUserIds && includeUserIds.length != 0) { | ||||
| 	if (ps.includeUserIds && ps.includeUserIds.length != 0) { | ||||
| 		push({ | ||||
| 			userId: { | ||||
| 				$in: includeUserIds | ||||
| 				$in: ps.includeUserIds | ||||
| 			} | ||||
| 		}); | ||||
| 	} else if (excludeUserIds && excludeUserIds.length != 0) { | ||||
| 	} else if (ps.excludeUserIds && ps.excludeUserIds.length != 0) { | ||||
| 		push({ | ||||
| 			userId: { | ||||
| 				$nin: excludeUserIds | ||||
| 				$nin: ps.excludeUserIds | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (following != null && me != null) { | ||||
| 	if (ps.following != null && me != null) { | ||||
| 		const ids = await getFriendIds(me._id, false); | ||||
| 		push({ | ||||
| 			userId: following ? { | ||||
| 			userId: ps.following ? { | ||||
| 				$in: ids | ||||
| 			} : { | ||||
| 				$nin: ids.concat(me._id) | ||||
|  | @ -131,7 +164,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		}); | ||||
| 		const mutedUserIds = mutes.map(m => m.muteeId); | ||||
| 
 | ||||
| 		switch (mute) { | ||||
| 		switch (ps.mute) { | ||||
| 			case 'mute_all': | ||||
| 				push({ | ||||
| 					userId: { | ||||
|  | @ -202,8 +235,8 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (reply != null) { | ||||
| 		if (reply) { | ||||
| 	if (ps.reply != null) { | ||||
| 		if (ps.reply) { | ||||
| 			push({ | ||||
| 				replyId: { | ||||
| 					$exists: true, | ||||
|  | @ -223,8 +256,8 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (renote != null) { | ||||
| 		if (renote) { | ||||
| 	if (ps.renote != null) { | ||||
| 		if (ps.renote) { | ||||
| 			push({ | ||||
| 				renoteId: { | ||||
| 					$exists: true, | ||||
|  | @ -244,6 +277,8 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	const withFiles = ps.withFiles != null ? ps.withFiles : ps.media; | ||||
| 
 | ||||
| 	if (withFiles != null) { | ||||
| 		if (withFiles) { | ||||
| 			push({ | ||||
|  | @ -265,8 +300,8 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (poll != null) { | ||||
| 		if (poll) { | ||||
| 	if (ps.poll != null) { | ||||
| 		if (ps.poll) { | ||||
| 			push({ | ||||
| 				poll: { | ||||
| 					$exists: true, | ||||
|  | @ -286,18 +321,18 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (sinceDate) { | ||||
| 	if (ps.sinceDate) { | ||||
| 		push({ | ||||
| 			createdAt: { | ||||
| 				$gt: new Date(sinceDate) | ||||
| 				$gt: new Date(ps.sinceDate) | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (untilDate) { | ||||
| 	if (ps.untilDate) { | ||||
| 		push({ | ||||
| 			createdAt: { | ||||
| 				$lt: new Date(untilDate) | ||||
| 				$lt: new Date(ps.untilDate) | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  | @ -312,8 +347,8 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 			sort: { | ||||
| 				_id: -1 | ||||
| 			}, | ||||
| 			limit: limit, | ||||
| 			skip: offset | ||||
| 			limit: ps.limit, | ||||
| 			skip: ps.offset | ||||
| 		}); | ||||
| 
 | ||||
| 	// Serialize
 | ||||
|  |  | |||
|  | @ -69,7 +69,13 @@ export const meta = { | |||
| 
 | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します' | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		mediaOnly: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 	} | ||||
|  | @ -193,7 +199,9 @@ export default async (params: any, user: ILocalUser) => { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ps.withFiles) { | ||||
| 	const withFiles = ps.withFiles != null ? ps.withFiles : ps.mediaOnly; | ||||
| 
 | ||||
| 	if (withFiles) { | ||||
| 		query.$and.push({ | ||||
| 			fileIds: { $exists: true, $ne: [] } | ||||
| 		}); | ||||
|  |  | |||
|  | @ -75,7 +75,13 @@ export const meta = { | |||
| 
 | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します' | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		mediaOnly: $.bool.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 	} | ||||
|  | @ -199,7 +205,9 @@ export default async (params: any, user: ILocalUser) => { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ps.withFiles) { | ||||
| 	const withFiles = ps.withFiles != null ? ps.withFiles : ps.mediaOnly; | ||||
| 
 | ||||
| 	if (withFiles) { | ||||
| 		query.$and.push({ | ||||
| 			fileIds: { $exists: true, $ne: [] } | ||||
| 		}); | ||||
|  |  | |||
|  | @ -2,63 +2,121 @@ import $ from 'cafy'; import ID from '../../../../misc/cafy-id'; | |||
| import getHostLower from '../../common/get-host-lower'; | ||||
| import Note, { pack } from '../../../../models/note'; | ||||
| import User, { ILocalUser } from '../../../../models/user'; | ||||
| import getParams from '../../get-params'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	desc: { | ||||
| 		'ja-JP': '指定したユーザーのタイムラインを取得します。' | ||||
| 	}, | ||||
| 
 | ||||
| 	params: { | ||||
| 		userId: $.type(ID).optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ユーザーID' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		username: $.str.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': 'ユーザー名' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		host: $.str.optional.note({ | ||||
| 		}), | ||||
| 
 | ||||
| 		includeReplies: $.bool.optional.note({ | ||||
| 			default: true, | ||||
| 
 | ||||
| 			desc: { | ||||
| 				'ja-JP': 'リプライを含めるか否か' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		limit: $.num.optional.range(1, 100).note({ | ||||
| 			default: 10, | ||||
| 			desc: { | ||||
| 				'ja-JP': '最大数' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		sinceId: $.type(ID).optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': '指定すると、この投稿を基点としてより新しい投稿を取得します' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		untilId: $.type(ID).optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': '指定すると、この投稿を基点としてより古い投稿を取得します' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		sinceDate: $.num.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		untilDate: $.num.optional.note({ | ||||
| 			desc: { | ||||
| 				'ja-JP': '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		includeMyRenotes: $.bool.optional.note({ | ||||
| 			default: true, | ||||
| 			desc: { | ||||
| 				'ja-JP': '自分の行ったRenoteを含めるかどうか' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		includeRenotedMyNotes: $.bool.optional.note({ | ||||
| 			default: true, | ||||
| 			desc: { | ||||
| 				'ja-JP': 'Renoteされた自分の投稿を含めるかどうか' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		includeLocalRenotes: $.bool.optional.note({ | ||||
| 			default: true, | ||||
| 			desc: { | ||||
| 				'ja-JP': 'Renoteされたローカルの投稿を含めるかどうか' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		withFiles: $.bool.optional.note({ | ||||
| 			default: false, | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します' | ||||
| 			} | ||||
| 		}), | ||||
| 
 | ||||
| 		mediaOnly: $.bool.optional.note({ | ||||
| 			default: false, | ||||
| 			desc: { | ||||
| 				'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します (このパラメータは廃止予定です。代わりに withFiles を使ってください。)' | ||||
| 			} | ||||
| 		}), | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Get notes of a user | ||||
|  */ | ||||
| export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { | ||||
| 	// Get 'userId' parameter
 | ||||
| 	const [userId, userIdErr] = $.type(ID).optional.get(params.userId); | ||||
| 	if (userIdErr) return rej('invalid userId param'); | ||||
| 	const [ps, psErr] = getParams(meta, params); | ||||
| 	if (psErr) throw psErr; | ||||
| 
 | ||||
| 	// Get 'username' parameter
 | ||||
| 	const [username, usernameErr] = $.str.optional.get(params.username); | ||||
| 	if (usernameErr) return rej('invalid username param'); | ||||
| 
 | ||||
| 	if (userId === undefined && username === undefined) { | ||||
| 	if (ps.userId === undefined && ps.username === undefined) { | ||||
| 		return rej('userId or username is required'); | ||||
| 	} | ||||
| 
 | ||||
| 	// Get 'host' parameter
 | ||||
| 	const [host, hostErr] = $.str.optional.get(params.host); | ||||
| 	if (hostErr) return rej('invalid host param'); | ||||
| 
 | ||||
| 	// Get 'includeReplies' parameter
 | ||||
| 	const [includeReplies = true, includeRepliesErr] = $.bool.optional.get(params.includeReplies); | ||||
| 	if (includeRepliesErr) return rej('invalid includeReplies param'); | ||||
| 
 | ||||
| 	// Get 'withFiles' parameter
 | ||||
| 	const [withFiles = false, withFilesErr] = $.bool.optional.get(params.withFiles); | ||||
| 	if (withFilesErr) return rej('invalid withFiles param'); | ||||
| 
 | ||||
| 	// Get 'limit' parameter
 | ||||
| 	const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); | ||||
| 	if (limitErr) return rej('invalid limit param'); | ||||
| 
 | ||||
| 	// Get 'sinceId' parameter
 | ||||
| 	const [sinceId, sinceIdErr] = $.type(ID).optional.get(params.sinceId); | ||||
| 	if (sinceIdErr) return rej('invalid sinceId param'); | ||||
| 
 | ||||
| 	// Get 'untilId' parameter
 | ||||
| 	const [untilId, untilIdErr] = $.type(ID).optional.get(params.untilId); | ||||
| 	if (untilIdErr) return rej('invalid untilId param'); | ||||
| 
 | ||||
| 	// Get 'sinceDate' parameter
 | ||||
| 	const [sinceDate, sinceDateErr] = $.num.optional.get(params.sinceDate); | ||||
| 	if (sinceDateErr) throw 'invalid sinceDate param'; | ||||
| 
 | ||||
| 	// Get 'untilDate' parameter
 | ||||
| 	const [untilDate, untilDateErr] = $.num.optional.get(params.untilDate); | ||||
| 	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) { | ||||
| 	if ([ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate].filter(x => x != null).length > 1) { | ||||
| 		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified'; | ||||
| 	} | ||||
| 
 | ||||
| 	const q = userId !== undefined | ||||
| 		? { _id: userId } | ||||
| 		: { usernameLower: username.toLowerCase(), host: getHostLower(host) } ; | ||||
| 	const q = ps.userId !== undefined | ||||
| 		? { _id: ps.userId } | ||||
| 		: { usernameLower: ps.username.toLowerCase(), host: getHostLower(ps.host) } ; | ||||
| 
 | ||||
| 	// Lookup user
 | ||||
| 	const user = await User.findOne(q, { | ||||
|  | @ -80,30 +138,32 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 		userId: user._id | ||||
| 	} as any; | ||||
| 
 | ||||
| 	if (sinceId) { | ||||
| 	if (ps.sinceId) { | ||||
| 		sort._id = 1; | ||||
| 		query._id = { | ||||
| 			$gt: sinceId | ||||
| 			$gt: ps.sinceId | ||||
| 		}; | ||||
| 	} else if (untilId) { | ||||
| 	} else if (ps.untilId) { | ||||
| 		query._id = { | ||||
| 			$lt: untilId | ||||
| 			$lt: ps.untilId | ||||
| 		}; | ||||
| 	} else if (sinceDate) { | ||||
| 	} else if (ps.sinceDate) { | ||||
| 		sort._id = 1; | ||||
| 		query.createdAt = { | ||||
| 			$gt: new Date(sinceDate) | ||||
| 			$gt: new Date(ps.sinceDate) | ||||
| 		}; | ||||
| 	} else if (untilDate) { | ||||
| 	} else if (ps.untilDate) { | ||||
| 		query.createdAt = { | ||||
| 			$lt: new Date(untilDate) | ||||
| 			$lt: new Date(ps.untilDate) | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!includeReplies) { | ||||
| 	if (!ps.includeReplies) { | ||||
| 		query.replyId = null; | ||||
| 	} | ||||
| 
 | ||||
| 	const withFiles = ps.withFiles != null ? ps.withFiles : ps.mediaOnly; | ||||
| 
 | ||||
| 	if (withFiles) { | ||||
| 		query.fileIds = { | ||||
| 			$exists: true, | ||||
|  | @ -115,12 +175,10 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => | |||
| 	// Issue query
 | ||||
| 	const notes = await Note | ||||
| 		.find(query, { | ||||
| 			limit: limit, | ||||
| 			limit: ps.limit, | ||||
| 			sort: sort | ||||
| 		}); | ||||
| 
 | ||||
| 	// Serialize
 | ||||
| 	res(await Promise.all(notes.map(async (note) => | ||||
| 		await pack(note, me) | ||||
| 	))); | ||||
| 	res(await Promise.all(notes.map(note => pack(note, me)))); | ||||
| }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue