互換性のためのコードを追加 & #2623
This commit is contained in:
		
							parent
							
								
									229e85b2c5
								
							
						
					
					
						commit
						b5ff2abdb9
					
				
					 8 changed files with 435 additions and 284 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue