統計で無視するハッシュタグを設定できるように
This commit is contained in:
		
							parent
							
								
									106d4cc0d6
								
							
						
					
					
						commit
						7343e6e2e8
					
				
					 6 changed files with 74 additions and 6 deletions
				
			
		
							
								
								
									
										41
									
								
								src/client/app/desktop/views/pages/admin/admin.hashtags.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/client/app/desktop/views/pages/admin/admin.hashtags.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="jdnqwkzlnxcfftthoybjxrebyolvoucw mk-admin-card">
 | 
			
		||||
	<header>%i18n:@hided-tags%</header>
 | 
			
		||||
	<textarea v-model="hidedTags"></textarea>
 | 
			
		||||
	<button class="ui" @click="save">%i18n:@save%</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			hidedTags: '',
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.hidedTags = meta.hidedTags.join('\n');
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		save() {
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				hidedTags: this.hidedTags.split('\n')
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
@import '~const.styl'
 | 
			
		||||
 | 
			
		||||
.jdnqwkzlnxcfftthoybjxrebyolvoucw
 | 
			
		||||
	textarea
 | 
			
		||||
		width 100%
 | 
			
		||||
		min-height 300px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,8 @@
 | 
			
		|||
			<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }">%fa:chalkboard .fw%%i18n:@dashboard%</li>
 | 
			
		||||
			<li @click="nav('users')" :class="{ active: page == 'users' }">%fa:users .fw%%i18n:@users%</li>
 | 
			
		||||
			<li @click="nav('announcements')" :class="{ active: page == 'announcements' }">%fa:broadcast-tower .fw%%i18n:@announcements%</li>
 | 
			
		||||
			<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }">%fa:hashtag .fw%%i18n:@hashtags%</li>
 | 
			
		||||
 | 
			
		||||
			<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }">%fa:cloud .fw%%i18n:@drive%</li> -->
 | 
			
		||||
			<!-- <li @click="nav('update')" :class="{ active: page == 'update' }">%i18n:@update%</li> -->
 | 
			
		||||
		</ul>
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +19,9 @@
 | 
			
		|||
		<div v-show="page == 'announcements'">
 | 
			
		||||
			<x-announcements/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div v-show="page == 'hashtags'">
 | 
			
		||||
			<x-hashtags/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div v-if="page == 'users'">
 | 
			
		||||
			<x-suspend-user/>
 | 
			
		||||
			<x-unsuspend-user/>
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +38,7 @@
 | 
			
		|||
import Vue from "vue";
 | 
			
		||||
import XDashboard from "./admin.dashboard.vue";
 | 
			
		||||
import XAnnouncements from "./admin.announcements.vue";
 | 
			
		||||
import XHashtags from "./admin.hashtags.vue";
 | 
			
		||||
import XSuspendUser from "./admin.suspend-user.vue";
 | 
			
		||||
import XUnsuspendUser from "./admin.unsuspend-user.vue";
 | 
			
		||||
