summaryrefslogtreecommitdiff
path: root/src/server/api
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-09-17 09:00:20 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-09-17 09:00:20 +0900
commit109738ccb9ef8c203685e6f4bc31986ac2a17046 (patch)
treef91e8bb9c9ec445a10b018a934c88ebbdfeb8db1 /src/server/api
parent8.44.1 (diff)
downloadsharkey-109738ccb9ef8c203685e6f4bc31986ac2a17046.tar.gz
sharkey-109738ccb9ef8c203685e6f4bc31986ac2a17046.tar.bz2
sharkey-109738ccb9ef8c203685e6f4bc31986ac2a17046.zip
ハッシュタグタイムラインを実装
Diffstat (limited to 'src/server/api')
-rw-r--r--src/server/api/endpoints/notes/search_by_tag.ts45
-rw-r--r--src/server/api/stream/hashtag.ts48
-rw-r--r--src/server/api/streaming.ts6
3 files changed, 74 insertions, 25 deletions
diff --git a/src/server/api/endpoints/notes/search_by_tag.ts b/src/server/api/endpoints/notes/search_by_tag.ts
index 11bfe34724..7beb97aec6 100644
--- a/src/server/api/endpoints/notes/search_by_tag.ts
+++ b/src/server/api/endpoints/notes/search_by_tag.ts
@@ -13,12 +13,18 @@ export const meta = {
},
params: {
- tag: $.str.note({
+ tag: $.str.optional.note({
desc: {
'ja-JP': 'タグ'
}
}),
+ query: $.arr($.arr($.str)).optional.note({
+ desc: {
+ 'ja-JP': 'クエリ'
+ }
+ }),
+
includeUserIds: $.arr($.type(ID)).optional.note({
default: []
}),
@@ -59,11 +65,9 @@ export const meta = {
}
}),
- withFiles: $.bool.optional.nullable.note({
- default: null,
-
+ withFiles: $.bool.optional.note({
desc: {
- 'ja-JP': 'ファイルが添付された投稿に限定するか否か'
+ 'ja-JP': 'true にすると、ファイルが添付された投稿だけ取得します'
}
}),
@@ -126,8 +130,14 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
}
const q: any = {
- $and: [{
+ $and: [ps.tag ? {
tagsLower: ps.tag.toLowerCase()
+ } : {
+ $or: ps.query.map(tags => ({
+ $and: tags.map(t => ({
+ tagsLower: t.toLowerCase()
+ }))
+ }))
}],
deletedAt: { $exists: false }
};
@@ -281,25 +291,10 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
const withFiles = ps.withFiles != null ? ps.withFiles : ps.media;
- if (withFiles != null) {
- if (withFiles) {
- push({
- fileIds: {
- $exists: true,
- $ne: null
- }
- });
- } else {
- push({
- $or: [{
- fileIds: {
- $exists: false
- }
- }, {
- fileIds: null
- }]
- });
- }
+ if (withFiles) {
+ push({
+ fileIds: { $exists: true, $ne: [] }
+ });
}
if (ps.poll != null) {
diff --git a/src/server/api/stream/hashtag.ts b/src/server/api/stream/hashtag.ts
new file mode 100644
index 0000000000..db2806e796
--- /dev/null
+++ b/src/server/api/stream/hashtag.ts
@@ -0,0 +1,48 @@
+import * as websocket from 'websocket';
+import Xev from 'xev';
+
+import { IUser } from '../../../models/user';
+import Mute from '../../../models/mute';
+import { pack } from '../../../models/note';
+
+export default async function(
+ request: websocket.request,
+ connection: websocket.connection,
+ subscriber: Xev,
+ user?: IUser
+) {
+ const mute = user ? await Mute.find({ muterId: user._id }) : null;
+ const mutedUserIds = mute ? mute.map(m => m.muteeId.toString()) : [];
+
+ const q: Array<string[]> = JSON.parse((request.resourceURL.query as any).q);
+
+ // Subscribe stream
+ subscriber.on('hashtag', async note => {
+ const matched = q.some(tags => tags.every(tag => note.tags.map((t: string) => t.toLowerCase()).includes(tag.toLowerCase())));
+ if (!matched) return;
+
+ // Renoteなら再pack
+ if (note.renoteId != null) {
+ note.renote = await pack(note.renoteId, user, {
+ detail: true
+ });
+ }
+
+ //#region 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
+ if (mutedUserIds.indexOf(note.userId) != -1) {
+ return;
+ }
+ if (note.reply != null && mutedUserIds.indexOf(note.reply.userId) != -1) {
+ return;
+ }
+ if (note.renote != null && mutedUserIds.indexOf(note.renote.userId) != -1) {
+ return;
+ }
+ //#endregion
+
+ connection.send(JSON.stringify({
+ type: 'note',
+ body: note
+ }));
+ });
+}
diff --git a/src/server/api/streaming.ts b/src/server/api/streaming.ts
index e6094a40b2..873719d031 100644
--- a/src/server/api/streaming.ts
+++ b/src/server/api/streaming.ts
@@ -14,6 +14,7 @@ import reversiGameStream from './stream/games/reversi-game';
import reversiStream from './stream/games/reversi';
import serverStatsStream from './stream/server-stats';
import notesStatsStream from './stream/notes-stats';
+import hashtagStream from './stream/hashtag';
import { ParsedUrlQuery } from 'querystring';
import authenticate from './authenticate';
@@ -57,6 +58,11 @@ module.exports = (server: http.Server) => {
return;
}
+ if (request.resourceURL.pathname === '/hashtag') {
+ hashtagStream(request, connection, ev, user);
+ return;
+ }
+
if (user == null) {
connection.send('authentication-failed');
connection.close();