From c7c08b7511f8ee86ed3d35918356d54e3ad5e8f9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 21 Feb 2020 00:28:45 +0900 Subject: [PATCH] Resolve #6043 --- CHANGELOG.md | 3 +++ locales/ja-JP.yml | 1 + migration/1582210532752-antenna-exclude.ts | 14 ++++++++++++++ src/client/pages/my-antennas/index.antenna.vue | 12 ++++++++++-- src/client/pages/my-antennas/index.vue | 1 + src/misc/check-hit-antenna.ts | 13 +++++++++++++ src/models/entities/antenna.ts | 5 +++++ src/models/repositories/antenna.ts | 1 + src/server/api/endpoints/antennas/create.ts | 5 +++++ src/server/api/endpoints/antennas/update.ts | 5 +++++ 10 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 migration/1582210532752-antenna-exclude.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index cde4ad96a..460e75b22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ChangeLog ========= ------------------- +### ✨Improvements +* アンテナで除外キーワードを設定できるように + ### 🐛Fixes * ハッシュタグをもっと見るできないのを修正 * 無効になっているタイムラインでも使用できるかのように表示される問題を修正 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index da255351e..e65deb61c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -286,6 +286,7 @@ manageAntennas: "アンテナの管理" name: "名前" antennaSource: "受信ソース" antennaKeywords: "受信キーワード" +antennaExcludeKeywords: "除外キーワード" antennaKeywordsDescription: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります" notifyAntenna: "新しいノートを通知する" withFileAntenna: "ファイルが添付されたノートのみ" diff --git a/migration/1582210532752-antenna-exclude.ts b/migration/1582210532752-antenna-exclude.ts new file mode 100644 index 000000000..bff47a3ec --- /dev/null +++ b/migration/1582210532752-antenna-exclude.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class antennaExclude1582210532752 implements MigrationInterface { + name = 'antennaExclude1582210532752' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "antenna" ADD "excludeKeywords" jsonb NOT NULL DEFAULT '[]'`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "excludeKeywords"`, undefined); + } + +} diff --git a/src/client/pages/my-antennas/index.antenna.vue b/src/client/pages/my-antennas/index.antenna.vue index d0259a55c..2a9aebbcb 100644 --- a/src/client/pages/my-antennas/index.antenna.vue +++ b/src/client/pages/my-antennas/index.antenna.vue @@ -30,6 +30,10 @@ {{ $t('antennaKeywords') }} + + {{ $t('antennaExcludeKeywords') }} + + {{ $t('caseSensitive') }} {{ $t('withFileAntenna') }} {{ $t('notifyAntenna') }} @@ -75,6 +79,7 @@ export default Vue.extend({ userGroupId: null, users: '', keywords: '', + excludeKeywords: '', caseSensitive: false, withReplies: false, withFile: false, @@ -107,6 +112,7 @@ export default Vue.extend({ this.userGroupId = this.antenna.userGroupId; this.users = this.antenna.users.join('\n'); this.keywords = this.antenna.keywords.map(x => x.join(' ')).join('\n'); + this.excludeKeywords = this.antenna.excludeKeywords.map(x => x.join(' ')).join('\n'); this.caseSensitive = this.antenna.caseSensitive; this.withReplies = this.antenna.withReplies; this.withFile = this.antenna.withFile; @@ -126,7 +132,8 @@ export default Vue.extend({ notify: this.notify, caseSensitive: this.caseSensitive, users: this.users.trim().split('\n').map(x => x.trim()), - keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')) + keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')), + excludeKeywords: this.excludeKeywords.trim().split('\n').map(x => x.trim().split(' ')), }); this.$emit('created'); } else { @@ -141,7 +148,8 @@ export default Vue.extend({ notify: this.notify, caseSensitive: this.caseSensitive, users: this.users.trim().split('\n').map(x => x.trim()), - keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')) + keywords: this.keywords.trim().split('\n').map(x => x.trim().split(' ')), + excludeKeywords: this.excludeKeywords.trim().split('\n').map(x => x.trim().split(' ')), }); } diff --git a/src/client/pages/my-antennas/index.vue b/src/client/pages/my-antennas/index.vue index 8ac70ac37..a5f6076eb 100644 --- a/src/client/pages/my-antennas/index.vue +++ b/src/client/pages/my-antennas/index.vue @@ -53,6 +53,7 @@ export default Vue.extend({ userGroupId: null, users: [], keywords: [], + excludeKeywords: [], withReplies: false, caseSensitive: false, withFile: false, diff --git a/src/misc/check-hit-antenna.ts b/src/misc/check-hit-antenna.ts index c229a07eb..0d72c3f34 100644 --- a/src/misc/check-hit-antenna.ts +++ b/src/misc/check-hit-antenna.ts @@ -52,6 +52,19 @@ export async function checkHitAntenna(antenna: Antenna, note: Note, noteUser: Us if (!matched) return false; } + if (antenna.excludeKeywords.length > 0) { + if (note.text == null) return false; + + const matched = antenna.excludeKeywords.some(keywords => + keywords.every(keyword => + antenna.caseSensitive + ? note.text!.includes(keyword) + : note.text!.toLowerCase().includes(keyword.toLowerCase()) + )); + + if (matched) return false; + } + if (antenna.withFile) { if (note.fileIds.length === 0) return false; } diff --git a/src/models/entities/antenna.ts b/src/models/entities/antenna.ts index 7c2027b6e..bcfe09a82 100644 --- a/src/models/entities/antenna.ts +++ b/src/models/entities/antenna.ts @@ -71,6 +71,11 @@ export class Antenna { }) public keywords: string[][]; + @Column('jsonb', { + default: [] + }) + public excludeKeywords: string[][]; + @Column('boolean', { default: false }) diff --git a/src/models/repositories/antenna.ts b/src/models/repositories/antenna.ts index 9f8aa1134..16ef2e5a3 100644 --- a/src/models/repositories/antenna.ts +++ b/src/models/repositories/antenna.ts @@ -21,6 +21,7 @@ export class AntennaRepository extends Repository { createdAt: antenna.createdAt.toISOString(), name: antenna.name, keywords: antenna.keywords, + excludeKeywords: antenna.excludeKeywords, src: antenna.src, userListId: antenna.userListId, userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null, diff --git a/src/server/api/endpoints/antennas/create.ts b/src/server/api/endpoints/antennas/create.ts index 658b8221f..f11b198f8 100644 --- a/src/server/api/endpoints/antennas/create.ts +++ b/src/server/api/endpoints/antennas/create.ts @@ -33,6 +33,10 @@ export const meta = { validator: $.arr($.arr($.str)) }, + excludeKeywords: { + validator: $.arr($.arr($.str)) + }, + users: { validator: $.arr($.str) }, @@ -102,6 +106,7 @@ export default define(meta, async (ps, user) => { userListId: userList ? userList.id : null, userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null, keywords: ps.keywords, + excludeKeywords: ps.excludeKeywords, users: ps.users, caseSensitive: ps.caseSensitive, withReplies: ps.withReplies, diff --git a/src/server/api/endpoints/antennas/update.ts b/src/server/api/endpoints/antennas/update.ts index 520e17c4a..ab4ce5793 100644 --- a/src/server/api/endpoints/antennas/update.ts +++ b/src/server/api/endpoints/antennas/update.ts @@ -36,6 +36,10 @@ export const meta = { validator: $.arr($.arr($.str)) }, + excludeKeywords: { + validator: $.arr($.arr($.str)) + }, + users: { validator: $.arr($.str) }, @@ -118,6 +122,7 @@ export default define(meta, async (ps, user) => { userListId: userList ? userList.id : null, userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null, keywords: ps.keywords, + excludeKeywords: ps.excludeKeywords, users: ps.users, caseSensitive: ps.caseSensitive, withReplies: ps.withReplies,