import XVerifyUser from "./admin.verify-user.vue";
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +49,7 @@ export default Vue.extend({
 | 
			
		|||
	components: {
 | 
			
		||||
		XDashboard,
 | 
			
		||||
		XAnnouncements,
 | 
			
		||||
		XHashtags,
 | 
			
		||||
		XSuspendUser,
 | 
			
		||||
		XUnsuspendUser,
 | 
			
		||||
		XVerifyUser,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,12 +4,13 @@ const Meta = db.get<IMeta>('meta');
 | 
			
		|||
export default Meta;
 | 
			
		||||
 | 
			
		||||
export type IMeta = {
 | 
			
		||||
	broadcasts: any[];
 | 
			
		||||
	stats: {
 | 
			
		||||
	broadcasts?: any[];
 | 
			
		||||
	stats?: {
 | 
			
		||||
		notesCount: number;
 | 
			
		||||
		originalNotesCount: number;
 | 
			
		||||
		usersCount: number;
 | 
			
		||||
		originalUsersCount: number;
 | 
			
		||||
	};
 | 
			
		||||
	disableRegistration: boolean;
 | 
			
		||||
	disableRegistration?: boolean;
 | 
			
		||||
	hidedTags?: string[];
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,13 @@ export const meta = {
 | 
			
		|||
			desc: {
 | 
			
		||||
				'ja-JP': '招待制か否か'
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
		}),
 | 
			
		||||
 | 
			
		||||
		hidedTags: $.arr($.str).optional.nullable.note({
 | 
			
		||||
			desc: {
 | 
			
		||||
				'ja-JP': '統計などで無視するハッシュタグ'
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +45,10 @@ export default (params: any) => new Promise(async (res, rej) => {
 | 
			
		|||
		set.disableRegistration = ps.disableRegistration;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Array.isArray(ps.hidedTags)) {
 | 
			
		||||
		set.hidedTags = ps.hidedTags;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	await Meta.update({}, {
 | 
			
		||||
		$set: set
 | 
			
		||||
	}, { upsert: true });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import Note from '../../../../models/note';
 | 
			
		||||
import { erase } from '../../../../prelude/array';
 | 
			
		||||
import Meta from '../../../../models/meta';
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
トレンドに載るためには「『直近a分間のユニーク投稿数が今からa分前~今からb分前の間のユニーク投稿数のn倍以上』のハッシュタグの上位5位以内に入る」ことが必要
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,9 @@ const max = 5;
 | 
			
		|||
 * Get trends of hashtags
 | 
			
		||||
 */
 | 
			
		||||
export default () => new Promise(async (res, rej) => {
 | 
			
		||||
	const meta = await Meta.findOne({});
 | 
			
		||||
	const hidedTags = (meta.hidedTags || []).map(t => t.toLowerCase());
 | 
			
		||||
 | 
			
		||||
	//#region 1. 直近Aの内に投稿されたハッシュタグ(とユーザーのペア)を集計
 | 
			
		||||
	const data = await Note.aggregate([{
 | 
			
		||||
		$match: {
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +57,9 @@ export default () => new Promise(async (res, rej) => {
 | 
			
		|||
 | 
			
		||||
	// カウント
 | 
			
		||||
	data.map(x => x._id).forEach(x => {
 | 
			
		||||
		// ブラックリストに登録されているタグなら弾く
 | 
			
		||||
		if (hidedTags.includes(x.tag)) return;
 | 
			
		||||
 | 
			
		||||
		const i = tags.findIndex(tag => tag.name == x.tag);
 | 
			
		||||
		if (i != -1) {
 | 
			
		||||
			tags[i].count++;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
import * as os from 'os';
 | 
			
		||||
import config from '../../../config';
 | 
			
		||||
import Meta from '../../../models/meta';
 | 
			
		||||
import { ILocalUser } from '../../../models/user';
 | 
			
		||||
 | 
			
		||||
const pkg = require('../../../../package.json');
 | 
			
		||||
const client = require('../../../../built/client/meta.json');
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +12,7 @@ const client = require('../../../../built/client/meta.json');
 | 
			
		|||
/**
 | 
			
		||||
 * Show core info
 | 
			
		||||
 */
 | 
			
		||||
export default () => new Promise(async (res, rej) => {
 | 
			
		||||
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
 | 
			
		||||
	const meta: any = (await Meta.findOne()) || {};
 | 
			
		||||
 | 
			
		||||
	res({
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +36,7 @@ export default () => new Promise(async (res, rej) => {
 | 
			
		|||
		disableRegistration: meta.disableRegistration,
 | 
			
		||||
		driveCapacityPerLocalUserMb: config.localDriveCapacityMb,
 | 
			
		||||
		recaptchaSitekey: config.recaptcha ? config.recaptcha.site_key : null,
 | 
			
		||||
		swPublickey: config.sw ? config.sw.public_key : null
 | 
			
		||||
		swPublickey: config.sw ? config.sw.public_key : null,
 | 
			
		||||
		hidedTags: (me && me.isAdmin) ? meta.hidedTags : undefined
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue