2018-07-07 10:19:00 +00:00
|
|
|
import $ from 'cafy'; import ID from '../../../../misc/cafy-id';
|
2018-06-10 03:19:19 +00:00
|
|
|
import Note from '../../../../models/note';
|
2018-06-18 00:54:53 +00:00
|
|
|
import User, { ILocalUser } from '../../../../models/user';
|
2018-06-10 03:19:19 +00:00
|
|
|
import Mute from '../../../../models/mute';
|
|
|
|
import { getFriendIds } from '../../common/get-friends';
|
|
|
|
import { pack } from '../../../../models/note';
|
2018-09-05 14:55:51 +00:00
|
|
|
import getParams from '../../get-params';
|
2018-09-06 15:02:55 +00:00
|
|
|
import { erase } from '../../../../prelude/array';
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
export const meta = {
|
|
|
|
desc: {
|
|
|
|
'ja-JP': '指定されたタグが付けられた投稿を取得します。'
|
|
|
|
},
|
|
|
|
|
|
|
|
params: {
|
2018-09-17 00:00:20 +00:00
|
|
|
tag: $.str.optional.note({
|
2018-09-05 14:55:51 +00:00
|
|
|
desc: {
|
|
|
|
'ja-JP': 'タグ'
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
|
2018-09-17 00:00:20 +00:00
|
|
|
query: $.arr($.arr($.str)).optional.note({
|
|
|
|
desc: {
|
|
|
|
'ja-JP': 'クエリ'
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
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'
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
reply: $.bool.optional.nullable.note({
|
|
|
|
default: null,
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
desc: {
|
|
|
|
'ja-JP': '返信に限定するか否か'
|
|
|
|
}
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
renote: $.bool.optional.nullable.note({
|
|
|
|
default: null,
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
desc: {
|
|
|
|
'ja-JP': 'Renoteに限定するか否か'
|
|
|
|
}
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-17 00:00:20 +00:00
|
|
|
withFiles: $.bool.optional.note({
|
2018-09-05 14:55:51 +00:00
|
|
|
desc: {
|
2018-09-17 00:00:20 +00:00
|
|
|
'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します'
|
2018-09-05 14:55:51 +00:00
|
|
|
}
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
media: $.bool.optional.nullable.note({
|
|
|
|
default: null,
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
desc: {
|
|
|
|
'ja-JP': 'ファイルが添付された投稿に限定するか否か (このパラメータは廃止予定です。代わりに withFiles を使ってください。)'
|
|
|
|
}
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
poll: $.bool.optional.nullable.note({
|
|
|
|
default: null,
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
desc: {
|
|
|
|
'ja-JP': 'アンケートが添付された投稿に限定するか否か'
|
|
|
|
}
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
sinceDate: $.num.optional.note({
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
untilDate: $.num.optional.note({
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
offset: $.num.optional.min(0).note({
|
|
|
|
default: 0
|
|
|
|
}),
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
limit: $.num.optional.range(1, 30).note({
|
|
|
|
default: 10
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
|
|
|
|
const [ps, psErr] = getParams(meta, params);
|
|
|
|
if (psErr) throw psErr;
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.includeUserUsernames != null) {
|
2018-09-06 15:02:55 +00:00
|
|
|
const ids = erase(null, await Promise.all(ps.includeUserUsernames.map(async (username) => {
|
2018-06-10 03:19:19 +00:00
|
|
|
const _user = await User.findOne({
|
|
|
|
usernameLower: username.toLowerCase()
|
|
|
|
});
|
|
|
|
return _user ? _user._id : null;
|
2018-09-06 15:02:55 +00:00
|
|
|
})));
|
2018-06-18 00:54:53 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
ids.forEach(id => ps.includeUserIds.push(id));
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.excludeUserUsernames != null) {
|
2018-09-06 15:02:55 +00:00
|
|
|
const ids = erase(null, await Promise.all(ps.excludeUserUsernames.map(async (username) => {
|
2018-06-10 03:19:19 +00:00
|
|
|
const _user = await User.findOne({
|
|
|
|
usernameLower: username.toLowerCase()
|
|
|
|
});
|
|
|
|
return _user ? _user._id : null;
|
2018-09-06 15:02:55 +00:00
|
|
|
})));
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
ids.forEach(id => ps.excludeUserIds.push(id));
|
2018-06-18 00:54:53 +00:00
|
|
|
}
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-09 18:39:00 +00:00
|
|
|
const q: any = {
|
2018-09-17 00:00:20 +00:00
|
|
|
$and: [ps.tag ? {
|
2018-09-05 14:55:51 +00:00
|
|
|
tagsLower: ps.tag.toLowerCase()
|
2018-09-17 00:00:20 +00:00
|
|
|
} : {
|
|
|
|
$or: ps.query.map(tags => ({
|
|
|
|
$and: tags.map(t => ({
|
|
|
|
tagsLower: t.toLowerCase()
|
|
|
|
}))
|
|
|
|
}))
|
2018-09-09 16:57:19 +00:00
|
|
|
}],
|
|
|
|
deletedAt: { $exists: false }
|
2018-06-10 03:19:19 +00:00
|
|
|
};
|
|
|
|
|
2018-06-18 00:54:53 +00:00
|
|
|
const push = (x: any) => q.$and.push(x);
|
2018-06-10 03:19:19 +00:00
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.includeUserIds && ps.includeUserIds.length != 0) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
userId: {
|
2018-09-05 14:55:51 +00:00
|
|
|
$in: ps.includeUserIds
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
});
|
2018-09-05 14:55:51 +00:00
|
|
|
} else if (ps.excludeUserIds && ps.excludeUserIds.length != 0) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
userId: {
|
2018-09-05 14:55:51 +00:00
|
|
|
$nin: ps.excludeUserIds
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.following != null && me != null) {
|
2018-06-10 03:19:19 +00:00
|
|
|
const ids = await getFriendIds(me._id, false);
|
|
|
|
push({
|
2018-09-05 14:55:51 +00:00
|
|
|
userId: ps.following ? {
|
2018-06-10 03:19:19 +00:00
|
|
|
$in: ids
|
|
|
|
} : {
|
|
|
|
$nin: ids.concat(me._id)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (me != null) {
|
|
|
|
const mutes = await Mute.find({
|
|
|
|
muterId: me._id,
|
|
|
|
deletedAt: { $exists: false }
|
|
|
|
});
|
|
|
|
const mutedUserIds = mutes.map(m => m.muteeId);
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
switch (ps.mute) {
|
2018-06-10 03:19:19 +00:00
|
|
|
case 'mute_all':
|
|
|
|
push({
|
|
|
|
userId: {
|
|
|
|
$nin: mutedUserIds
|
|
|
|
},
|
|
|
|
'_reply.userId': {
|
|
|
|
$nin: mutedUserIds
|
|
|
|
},
|
|
|
|
'_renote.userId': {
|
|
|
|
$nin: mutedUserIds
|
|
|
|
}
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'mute_related':
|
|
|
|
push({
|
|
|
|
'_reply.userId': {
|
|
|
|
$nin: mutedUserIds
|
|
|
|
},
|
|
|
|
'_renote.userId': {
|
|
|
|
$nin: mutedUserIds
|
|
|
|
}
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'mute_direct':
|
|
|
|
push({
|
|
|
|
userId: {
|
|
|
|
$nin: mutedUserIds
|
|
|
|
}
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'direct_only':
|
|
|
|
push({
|
|
|
|
userId: {
|
|
|
|
$in: mutedUserIds
|
|
|
|
}
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'related_only':
|
|
|
|
push({
|
|
|
|
$or: [{
|
|
|
|
'_reply.userId': {
|
|
|
|
$in: mutedUserIds
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
'_renote.userId': {
|
|
|
|
$in: mutedUserIds
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case 'all_only':
|
|
|
|
push({
|
|
|
|
$or: [{
|
|
|
|
userId: {
|
|
|
|
$in: mutedUserIds
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
'_reply.userId': {
|
|
|
|
$in: mutedUserIds
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
'_renote.userId': {
|
|
|
|
$in: mutedUserIds
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.reply != null) {
|
|
|
|
if (ps.reply) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
replyId: {
|
|
|
|
$exists: true,
|
|
|
|
$ne: null
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
push({
|
|
|
|
$or: [{
|
|
|
|
replyId: {
|
|
|
|
$exists: false
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
replyId: null
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.renote != null) {
|
|
|
|
if (ps.renote) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
renoteId: {
|
|
|
|
$exists: true,
|
|
|
|
$ne: null
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
push({
|
|
|
|
$or: [{
|
|
|
|
renoteId: {
|
|
|
|
$exists: false
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
renoteId: null
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
const withFiles = ps.withFiles != null ? ps.withFiles : ps.media;
|
|
|
|
|
2018-09-17 00:00:20 +00:00
|
|
|
if (withFiles) {
|
|
|
|
push({
|
|
|
|
fileIds: { $exists: true, $ne: [] }
|
|
|
|
});
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.poll != null) {
|
|
|
|
if (ps.poll) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
poll: {
|
|
|
|
$exists: true,
|
|
|
|
$ne: null
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
push({
|
|
|
|
$or: [{
|
|
|
|
poll: {
|
|
|
|
$exists: false
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
poll: null
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.sinceDate) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
createdAt: {
|
2018-09-05 14:55:51 +00:00
|
|
|
$gt: new Date(ps.sinceDate)
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-09-05 14:55:51 +00:00
|
|
|
if (ps.untilDate) {
|
2018-06-10 03:19:19 +00:00
|
|
|
push({
|
|
|
|
createdAt: {
|
2018-09-05 14:55:51 +00:00
|
|
|
$lt: new Date(ps.untilDate)
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (q.$and.length == 0) {
|
2018-09-09 16:57:19 +00:00
|
|
|
delete q.$and;
|
2018-06-10 03:19:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Search notes
|
|
|
|
const notes = await Note
|
|
|
|
.find(q, {
|
|
|
|
sort: {
|
|
|
|
_id: -1
|
|
|
|
},
|
2018-09-05 14:55:51 +00:00
|
|
|
limit: ps.limit,
|
|
|
|
skip: ps.offset
|
2018-06-10 03:19:19 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// Serialize
|
|
|
|
res(await Promise.all(notes.map(note => pack(note, me))));
|
2018-06-18 00:54:53 +00:00
|
|
|
});
|