From 82ab386b83a054d32597edaa89743639a50205a3 Mon Sep 17 00:00:00 2001 From: Hakaba Hitoyo Date: Wed, 21 Nov 2018 23:44:59 +0900 Subject: [PATCH] Feature / user recommendation config in admin ui (#3357) * add config for external user recommendation into admin ui * debug * correct admin ui * switch external user recommendation to admin ui config * debug * debug * debug * Revert "debug" This reverts commit f4a0460e5bde21cd1f39a735f496a2d74233ef3f. * explicit parseInt radix * add Japanese message * change default engine to https * remove unused settings * debug * nullable externalUserRecommendationTimeout --- .config/example.yml | 6 ---- locales/ja-JP.yml | 6 ++++ src/client/app/admin/views/instance.vue | 21 ++++++++++-- src/misc/fetch-meta.ts | 5 ++- src/models/meta.ts | 17 ++++++++++ src/server/api/endpoints/admin/update-meta.ts | 33 +++++++++++++++++++ src/server/api/endpoints/meta.ts | 10 +++++- .../api/endpoints/users/recommendation.ts | 10 ++++-- 8 files changed, 94 insertions(+), 14 deletions(-) diff --git a/.config/example.yml b/.config/example.yml index 0f416ab96..3eb5bf0b1 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -121,9 +121,3 @@ autoAdmin: true # Summaly proxy #summalyProxy: "http://example.com" - -# User recommendation -#user_recommendation: -# external: true -# engine: http://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}} -# timeout: 300000 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 5ff234ef1..8a27a1ad3 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1117,6 +1117,12 @@ admin/views/instance.vue: invite: "招待" save: "保存" saved: "保存しました" + user-recommendation-config: "おすすめユーザー" + enable-external-user-recommendation: "外部ユーザーレコメンデーションを有効にする" + external-user-recommendation-engine: "エンジン" + external-user-recommendation-engine-desc: "例: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}" + external-user-recommendation-timeout: "タイムアウト" + external-user-recommendation-timeout-desc: "ミリ秒単位 (例: 300000)" admin/views/charts.vue: title: "チャート" diff --git a/src/client/app/admin/views/instance.vue b/src/client/app/admin/views/instance.vue index 4c234ec26..7252a4c7e 100644 --- a/src/client/app/admin/views/instance.vue +++ b/src/client/app/admin/views/instance.vue @@ -42,6 +42,12 @@
{{ $t('disable-local-timeline') }}
+
+
{{ $t('user-recommendation-config') }}
+ {{ $t('enable-external-user-recommendation') }} + {{ $t('external-user-recommendation-engine') }}{{ $t('external-user-recommendation-engine-desc') }} + {{ $t('external-user-recommendation-timeout') }}ms{{ $t('external-user-recommendation-timeout-desc') }} +
{{ $t('save') }}
@@ -95,7 +101,7 @@ import Vue from 'vue'; import i18n from '../../i18n'; import { host } from '../../config'; import { toUnicode } from 'punycode'; -import { faHeadset, faShieldAlt, faGhost } from '@fortawesome/free-solid-svg-icons'; +import { faHeadset, faShieldAlt, faGhost, faUserPlus } from '@fortawesome/free-solid-svg-icons'; export default Vue.extend({ i18n: i18n('admin/views/instance.vue'), @@ -129,7 +135,10 @@ export default Vue.extend({ discordClientSecret: null, proxyAccount: null, inviteCode: null, - faHeadset, faShieldAlt, faGhost + enableExternalUserRecommendation: false, + externalUserRecommendationEngine: null, + externalUserRecommendationTimeout: null, + faHeadset, faShieldAlt, faGhost, faUserPlus }; }, @@ -158,6 +167,9 @@ export default Vue.extend({ this.enableDiscordIntegration = meta.enableDiscordIntegration; this.discordClientId = meta.discordClientId; this.discordClientSecret = meta.discordClientSecret; + this.enableExternalUserRecommendation = meta.enableExternalUserRecommendation; + this.externalUserRecommendationEngine = meta.externalUserRecommendationEngine; + this.externalUserRecommendationTimeout = meta.externalUserRecommendationTimeout; }); }, @@ -199,7 +211,10 @@ export default Vue.extend({ githubClientSecret: this.githubClientSecret, enableDiscordIntegration: this.enableDiscordIntegration, discordClientId: this.discordClientId, - discordClientSecret: this.discordClientSecret + discordClientSecret: this.discordClientSecret, + enableExternalUserRecommendation: this.enableExternalUserRecommendation, + externalUserRecommendationEngine: this.externalUserRecommendationEngine, + externalUserRecommendationTimeout: parseInt(this.externalUserRecommendationTimeout, 10) }).then(() => { this.$root.alert({ type: 'success', diff --git a/src/misc/fetch-meta.ts b/src/misc/fetch-meta.ts index e855097c4..509d02ef4 100644 --- a/src/misc/fetch-meta.ts +++ b/src/misc/fetch-meta.ts @@ -15,7 +15,10 @@ const defaultMeta: any = { maxNoteTextLength: 1000, enableTwitterIntegration: false, enableGithubIntegration: false, - enableDiscordIntegration: false + enableDiscordIntegration: false, + enableExternalUserRecommendation: false, + externalUserRecommendationEngine: "https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}", + externalUserRecommendationTimeout: 300000 }; export default async function(): Promise { diff --git a/src/models/meta.ts b/src/models/meta.ts index 34117afd2..c91e66ce2 100644 --- a/src/models/meta.ts +++ b/src/models/meta.ts @@ -125,6 +125,19 @@ if ((config as any).github) { } }); } +if ((config as any).user_recommendation) { + Meta.findOne({}).then(m => { + if (m != null && m.enableExternalUserRecommendation == null) { + Meta.update({}, { + $set: { + enableExternalUserRecommendation: true, + externalUserRecommendationEngine: (config as any).user_recommendation.engine, + externalUserRecommendationTimeout: (config as any).user_recommendation.timeout + } + }); + } + }); +} export type IMeta = { name?: string; @@ -195,4 +208,8 @@ export type IMeta = { enableDiscordIntegration?: boolean; discordClientId?: string; discordClientSecret?: string; + + enableExternalUserRecommendation?: boolean; + externalUserRecommendationEngine?: string; + externalUserRecommendationTimeout?: number; }; diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index bbae212bd..edbb51e3d 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -200,6 +200,27 @@ export const meta = { desc: { 'ja-JP': 'DiscordアプリのClient Secret' } + }, + + enableExternalUserRecommendation: { + validator: $.bool.optional, + desc: { + 'ja-JP': '外部ユーザーレコメンデーションを有効にする' + } + }, + + externalUserRecommendationEngine: { + validator: $.str.optional.nullable, + desc: { + 'ja-JP': '外部ユーザーレコメンデーションのサードパーティエンジン' + } + }, + + externalUserRecommendationTimeout: { + validator: $.num.optional.nullable.min(0), + desc: { + 'ja-JP': '外部ユーザーレコメンデーションのタイムアウト (ミリ秒)' + } } } }; @@ -315,6 +336,18 @@ export default define(meta, (ps) => new Promise(async (res, rej) => { set.discordClientSecret = ps.discordClientSecret; } + if (ps.enableExternalUserRecommendation !== undefined) { + set.enableExternalUserRecommendation = ps.enableExternalUserRecommendation; + } + + if (ps.externalUserRecommendationEngine !== undefined) { + set.externalUserRecommendationEngine = ps.externalUserRecommendationEngine; + } + + if (ps.externalUserRecommendationTimeout !== undefined) { + set.externalUserRecommendationTimeout = ps.externalUserRecommendationTimeout; + } + await Meta.update({}, { $set: set }, { upsert: true }); diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 9846e9595..faee9423d 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -72,6 +72,10 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { enableTwitterIntegration: instance.enableTwitterIntegration, enableGithubIntegration: instance.enableGithubIntegration, enableDiscordIntegration: instance.enableDiscordIntegration, + + enableExternalUserRecommendation: instance.enableExternalUserRecommendation, + externalUserRecommendationEngine: instance.externalUserRecommendationEngine, + externalUserRecommendationTimeout: instance.externalUserRecommendationTimeout }; if (ps.detail) { @@ -85,7 +89,11 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { github: instance.enableGithubIntegration, discord: instance.enableDiscordIntegration, serviceWorker: config.sw ? true : false, - userRecommendation: config.user_recommendation ? config.user_recommendation : {} + userRecommendation: { + external: instance.enableExternalUserRecommendation, + engine: instance.externalUserRecommendationEngine, + timeout: instance.externalUserRecommendationTimeout + } }; } diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts index 127029f83..52e075006 100644 --- a/src/server/api/endpoints/users/recommendation.ts +++ b/src/server/api/endpoints/users/recommendation.ts @@ -6,6 +6,8 @@ import Mute from '../../../../models/mute'; import * as request from 'request'; import config from '../../../../config'; import define from '../../define'; +import fetchMeta from '../../../../misc/fetch-meta'; + export const meta = { desc: { @@ -30,13 +32,15 @@ export const meta = { }; export default define(meta, (ps, me) => new Promise(async (res, rej) => { - if (config.user_recommendation && config.user_recommendation.external) { + const instance = await fetchMeta(); + + if (instance.enableExternalUserRecommendation) { const userName = me.username; const hostName = config.hostname; const limit = ps.limit; const offset = ps.offset; - const timeout = config.user_recommendation.timeout; - const engine = config.user_recommendation.engine; + const timeout = instance.externalUserRecommendationTimeout; + const engine = instance.externalUserRecommendationEngine; const url = engine .replace('{{host}}', hostName) .replace('{{user}}', userName)