From 4fb7ee760aacdd2d52e8c43b3156fc0ef6deb11e Mon Sep 17 00:00:00 2001 From: rinsuki <428rinsuki+git@gmail.com> Date: Thu, 23 Aug 2018 11:58:44 +0900 Subject: [PATCH 1/3] =?UTF-8?q?https://misskey.xyz/notes/5b7e20bd248403003?= =?UTF-8?q?019b860=20=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/remote/resolve-user.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote/resolve-user.ts b/src/remote/resolve-user.ts index 1e8fc5d75..e199b6f14 100644 --- a/src/remote/resolve-user.ts +++ b/src/remote/resolve-user.ts @@ -15,7 +15,7 @@ export default async (username: string, _host: string, option?: any): Promise Date: Thu, 23 Aug 2018 14:56:39 +0900 Subject: [PATCH 2/3] Fix bug: Check following request existance --- src/server/api/endpoints/following/requests/cancel.ts | 6 +++++- src/services/following/requests/cancel.ts | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/server/api/endpoints/following/requests/cancel.ts b/src/server/api/endpoints/following/requests/cancel.ts index 9bfc40ce6..c46b948d2 100644 --- a/src/server/api/endpoints/following/requests/cancel.ts +++ b/src/server/api/endpoints/following/requests/cancel.ts @@ -27,7 +27,11 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) = return rej('followee not found'); } - await cancelFollowRequest(followee, user); + try { + await cancelFollowRequest(followee, user); + } catch (e) { + return rej(e); + } // Send response res(await pack(followee._id, user)); diff --git a/src/services/following/requests/cancel.ts b/src/services/following/requests/cancel.ts index b0b574da5..26e4544d5 100644 --- a/src/services/following/requests/cancel.ts +++ b/src/services/following/requests/cancel.ts @@ -12,6 +12,15 @@ export default async function(followee: IUser, follower: IUser) { deliver(follower as ILocalUser, content, followee.inbox); } + const request = await FollowRequest.findOne({ + followeeId: followee._id, + followerId: follower._id + }); + + if (request == null) { + throw 'request not found'; + } + await FollowRequest.remove({ followeeId: followee._id, followerId: follower._id From 8fc1e07136d5ee203cbd1a1bc2ec00dfeb0e8cf0 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 23 Aug 2018 15:40:24 +0900 Subject: [PATCH 3/3] =?UTF-8?q?1=E6=99=82=E9=96=93=E5=8D=98=E4=BD=8D?= =?UTF-8?q?=E3=81=A7=E3=81=AE=E9=9B=86=E8=A8=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cli/migration/8.0.0.js | 144 ++++++++++++++++++++ package.json | 2 +- src/models/stats.ts | 2 + src/server/api/endpoints/admin/chart.ts | 2 + src/services/update-chart.ts | 172 +++++++++++++----------- 5 files changed, 245 insertions(+), 77 deletions(-) create mode 100644 cli/migration/8.0.0.js diff --git a/cli/migration/8.0.0.js b/cli/migration/8.0.0.js new file mode 100644 index 000000000..fd6cb2452 --- /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 03f63a029..077d30b96 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo ", - "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 7bff475c6..c481c3196 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 a0566b11f..c351c7167 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 6b69adbdc..0a0f58bb9 100644 --- a/src/services/update-chart.ts +++ b/src/services/update-chart.ts @@ -5,89 +5,46 @@ import { IDriveFile } from '../models/drive-file'; type Omit = Pick>; -async function getTodayStats(): Promise { +async function getCurrentStats(span: 'day' | 'hour'): Promise { 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 = { - date: today, - users: { - local: { - total: 0, - diff: 0 - }, - remote: { - total: 0, - diff: 0 - } - }, - notes: { - local: { - total: 0, - diff: 0, - diffs: { - normal: 0, - reply: 0, - renote: 0 - } - }, - remote: { - total: 0, - diff: 0, - diffs: { - normal: 0, - reply: 0, - renote: 0 - } - } - }, - drive: { - local: { - totalCount: 0, - totalSize: 0, - diffCount: 0, - diffSize: 0 - }, - remote: { - totalCount: 0, - totalSize: 0, - diffCount: 0, - diffSize: 0 - } - } - }; - - const stats = await Stats.insert(data); - - return stats; - } else { - // 今日の統計を初期挿入 - const data: Omit = { - date: today, + span: span, + date: current, users: { local: { total: mostRecentStats.users.local.total, @@ -136,20 +93,83 @@ async function getTodayStats(): Promise { const stats = await Stats.insert(data); + return stats; + } else { + // 統計が存在しなかったら + // * Misskeyインスタンスを建てて初めてのチャート更新時など + + // 空の統計を作成 + const emptyStat: Omit = { + span: span, + date: current, + users: { + local: { + total: 0, + diff: 0 + }, + remote: { + total: 0, + diff: 0 + } + }, + notes: { + local: { + total: 0, + diff: 0, + diffs: { + normal: 0, + reply: 0, + renote: 0 + } + }, + remote: { + total: 0, + diff: 0, + diffs: { + normal: 0, + reply: 0, + renote: 0 + } + } + }, + drive: { + local: { + totalCount: 0, + totalSize: 0, + diffCount: 0, + diffSize: 0 + }, + remote: { + totalCount: 0, + totalSize: 0, + diffCount: 0, + diffSize: 0 + } + } + }; + + 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 + }); }); }