summaryrefslogtreecommitdiff
path: root/src/server/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api')
-rw-r--r--src/server/api/endpoints/ap/show.ts10
-rw-r--r--src/server/api/endpoints/drive/files/check_existence.ts3
-rw-r--r--src/server/api/endpoints/drive/files/show.ts3
-rw-r--r--src/server/api/endpoints/meta.ts20
-rw-r--r--src/server/api/endpoints/notes/global-timeline.ts2
-rw-r--r--src/server/api/endpoints/notes/hybrid-timeline.ts2
-rw-r--r--src/server/api/endpoints/notes/local-timeline.ts2
-rw-r--r--src/server/api/endpoints/notes/mentions.ts2
-rw-r--r--src/server/api/endpoints/notes/timeline.ts2
-rw-r--r--src/server/api/endpoints/notes/user-list-timeline.ts2
-rw-r--r--src/server/api/endpoints/users/notes.ts1
-rw-r--r--src/server/api/endpoints/users/recommendation.ts94
-rw-r--r--src/server/api/limitter.ts6
-rw-r--r--src/server/api/service/twitter.ts2
-rw-r--r--src/server/api/stream/channel.ts2
-rw-r--r--src/server/api/stream/channels/drive.ts3
-rw-r--r--src/server/api/stream/channels/games/reversi-game.ts16
-rw-r--r--src/server/api/stream/channels/games/reversi.ts3
-rw-r--r--src/server/api/stream/channels/global-timeline.ts3
-rw-r--r--src/server/api/stream/channels/hashtag.ts3
-rw-r--r--src/server/api/stream/channels/home-timeline.ts3
-rw-r--r--src/server/api/stream/channels/hybrid-timeline.ts3
-rw-r--r--src/server/api/stream/channels/local-timeline.ts3
-rw-r--r--src/server/api/stream/channels/main.ts3
-rw-r--r--src/server/api/stream/channels/messaging-index.ts3
-rw-r--r--src/server/api/stream/channels/messaging.ts3
-rw-r--r--src/server/api/stream/channels/notes-stats.ts3
-rw-r--r--src/server/api/stream/channels/server-stats.ts3
-rw-r--r--src/server/api/stream/channels/user-list.ts3
-rw-r--r--src/server/api/stream/index.ts25
-rw-r--r--src/server/api/streaming.ts43
31 files changed, 209 insertions, 67 deletions
diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts
index 1f390d01aa..6cbd4ef87e 100644
--- a/src/server/api/endpoints/ap/show.ts
+++ b/src/server/api/endpoints/ap/show.ts
@@ -24,15 +24,15 @@ export const meta = {
},
};
-export default (params: any) => new Promise(async (res, rej) => {
+export default async (params: any) => {
const [ps, psErr] = getParams(meta, params);
- if (psErr) return rej(psErr);
+ if (psErr) throw psErr;
const object = await fetchAny(ps.uri);
- if (object !== null) return res(object);
+ if (object !== null) return object;
- return rej('object not found');
-});
+ throw new Error('object not found');
+};
/***
* URIからUserかNoteを解決する
diff --git a/src/server/api/endpoints/drive/files/check_existence.ts b/src/server/api/endpoints/drive/files/check_existence.ts
index 73d75b7caf..a024701655 100644
--- a/src/server/api/endpoints/drive/files/check_existence.ts
+++ b/src/server/api/endpoints/drive/files/check_existence.ts
@@ -27,7 +27,8 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
const file = await DriveFile.findOne({
md5: md5,
- 'metadata.userId': user._id
+ 'metadata.userId': user._id,
+ 'metadata.deletedAt': { $exists: false }
});
if (file === null) {
diff --git a/src/server/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts
index 718fb8c2d7..e35c5e3ca2 100644
--- a/src/server/api/endpoints/drive/files/show.ts
+++ b/src/server/api/endpoints/drive/files/show.ts
@@ -22,7 +22,8 @@ export default async (params: any, user: ILocalUser) => {
const file = await DriveFile
.findOne({
_id: fileId,
- 'metadata.userId': user._id
+ 'metadata.userId': user._id,
+ 'metadata.deletedAt': { $exists: false }
});
if (file === null) {
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index c76d7f2e8f..152559337d 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -1,6 +1,3 @@
-/**
- * Module dependencies
- */
import * as os from 'os';
import config from '../../../config';
import Meta from '../../../models/meta';
@@ -9,9 +6,17 @@ import { ILocalUser } from '../../../models/user';
const pkg = require('../../../../package.json');
const client = require('../../../../built/client/meta.json');
-/**
- * Show core info
- */
+export const meta = {
+ desc: {
+ 'ja-JP': 'インスタンス情報を取得します。',
+ 'en-US': 'Get the information of this instance.'
+ },
+
+ requireCredential: false,
+
+ params: {},
+};
+
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
const meta: any = (await Meta.findOne()) || {};
@@ -28,10 +33,12 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
machine: os.hostname(),
os: os.platform(),
node: process.version,
+
cpu: {
model: os.cpus()[0].model,
cores: os.cpus().length
},
+
broadcasts: meta.broadcasts || [],
disableRegistration: meta.disableRegistration,
disableLocalTimeline: meta.disableLocalTimeline,
@@ -40,6 +47,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
swPublickey: config.sw ? config.sw.public_key : null,
hidedTags: (me && me.isAdmin) ? meta.hidedTags : undefined,
bannerUrl: meta.bannerUrl,
+
features: {
registration: !meta.disableRegistration,
localTimeLine: !meta.disableLocalTimeline,
diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts
index 8362143bb2..8a6c848943 100644
--- a/src/server/api/endpoints/notes/global-timeline.ts
+++ b/src/server/api/endpoints/notes/global-timeline.ts
@@ -58,6 +58,8 @@ export default async (params: any, user: ILocalUser) => {
};
const query = {
+ deletedAt: null,
+
// public only
visibility: 'public',
diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts
index 14b4432b33..b2ea9c60ac 100644
--- a/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -129,6 +129,8 @@ export default async (params: any, user: ILocalUser) => {
const query = {
$and: [{
+ deletedAt: null,
+
$or: [{
// フォローしている人の投稿
$or: followQuery
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index 8ab07d8ea7..510564129c 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -71,6 +71,8 @@ export default async (params: any, user: ILocalUser) => {
};
const query = {
+ deletedAt: null,
+
// public only
visibility: 'public',
diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts
index 592a94263d..27b6245eb6 100644
--- a/src/server/api/endpoints/notes/mentions.ts
+++ b/src/server/api/endpoints/notes/mentions.ts
@@ -45,6 +45,8 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
// Construct query
const query = {
+ deletedAt: null,
+
$or: [{
mentions: user._id
}, {
diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts
index 44a504eb18..31a4978407 100644
--- a/src/server/api/endpoints/notes/timeline.ts
+++ b/src/server/api/endpoints/notes/timeline.ts
@@ -132,6 +132,8 @@ export default async (params: any, user: ILocalUser) => {
const query = {
$and: [{
+ deletedAt: null,
+
// フォローしている人の投稿
$or: followQuery,
diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts
index 6758b4eb73..7dddc4834e 100644
--- a/src/server/api/endpoints/notes/user-list-timeline.ts
+++ b/src/server/api/endpoints/notes/user-list-timeline.ts
@@ -137,6 +137,8 @@ export default async (params: any, user: ILocalUser) => {
const query = {
$and: [{
+ deletedAt: null,
+
// リストに入っている人のタイムラインへの投稿
$or: listQuery,
diff --git a/src/server/api/endpoints/users/notes.ts b/src/server/api/endpoints/users/notes.ts
index 1bfe832c51..002ddf23e5 100644
--- a/src/server/api/endpoints/users/notes.ts
+++ b/src/server/api/endpoints/users/notes.ts
@@ -136,6 +136,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
};
const query = {
+ deletedAt: null,
userId: user._id
} as any;
diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts
index e0a5cb9e36..f54326b566 100644
--- a/src/server/api/endpoints/users/recommendation.ts
+++ b/src/server/api/endpoints/users/recommendation.ts
@@ -3,6 +3,8 @@ import $ from 'cafy';
import User, { pack, ILocalUser } from '../../../../models/user';
import { getFriendIds } from '../../common/get-friends';
import Mute from '../../../../models/mute';
+import * as request from 'request';
+import config from '../../../../config';
export const meta = {
desc: {
@@ -15,44 +17,72 @@ export const meta = {
};
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
- // Get 'limit' parameter
- const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit);
- if (limitErr) return rej('invalid limit param');
+ if (config.user_recommendation && config.user_recommendation.external) {
+ const userName = me.username;
+ const hostName = config.hostname;
+ const limit = params.limit;
+ const offset = params.offset;
+ const timeout = config.user_recommendation.timeout;
+ const engine = config.user_recommendation.engine;
+ const url = engine
+ .replace('{{host}}', hostName)
+ .replace('{{user}}', userName)
+ .replace('{{limit}}', limit)
+ .replace('{{offset}}', offset);
- // Get 'offset' parameter
- const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset);
- if (offsetErr) return rej('invalid offset param');
+ request(
+ {
+ url: url,
+ timeout: timeout,
+ json: true,
+ followRedirect: true,
+ followAllRedirects: true
+ },
+ (error: any, response: any, body: any) => {
+ if (!error && response.statusCode == 200) {
+ res(body);
+ } else {
+ res([]);
+ }
+ }
+ );
+ } else {
+ // Get 'limit' parameter
+ const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit);
+ if (limitErr) return rej('invalid limit param');
- // ID list of the user itself and other users who the user follows
- const followingIds = await getFriendIds(me._id);
+ // Get 'offset' parameter
+ const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset);
+ if (offsetErr) return rej('invalid offset param');
- // ミュートしているユーザーを取得
- const mutedUserIds = (await Mute.find({
- muterId: me._id
- })).map(m => m.muteeId);
+ // ID list of the user itself and other users who the user follows
+ const followingIds = await getFriendIds(me._id);
- const users = await User
- .find({
- _id: {
- $nin: followingIds.concat(mutedUserIds)
- },
- isLocked: false,
- $or: [{
+ // ミュートしているユーザーを取得
+ const mutedUserIds = (await Mute.find({
+ muterId: me._id
+ })).map(m => m.muteeId);
+
+ const users = await User
+ .find({
+ _id: {
+ $nin: followingIds.concat(mutedUserIds)
+ },
+ isLocked: { $ne: true },
lastUsedAt: {
$gte: new Date(Date.now() - ms('7days'))
- }
- }, {
+ },
host: null
- }]
- }, {
- limit: limit,
- skip: offset,
- sort: {
- followersCount: -1
- }
- });
+ }, {
+ limit: limit,
+ skip: offset,
+ sort: {
+ followersCount: -1
+ }
+ });
- // Serialize
- res(await Promise.all(users.map(async user =>
- await pack(user, me, { detail: true }))));
+ // Serialize
+ res(await Promise.all(users.map(async user =>
+ await pack(user, me, { detail: true }))));
+ }
});
diff --git a/src/server/api/limitter.ts b/src/server/api/limitter.ts
index 20a18a7098..abf7627ab8 100644
--- a/src/server/api/limitter.ts
+++ b/src/server/api/limitter.ts
@@ -8,6 +8,12 @@ import { IUser } from '../../models/user';
const log = debug('misskey:limitter');
export default (endpoint: IEndpoint, user: IUser) => new Promise((ok, reject) => {
+ // Redisがインストールされてない場合は常に許可
+ if (limiterDB == null) {
+ ok();
+ return;
+ }
+
const limitation = endpoint.meta.limit;
const key = limitation.hasOwnProperty('key')
diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts
index f71e588628..6c3cdaa138 100644
--- a/src/server/api/service/twitter.ts
+++ b/src/server/api/service/twitter.ts
@@ -55,7 +55,7 @@ router.get('/disconnect/twitter', async ctx => {
}));
});
-if (config.twitter == null) {
+if (config.twitter == null || redis == null) {
router.get('/connect/twitter', ctx => {
ctx.body = '現在Twitterへ接続できません (このインスタンスではTwitterはサポートされていません)';
});
diff --git a/src/server/api/stream/channel.ts b/src/server/api/stream/channel.ts
index e2726060dc..75914964cb 100644
--- a/src/server/api/stream/channel.ts
+++ b/src/server/api/stream/channel.ts
@@ -7,6 +7,8 @@ import Connection from '.';
export default abstract class Channel {
protected connection: Connection;
public id: string;
+ public abstract readonly chName: string;
+ public static readonly shouldShare: boolean;
protected get user() {
return this.connection.user;
diff --git a/src/server/api/stream/channels/drive.ts b/src/server/api/stream/channels/drive.ts
index 807fc93cd0..7425a620ff 100644
--- a/src/server/api/stream/channels/drive.ts
+++ b/src/server/api/stream/channels/drive.ts
@@ -2,6 +2,9 @@ import autobind from 'autobind-decorator';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'drive';
+ public static shouldShare = true;
+
@autobind
public async init(params: any) {
// Subscribe drive stream
diff --git a/src/server/api/stream/channels/games/reversi-game.ts b/src/server/api/stream/channels/games/reversi-game.ts
index 11f1fb1feb..5dc9ca0608 100644
--- a/src/server/api/stream/channels/games/reversi-game.ts
+++ b/src/server/api/stream/channels/games/reversi-game.ts
@@ -1,5 +1,6 @@
import autobind from 'autobind-decorator';
import * as CRC32 from 'crc-32';
+import * as mongo from 'mongodb';
import ReversiGame, { pack } from '../../../../../models/games/reversi/game';
import { publishReversiGameStream } from '../../../../../stream';
import Reversi from '../../../../../games/reversi/core';
@@ -7,11 +8,14 @@ import * as maps from '../../../../../games/reversi/maps';
import Channel from '../../channel';
export default class extends Channel {
- private gameId: string;
+ public readonly chName = 'gamesReversiGame';
+ public static shouldShare = false;
+
+ private gameId: mongo.ObjectID;
@autobind
public async init(params: any) {
- this.gameId = params.gameId as string;
+ this.gameId = new mongo.ObjectID(params.gameId as string);
// Subscribe game stream
this.subscriber.on(`reversiGameStream:${this.gameId}`, data => {
@@ -23,10 +27,10 @@ export default class extends Channel {
public onMessage(type: string, body: any) {
switch (type) {
case 'accept': this.accept(true); break;
- case 'cancel-accept': this.accept(false); break;
- case 'update-settings': this.updateSettings(body.settings); break;
- case 'init-form': this.initForm(body); break;
- case 'update-form': this.updateForm(body.id, body.value); break;
+ case 'cancelAccept': this.accept(false); break;
+ case 'updateSettings': this.updateSettings(body.settings); break;
+ case 'initForm': this.initForm(body); break;
+ case 'updateForm': this.updateForm(body.id, body.value); break;
case 'message': this.message(body); break;
case 'set': this.set(body.pos); break;
case 'check': this.check(body.crc32); break;
diff --git a/src/server/api/stream/channels/games/reversi.ts b/src/server/api/stream/channels/games/reversi.ts
index d75025c944..51cb264d98 100644
--- a/src/server/api/stream/channels/games/reversi.ts
+++ b/src/server/api/stream/channels/games/reversi.ts
@@ -5,6 +5,9 @@ import { publishMainStream } from '../../../../../stream';
import Channel from '../../channel';
export default class extends Channel {
+ public readonly chName = 'gamesReversi';
+ public static shouldShare = true;
+
@autobind
public async init(params: any) {
// Subscribe reversi stream
diff --git a/src/server/api/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts
index ab0fe5d094..e39ea269a6 100644
--- a/src/server/api/stream/channels/global-timeline.ts
+++ b/src/server/api/stream/channels/global-timeline.ts
@@ -5,6 +5,9 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'globalTimeline';
+ public static shouldShare = true;
+
private mutedUserIds: string[] = [];
@autobind
diff --git a/src/server/api/stream/channels/hashtag.ts b/src/server/api/stream/channels/hashtag.ts
index 652b0caa5b..cf652c166c 100644
--- a/src/server/api/stream/channels/hashtag.ts
+++ b/src/server/api/stream/channels/hashtag.ts
@@ -5,6 +5,9 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'hashtag';
+ public static shouldShare = false;
+
@autobind
public async init(params: any) {
const mute = this.user ? await Mute.find({ muterId: this.user._id }) : null;
diff --git a/src/server/api/stream/channels/home-timeline.ts b/src/server/api/stream/channels/home-timeline.ts
index 4c674e75ef..3fa887f1e5 100644
--- a/src/server/api/stream/channels/home-timeline.ts
+++ b/src/server/api/stream/channels/home-timeline.ts
@@ -5,6 +5,9 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'homeTimeline';
+ public static shouldShare = true;
+
private mutedUserIds: string[] = [];
@autobind
diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts
index 0b12ab3a8f..d72545e4c8 100644
--- a/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/src/server/api/stream/channels/hybrid-timeline.ts
@@ -5,6 +5,9 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'hybridTimeline';
+ public static shouldShare = true;
+
private mutedUserIds: string[] = [];
@autobind
diff --git a/src/server/api/stream/channels/local-timeline.ts b/src/server/api/stream/channels/local-timeline.ts
index 769ec6392f..0ba0b1b195 100644
--- a/src/server/api/stream/channels/local-timeline.ts
+++ b/src/server/api/stream/channels/local-timeline.ts
@@ -5,6 +5,9 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'localTimeline';
+ public static shouldShare = true;
+
private mutedUserIds: string[] = [];
@autobind
diff --git a/src/server/api/stream/channels/main.ts b/src/server/api/stream/channels/main.ts
index fd0984c833..7d5462c092 100644
--- a/src/server/api/stream/channels/main.ts
+++ b/src/server/api/stream/channels/main.ts
@@ -3,6 +3,9 @@ import Mute from '../../../../models/mute';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'main';
+ public static shouldShare = true;
+
@autobind
public async init(params: any) {
const mute = await Mute.find({ muterId: this.user._id });
diff --git a/src/server/api/stream/channels/messaging-index.ts b/src/server/api/stream/channels/messaging-index.ts
index 6e87cca7f4..0211d702cf 100644
--- a/src/server/api/stream/channels/messaging-index.ts
+++ b/src/server/api/stream/channels/messaging-index.ts
@@ -2,6 +2,9 @@ import autobind from 'autobind-decorator';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'messagingIndex';
+ public static shouldShare = true;
+
@autobind
public async init(params: any) {
// Subscribe messaging index stream
diff --git a/src/server/api/stream/channels/messaging.ts b/src/server/api/stream/channels/messaging.ts
index e1a78c8678..ab04a332cf 100644
--- a/src/server/api/stream/channels/messaging.ts
+++ b/src/server/api/stream/channels/messaging.ts
@@ -3,6 +3,9 @@ import read from '../../common/read-messaging-message';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'messaging';
+ public static shouldShare = false;
+
private otherpartyId: string;
@autobind
diff --git a/src/server/api/stream/channels/notes-stats.ts b/src/server/api/stream/channels/notes-stats.ts
index cc68d9886d..2282f8bc70 100644
--- a/src/server/api/stream/channels/notes-stats.ts
+++ b/src/server/api/stream/channels/notes-stats.ts
@@ -5,6 +5,9 @@ import Channel from '../channel';
const ev = new Xev();
export default class extends Channel {
+ public readonly chName = 'notesStats';
+ public static shouldShare = true;
+
@autobind
public async init(params: any) {
ev.addListener('notesStats', this.onStats);
diff --git a/src/server/api/stream/channels/server-stats.ts b/src/server/api/stream/channels/server-stats.ts
index 28a566e8ae..912dcf5305 100644
--- a/src/server/api/stream/channels/server-stats.ts
+++ b/src/server/api/stream/channels/server-stats.ts
@@ -5,6 +5,9 @@ import Channel from '../channel';
const ev = new Xev();
export default class extends Channel {
+ public readonly chName = 'serverStats';
+ public static shouldShare = true;
+
@autobind
public async init(params: any) {
ev.addListener('serverStats', this.onStats);
diff --git a/src/server/api/stream/channels/user-list.ts b/src/server/api/stream/channels/user-list.ts
index 4ace308923..b526a5f986 100644
--- a/src/server/api/stream/channels/user-list.ts
+++ b/src/server/api/stream/channels/user-list.ts
@@ -2,6 +2,9 @@ import autobind from 'autobind-decorator';
import Channel from '../channel';
export default class extends Channel {
+ public readonly chName = 'userList';
+ public static shouldShare = false;
+
@autobind
public async init(params: any) {
const listId = params.listId as string;
diff --git a/src/server/api/stream/index.ts b/src/server/api/stream/index.ts
index ef6397fcd9..6d3675c94b 100644
--- a/src/server/api/stream/index.ts
+++ b/src/server/api/stream/index.ts
@@ -1,6 +1,5 @@
import autobind from 'autobind-decorator';
import * as websocket from 'websocket';
-import Xev from 'xev';
import * as debug from 'debug';
import User, { IUser } from '../../../models/user';
@@ -11,6 +10,7 @@ import readNote from '../../../services/note/read';
import Channel from './channel';
import channels from './channels';
+import { EventEmitter } from 'events';
const log = debug('misskey');
@@ -21,14 +21,14 @@ export default class Connection {
public user?: IUser;
public app: IApp;
private wsConnection: websocket.connection;
- public subscriber: Xev;
+ public subscriber: EventEmitter;
private channels: Channel[] = [];
private subscribingNotes: any = {};
public sendMessageToWsOverride: any = null; // 後方互換性のため
constructor(
wsConnection: websocket.connection,
- subscriber: Xev,
+ subscriber: EventEmitter,
user: IUser,
app: IApp
) {
@@ -58,6 +58,7 @@ export default class Connection {
case 'connect': this.onChannelConnectRequested(body); break;
case 'disconnect': this.onChannelDisconnectRequested(body); break;
case 'channel': this.onChannelMessageRequested(body); break;
+ case 'ch': this.onChannelMessageRequested(body); break; // alias
}
}
@@ -147,7 +148,7 @@ export default class Connection {
private onChannelConnectRequested(payload: any) {
const { channel, id, params } = payload;
log(`CH CONNECT: ${id} ${channel} by @${this.user.username}`);
- this.connectChannel(id, params, (channels as any)[channel]);
+ this.connectChannel(id, params, channel);
}
/**
@@ -176,10 +177,18 @@ export default class Connection {
* チャンネルに接続
*/
@autobind
- public connectChannel(id: string, params: any, channelClass: { new(id: string, connection: Connection): Channel }) {
- const channel = new channelClass(id, this);
- this.channels.push(channel);
- channel.init(params);
+ public connectChannel(id: string, params: any, channel: string) {
+ // 共有可能チャンネルに接続しようとしていて、かつそのチャンネルに既に接続していたら無意味なので無視
+ if ((channels as any)[channel].shouldShare && this.channels.some(c => c.chName === channel)) {
+ return;
+ }
+
+ const ch: Channel = new (channels as any)[channel](id, this);
+ this.channels.push(ch);
+ ch.init(params);
+ this.sendMessageToWs('connected', {
+ id: id
+ });
}
/**
diff --git a/src/server/api/streaming.ts b/src/server/api/streaming.ts
index c8c4a8a294..1a0543b364 100644
--- a/src/server/api/streaming.ts
+++ b/src/server/api/streaming.ts
@@ -1,11 +1,13 @@
import * as http from 'http';
import * as websocket from 'websocket';
+import * as redis from 'redis';
import Xev from 'xev';
import MainStreamConnection from './stream';
import { ParsedUrlQuery } from 'querystring';
import authenticate from './authenticate';
-import channels from './stream/channels';
+import { EventEmitter } from 'events';
+import config from '../../config';
module.exports = (server: http.Server) => {
// Init websocket server
@@ -16,11 +18,34 @@ module.exports = (server: http.Server) => {
ws.on('request', async (request) => {
const connection = request.accept();
- const ev = new Xev();
-
const q = request.resourceURL.query as ParsedUrlQuery;
const [user, app] = await authenticate(q.i as string);
+ let ev: EventEmitter;
+
+ if (config.redis) {
+ // Connect to Redis
+ const subscriber = redis.createClient(
+ config.redis.port, config.redis.host);
+
+ subscriber.subscribe('misskey');
+
+ ev = new EventEmitter();
+
+ subscriber.on('message', async (_, data) => {
+ const obj = JSON.parse(data);
+
+ ev.emit(obj.channel, obj.message);
+ });
+
+ connection.once('close', () => {
+ subscriber.unsubscribe();
+ subscriber.quit();
+ });
+ } else {
+ ev = new Xev();
+ }
+
const main = new MainStreamConnection(connection, ev, user, app);
// 後方互換性のため
@@ -40,10 +65,14 @@ module.exports = (server: http.Server) => {
};
main.connectChannel(Math.random().toString(), null,
- request.resourceURL.pathname === '/' ? channels.homeTimeline :
- request.resourceURL.pathname === '/local-timeline' ? channels.localTimeline :
- request.resourceURL.pathname === '/hybrid-timeline' ? channels.hybridTimeline :
- request.resourceURL.pathname === '/global-timeline' ? channels.globalTimeline : null);
+ request.resourceURL.pathname === '/' ? 'homeTimeline' :
+ request.resourceURL.pathname === '/local-timeline' ? 'localTimeline' :
+ request.resourceURL.pathname === '/hybrid-timeline' ? 'hybridTimeline' :
+ request.resourceURL.pathname === '/global-timeline' ? 'globalTimeline' : null);
+
+ if (request.resourceURL.pathname === '/') {
+ main.connectChannel(Math.random().toString(), null, 'main');
+ }
}
connection.once('close', () => {