diff --git a/.config/example.yml b/.config/example.yml
index 0f416ab96f..3eb5bf0b11 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 5ff234ef12..8a27a1ad3b 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 4c234ec260..7252a4c7ea 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') }}
+
@@ -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 e855097c42..509d02ef43 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 34117afd25..c91e66ce2d 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 bbae212bd7..edbb51e3dc 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 9846e95959..faee9423d8 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 127029f83c..52e075006f 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)