diff options
| -rw-r--r-- | cli/migration/8.0.0.js | 144 | ||||
| -rw-r--r-- | package.json | 2 | ||||
| -rw-r--r-- | src/models/stats.ts | 2 | ||||
| -rw-r--r-- | src/server/api/endpoints/admin/chart.ts | 2 | ||||
| -rw-r--r-- | src/services/update-chart.ts | 106 |
5 files changed, 212 insertions, 44 deletions
diff --git a/cli/migration/8.0.0.js b/cli/migration/8.0.0.js new file mode 100644 index 0000000000..fd6cb24525 --- /dev/null +++ b/cli/migration/8.0.0.js @@ -0,0 +1,144 @@ +const { default: Stats } = require('../../built/models/stats'); +const { default: User } = require('../../built/models/user'); +const { default: Note } = require('../../built/models/note'); +const { default: DriveFile } = require('../../built/models/drive-file'); + +const now = new Date(); +const y = now.getFullYear(); +const m = now.getMonth(); +const d = now.getDate(); +const h = now.getHours(); +const date = new Date(y, m, d, h); + +async function main() { + await Stats.update({}, { + $set: { + span: 'day' + } + }, { + multi: true + }); + + const localUsersCount = await User.count({ + host: null + }); + + const remoteUsersCount = await User.count({ + host: { $ne: null } + }); + + const localNotesCount = await Note.count({ + '_user.host': null + }); + + const remoteNotesCount = await Note.count({ + '_user.host': { $ne: null } + }); + + const localDriveFilesCount = await DriveFile.count({ + 'metadata._user.host': null + }); + + const remoteDriveFilesCount = await DriveFile.count({ + 'metadata._user.host': { $ne: null } + }); + + const localDriveFilesSize = await DriveFile + .aggregate([{ + $match: { + 'metadata._user.host': null, + 'metadata.deletedAt': { $exists: false } + } + }, { + $project: { + length: true + } + }, { + $group: { + _id: null, + usage: { $sum: '$length' } + } + }]) + .then(aggregates => { + if (aggregates.length > 0) { + return aggregates[0].usage; + } + return 0; + }); + + const remoteDriveFilesSize = await DriveFile + .aggregate([{ + $match: { + 'metadata._user.host': { $ne: null }, + 'metadata.deletedAt': { $exists: false } + } + }, { + $project: { + length: true + } + }, { + $group: { + _id: null, + usage: { $sum: '$length' } + } + }]) + .then(aggregates => { + if (aggregates.length > 0) { + return aggregates[0].usage; + } + return 0; + }); + + await Stats.insert({ + date: date, + span: 'hour', + users: { + local: { + total: localUsersCount, + diff: 0 + }, + remote: { + total: remoteUsersCount, + diff: 0 + } + }, + notes: { + local: { + total: localNotesCount, + diff: 0, + diffs: { + normal: 0, + reply: 0, + renote: 0 + } + }, + remote: { + total: remoteNotesCount, + diff: 0, + diffs: { + normal: 0, + reply: 0, + renote: 0 + } + } + }, + drive: { + local: { + totalCount: localDriveFilesCount, + totalSize: localDriveFilesSize, + diffCount: 0, + diffSize: 0 + }, + remote: { + totalCount: remoteDriveFilesCount, + totalSize: remoteDriveFilesSize, + diffCount: 0, + diffSize: 0 + } + } + }); + + console.log('done'); +} + +main(); diff --git a/package.json b/package.json index 03f63a029d..077d30b96a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo <i@syuilo.com>", - "version": "7.4.1", + "version": "8.0.0", "clientVersion": "1.0.8790", "codename": "nighthike", "main": "./built/index.js", diff --git a/src/models/stats.ts b/src/models/stats.ts index 7bff475c63..c481c3196e 100644 --- a/src/models/stats.ts +++ b/src/models/stats.ts @@ -10,6 +10,8 @@ export interface IStats { date: Date; + span: 'day' | 'hour'; + /** * ユーザーに関する統計 */ diff --git a/src/server/api/endpoints/admin/chart.ts b/src/server/api/endpoints/admin/chart.ts index a0566b11f5..c351c7167d 100644 --- a/src/server/api/endpoints/admin/chart.ts +++ b/src/server/api/endpoints/admin/chart.ts @@ -14,6 +14,7 @@ export default (params: any) => new Promise(async (res, rej) => { const d = now.getDate(); const stats = await Stats.find({ + span: 'day', date: { $gt: new Date(y - 1, m, d) } @@ -44,6 +45,7 @@ export default (params: any) => new Promise(async (res, rej) => { } else { chart.unshift({ date: day, + span: 'day', users: { local: { total: 0, diff --git a/src/services/update-chart.ts b/src/services/update-chart.ts index 6b69adbdc3..0a0f58bb92 100644 --- a/src/services/update-chart.ts +++ b/src/services/update-chart.ts @@ -5,49 +5,59 @@ import { IDriveFile } from '../models/drive-file'; type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; -async function getTodayStats(): Promise<IStats> { +async function getCurrentStats(span: 'day' | 'hour'): Promise<IStats> { const now = new Date(); const y = now.getFullYear(); const m = now.getMonth(); const d = now.getDate(); - const today = new Date(y, m, d); + const h = now.getHours(); - // 今日の統計 - const todayStats = await Stats.findOne({ - date: today + const current = + span == 'day' ? new Date(y, m, d) : + span == 'hour' ? new Date(y, m, d, h) : + null; + + // 現在(今日または今のHour)の統計 + const currentStats = await Stats.findOne({ + span: span, + date: current }); - // 日付が変わってから、初めてのチャート更新なら - if (todayStats == null) { + if (currentStats) { + return currentStats; + } else { + // 集計期間が変わってから、初めてのチャート更新なら // 最も最近の統計を持ってくる + // * 例えば集計期間が「日」である場合で考えると、 // * 昨日何もチャートを更新するような出来事がなかった場合は、 - // 統計がそもそも作られずドキュメントが存在しないということがあり得るため、 - // 「昨日の」と決め打ちせずに「もっとも最近の」とします - const mostRecentStats = await Stats.findOne({}, { + // * 統計がそもそも作られずドキュメントが存在しないということがあり得るため、 + // * 「昨日の」と決め打ちせずに「もっとも最近の」とします + const mostRecentStats = await Stats.findOne({ + span: span + }, { sort: { date: -1 } }); - // 統計が存在しなかったら - // * Misskeyインスタンスを建てて初めてのチャート更新時など - if (mostRecentStats == null) { - // 空の統計を作成 + if (mostRecentStats) { + // 現在の統計を初期挿入 const data: Omit<IStats, '_id'> = { - date: today, + span: span, + date: current, users: { local: { - total: 0, + total: mostRecentStats.users.local.total, diff: 0 }, remote: { - total: 0, + total: mostRecentStats.users.remote.total, diff: 0 } }, notes: { local: { - total: 0, + total: mostRecentStats.notes.local.total, diff: 0, diffs: { normal: 0, @@ -56,7 +66,7 @@ async function getTodayStats(): Promise<IStats> { } }, remote: { - total: 0, + total: mostRecentStats.notes.remote.total, diff: 0, diffs: { normal: 0, @@ -67,14 +77,14 @@ async function getTodayStats(): Promise<IStats> { }, drive: { local: { - totalCount: 0, - totalSize: 0, + totalCount: mostRecentStats.drive.local.totalCount, + totalSize: mostRecentStats.drive.local.totalSize, diffCount: 0, diffSize: 0 }, remote: { - totalCount: 0, - totalSize: 0, + totalCount: mostRecentStats.drive.remote.totalCount, + totalSize: mostRecentStats.drive.remote.totalSize, diffCount: 0, diffSize: 0 } @@ -85,22 +95,26 @@ async function getTodayStats(): Promise<IStats> { return stats; } else { - // 今日の統計を初期挿入 - const data: Omit<IStats, '_id'> = { - date: today, + // 統計が存在しなかったら + // * Misskeyインスタンスを建てて初めてのチャート更新時など + + // 空の統計を作成 + const emptyStat: Omit<IStats, '_id'> = { + span: span, + date: current, users: { local: { - total: mostRecentStats.users.local.total, + total: 0, diff: 0 }, remote: { - total: mostRecentStats.users.remote.total, + total: 0, diff: 0 } }, notes: { local: { - total: mostRecentStats.notes.local.total, + total: 0, diff: 0, diffs: { normal: 0, @@ -109,7 +123,7 @@ async function getTodayStats(): Promise<IStats> { } }, remote: { - total: mostRecentStats.notes.remote.total, + total: 0, diff: 0, diffs: { normal: 0, @@ -120,36 +134,42 @@ async function getTodayStats(): Promise<IStats> { }, drive: { local: { - totalCount: mostRecentStats.drive.local.totalCount, - totalSize: mostRecentStats.drive.local.totalSize, + totalCount: 0, + totalSize: 0, diffCount: 0, diffSize: 0 }, remote: { - totalCount: mostRecentStats.drive.remote.totalCount, - totalSize: mostRecentStats.drive.remote.totalSize, + totalCount: 0, + totalSize: 0, diffCount: 0, diffSize: 0 } } }; - const stats = await Stats.insert(data); + const stats = await Stats.insert(emptyStat); return stats; } - } else { - return todayStats; } } -async function update(inc: any) { - const stats = await getTodayStats(); +function update(inc: any) { + getCurrentStats('day').then(stats => { + Stats.findOneAndUpdate({ + _id: stats._id + }, { + $inc: inc + }); + }); - await Stats.findOneAndUpdate({ - _id: stats._id - }, { - $inc: inc + getCurrentStats('hour').then(stats => { + Stats.findOneAndUpdate({ + _id: stats._id + }, { + $inc: inc + }); }); } |