Post --> Note

Closes #1411
This commit is contained in:
syuilo
2018-04-08 02:30:37 +09:00
parent c7106d250c
commit a1b490afa7
167 changed files with 4440 additions and 1762 deletions

View File

@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs';
import User, { IUser, init as initUser, ILocalUser } from '../../../models/user';
import getPostSummary from '../../../renderers/get-post-summary';
import getNoteSummary from '../../../renderers/get-note-summary';
import getUserName from '../../../renderers/get-user-name';
import getUserSummary from '../../../renderers/get-user-summary';
import parseAcct from '../../../acct/parse';
@ -83,7 +83,7 @@ export default class BotCore extends EventEmitter {
'me: アカウント情報を見ます\n' +
'login, signin: サインインします\n' +
'logout, signout: サインアウトします\n' +
'post: 投稿します\n' +
'note: 投稿します\n' +
'tl: タイムラインを見ます\n' +
'no: 通知を見ます\n' +
'@<ユーザー名>: ユーザーを表示します\n' +
@ -109,10 +109,10 @@ export default class BotCore extends EventEmitter {
this.signout();
return 'ご利用ありがとうございました <3';
case 'post':
case 'note':
case '投稿':
if (this.user == null) return 'まずサインインしてください。';
this.setContext(new PostContext(this));
this.setContext(new NoteContext(this));
return await this.context.greet();
case 'tl':
@ -190,7 +190,7 @@ abstract class Context extends EventEmitter {
public static import(bot: BotCore, data: any) {
if (data.type == 'guessing-game') return GuessingGameContext.import(bot, data.content);
if (data.type == 'post') return PostContext.import(bot, data.content);
if (data.type == 'note') return NoteContext.import(bot, data.content);
if (data.type == 'tl') return TlContext.import(bot, data.content);
if (data.type == 'notifications') return NotificationsContext.import(bot, data.content);
if (data.type == 'signin') return SigninContext.import(bot, data.content);
@ -254,13 +254,13 @@ class SigninContext extends Context {
}
}
class PostContext extends Context {
class NoteContext extends Context {
public async greet(): Promise<string> {
return '内容:';
}
public async q(query: string): Promise<string> {
await require('../endpoints/posts/create')({
await require('../endpoints/notes/create')({
text: query
}, this.bot.user);
this.bot.clearContext();
@ -269,12 +269,12 @@ class PostContext extends Context {
public export() {
return {
type: 'post'
type: 'note'
};
}
public static import(bot: BotCore, data: any) {
const context = new PostContext(bot);
const context = new NoteContext(bot);
return context;
}
}
@ -296,7 +296,7 @@ class TlContext extends Context {
}
private async getTl() {
const tl = await require('../endpoints/posts/timeline')({
const tl = await require('../endpoints/notes/timeline')({
limit: 5,
untilId: this.next ? this.next : undefined
}, this.bot.user);
@ -306,7 +306,7 @@ class TlContext extends Context {
this.emit('updated');
const text = tl
.map(post => `${getUserName(post.user)}\n「${getPostSummary(post)}`)
.map(note => `${getUserName(note.user)}\n「${getNoteSummary(note)}`)
.join('\n-----\n');
return text;

View File

@ -9,7 +9,7 @@ import _redis from '../../../../db/redis';
import prominence = require('prominence');
import getAcct from '../../../../acct/render';
import parseAcct from '../../../../acct/parse';
import getPostSummary from '../../../../renderers/get-post-summary';
import getNoteSummary from '../../../../renderers/get-note-summary';
import getUserName from '../../../../renderers/get-user-name';
const redis = prominence(_redis);
@ -80,14 +80,14 @@ class LineBot extends BotCore {
}
break;
// postback
case 'postback':
const data = ev.postback.data;
// noteback
case 'noteback':
const data = ev.noteback.data;
const cmd = data.split('|')[0];
const arg = data.split('|')[1];
switch (cmd) {
case 'showtl':
this.showUserTimelinePostback(arg);
this.showUserTimelineNoteback(arg);
break;
}
break;
@ -107,7 +107,7 @@ class LineBot extends BotCore {
const actions = [];
actions.push({
type: 'postback',
type: 'noteback',
label: 'タイムラインを見る',
data: `showtl|${user.id}`
});
@ -141,14 +141,14 @@ class LineBot extends BotCore {
return null;
}
public async showUserTimelinePostback(userId: string) {
const tl = await require('../../endpoints/users/posts')({
public async showUserTimelineNoteback(userId: string) {
const tl = await require('../../endpoints/users/notes')({
userId: userId,
limit: 5
}, this.user);
const text = `${getUserName(tl[0].user)}さんのタイムラインはこちらです:\n\n` + tl
.map(post => getPostSummary(post))
.map(note => getNoteSummary(note))
.join('\n-----\n');
this.reply([{

View File

@ -113,7 +113,7 @@ const endpoints: Endpoint[] = [
secure: true
},
{
name: 'aggregation/posts',
name: 'aggregation/notes',
},
{
name: 'aggregation/users',
@ -122,7 +122,7 @@ const endpoints: Endpoint[] = [
name: 'aggregation/users/activity',
},
{
name: 'aggregation/users/post',
name: 'aggregation/users/note',
},
{
name: 'aggregation/users/followers'
@ -134,16 +134,16 @@ const endpoints: Endpoint[] = [
name: 'aggregation/users/reaction'
},
{
name: 'aggregation/posts/repost'
name: 'aggregation/notes/renote'
},
{
name: 'aggregation/posts/reply'
name: 'aggregation/notes/reply'
},
{
name: 'aggregation/posts/reaction'
name: 'aggregation/notes/reaction'
},
{
name: 'aggregation/posts/reactions'
name: 'aggregation/notes/reactions'
},
{
@ -391,7 +391,7 @@ const endpoints: Endpoint[] = [
name: 'users/search_by_username'
},
{
name: 'users/posts'
name: 'users/notes'
},
{
name: 'users/following'
@ -428,35 +428,35 @@ const endpoints: Endpoint[] = [
},
{
name: 'posts'
name: 'notes'
},
{
name: 'posts/show'
name: 'notes/show'
},
{
name: 'posts/replies'
name: 'notes/replies'
},
{
name: 'posts/context'
name: 'notes/context'
},
{
name: 'posts/create',
name: 'notes/create',
withCredential: true,
limit: {
duration: ms('1hour'),
max: 120,
minInterval: ms('1second')
},
kind: 'post-write'
kind: 'note-write'
},
{
name: 'posts/reposts'
name: 'notes/renotes'
},
{
name: 'posts/search'
name: 'notes/search'
},
{
name: 'posts/timeline',
name: 'notes/timeline',
withCredential: true,
limit: {
duration: ms('10minutes'),
@ -464,7 +464,7 @@ const endpoints: Endpoint[] = [
}
},
{
name: 'posts/mentions',
name: 'notes/mentions',
withCredential: true,
limit: {
duration: ms('10minutes'),
@ -472,19 +472,19 @@ const endpoints: Endpoint[] = [
}
},
{
name: 'posts/trend',
name: 'notes/trend',
withCredential: true
},
{
name: 'posts/categorize',
name: 'notes/categorize',
withCredential: true
},
{
name: 'posts/reactions',
name: 'notes/reactions',
withCredential: true
},
{
name: 'posts/reactions/create',
name: 'notes/reactions/create',
withCredential: true,
limit: {
duration: ms('1hour'),
@ -493,7 +493,7 @@ const endpoints: Endpoint[] = [
kind: 'reaction-write'
},
{
name: 'posts/reactions/delete',
name: 'notes/reactions/delete',
withCredential: true,
limit: {
duration: ms('1hour'),
@ -502,7 +502,7 @@ const endpoints: Endpoint[] = [
kind: 'reaction-write'
},
{
name: 'posts/favorites/create',
name: 'notes/favorites/create',
withCredential: true,
limit: {
duration: ms('1hour'),
@ -511,7 +511,7 @@ const endpoints: Endpoint[] = [
kind: 'favorite-write'
},
{
name: 'posts/favorites/delete',
name: 'notes/favorites/delete',
withCredential: true,
limit: {
duration: ms('1hour'),
@ -520,7 +520,7 @@ const endpoints: Endpoint[] = [
kind: 'favorite-write'
},
{
name: 'posts/polls/vote',
name: 'notes/polls/vote',
withCredential: true,
limit: {
duration: ms('1hour'),
@ -529,7 +529,7 @@ const endpoints: Endpoint[] = [
kind: 'vote-write'
},
{
name: 'posts/polls/recommendation',
name: 'notes/polls/recommendation',
withCredential: true
},
@ -566,7 +566,7 @@ const endpoints: Endpoint[] = [
name: 'channels/show'
},
{
name: 'channels/posts'
name: 'channels/notes'
},
{
name: 'channels/watch',

View File

@ -2,32 +2,32 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../../models/post';
import Reaction from '../../../../../models/post-reaction';
import Note from '../../../../../models/note';
import Reaction from '../../../../../models/note-reaction';
/**
* Aggregate reaction of a post
* Aggregate reaction of a note
*
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
const datas = await Reaction
.aggregate([
{ $match: { postId: post._id } },
{ $match: { noteId: note._id } },
{ $project: {
createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
}},

View File

@ -2,34 +2,34 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../../models/post';
import Reaction from '../../../../../models/post-reaction';
import Note from '../../../../../models/note';
import Reaction from '../../../../../models/note-reaction';
/**
* Aggregate reactions of a post
* Aggregate reactions of a note
*
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
const startTime = new Date(new Date().setMonth(new Date().getMonth() - 1));
const reactions = await Reaction
.find({
postId: post._id,
noteId: note._id,
$or: [
{ deletedAt: { $exists: false } },
{ deletedAt: { $gt: startTime } }
@ -40,7 +40,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
},
fields: {
_id: false,
postId: false
noteId: false
}
});

View File

@ -2,31 +2,31 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../../models/post';
import Note from '../../../../../models/note';
/**
* Aggregate reply of a post
* Aggregate reply of a note
*
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
const datas = await Post
const datas = await Note
.aggregate([
{ $match: { reply: post._id } },
{ $match: { reply: note._id } },
{ $project: {
createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
}},

View File

@ -2,31 +2,31 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../../models/post';
import Note from '../../../../../models/note';
/**
* Aggregate repost of a post
* Aggregate renote of a note
*
* @param {any} params
* @return {Promise<any>}
*/
module.exports = (params) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
const datas = await Post
const datas = await Note
.aggregate([
{ $match: { repostId: post._id } },
{ $match: { renoteId: note._id } },
{ $project: {
createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
}},

View File

@ -2,10 +2,10 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../models/post';
import Note from '../../../../models/note';
/**
* Aggregate posts
* Aggregate notes
*
* @param {any} params
* @return {Promise<any>}
@ -15,10 +15,10 @@ module.exports = params => new Promise(async (res, rej) => {
const [limit = 365, limitErr] = $(params.limit).optional.number().range(1, 365).$;
if (limitErr) return rej('invalid limit param');
const datas = await Post
const datas = await Note
.aggregate([
{ $project: {
repostId: '$repostId',
renoteId: '$renoteId',
replyId: '$replyId',
createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
}},
@ -30,13 +30,13 @@ module.exports = params => new Promise(async (res, rej) => {
},
type: {
$cond: {
if: { $ne: ['$repostId', null] },
then: 'repost',
if: { $ne: ['$renoteId', null] },
then: 'renote',
else: {
$cond: {
if: { $ne: ['$replyId', null] },
then: 'reply',
else: 'post'
else: 'note'
}
}
}
@ -59,8 +59,8 @@ module.exports = params => new Promise(async (res, rej) => {
data.date = data._id;
delete data._id;
data.posts = (data.data.filter(x => x.type == 'post')[0] || { count: 0 }).count;
data.reposts = (data.data.filter(x => x.type == 'repost')[0] || { count: 0 }).count;
data.notes = (data.data.filter(x => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter(x => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter(x => x.type == 'reply')[0] || { count: 0 }).count;
delete data.data;
@ -79,8 +79,8 @@ module.exports = params => new Promise(async (res, rej) => {
graph.push(data);
} else {
graph.push({
posts: 0,
reposts: 0,
notes: 0,
renotes: 0,
replies: 0
});
}

View File

@ -3,7 +3,7 @@
*/
import $ from 'cafy';
import User from '../../../../../models/user';
import Post from '../../../../../models/post';
import Note from '../../../../../models/note';
// TODO: likeやfollowも集計
@ -35,11 +35,11 @@ module.exports = (params) => new Promise(async (res, rej) => {
return rej('user not found');
}
const datas = await Post
const datas = await Note
.aggregate([
{ $match: { userId: user._id } },
{ $project: {
repostId: '$repostId',
renoteId: '$renoteId',
replyId: '$replyId',
createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
}},
@ -51,13 +51,13 @@ module.exports = (params) => new Promise(async (res, rej) => {
},
type: {
$cond: {
if: { $ne: ['$repostId', null] },
then: 'repost',
if: { $ne: ['$renoteId', null] },
then: 'renote',
else: {
$cond: {
if: { $ne: ['$replyId', null] },
then: 'reply',
else: 'post'
else: 'note'
}
}
}
@ -80,8 +80,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
data.date = data._id;
delete data._id;
data.posts = (data.data.filter(x => x.type == 'post')[0] || { count: 0 }).count;
data.reposts = (data.data.filter(x => x.type == 'repost')[0] || { count: 0 }).count;
data.notes = (data.data.filter(x => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter(x => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter(x => x.type == 'reply')[0] || { count: 0 }).count;
delete data.data;
@ -105,8 +105,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
month: day.getMonth() + 1, // In JavaScript, month is zero-based.
day: day.getDate()
},
posts: 0,
reposts: 0,
notes: 0,
renotes: 0,
replies: 0
});
}

View File

@ -3,10 +3,10 @@
*/
import $ from 'cafy';
import User from '../../../../../models/user';
import Post from '../../../../../models/post';
import Note from '../../../../../models/note';
/**
* Aggregate post of a user
* Aggregate note of a user
*
* @param {any} params
* @return {Promise<any>}
@ -29,11 +29,11 @@ module.exports = (params) => new Promise(async (res, rej) => {
return rej('user not found');
}
const datas = await Post
const datas = await Note
.aggregate([
{ $match: { userId: user._id } },
{ $project: {
repostId: '$repostId',
renoteId: '$renoteId',
replyId: '$replyId',
createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
}},
@ -45,13 +45,13 @@ module.exports = (params) => new Promise(async (res, rej) => {
},
type: {
$cond: {
if: { $ne: ['$repostId', null] },
then: 'repost',
if: { $ne: ['$renoteId', null] },
then: 'renote',
else: {
$cond: {
if: { $ne: ['$replyId', null] },
then: 'reply',
else: 'post'
else: 'note'
}
}
}
@ -74,8 +74,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
data.date = data._id;
delete data._id;
data.posts = (data.data.filter(x => x.type == 'post')[0] || { count: 0 }).count;
data.reposts = (data.data.filter(x => x.type == 'repost')[0] || { count: 0 }).count;
data.notes = (data.data.filter(x => x.type == 'note')[0] || { count: 0 }).count;
data.renotes = (data.data.filter(x => x.type == 'renote')[0] || { count: 0 }).count;
data.replies = (data.data.filter(x => x.type == 'reply')[0] || { count: 0 }).count;
delete data.data;
@ -99,8 +99,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
month: day.getMonth() + 1, // In JavaScript, month is zero-based.
day: day.getDate()
},
posts: 0,
reposts: 0,
notes: 0,
renotes: 0,
replies: 0
});
}

View File

@ -3,7 +3,7 @@
*/
import $ from 'cafy';
import User from '../../../../../models/user';
import Reaction from '../../../../../models/post-reaction';
import Reaction from '../../../../../models/note-reaction';
/**
* Aggregate reaction of a user

View File

@ -8,7 +8,7 @@ import App, { isValidNameId, pack } from '../../../../models/app';
/**
* @swagger
* /app/create:
* post:
* note:
* summary: Create an application
* parameters:
* - $ref: "#/parameters/AccessToken"

View File

@ -8,7 +8,7 @@ import { isValidNameId } from '../../../../../models/app';
/**
* @swagger
* /app/nameId/available:
* post:
* note:
* summary: Check available nameId on creation an application
* parameters:
* -

View File

@ -7,7 +7,7 @@ import App, { pack } from '../../../../models/app';
/**
* @swagger
* /app/show:
* post:
* note:
* summary: Show an application's information
* description: Require appId or nameId
* parameters:

View File

@ -11,7 +11,7 @@ import AccessToken from '../../../../models/access-token';
/**
* @swagger
* /auth/accept:
* post:
* note:
* summary: Accept a session
* parameters:
* - $ref: "#/parameters/NativeToken"

View File

@ -10,7 +10,7 @@ import config from '../../../../../config';
/**
* @swagger
* /auth/session/generate:
* post:
* note:
* summary: Generate a session
* parameters:
* -

View File

@ -7,7 +7,7 @@ import AuthSess, { pack } from '../../../../../models/auth-session';
/**
* @swagger
* /auth/session/show:
* post:
* note:
* summary: Show a session information
* parameters:
* -

View File

@ -10,7 +10,7 @@ import { pack } from '../../../../../models/user';
/**
* @swagger
* /auth/session/userkey:
* post:
* note:
* summary: Get an access token(userkey)
* parameters:
* -

View File

@ -3,10 +3,10 @@
*/
import $ from 'cafy';
import { default as Channel, IChannel } from '../../../../models/channel';
import Post, { pack } from '../../../../models/post';
import Note, { pack } from '../../../../models/note';
/**
* Show a posts of a channel
* Show a notes of a channel
*
* @param {any} params
* @param {any} user
@ -65,14 +65,14 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
//#endregion Construct query
// Issue query
const posts = await Post
const notes = await Note
.find(query, {
limit: limit,
sort: sort
});
// Serialize
res(await Promise.all(posts.map(async (post) =>
await pack(post, user)
res(await Promise.all(notes.map(async (note) =>
await pack(note, user)
)));
});

View File

@ -3,7 +3,7 @@
*/
import $ from 'cafy';
import Favorite from '../../../../models/favorite';
import { pack } from '../../../../models/post';
import { pack } from '../../../../models/note';
/**
* Get followers of a user
@ -39,6 +39,6 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
// Serialize
res(await Promise.all(favorites.map(async favorite =>
await pack(favorite.postId)
await pack(favorite.noteId)
)));
});

View File

@ -3,34 +3,34 @@
*/
import $ from 'cafy';
import User from '../../../../models/user';
import Post from '../../../../models/post';
import Note from '../../../../models/note';
import { pack } from '../../../../models/user';
/**
* Pin post
* Pin note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = async (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Fetch pinee
const post = await Post.findOne({
_id: postId,
const note = await Note.findOne({
_id: noteId,
userId: user._id
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
await User.update(user._id, {
$set: {
pinnedPostId: post._id
pinnedNoteId: note._id
}
});

View File

@ -9,7 +9,7 @@ import Meta from '../../../models/meta';
/**
* @swagger
* /meta:
* post:
* note:
* summary: Show the misskey's information
* responses:
* 200:

View File

@ -2,19 +2,19 @@
* Module dependencies
*/
import $ from 'cafy';
import Post, { pack } from '../../../../models/post';
import Note, { pack } from '../../../../models/note';
/**
* Show a context of a post
* Show a context of a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@ -24,13 +24,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
if (offsetErr) return rej('invalid offset param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
const context = [];
@ -38,7 +38,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
async function get(id) {
i++;
const p = await Post.findOne({ _id: id });
const p = await Note.findOne({ _id: id });
if (i > offset) {
context.push(p);
@ -53,11 +53,11 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}
}
if (post.replyId) {
await get(post.replyId);
if (note.replyId) {
await get(note.replyId);
}
// Serialize
res(await Promise.all(context.map(async post =>
await pack(post, user))));
res(await Promise.all(context.map(async note =>
await pack(note, user))));
});

View File

@ -0,0 +1,251 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import deepEqual = require('deep-equal');
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
import { ILocalUser } from '../../../../models/user';
import Channel, { IChannel } from '../../../../models/channel';
import DriveFile from '../../../../models/drive-file';
import create from '../../../../services/note/create';
import { IApp } from '../../../../models/app';
/**
* Create a note
*
* @param {any} params
* @param {any} user
* @param {any} app
* @return {Promise<any>}
*/
module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
// Get 'visibility' parameter
const [visibility = 'public', visibilityErr] = $(params.visibility).optional.string().or(['public', 'unlisted', 'private', 'direct']).$;
if (visibilityErr) return rej('invalid visibility');
// Get 'text' parameter
const [text, textErr] = $(params.text).optional.string().pipe(isValidText).$;
if (textErr) return rej('invalid text');
// Get 'cw' parameter
const [cw, cwErr] = $(params.cw).optional.string().pipe(isValidCw).$;
if (cwErr) return rej('invalid cw');
// Get 'viaMobile' parameter
const [viaMobile = false, viaMobileErr] = $(params.viaMobile).optional.boolean().$;
if (viaMobileErr) return rej('invalid viaMobile');
// Get 'tags' parameter
const [tags = [], tagsErr] = $(params.tags).optional.array('string').unique().eachQ(t => t.range(1, 32)).$;
if (tagsErr) return rej('invalid tags');
// Get 'geo' parameter
const [geo, geoErr] = $(params.geo).optional.nullable.strict.object()
.have('coordinates', $().array().length(2)
.item(0, $().number().range(-180, 180))
.item(1, $().number().range(-90, 90)))
.have('altitude', $().nullable.number())
.have('accuracy', $().nullable.number())
.have('altitudeAccuracy', $().nullable.number())
.have('heading', $().nullable.number().range(0, 360))
.have('speed', $().nullable.number())
.$;
if (geoErr) return rej('invalid geo');
// Get 'mediaIds' parameter
const [mediaIds, mediaIdsErr] = $(params.mediaIds).optional.array('id').unique().range(1, 4).$;
if (mediaIdsErr) return rej('invalid mediaIds');
let files = [];
if (mediaIds !== undefined) {
// Fetch files
// forEach だと途中でエラーなどがあっても return できないので
// 敢えて for を使っています。
for (const mediaId of mediaIds) {
// Fetch file
// SELECT _id
const entity = await DriveFile.findOne({
_id: mediaId,
'metadata.userId': user._id
});
if (entity === null) {
return rej('file not found');
} else {
files.push(entity);
}
}
} else {
files = null;
}
// Get 'renoteId' parameter
const [renoteId, renoteIdErr] = $(params.renoteId).optional.id().$;
if (renoteIdErr) return rej('invalid renoteId');
let renote: INote = null;
let isQuote = false;
if (renoteId !== undefined) {
// Fetch renote to note
renote = await Note.findOne({
_id: renoteId
});
if (renote == null) {
return rej('renoteee is not found');
} else if (renote.renoteId && !renote.text && !renote.mediaIds) {
return rej('cannot renote to renote');
}
// Fetch recently note
const latestNote = await Note.findOne({
userId: user._id
}, {
sort: {
_id: -1
}
});
isQuote = text != null || files != null;
// 直近と同じRenote対象かつ引用じゃなかったらエラー
if (latestNote &&
latestNote.renoteId &&
latestNote.renoteId.equals(renote._id) &&
!isQuote) {
return rej('cannot renote same note that already reposted in your latest note');
}
// 直近がRenote対象かつ引用じゃなかったらエラー
if (latestNote &&
latestNote._id.equals(renote._id) &&
!isQuote) {
return rej('cannot renote your latest note');
}
}
// Get 'replyId' parameter
const [replyId, replyIdErr] = $(params.replyId).optional.id().$;
if (replyIdErr) return rej('invalid replyId');
let reply: INote = null;
if (replyId !== undefined) {
// Fetch reply
reply = await Note.findOne({
_id: replyId
});
if (reply === null) {
return rej('in reply to note is not found');
}
// 返信対象が引用でないRenoteだったらエラー
if (reply.renoteId && !reply.text && !reply.mediaIds) {
return rej('cannot reply to renote');
}
}
// Get 'channelId' parameter
const [channelId, channelIdErr] = $(params.channelId).optional.id().$;
if (channelIdErr) return rej('invalid channelId');
let channel: IChannel = null;
if (channelId !== undefined) {
// Fetch channel
channel = await Channel.findOne({
_id: channelId
});
if (channel === null) {
return rej('channel not found');
}
// 返信対象の投稿がこのチャンネルじゃなかったらダメ
if (reply && !channelId.equals(reply.channelId)) {
return rej('チャンネル内部からチャンネル外部の投稿に返信することはできません');
}
// Renote対象の投稿がこのチャンネルじゃなかったらダメ
if (renote && !channelId.equals(renote.channelId)) {
return rej('チャンネル内部からチャンネル外部の投稿をRenoteすることはできません');
}
// 引用ではないRenoteはダメ
if (renote && !isQuote) {
return rej('チャンネル内部では引用ではないRenoteをすることはできません');
}
} else {
// 返信対象の投稿がチャンネルへの投稿だったらダメ
if (reply && reply.channelId != null) {
return rej('チャンネル外部からチャンネル内部の投稿に返信することはできません');
}
// Renote対象の投稿がチャンネルへの投稿だったらダメ
if (renote && renote.channelId != null) {
return rej('チャンネル外部からチャンネル内部の投稿をRenoteすることはできません');
}
}
// Get 'poll' parameter
const [poll, pollErr] = $(params.poll).optional.strict.object()
.have('choices', $().array('string')
.unique()
.range(2, 10)
.each(c => c.length > 0 && c.length < 50))
.$;
if (pollErr) return rej('invalid poll');
if (poll) {
(poll as any).choices = (poll as any).choices.map((choice, i) => ({
id: i, // IDを付与
text: choice.trim(),
votes: 0
}));
}
// テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー
if (text === undefined && files === null && renote === null && poll === undefined) {
return rej('text, mediaIds, renoteId or poll is required');
}
// 直近の投稿と重複してたらエラー
// TODO: 直近の投稿が一日前くらいなら重複とは見なさない
if (user.latestNote) {
if (deepEqual({
text: user.latestNote.text,
reply: user.latestNote.replyId ? user.latestNote.replyId.toString() : null,
renote: user.latestNote.renoteId ? user.latestNote.renoteId.toString() : null,
mediaIds: (user.latestNote.mediaIds || []).map(id => id.toString())
}, {
text: text,
reply: reply ? reply._id.toString() : null,
renote: renote ? renote._id.toString() : null,
mediaIds: (files || []).map(file => file._id.toString())
})) {
return rej('duplicate');
}
}
// 投稿を作成
const note = await create(user, {
createdAt: new Date(),
media: files,
poll: poll,
text: text,
reply,
renote,
cw: cw,
tags: tags,
app: app,
viaMobile: viaMobile,
visibility,
geo
});
const noteObj = await pack(note, user);
// Reponse
res({
createdNote: noteObj
});
});

View File

@ -3,32 +3,32 @@
*/
import $ from 'cafy';
import Favorite from '../../../../../models/favorite';
import Post from '../../../../../models/post';
import Note from '../../../../../models/note';
/**
* Favorite a post
* Favorite a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get favoritee
const post = await Post.findOne({
_id: postId
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
// if already favorited
const exist = await Favorite.findOne({
postId: post._id,
noteId: note._id,
userId: user._id
});
@ -39,7 +39,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
// Create favorite
await Favorite.insert({
createdAt: new Date(),
postId: post._id,
noteId: note._id,
userId: user._id
});

View File

@ -3,32 +3,32 @@
*/
import $ from 'cafy';
import Favorite from '../../../../../models/favorite';
import Post from '../../../../../models/post';
import Note from '../../../../../models/note';
/**
* Unfavorite a post
* Unfavorite a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get favoritee
const post = await Post.findOne({
_id: postId
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
// if already favorited
const exist = await Favorite.findOne({
postId: post._id,
noteId: note._id,
userId: user._id
});

View File

@ -2,9 +2,9 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../models/post';
import Note from '../../../../models/note';
import getFriends from '../../common/get-friends';
import { pack } from '../../../../models/post';
import { pack } from '../../../../models/note';
/**
* Get mentions of myself
@ -65,7 +65,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}
// Issue query
const mentions = await Post
const mentions = await Note
.find(query, {
limit: limit,
sort: sort

View File

@ -3,7 +3,7 @@
*/
import $ from 'cafy';
import Vote from '../../../../../models/poll-vote';
import Post, { pack } from '../../../../../models/post';
import Note, { pack } from '../../../../../models/note';
/**
* Get recommended polls
@ -27,13 +27,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}, {
fields: {
_id: false,
postId: true
noteId: true
}
});
const nin = votes && votes.length != 0 ? votes.map(v => v.postId) : [];
const nin = votes && votes.length != 0 ? votes.map(v => v.noteId) : [];
const posts = await Post
const notes = await Note
.find({
_id: {
$nin: nin
@ -54,6 +54,6 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
});
// Serialize
res(await Promise.all(posts.map(async post =>
await pack(post, user, { detail: true }))));
res(await Promise.all(notes.map(async note =>
await pack(note, user, { detail: true }))));
});

View File

@ -3,47 +3,47 @@
*/
import $ from 'cafy';
import Vote from '../../../../../models/poll-vote';
import Post from '../../../../../models/post';
import Watching from '../../../../../models/post-watching';
import watch from '../../../../../post/watch';
import { publishPostStream } from '../../../../../publishers/stream';
import Note from '../../../../../models/note';
import Watching from '../../../../../models/note-watching';
import watch from '../../../../../note/watch';
import { publishNoteStream } from '../../../../../publishers/stream';
import notify from '../../../../../publishers/notify';
/**
* Vote poll of a post
* Vote poll of a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get votee
const post = await Post.findOne({
_id: postId
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
if (post.poll == null) {
if (note.poll == null) {
return rej('poll not found');
}
// Get 'choice' parameter
const [choice, choiceError] =
$(params.choice).number()
.pipe(c => post.poll.choices.some(x => x.id == c))
.pipe(c => note.poll.choices.some(x => x.id == c))
.$;
if (choiceError) return rej('invalid choice param');
// if already voted
const exist = await Vote.findOne({
postId: post._id,
noteId: note._id,
userId: user._id
});
@ -54,7 +54,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
// Create vote
await Vote.insert({
createdAt: new Date(),
postId: post._id,
noteId: note._id,
userId: user._id,
choice: choice
});
@ -63,25 +63,25 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
res();
const inc = {};
inc[`poll.choices.${findWithAttr(post.poll.choices, 'id', choice)}.votes`] = 1;
inc[`poll.choices.${findWithAttr(note.poll.choices, 'id', choice)}.votes`] = 1;
// Increment votes count
await Post.update({ _id: post._id }, {
await Note.update({ _id: note._id }, {
$inc: inc
});
publishPostStream(post._id, 'poll_voted');
publishNoteStream(note._id, 'poll_voted');
// Notify
notify(post.userId, user._id, 'poll_vote', {
postId: post._id,
notify(note.userId, user._id, 'poll_vote', {
noteId: note._id,
choice: choice
});
// Fetch watchers
Watching
.find({
postId: post._id,
noteId: note._id,
userId: { $ne: user._id },
// 削除されたドキュメントは除く
deletedAt: { $exists: false }
@ -93,7 +93,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
.then(watchers => {
watchers.forEach(watcher => {
notify(watcher.userId, user._id, 'poll_vote', {
postId: post._id,
noteId: note._id,
choice: choice
});
});
@ -101,7 +101,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
// この投稿をWatchする
if (user.account.settings.autoWatch !== false) {
watch(user._id, post);
watch(user._id, note);
}
});

View File

@ -2,20 +2,20 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../models/post';
import Reaction, { pack } from '../../../../models/post-reaction';
import Note from '../../../../models/note';
import Reaction, { pack } from '../../../../models/note-reaction';
/**
* Show reactions of a post
* Show reactions of a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@ -29,19 +29,19 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$;
if (sortError) return rej('invalid sort param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
// Issue query
const reactions = await Reaction
.find({
postId: post._id,
noteId: note._id,
deletedAt: { $exists: false }
}, {
limit: limit,

View File

@ -2,17 +2,17 @@
* Module dependencies
*/
import $ from 'cafy';
import Reaction from '../../../../../models/post-reaction';
import Post from '../../../../../models/post';
import create from '../../../../../services/post/reaction/create';
import Reaction from '../../../../../models/note-reaction';
import Note from '../../../../../models/note';
import create from '../../../../../services/note/reaction/create';
/**
* React to a post
* React to a note
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'reaction' parameter
const [reaction, reactionErr] = $(params.reaction).string().or([
@ -29,16 +29,16 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
if (reactionErr) return rej('invalid reaction param');
// Fetch reactee
const post = await Post.findOne({
_id: postId
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
try {
await create(user, post, reaction);
await create(user, note, reaction);
} catch (e) {
rej(e);
}

View File

@ -2,34 +2,34 @@
* Module dependencies
*/
import $ from 'cafy';
import Reaction from '../../../../../models/post-reaction';
import Post from '../../../../../models/post';
import Reaction from '../../../../../models/note-reaction';
import Note from '../../../../../models/note';
// import event from '../../../publishers/stream';
/**
* Unreact to a post
* Unreact to a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Fetch unreactee
const post = await Post.findOne({
_id: postId
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
// if already unreacted
const exist = await Reaction.findOne({
postId: post._id,
noteId: note._id,
userId: user._id,
deletedAt: { $exists: false }
});
@ -54,7 +54,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
dec[`reactionCounts.${exist.reaction}`] = -1;
// Decrement reactions count
Post.update({ _id: post._id }, {
Note.update({ _id: note._id }, {
$inc: dec
});
});

View File

@ -2,19 +2,19 @@
* Module dependencies
*/
import $ from 'cafy';
import Post, { pack } from '../../../../models/post';
import Note, { pack } from '../../../../models/note';
/**
* Show a replies of a post
* Show a replies of a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@ -28,18 +28,18 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$;
if (sortError) return rej('invalid sort param');
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
// Issue query
const replies = await Post
.find({ replyId: post._id }, {
const replies = await Note
.find({ replyId: note._id }, {
limit: limit,
skip: offset,
sort: {
@ -48,6 +48,6 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
});
// Serialize
res(await Promise.all(replies.map(async post =>
await pack(post, user))));
res(await Promise.all(replies.map(async note =>
await pack(note, user))));
});

View File

@ -2,19 +2,19 @@
* Module dependencies
*/
import $ from 'cafy';
import Post, { pack } from '../../../../models/post';
import Note, { pack } from '../../../../models/note';
/**
* Show a reposts of a post
* Show a renotes of a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get 'limit' parameter
const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@ -33,13 +33,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
return rej('cannot set sinceId and untilId');
}
// Lookup post
const post = await Post.findOne({
_id: postId
// Lookup note
const note = await Note.findOne({
_id: noteId
});
if (post === null) {
return rej('post not found');
if (note === null) {
return rej('note not found');
}
// Construct query
@ -47,7 +47,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
_id: -1
};
const query = {
repostId: post._id
renoteId: note._id
} as any;
if (sinceId) {
sort._id = 1;
@ -61,13 +61,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}
// Issue query
const reposts = await Post
const renotes = await Note
.find(query, {
limit: limit,
sort: sort
});
// Serialize
res(await Promise.all(reposts.map(async post =>
await pack(post, user))));
res(await Promise.all(renotes.map(async note =>
await pack(note, user))));
});

View File

@ -3,14 +3,14 @@
*/
import $ from 'cafy';
const escapeRegexp = require('escape-regexp');
import Post from '../../../../models/post';
import Note from '../../../../models/note';
import User from '../../../../models/user';
import Mute from '../../../../models/mute';
import getFriends from '../../common/get-friends';
import { pack } from '../../../../models/post';
import { pack } from '../../../../models/note';
/**
* Search a post
* Search a note
*
* @param {any} params
* @param {any} me
@ -49,9 +49,9 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
const [reply = null, replyErr] = $(params.reply).optional.nullable.boolean().$;
if (replyErr) return rej('invalid reply param');
// Get 'repost' parameter
const [repost = null, repostErr] = $(params.repost).optional.nullable.boolean().$;
if (repostErr) return rej('invalid repost param');
// Get 'renote' parameter
const [renote = null, renoteErr] = $(params.renote).optional.nullable.boolean().$;
if (renoteErr) return rej('invalid renote param');
// Get 'media' parameter
const [media = null, mediaErr] = $(params.media).optional.nullable.boolean().$;
@ -100,12 +100,12 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
}
search(res, rej, me, text, includeUsers, excludeUsers, following,
mute, reply, repost, media, poll, sinceDate, untilDate, offset, limit);
mute, reply, renote, media, poll, sinceDate, untilDate, offset, limit);
});
async function search(
res, rej, me, text, includeUserIds, excludeUserIds, following,
mute, reply, repost, media, poll, sinceDate, untilDate, offset, max) {
mute, reply, renote, media, poll, sinceDate, untilDate, offset, max) {
let q: any = {
$and: []
@ -182,7 +182,7 @@ async function search(
'_reply.userId': {
$nin: mutedUserIds
},
'_repost.userId': {
'_renote.userId': {
$nin: mutedUserIds
}
});
@ -192,7 +192,7 @@ async function search(
'_reply.userId': {
$nin: mutedUserIds
},
'_repost.userId': {
'_renote.userId': {
$nin: mutedUserIds
}
});
@ -218,7 +218,7 @@ async function search(
$in: mutedUserIds
}
}, {
'_repost.userId': {
'_renote.userId': {
$in: mutedUserIds
}
}]
@ -235,7 +235,7 @@ async function search(
$in: mutedUserIds
}
}, {
'_repost.userId': {
'_renote.userId': {
$in: mutedUserIds
}
}]
@ -265,10 +265,10 @@ async function search(
}
}
if (repost != null) {
if (repost) {
if (renote != null) {
if (renote) {
push({
repostId: {
renoteId: {
$exists: true,
$ne: null
}
@ -276,11 +276,11 @@ async function search(
} else {
push({
$or: [{
repostId: {
renoteId: {
$exists: false
}
}, {
repostId: null
renoteId: null
}]
});
}
@ -348,8 +348,8 @@ async function search(
q = {};
}
// Search posts
const posts = await Post
// Search notes
const notes = await Note
.find(q, {
sort: {
_id: -1
@ -359,6 +359,6 @@ async function search(
});
// Serialize
res(await Promise.all(posts.map(async post =>
await pack(post, me))));
res(await Promise.all(notes.map(async note =>
await pack(note, me))));
}

View File

@ -0,0 +1,32 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import Note, { pack } from '../../../../models/note';
/**
* Show a note
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'noteId' parameter
const [noteId, noteIdErr] = $(params.noteId).id().$;
if (noteIdErr) return rej('invalid noteId param');
// Get note
const note = await Note.findOne({
_id: noteId
});
if (note === null) {
return rej('note not found');
}
// Serialize
res(await pack(note, user, {
detail: true
}));
});

View File

@ -3,11 +3,11 @@
*/
import $ from 'cafy';
import rap from '@prezzemolo/rap';
import Post from '../../../../models/post';
import Note from '../../../../models/note';
import Mute from '../../../../models/mute';
import ChannelWatching from '../../../../models/channel-watching';
import getFriends from '../../common/get-friends';
import { pack } from '../../../../models/post';
import { pack } from '../../../../models/note';
/**
* Get timeline of myself
@ -94,7 +94,7 @@ module.exports = async (params, user, app) => {
'_reply.userId': {
$nin: mutedUserIds
},
'_repost.userId': {
'_renote.userId': {
$nin: mutedUserIds
},
} as any;
@ -121,12 +121,12 @@ module.exports = async (params, user, app) => {
//#endregion
// Issue query
const timeline = await Post
const timeline = await Note
.find(query, {
limit: limit,
sort: sort
});
// Serialize
return await Promise.all(timeline.map(post => pack(post, user)));
return await Promise.all(timeline.map(note => pack(note, user)));
};

View File

@ -3,10 +3,10 @@
*/
const ms = require('ms');
import $ from 'cafy';
import Post, { pack } from '../../../../models/post';
import Note, { pack } from '../../../../models/note';
/**
* Get trend posts
* Get trend notes
*
* @param {any} params
* @param {any} user
@ -25,9 +25,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
const [reply, replyErr] = $(params.reply).optional.boolean().$;
if (replyErr) return rej('invalid reply param');
// Get 'repost' parameter
const [repost, repostErr] = $(params.repost).optional.boolean().$;
if (repostErr) return rej('invalid repost param');
// Get 'renote' parameter
const [renote, renoteErr] = $(params.renote).optional.boolean().$;
if (renoteErr) return rej('invalid renote param');
// Get 'media' parameter
const [media, mediaErr] = $(params.media).optional.boolean().$;
@ -41,7 +41,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
createdAt: {
$gte: new Date(Date.now() - ms('1days'))
},
repostCount: {
renoteCount: {
$gt: 0
}
} as any;
@ -50,8 +50,8 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
query.replyId = reply ? { $exists: true, $ne: null } : null;
}
if (repost != undefined) {
query.repostId = repost ? { $exists: true, $ne: null } : null;
if (renote != undefined) {
query.renoteId = renote ? { $exists: true, $ne: null } : null;
}
if (media != undefined) {
@ -63,17 +63,17 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
}
// Issue query
const posts = await Post
const notes = await Note
.find(query, {
limit: limit,
skip: offset,
sort: {
repostCount: -1,
renoteCount: -1,
_id: -1
}
});
// Serialize
res(await Promise.all(posts.map(async post =>
await pack(post, user, { detail: true }))));
res(await Promise.all(notes.map(async note =>
await pack(note, user, { detail: true }))));
});

View File

@ -2,10 +2,10 @@
* Module dependencies
*/
import $ from 'cafy';
import Post, { pack } from '../../../models/post';
import Note, { pack } from '../../../models/note';
/**
* Lists all posts
* Lists all notes
*
* @param {any} params
* @return {Promise<any>}
@ -15,9 +15,9 @@ module.exports = (params) => new Promise(async (res, rej) => {
const [reply, replyErr] = $(params.reply).optional.boolean().$;
if (replyErr) return rej('invalid reply param');
// Get 'repost' parameter
const [repost, repostErr] = $(params.repost).optional.boolean().$;
if (repostErr) return rej('invalid repost param');
// Get 'renote' parameter
const [renote, renoteErr] = $(params.renote).optional.boolean().$;
if (renoteErr) return rej('invalid renote param');
// Get 'media' parameter
const [media, mediaErr] = $(params.media).optional.boolean().$;
@ -68,8 +68,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
query.replyId = reply ? { $exists: true, $ne: null } : null;
}
if (repost != undefined) {
query.repostId = repost ? { $exists: true, $ne: null } : null;
if (renote != undefined) {
query.renoteId = renote ? { $exists: true, $ne: null } : null;
}
if (media != undefined) {
@ -86,12 +86,12 @@ module.exports = (params) => new Promise(async (res, rej) => {
//}
// Issue query
const posts = await Post
const notes = await Note
.find(query, {
limit: limit,
sort: sort
});
// Serialize
res(await Promise.all(posts.map(async post => await pack(post))));
res(await Promise.all(notes.map(async note => await pack(note))));
});

View File

@ -3,15 +3,15 @@
*/
import $ from 'cafy';
import deepEqual = require('deep-equal');
import Post, { IPost, isValidText, isValidCw, pack } from '../../../../models/post';
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
import { ILocalUser } from '../../../../models/user';
import Channel, { IChannel } from '../../../../models/channel';
import DriveFile from '../../../../models/drive-file';
import create from '../../../../services/post/create';
import create from '../../../../services/note/create';
import { IApp } from '../../../../models/app';
/**
* Create a post
* Create a note
*
* @param {any} params
* @param {any} user
@ -79,26 +79,26 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
files = null;
}
// Get 'repostId' parameter
const [repostId, repostIdErr] = $(params.repostId).optional.id().$;
if (repostIdErr) return rej('invalid repostId');
// Get 'renoteId' parameter
const [renoteId, renoteIdErr] = $(params.renoteId).optional.id().$;
if (renoteIdErr) return rej('invalid renoteId');
let repost: IPost = null;
let renote: INote = null;
let isQuote = false;
if (repostId !== undefined) {
// Fetch repost to post
repost = await Post.findOne({
_id: repostId
if (renoteId !== undefined) {
// Fetch renote to note
renote = await Note.findOne({
_id: renoteId
});
if (repost == null) {
return rej('repostee is not found');
} else if (repost.repostId && !repost.text && !repost.mediaIds) {
return rej('cannot repost to repost');
if (renote == null) {
return rej('renoteee is not found');
} else if (renote.renoteId && !renote.text && !renote.mediaIds) {
return rej('cannot renote to renote');
}
// Fetch recently post
const latestPost = await Post.findOne({
// Fetch recently note
const latestNote = await Note.findOne({
userId: user._id
}, {
sort: {
@ -108,19 +108,19 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
isQuote = text != null || files != null;
// 直近と同じRepost対象かつ引用じゃなかったらエラー
if (latestPost &&
latestPost.repostId &&
latestPost.repostId.equals(repost._id) &&
// 直近と同じRenote対象かつ引用じゃなかったらエラー
if (latestNote &&
latestNote.renoteId &&
latestNote.renoteId.equals(renote._id) &&
!isQuote) {
return rej('cannot repost same post that already reposted in your latest post');
return rej('cannot renote same note that already reposted in your latest note');
}
// 直近がRepost対象かつ引用じゃなかったらエラー
if (latestPost &&
latestPost._id.equals(repost._id) &&
// 直近がRenote対象かつ引用じゃなかったらエラー
if (latestNote &&
latestNote._id.equals(renote._id) &&
!isQuote) {
return rej('cannot repost your latest post');
return rej('cannot renote your latest note');
}
}
@ -128,20 +128,20 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
const [replyId, replyIdErr] = $(params.replyId).optional.id().$;
if (replyIdErr) return rej('invalid replyId');
let reply: IPost = null;
let reply: INote = null;
if (replyId !== undefined) {
// Fetch reply
reply = await Post.findOne({
reply = await Note.findOne({
_id: replyId
});
if (reply === null) {
return rej('in reply to post is not found');
return rej('in reply to note is not found');
}
// 返信対象が引用でないRepostだったらエラー
if (reply.repostId && !reply.text && !reply.mediaIds) {
return rej('cannot reply to repost');
// 返信対象が引用でないRenoteだったらエラー
if (reply.renoteId && !reply.text && !reply.mediaIds) {
return rej('cannot reply to renote');
}
}
@ -165,14 +165,14 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
return rej('チャンネル内部からチャンネル外部の投稿に返信することはできません');
}
// Repost対象の投稿がこのチャンネルじゃなかったらダメ
if (repost && !channelId.equals(repost.channelId)) {
return rej('チャンネル内部からチャンネル外部の投稿をRepostすることはできません');
// Renote対象の投稿がこのチャンネルじゃなかったらダメ
if (renote && !channelId.equals(renote.channelId)) {
return rej('チャンネル内部からチャンネル外部の投稿をRenoteすることはできません');
}
// 引用ではないRepostはダメ
if (repost && !isQuote) {
return rej('チャンネル内部では引用ではないRepostをすることはできません');
// 引用ではないRenoteはダメ
if (renote && !isQuote) {
return rej('チャンネル内部では引用ではないRenoteをすることはできません');
}
} else {
// 返信対象の投稿がチャンネルへの投稿だったらダメ
@ -180,9 +180,9 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
return rej('チャンネル外部からチャンネル内部の投稿に返信することはできません');
}
// Repost対象の投稿がチャンネルへの投稿だったらダメ
if (repost && repost.channelId != null) {
return rej('チャンネル外部からチャンネル内部の投稿をRepostすることはできません');
// Renote対象の投稿がチャンネルへの投稿だったらダメ
if (renote && renote.channelId != null) {
return rej('チャンネル外部からチャンネル内部の投稿をRenoteすることはできません');
}
}
@ -203,23 +203,23 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
}));
}
// テキストが無いかつ添付ファイルが無いかつRepostも無いかつ投票も無かったらエラー
if (text === undefined && files === null && repost === null && poll === undefined) {
return rej('text, mediaIds, repostId or poll is required');
// テキストが無いかつ添付ファイルが無いかつRenoteも無いかつ投票も無かったらエラー
if (text === undefined && files === null && renote === null && poll === undefined) {
return rej('text, mediaIds, renoteId or poll is required');
}
// 直近の投稿と重複してたらエラー
// TODO: 直近の投稿が一日前くらいなら重複とは見なさない
if (user.latestPost) {
if (user.latestNote) {
if (deepEqual({
text: user.latestPost.text,
reply: user.latestPost.replyId ? user.latestPost.replyId.toString() : null,
repost: user.latestPost.repostId ? user.latestPost.repostId.toString() : null,
mediaIds: (user.latestPost.mediaIds || []).map(id => id.toString())
text: user.latestNote.text,
reply: user.latestNote.replyId ? user.latestNote.replyId.toString() : null,
renote: user.latestNote.renoteId ? user.latestNote.renoteId.toString() : null,
mediaIds: (user.latestNote.mediaIds || []).map(id => id.toString())
}, {
text: text,
reply: reply ? reply._id.toString() : null,
repost: repost ? repost._id.toString() : null,
renote: renote ? renote._id.toString() : null,
mediaIds: (files || []).map(file => file._id.toString())
})) {
return rej('duplicate');
@ -227,13 +227,13 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
}
// 投稿を作成
const post = await create(user, {
const note = await create(user, {
createdAt: new Date(),
media: files,
poll: poll,
text: text,
reply,
repost,
renote,
cw: cw,
tags: tags,
app: app,
@ -242,10 +242,10 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
geo
});
const postObj = await pack(post, user);
const noteObj = await pack(note, user);
// Reponse
res({
createdPost: postObj
createdNote: noteObj
});
});

View File

@ -1,32 +0,0 @@
/**
* Module dependencies
*/
import $ from 'cafy';
import Post, { pack } from '../../../../models/post';
/**
* Show a post
*
* @param {any} params
* @param {any} user
* @return {Promise<any>}
*/
module.exports = (params, user) => new Promise(async (res, rej) => {
// Get 'postId' parameter
const [postId, postIdErr] = $(params.postId).id().$;
if (postIdErr) return rej('invalid postId param');
// Get post
const post = await Post.findOne({
_id: postId
});
if (post === null) {
return rej('post not found');
}
// Serialize
res(await pack(post, user, {
detail: true
}));
});

View File

@ -1,13 +1,13 @@
/**
* Module dependencies
*/
import Post from '../../../models/post';
import Note from '../../../models/note';
import User from '../../../models/user';
/**
* @swagger
* /stats:
* post:
* note:
* summary: Show the misskey's statistics
* responses:
* 200:
@ -15,8 +15,8 @@ import User from '../../../models/user';
* schema:
* type: object
* properties:
* postsCount:
* description: count of all posts of misskey
* notesCount:
* description: count of all notes of misskey
* type: number
* usersCount:
* description: count of all users of misskey
@ -35,14 +35,14 @@ import User from '../../../models/user';
* @return {Promise<any>}
*/
module.exports = params => new Promise(async (res, rej) => {
const postsCount = await Post
const notesCount = await Note
.count();
const usersCount = await User
.count();
res({
postsCount: postsCount,
notesCount: notesCount,
usersCount: usersCount
});
});

View File

@ -2,7 +2,7 @@
* Module dependencies
*/
import $ from 'cafy';
import Post from '../../../../models/post';
import Note from '../../../../models/note';
import User, { pack } from '../../../../models/user';
module.exports = (params, me) => new Promise(async (res, rej) => {
@ -27,8 +27,8 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
return rej('user not found');
}
// Fetch recent posts
const recentPosts = await Post.find({
// Fetch recent notes
const recentNotes = await Note.find({
userId: user._id,
replyId: {
$exists: true,
@ -46,13 +46,13 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
});
// 投稿が少なかったら中断
if (recentPosts.length === 0) {
if (recentNotes.length === 0) {
return res([]);
}
const replyTargetPosts = await Post.find({
const replyTargetNotes = await Note.find({
_id: {
$in: recentPosts.map(p => p.replyId)
$in: recentNotes.map(p => p.replyId)
},
userId: {
$ne: user._id
@ -66,9 +66,9 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
const repliedUsers = {};
// Extract replies from recent posts
replyTargetPosts.forEach(post => {
const userId = post.userId.toString();
// Extract replies from recent notes
replyTargetNotes.forEach(note => {
const userId = note.userId.toString();
if (repliedUsers[userId]) {
repliedUsers[userId]++;
} else {

View File

@ -3,11 +3,11 @@
*/
import $ from 'cafy';
import getHostLower from '../../common/get-host-lower';
import Post, { pack } from '../../../../models/post';
import Note, { pack } from '../../../../models/note';
import User from '../../../../models/user';
/**
* Get posts of a user
* Get notes of a user
*
* @param {any} params
* @param {any} me
@ -124,14 +124,14 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
//#endregion
// Issue query
const posts = await Post
const notes = await Note
.find(query, {
limit: limit,
sort: sort
});
// Serialize
res(await Promise.all(posts.map(async (post) =>
await pack(post, me)
res(await Promise.all(notes.map(async (note) =>
await pack(note, me)
)));
});

View File

@ -113,7 +113,7 @@ export default async (req: express.Request, res: express.Response) => {
followersCount: 0,
followingCount: 0,
name: null,
postsCount: 0,
notesCount: 0,
driveCapacity: 1024 * 1024 * 128, // 128MiB
username: username,
usernameLower: username.toLowerCase(),

View File

@ -18,7 +18,7 @@ module.exports = async (app: express.Application) => {
return;
}
const post = text => require('../endpoints/posts/create')({ text }, bot);
const post = text => require('../endpoints/notes/create')({ text }, bot);
const handler = new EventEmitter();

View File

@ -4,7 +4,7 @@ import * as debug from 'debug';
import User from '../../../models/user';
import Mute from '../../../models/mute';
import { pack as packPost } from '../../../models/post';
import { pack as packNote } from '../../../models/note';
import readNotification from '../common/read-notification';
const log = debug('misskey');
@ -25,14 +25,14 @@ export default async function(request: websocket.request, connection: websocket.
try {
const x = JSON.parse(data);
if (x.type == 'post') {
if (x.type == 'note') {
if (mutedUserIds.indexOf(x.body.userId) != -1) {
return;
}
if (x.body.reply != null && mutedUserIds.indexOf(x.body.reply.userId) != -1) {
return;
}
if (x.body.repost != null && mutedUserIds.indexOf(x.body.repost.userId) != -1) {
if (x.body.renote != null && mutedUserIds.indexOf(x.body.renote.userId) != -1) {
return;
}
} else if (x.type == 'notification') {
@ -46,16 +46,16 @@ export default async function(request: websocket.request, connection: websocket.
connection.send(data);
}
break;
case 'post-stream':
const postId = channel.split(':')[2];
log(`RECEIVED: ${postId} ${data} by @${user.username}`);
const post = await packPost(postId, user, {
case 'note-stream':
const noteId = channel.split(':')[2];
log(`RECEIVED: ${noteId} ${data} by @${user.username}`);
const note = await packNote(noteId, user, {
detail: true
});
connection.send(JSON.stringify({
type: 'post-updated',
type: 'note-updated',
body: {
post: post
note: note
}
}));
break;
@ -86,9 +86,9 @@ export default async function(request: websocket.request, connection: websocket.
case 'capture':
if (!msg.id) return;
const postId = msg.id;
log(`CAPTURE: ${postId} by @${user.username}`);
subscriber.subscribe(`misskey:post-stream:${postId}`);
const noteId = msg.id;
log(`CAPTURE: ${noteId} by @${user.username}`);
subscriber.subscribe(`misskey:note-stream:${noteId}`);
break;
}
});