From 8ba178f795c771fd84739f4ff5ce65f135ca69ca Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 23 Aug 2018 03:19:57 +0900 Subject: コントロールパネルから招待制のオンオフを切り替えられるように MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/api/endpoints/admin/update-meta.ts | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/server/api/endpoints/admin/update-meta.ts (limited to 'src/server/api/endpoints') diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts new file mode 100644 index 0000000000..bfcab9d6a6 --- /dev/null +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -0,0 +1,37 @@ +import $ from 'cafy'; +import Meta from '../../../../models/meta'; +import getParams from '../../get-params'; + +export const meta = { + desc: { + ja: 'インスタンスの設定を更新します。' + }, + + requireCredential: true, + requireAdmin: true, + + params: { + disableRegistration: $.bool.optional.nullable.note({ + desc: { + ja: '招待制か否か' + } + }), + } +}; + +export default (params: any) => new Promise(async (res, rej) => { + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); + + const set = {} as any; + + if (ps.disableRegistration === true || ps.disableRegistration === false) { + set.disableRegistration = ps.disableRegistration; + } + + await Meta.update({}, { + $set: set + }, { upsert: true }); + + res(); +}); -- cgit v1.2.3-freya From e31a2f7e55bb96d661945d0475cc5cc678c0eb18 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 23 Aug 2018 14:56:39 +0900 Subject: 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(-) (limited to 'src/server/api/endpoints') diff --git a/src/server/api/endpoints/following/requests/cancel.ts b/src/server/api/endpoints/following/requests/cancel.ts index 9bfc40ce65..c46b948d29 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 b0b574da58..26e4544d5c 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 -- cgit v1.2.3-freya From 8fc1e07136d5ee203cbd1a1bc2ec00dfeb0e8cf0 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 23 Aug 2018 15:40:24 +0900 Subject: 1時間単位での集計を追加 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 | 106 +++++++++++++---------- 5 files changed, 212 insertions(+), 44 deletions(-) create mode 100644 cli/migration/8.0.0.js (limited to 'src/server/api/endpoints') 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 ", - "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 = 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, + 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 { } }, remote: { - total: 0, + total: mostRecentStats.notes.remote.total, diff: 0, diffs: { normal: 0, @@ -67,14 +77,14 @@ async function getTodayStats(): Promise { }, 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 { return stats; } else { - // 今日の統計を初期挿入 - const data: Omit = { - date: today, + // 統計が存在しなかったら + // * Misskeyインスタンスを建てて初めてのチャート更新時など + + // 空の統計を作成 + const emptyStat: Omit = { + 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 { } }, remote: { - total: mostRecentStats.notes.remote.total, + total: 0, diff: 0, diffs: { normal: 0, @@ -120,36 +134,42 @@ async function getTodayStats(): Promise { }, 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 + }); }); } -- cgit v1.2.3-freya From 71a5662195b4b6a8d4d2c2fc357752b9da350b6f Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 23 Aug 2018 16:36:23 +0900 Subject: 一時間ごとのグラフも見れるように MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/pages/admin/admin.drive-chart.chart.vue | 57 +++++-- .../views/pages/admin/admin.notes-chart.chart.vue | 101 +++++++----- .../views/pages/admin/admin.users-chart.chart.vue | 57 +++++-- src/server/api/endpoints/admin/chart.ts | 182 ++++++++++++--------- 4 files changed, 250 insertions(+), 147 deletions(-) (limited to 'src/server/api/endpoints') diff --git a/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue b/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue index 3c537d8d6d..97f05571c3 100644 --- a/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue +++ b/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue @@ -1,11 +1,14 @@ + + diff --git a/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue b/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue deleted file mode 100644 index 97f05571c3..0000000000 --- a/src/client/app/desktop/views/pages/admin/admin.drive-chart.chart.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/src/client/app/desktop/views/pages/admin/admin.drive-chart.vue b/src/client/app/desktop/views/pages/admin/admin.drive-chart.vue deleted file mode 100644 index 4f94fd2372..0000000000 --- a/src/client/app/desktop/views/pages/admin/admin.drive-chart.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - diff --git a/src/client/app/desktop/views/pages/admin/admin.notes-chart.chart.vue b/src/client/app/desktop/views/pages/admin/admin.notes-chart.chart.vue deleted file mode 100644 index fabb3f1bd1..0000000000 --- a/src/client/app/desktop/views/pages/admin/admin.notes-chart.chart.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - - - diff --git a/src/client/app/desktop/views/pages/admin/admin.notes-chart.vue b/src/client/app/desktop/views/pages/admin/admin.notes-chart.vue deleted file mode 100644 index e4d396d9c6..0000000000 --- a/src/client/app/desktop/views/pages/admin/admin.notes-chart.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - diff --git a/src/client/app/desktop/views/pages/admin/admin.users-chart.chart.vue b/src/client/app/desktop/views/pages/admin/admin.users-chart.chart.vue deleted file mode 100644 index 45ecc13929..0000000000 --- a/src/client/app/desktop/views/pages/admin/admin.users-chart.chart.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/src/client/app/desktop/views/pages/admin/admin.users-chart.vue b/src/client/app/desktop/views/pages/admin/admin.users-chart.vue deleted file mode 100644 index e620012702..0000000000 --- a/src/client/app/desktop/views/pages/admin/admin.users-chart.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - - - diff --git a/src/client/app/desktop/views/pages/admin/admin.vue b/src/client/app/desktop/views/pages/admin/admin.vue index cbb1890cc3..066c1a4f4f 100644 --- a/src/client/app/desktop/views/pages/admin/admin.vue +++ b/src/client/app/desktop/views/pages/admin/admin.vue @@ -11,9 +11,7 @@
- - - +
@@ -34,9 +32,7 @@ import XSuspendUser from "./admin.suspend-user.vue"; import XUnsuspendUser from "./admin.unsuspend-user.vue"; import XVerifyUser from "./admin.verify-user.vue"; import XUnverifyUser from "./admin.unverify-user.vue"; -import XUsersChart from "./admin.users-chart.vue"; -import XNotesChart from "./admin.notes-chart.vue"; -import XDriveChart from "./admin.drive-chart.vue"; +import XChart from "./admin.chart.vue"; export default Vue.extend({ components: { @@ -45,9 +41,7 @@ export default Vue.extend({ XUnsuspendUser, XVerifyUser, XUnverifyUser, - XUsersChart, - XNotesChart, - XDriveChart + XChart }, data() { return { diff --git a/src/server/api/endpoints/admin/chart.ts b/src/server/api/endpoints/admin/chart.ts index 1897879d65..1b88af00bd 100644 --- a/src/server/api/endpoints/admin/chart.ts +++ b/src/server/api/endpoints/admin/chart.ts @@ -8,7 +8,7 @@ export const meta = { }; export default (params: any) => new Promise(async (res, rej) => { - const daysRange = 365; + const daysRange = 90; const hoursRange = 24; const now = new Date(); @@ -123,7 +123,6 @@ export default (params: any) => new Promise(async (res, rej) => { } chart.forEach(x => { - delete x.date; delete (x as any).span; }); -- cgit v1.2.3-freya From b21287262e85e3e09e19217ba4168b83e4fdf4a7 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 24 Aug 2018 07:23:04 +0900 Subject: チャート取得APIを誰でも利用できるようにするなど MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/desktop/views/pages/admin/admin.chart.vue | 11 +- src/client/app/desktop/views/pages/admin/admin.vue | 7 +- src/server/api/endpoints/admin/chart.ts | 136 --------------------- src/server/api/endpoints/chart.ts | 134 ++++++++++++++++++++ 4 files changed, 141 insertions(+), 147 deletions(-) delete mode 100644 src/server/api/endpoints/admin/chart.ts create mode 100644 src/server/api/endpoints/chart.ts (limited to 'src/server/api/endpoints') diff --git a/src/client/app/desktop/views/pages/admin/admin.chart.vue b/src/client/app/desktop/views/pages/admin/admin.chart.vue index f40f89b2e0..b02f6c31b7 100644 --- a/src/client/app/desktop/views/pages/admin/admin.chart.vue +++ b/src/client/app/desktop/views/pages/admin/admin.chart.vue @@ -44,13 +44,9 @@ export default Vue.extend({ components: { XChart }, - props: { - chart: { - required: true - } - }, data() { return { + chart: null, chartType: 'local-notes', span: 'hour' }; @@ -85,6 +81,11 @@ export default Vue.extend({ ); } }, + created() { + (this as any).api('chart').then(chart => { + this.chart = chart; + }); + }, methods: { notesChart(local: boolean): any { const data = this.stats.slice().reverse().map(x => ({ diff --git a/src/client/app/desktop/views/pages/admin/admin.vue b/src/client/app/desktop/views/pages/admin/admin.vue index 066c1a4f4f..0bb5ed0a0f 100644 --- a/src/client/app/desktop/views/pages/admin/admin.vue +++ b/src/client/app/desktop/views/pages/admin/admin.vue @@ -11,7 +11,7 @@
- +
@@ -49,11 +49,6 @@ export default Vue.extend({ chart: null }; }, - created() { - (this as any).api('admin/chart').then(chart => { - this.chart = chart; - }); - }, methods: { nav(page: string) { this.page = page; diff --git a/src/server/api/endpoints/admin/chart.ts b/src/server/api/endpoints/admin/chart.ts deleted file mode 100644 index 1b88af00bd..0000000000 --- a/src/server/api/endpoints/admin/chart.ts +++ /dev/null @@ -1,136 +0,0 @@ -import Stats, { IStats } from '../../../../models/stats'; - -type Omit = Pick>; - -export const meta = { - requireCredential: true, - requireAdmin: true -}; - -export default (params: any) => new Promise(async (res, rej) => { - const daysRange = 90; - const hoursRange = 24; - - const now = new Date(); - const y = now.getFullYear(); - const m = now.getMonth(); - const d = now.getDate(); - const h = now.getHours(); - - const [statsPerDay, statsPerHour] = await Promise.all([ - Stats.find({ - span: 'day', - date: { - $gt: new Date(y, m, d - daysRange) - } - }, { - sort: { - date: -1 - }, - fields: { - _id: 0 - } - }), - Stats.find({ - span: 'hour', - date: { - $gt: new Date(y, m, d, h - hoursRange) - } - }, { - sort: { - date: -1 - }, - fields: { - _id: 0 - } - }), - ]); - - const format = (src: IStats[], span: 'day' | 'hour') => { - const chart: Array, 'span'>> = []; - - const range = - span == 'day' ? daysRange : - span == 'hour' ? hoursRange : - null; - - for (let i = (range - 1); i >= 0; i--) { - const current = - span == 'day' ? new Date(y, m, d - i) : - span == 'hour' ? new Date(y, m, d, h - i) : - null; - - const stat = src.find(s => s.date.getTime() == current.getTime()); - - if (stat) { - chart.unshift(stat); - } else { // 隙間埋め - const mostRecent = src.find(s => s.date.getTime() < current.getTime()); - if (mostRecent) { - chart.unshift(Object.assign({}, mostRecent, { - date: current - })); - } else { - chart.unshift({ - 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 - } - } - }); - } - } - } - - chart.forEach(x => { - delete (x as any).span; - }); - - return chart; - }; - - res({ - perDay: format(statsPerDay, 'day'), - perHour: format(statsPerHour, 'hour') - }); -}); diff --git a/src/server/api/endpoints/chart.ts b/src/server/api/endpoints/chart.ts new file mode 100644 index 0000000000..a58f0b163e --- /dev/null +++ b/src/server/api/endpoints/chart.ts @@ -0,0 +1,134 @@ +import Stats, { IStats } from '../../../models/stats'; + +type Omit = Pick>; + +export const meta = { +}; + +export default (params: any) => new Promise(async (res, rej) => { + const daysRange = 90; + const hoursRange = 24; + + const now = new Date(); + const y = now.getFullYear(); + const m = now.getMonth(); + const d = now.getDate(); + const h = now.getHours(); + + const [statsPerDay, statsPerHour] = await Promise.all([ + Stats.find({ + span: 'day', + date: { + $gt: new Date(y, m, d - daysRange) + } + }, { + sort: { + date: -1 + }, + fields: { + _id: 0 + } + }), + Stats.find({ + span: 'hour', + date: { + $gt: new Date(y, m, d, h - hoursRange) + } + }, { + sort: { + date: -1 + }, + fields: { + _id: 0 + } + }), + ]); + + const format = (src: IStats[], span: 'day' | 'hour') => { + const chart: Array, 'span'>> = []; + + const range = + span == 'day' ? daysRange : + span == 'hour' ? hoursRange : + null; + + for (let i = (range - 1); i >= 0; i--) { + const current = + span == 'day' ? new Date(y, m, d - i) : + span == 'hour' ? new Date(y, m, d, h - i) : + null; + + const stat = src.find(s => s.date.getTime() == current.getTime()); + + if (stat) { + chart.unshift(stat); + } else { // 隙間埋め + const mostRecent = src.find(s => s.date.getTime() < current.getTime()); + if (mostRecent) { + chart.unshift(Object.assign({}, mostRecent, { + date: current + })); + } else { + chart.unshift({ + 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 + } + } + }); + } + } + } + + chart.forEach(x => { + delete (x as any).span; + }); + + return chart; + }; + + res({ + perDay: format(statsPerDay, 'day'), + perHour: format(statsPerHour, 'hour') + }); +}); -- cgit v1.2.3-freya From 13624ea7c25870162d1c60e82c3a0e064e8478da Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 24 Aug 2018 14:55:58 +0900 Subject: バグ修正など MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/ja-JP.yml | 27 +- .../app/desktop/views/pages/admin/admin.chart.vue | 280 +++++++++++++++------ src/server/api/endpoints/chart.ts | 54 +++- 3 files changed, 268 insertions(+), 93 deletions(-) (limited to 'src/server/api/endpoints') diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 3755f55f36..c44254439c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -946,22 +946,17 @@ desktop/views/pages/admin/admin.chart.vue: notes: "投稿" users: "ユーザー" drive: "ドライブ" - local-notes: "ローカルの投稿の増減" - remote-notes: "リモートの投稿の増減" - local-notes-total: "ローカルの投稿の累計" - remote-notes-total: "リモートの投稿の累計" - local-users: "ローカルのユーザーの増減" - remote-users: "リモートのユーザーの増減" - local-users-total: "ローカルのユーザーの累計" - remote-users-total: "リモートのユーザーの累計" - local-drive: "ローカルのドライブ使用量の増減" - remote-drive: "リモートのドライブ使用量の増減" - local-drive-total: "ローカルのドライブ使用量の累計" - remote-drive-total: "リモートのドライブ使用量の累計" - local-drive-files: "ローカルのドライブのファイル数の増減" - remote-drive-files: "リモートのドライブのファイル数の増減" - local-drive-files-total: "ローカルのドライブのファイル数の累計" - remote-drive-files-total: "リモートのドライブのファイル数の累計" + charts: + notes: "投稿の増減 (統合)" + local-notes: "投稿の増減 (ローカル)" + remote-notes: "投稿の増減 (リモート)" + notes-total: "投稿の累計" + users: "ユーザーの増減" + users-total: "ユーザーの累計" + drive: "ドライブ使用量の増減" + drive-total: "ドライブ使用量の累計" + drive-files: "ドライブのファイル数の増減" + drive-files-total: "ドライブのファイル数の累計" desktop/views/pages/deck/deck.tl-column.vue: is-media-only: "メディア投稿のみ" diff --git a/src/client/app/desktop/views/pages/admin/admin.chart.vue b/src/client/app/desktop/views/pages/admin/admin.chart.vue index 4301f9978b..89e61d4c74 100644 --- a/src/client/app/desktop/views/pages/admin/admin.chart.vue +++ b/src/client/app/desktop/views/pages/admin/admin.chart.vue @@ -4,30 +4,24 @@ %i18n:@title%:
- %i18n:@per-day% | %i18n:@per-hour% + %i18n:@per-day% | %i18n:@per-hour%
@@ -47,7 +41,7 @@ export default Vue.extend({ data() { return { chart: null, - chartType: 'local-notes', + chartType: 'notes', span: 'hour' }; }, @@ -55,22 +49,16 @@ export default Vue.extend({ data(): any { if (this.chart == null) return null; switch (this.chartType) { - case 'local-users': return this.usersChart(true, false); - case 'remote-users': return this.usersChart(false, false); - case 'local-users-total': return this.usersChart(true, true); - case 'remote-users-total': return this.usersChart(false, true); - case 'local-notes': return this.notesChart(true); - case 'remote-notes': return this.notesChart(false); - case 'local-notes-total': return this.notesTotalChart(true); - case 'remote-notes-total': return this.notesTotalChart(false); - case 'local-drive': return this.driveChart(true, false); - case 'remote-drive': return this.driveChart(false, false); - case 'local-drive-total': return this.driveChart(true, true); - case 'remote-drive-total': return this.driveChart(false, true); - case 'local-drive-files': return this.driveFilesChart(true, false); - case 'remote-drive-files': return this.driveFilesChart(false, false); - case 'local-drive-files-total': return this.driveFilesChart(true, true); - case 'remote-drive-files-total': return this.driveFilesChart(false, true); + case 'users': return this.usersChart(false); + case 'users-total': return this.usersChart(true); + case 'notes': return this.notesChart('combined'); + case 'local-notes': return this.notesChart('local'); + case 'remote-notes': return this.notesChart('remote'); + case 'notes-total': return this.notesTotalChart(); + case 'drive': return this.driveChart(false); + case 'drive-total': return this.driveChart(true); + case 'drive-files': return this.driveFilesChart(false); + case 'drive-files-total': return this.driveFilesChart(true); } }, stats(): any[] { @@ -87,13 +75,13 @@ export default Vue.extend({ }); }, methods: { - notesChart(local: boolean): any { + notesChart(type: string): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - normal: local ? x.notes.local.diffs.normal : x.notes.remote.diffs.normal, - reply: local ? x.notes.local.diffs.reply : x.notes.remote.diffs.reply, - renote: local ? x.notes.local.diffs.renote : x.notes.remote.diffs.renote, - all: local ? x.notes.local.diff : x.notes.remote.diff + normal: type == 'local' ? x.notes.local.diffs.normal : type == 'remote' ? x.notes.remote.diffs.normal : x.notes.local.diffs.normal + x.notes.remote.diffs.normal, + reply: type == 'local' ? x.notes.local.diffs.reply : type == 'remote' ? x.notes.remote.diffs.reply : x.notes.local.diffs.reply + x.notes.remote.diffs.reply, + renote: type == 'local' ? x.notes.local.diffs.renote : type == 'remote' ? x.notes.remote.diffs.renote : x.notes.local.diffs.renote + x.notes.remote.diffs.renote, + all: type == 'local' ? x.notes.local.diff : type == 'remote' ? x.notes.remote.diff : x.notes.local.diff + x.notes.remote.diff })); return [{ @@ -107,14 +95,14 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.all })) }, { - label: 'Normal', + label: 'Renotes', fill: true, - backgroundColor: 'rgba(65, 221, 222, 0.1)', - borderColor: '#41ddde', + backgroundColor: 'rgba(161, 222, 65, 0.1)', + borderColor: '#a1de41', borderWidth: 2, pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.normal })) + data: data.map(x => ({ t: x.date, y: x.renote })) }, { label: 'Replies', fill: true, @@ -125,78 +113,185 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.reply })) }, { - label: 'Renotes', + label: 'Normal', fill: true, - backgroundColor: 'rgba(161, 222, 65, 0.1)', - borderColor: '#a1de41', + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', borderWidth: 2, pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.renote })) + data: data.map(x => ({ t: x.date, y: x.normal })) }] + }, { + scales: { + yAxes: [{ + ticks: { + callback: value => { + return Vue.filter('number')(value); + } + } + }] + }, + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`; + } + } + } }]; }, - notesTotalChart(local: boolean): any { + notesTotalChart(): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - count: local ? x.notes.local.total : x.notes.remote.total, + localCount: x.notes.local.total, + remoteCount: x.notes.remote.total })); return [{ datasets: [{ - label: local ? 'Local Notes' : 'Remote Notes', + label: 'Notes', + fill: false, + borderColor: '#555', + borderWidth: 2, + borderDash: [4, 4], + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) + }, { + label: 'Remote Notes', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteCount })) + }, { + label: 'Local Notes', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', borderWidth: 2, pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.count })) + data: data.map(x => ({ t: x.date, y: x.localCount })) }] + }, { + scales: { + yAxes: [{ + ticks: { + callback: value => { + return Vue.filter('number')(value); + } + } + }] + }, + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`; + } + } + } }]; }, - usersChart(local: boolean, total: boolean): any { + usersChart(total: boolean): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - count: local ? - total ? x.users.local.total : x.users.local.diff : - total ? x.users.remote.total : x.users.remote.diff + localCount: total ? x.users.local.total : x.users.local.diff, + remoteCount: total ? x.users.remote.total : x.users.remote.diff })); return [{ datasets: [{ - label: local ? 'Local Users' : 'Remote Users', + label: 'Users', + fill: false, + borderColor: '#555', + borderWidth: 2, + borderDash: [4, 4], + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) + }, { + label: 'Remote Users', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteCount })) + }, { + label: 'Local Users', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', borderWidth: 2, pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.count })) + data: data.map(x => ({ t: x.date, y: x.localCount })) }] + }, { + scales: { + yAxes: [{ + ticks: { + callback: value => { + return Vue.filter('number')(value); + } + } + }] + }, + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`; + } + } + } }]; }, - driveChart(local: boolean, total: boolean): any { + driveChart(total: boolean): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - size: local ? - total ? x.drive.local.totalSize : x.drive.local.diffSize : - total ? x.drive.remote.totalSize : x.drive.remote.diffSize + localSize: total ? x.drive.local.totalSize : x.drive.local.diffSize, + remoteSize: total ? x.drive.remote.totalSize : x.drive.remote.diffSize })); return [{ datasets: [{ - label: local ? 'Local Drive Usage' : 'Remote Drive Usage', + label: 'Drive Usage', + fill: false, + borderColor: '#555', + borderWidth: 2, + borderDash: [4, 4], + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteSize + x.localSize })) + }, { + label: 'Remote Drive Usage', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteSize })) + }, { + label: 'Local Drive Usage', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', borderWidth: 2, pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.size })) + data: data.map(x => ({ t: x.date, y: x.localSize })) }] }, { scales: { @@ -210,35 +305,71 @@ export default Vue.extend({ }, tooltips: { callbacks: { - label: tooltipItem => { - return Vue.filter('bytes')(tooltipItem.yLabel); + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel)}`; } } } }]; }, - driveFilesChart(local: boolean, total: boolean): any { + driveFilesChart(total: boolean): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - count: local ? - total ? x.drive.local.totalCount : x.drive.local.diffCount : - total ? x.drive.remote.totalCount : x.drive.remote.diffCount + localCount: total ? x.drive.local.totalCount : x.drive.local.diffCount, + remoteCount: total ? x.drive.remote.totalCount : x.drive.remote.diffCount })); return [{ datasets: [{ - label: local ? 'Local Drive Files' : 'Remote Drive Files', + label: 'Drive Files', + fill: false, + borderColor: '#555', + borderWidth: 2, + borderDash: [4, 4], + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) + }, { + label: 'Remote Drive Files', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteCount })) + }, { + label: 'Local Drive Files', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', borderWidth: 2, pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.count })) + data: data.map(x => ({ t: x.date, y: x.localCount })) }] + }, { + scales: { + yAxes: [{ + ticks: { + callback: value => { + return Vue.filter('number')(value); + } + } + }] + }, + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`; + } + } + } }]; - }, + } } }); @@ -259,6 +390,11 @@ export default Vue.extend({ > *:last-child margin-left auto + * + &:not(.active) + color $theme-color + cursor pointer + > div > * display block diff --git a/src/server/api/endpoints/chart.ts b/src/server/api/endpoints/chart.ts index a58f0b163e..da3476f067 100644 --- a/src/server/api/endpoints/chart.ts +++ b/src/server/api/endpoints/chart.ts @@ -6,8 +6,8 @@ export const meta = { }; export default (params: any) => new Promise(async (res, rej) => { - const daysRange = 90; - const hoursRange = 24; + const daysRange = 30; + const hoursRange = 30; const now = new Date(); const y = now.getFullYear(); @@ -65,9 +65,53 @@ export default (params: any) => new Promise(async (res, rej) => { } else { // 隙間埋め const mostRecent = src.find(s => s.date.getTime() < current.getTime()); if (mostRecent) { - chart.unshift(Object.assign({}, mostRecent, { - date: current - })); + chart.unshift({ + date: current, + users: { + local: { + total: mostRecent.users.local.total, + diff: 0 + }, + remote: { + total: mostRecent.users.remote.total, + diff: 0 + } + }, + notes: { + local: { + total: mostRecent.notes.local.total, + diff: 0, + diffs: { + normal: 0, + reply: 0, + renote: 0 + } + }, + remote: { + total: mostRecent.notes.remote.total, + diff: 0, + diffs: { + normal: 0, + reply: 0, + renote: 0 + } + } + }, + drive: { + local: { + totalCount: mostRecent.drive.local.totalCount, + totalSize: mostRecent.drive.local.totalSize, + diffCount: 0, + diffSize: 0 + }, + remote: { + totalCount: mostRecent.drive.remote.totalCount, + totalSize: mostRecent.drive.remote.totalSize, + diffCount: 0, + diffSize: 0 + } + } + }); } else { chart.unshift({ date: current, -- cgit v1.2.3-freya From 7b6e55047f0bdf02ba0cafd5b90147737a75b556 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 25 Aug 2018 08:35:41 +0900 Subject: #2460 --- .../app/desktop/views/pages/admin/admin.chart.vue | 206 ++++++++++++++++++--- src/models/stats.ts | 106 ++++++++--- src/server/api/endpoints/chart.ts | 77 ++++++-- src/services/update-chart.ts | 88 +++++---- 4 files changed, 374 insertions(+), 103 deletions(-) (limited to 'src/server/api/endpoints') diff --git a/src/client/app/desktop/views/pages/admin/admin.chart.vue b/src/client/app/desktop/views/pages/admin/admin.chart.vue index 89e61d4c74..4310ce03d6 100644 --- a/src/client/app/desktop/views/pages/admin/admin.chart.vue +++ b/src/client/app/desktop/views/pages/admin/admin.chart.vue @@ -55,10 +55,10 @@ export default Vue.extend({ case 'local-notes': return this.notesChart('local'); case 'remote-notes': return this.notesChart('remote'); case 'notes-total': return this.notesTotalChart(); - case 'drive': return this.driveChart(false); - case 'drive-total': return this.driveChart(true); - case 'drive-files': return this.driveFilesChart(false); - case 'drive-files-total': return this.driveFilesChart(true); + case 'drive': return this.driveChart(); + case 'drive-total': return this.driveTotalChart(); + case 'drive-files': return this.driveFilesChart(); + case 'drive-files-total': return this.driveFilesTotalChart(); } }, stats(): any[] { @@ -81,7 +81,7 @@ export default Vue.extend({ normal: type == 'local' ? x.notes.local.diffs.normal : type == 'remote' ? x.notes.remote.diffs.normal : x.notes.local.diffs.normal + x.notes.remote.diffs.normal, reply: type == 'local' ? x.notes.local.diffs.reply : type == 'remote' ? x.notes.remote.diffs.reply : x.notes.local.diffs.reply + x.notes.remote.diffs.reply, renote: type == 'local' ? x.notes.local.diffs.renote : type == 'remote' ? x.notes.remote.diffs.renote : x.notes.local.diffs.renote + x.notes.remote.diffs.renote, - all: type == 'local' ? x.notes.local.diff : type == 'remote' ? x.notes.remote.diff : x.notes.local.diff + x.notes.remote.diff + all: type == 'local' ? (x.notes.local.inc + -x.notes.local.dec) : type == 'remote' ? (x.notes.remote.inc + -x.notes.remote.dec) : (x.notes.local.inc + -x.notes.local.dec) + (x.notes.remote.inc + -x.notes.remote.dec) })); return [{ @@ -152,7 +152,7 @@ export default Vue.extend({ return [{ datasets: [{ - label: 'Notes', + label: 'Combined', fill: false, borderColor: '#555', borderWidth: 2, @@ -161,7 +161,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) }, { - label: 'Remote Notes', + label: 'Remote', fill: true, backgroundColor: 'rgba(65, 221, 222, 0.1)', borderColor: '#41ddde', @@ -170,7 +170,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteCount })) }, { - label: 'Local Notes', + label: 'Local', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', @@ -203,13 +203,13 @@ export default Vue.extend({ usersChart(total: boolean): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - localCount: total ? x.users.local.total : x.users.local.diff, - remoteCount: total ? x.users.remote.total : x.users.remote.diff + localCount: total ? x.users.local.total : (x.users.local.inc + -x.users.local.dec), + remoteCount: total ? x.users.remote.total : (x.users.remote.inc + -x.users.remote.dec) })); return [{ datasets: [{ - label: 'Users', + label: 'Combined', fill: false, borderColor: '#555', borderWidth: 2, @@ -218,7 +218,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) }, { - label: 'Remote Users', + label: 'Remote', fill: true, backgroundColor: 'rgba(65, 221, 222, 0.1)', borderColor: '#41ddde', @@ -227,7 +227,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteCount })) }, { - label: 'Local Users', + label: 'Local', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', @@ -257,16 +257,93 @@ export default Vue.extend({ }]; }, - driveChart(total: boolean): any { + driveChart(): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - localSize: total ? x.drive.local.totalSize : x.drive.local.diffSize, - remoteSize: total ? x.drive.remote.totalSize : x.drive.remote.diffSize + localInc: x.drive.local.incSize, + localDec: -x.drive.local.decSize, + remoteInc: x.drive.remote.incSize, + remoteDec: -x.drive.remote.decSize, })); return [{ datasets: [{ - label: 'Drive Usage', + label: 'All', + fill: false, + borderColor: '#555', + borderWidth: 2, + borderDash: [4, 4], + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.localInc + x.localDec + x.remoteInc + x.remoteDec })) + }, { + label: 'Remote +', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteInc })) + }, { + label: 'Remote -', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteDec })) + }, { + label: 'Local +', + fill: true, + backgroundColor: 'rgba(246, 88, 79, 0.1)', + borderColor: '#f6584f', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.localInc })) + }, { + label: 'Local -', + fill: true, + backgroundColor: 'rgba(246, 88, 79, 0.1)', + borderColor: '#f6584f', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.localDec })) + }] + }, { + scales: { + yAxes: [{ + ticks: { + callback: value => { + return Vue.filter('bytes')(value); + } + } + }] + }, + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel)}`; + } + } + } + }]; + }, + + driveTotalChart(): any { + const data = this.stats.slice().reverse().map(x => ({ + date: new Date(x.date), + localSize: x.drive.local.totalSize, + remoteSize: x.drive.remote.totalSize + })); + + return [{ + datasets: [{ + label: 'Combined', fill: false, borderColor: '#555', borderWidth: 2, @@ -275,7 +352,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteSize + x.localSize })) }, { - label: 'Remote Drive Usage', + label: 'Remote', fill: true, backgroundColor: 'rgba(65, 221, 222, 0.1)', borderColor: '#41ddde', @@ -284,7 +361,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteSize })) }, { - label: 'Local Drive Usage', + label: 'Local', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', @@ -314,25 +391,102 @@ export default Vue.extend({ }]; }, - driveFilesChart(total: boolean): any { + driveFilesChart(): any { const data = this.stats.slice().reverse().map(x => ({ date: new Date(x.date), - localCount: total ? x.drive.local.totalCount : x.drive.local.diffCount, - remoteCount: total ? x.drive.remote.totalCount : x.drive.remote.diffCount + localInc: x.drive.local.incCount, + localDec: -x.drive.local.decCount, + remoteInc: x.drive.remote.incCount, + remoteDec: -x.drive.remote.decCount })); return [{ datasets: [{ - label: 'Drive Files', + label: 'All', fill: false, borderColor: '#555', borderWidth: 2, borderDash: [4, 4], pointBackgroundColor: '#fff', lineTension: 0, - data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) + data: data.map(x => ({ t: x.date, y: x.localInc + x.localDec + x.remoteInc + x.remoteDec })) + }, { + label: 'Remote +', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteInc })) + }, { + label: 'Remote -', + fill: true, + backgroundColor: 'rgba(65, 221, 222, 0.1)', + borderColor: '#41ddde', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.remoteDec })) + }, { + label: 'Local +', + fill: true, + backgroundColor: 'rgba(246, 88, 79, 0.1)', + borderColor: '#f6584f', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.localInc })) + }, { + label: 'Local -', + fill: true, + backgroundColor: 'rgba(246, 88, 79, 0.1)', + borderColor: '#f6584f', + borderWidth: 2, + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.localDec })) + }] + }, { + scales: { + yAxes: [{ + ticks: { + callback: value => { + return Vue.filter('number')(value); + } + } + }] + }, + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + const label = data.datasets[tooltipItem.datasetIndex].label || ''; + return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`; + } + } + } + }]; + }, + + driveFilesTotalChart(): any { + const data = this.stats.slice().reverse().map(x => ({ + date: new Date(x.date), + localCount: x.drive.local.totalCount, + remoteCount: x.drive.remote.totalCount, + })); + + return [{ + datasets: [{ + label: 'Combined', + fill: false, + borderColor: '#555', + borderWidth: 2, + borderDash: [4, 4], + pointBackgroundColor: '#fff', + lineTension: 0, + data: data.map(x => ({ t: x.date, y: x.localCount + x.remoteCount })) }, { - label: 'Remote Drive Files', + label: 'Remote', fill: true, backgroundColor: 'rgba(65, 221, 222, 0.1)', borderColor: '#41ddde', @@ -341,7 +495,7 @@ export default Vue.extend({ lineTension: 0, data: data.map(x => ({ t: x.date, y: x.remoteCount })) }, { - label: 'Local Drive Files', + label: 'Local', fill: true, backgroundColor: 'rgba(246, 88, 79, 0.1)', borderColor: '#f6584f', diff --git a/src/models/stats.ts b/src/models/stats.ts index c481c3196e..3041d3852b 100644 --- a/src/models/stats.ts +++ b/src/models/stats.ts @@ -8,8 +8,14 @@ export default Stats; export interface IStats { _id: mongo.ObjectID; + /** + * 集計日時 + */ date: Date; + /** + * 集計期間 + */ span: 'day' | 'hour'; /** @@ -18,26 +24,36 @@ export interface IStats { users: { local: { /** - * この日時点での、ローカルのユーザーの総計 + * 集計期間時点での、全ユーザー数 (ローカル) */ total: number; /** - * ローカルのユーザー数の前日比 + * 増加したユーザー数 (ローカル) + */ + inc: number; + + /** + * 減少したユーザー数 (ローカル) */ - diff: number; + dec: number; }; remote: { /** - * この日時点での、リモートのユーザーの総計 + * 集計期間時点での、全ユーザー数 (リモート) */ total: number; /** - * リモートのユーザー数の前日比 + * 増加したユーザー数 (リモート) */ - diff: number; + inc: number; + + /** + * 減少したユーザー数 (リモート) + */ + dec: number; }; }; @@ -47,28 +63,33 @@ export interface IStats { notes: { local: { /** - * この日時点での、ローカルの投稿の総計 + * 集計期間時点での、全投稿数 (ローカル) */ total: number; /** - * ローカルの投稿数の前日比 + * 増加した投稿数 (ローカル) */ - diff: number; + inc: number; + + /** + * 減少した投稿数 (ローカル) + */ + dec: number; diffs: { /** - * ローカルの通常の投稿数の前日比 + * 通常の投稿数の差分 (ローカル) */ normal: number; /** - * ローカルのリプライの投稿数の前日比 + * リプライの投稿数の差分 (ローカル) */ reply: number; /** - * ローカルのRenoteの投稿数の前日比 + * Renoteの投稿数の差分 (ローカル) */ renote: number; }; @@ -76,28 +97,33 @@ export interface IStats { remote: { /** - * この日時点での、リモートの投稿の総計 + * 集計期間時点での、全投稿数 (リモート) */ total: number; /** - * リモートの投稿数の前日比 + * 増加した投稿数 (リモート) + */ + inc: number; + + /** + * 減少した投稿数 (リモート) */ - diff: number; + dec: number; diffs: { /** - * リモートの通常の投稿数の前日比 + * 通常の投稿数の差分 (リモート) */ normal: number; /** - * リモートのリプライの投稿数の前日比 + * リプライの投稿数の差分 (リモート) */ reply: number; /** - * リモートのRenoteの投稿数の前日比 + * Renoteの投稿数の差分 (リモート) */ renote: number; }; @@ -110,46 +136,66 @@ export interface IStats { drive: { local: { /** - * この日時点での、ローカルのドライブファイル数の総計 + * 集計期間時点での、全ドライブファイル数 (ローカル) */ totalCount: number; /** - * この日時点での、ローカルのドライブファイルサイズの総計 + * 集計期間時点での、全ドライブファイルの合計サイズ (ローカル) */ totalSize: number; /** - * ローカルのドライブファイル数の前日比 + * 増加したドライブファイル数 (ローカル) + */ + incCount: number; + + /** + * 増加したドライブ使用量 (ローカル) + */ + incSize: number; + + /** + * 減少したドライブファイル数 (ローカル) */ - diffCount: number; + decCount: number; /** - * ローカルのドライブファイルサイズの前日比 + * 減少したドライブ使用量 (ローカル) */ - diffSize: number; + decSize: number; }; remote: { /** - * この日時点での、リモートのドライブファイル数の総計 + * 集計期間時点での、全ドライブファイル数 (リモート) */ totalCount: number; /** - * この日時点での、リモートのドライブファイルサイズの総計 + * 集計期間時点での、全ドライブファイルの合計サイズ (リモート) */ totalSize: number; /** - * リモートのドライブファイル数の前日比 + * 増加したドライブファイル数 (リモート) + */ + incCount: number; + + /** + * 増加したドライブ使用量 (リモート) + */ + incSize: number; + + /** + * 減少したドライブファイル数 (リモート) */ - diffCount: number; + decCount: number; /** - * リモートのドライブファイルサイズの前日比 + * 減少したドライブ使用量 (リモート) */ - diffSize: number; + decSize: number; }; }; } diff --git a/src/server/api/endpoints/chart.ts b/src/server/api/endpoints/chart.ts index da3476f067..514bacaa84 100644 --- a/src/server/api/endpoints/chart.ts +++ b/src/server/api/endpoints/chart.ts @@ -2,6 +2,31 @@ import Stats, { IStats } from '../../../models/stats'; type Omit = Pick>; +function migrateStats(stats: IStats[]) { + stats.forEach(stat => { + const isOldData = stat.users.local.inc == null; + + if (!isOldData) return; + + stat.users.local.inc = (stat as any).users.local.diff; + stat.users.local.dec = 0; + stat.users.remote.inc = (stat as any).users.remote.diff; + stat.users.remote.dec = 0; + stat.notes.local.inc = (stat as any).notes.local.diff; + stat.notes.local.dec = 0; + stat.notes.remote.inc = (stat as any).notes.remote.diff; + stat.notes.remote.dec = 0; + stat.drive.local.incCount = (stat as any).drive.local.diffCount; + stat.drive.local.decCount = 0; + stat.drive.local.incSize = (stat as any).drive.local.diffSize; + stat.drive.local.decSize = 0; + stat.drive.remote.incCount = (stat as any).drive.remote.diffCount; + stat.drive.remote.decCount = 0; + stat.drive.remote.incSize = (stat as any).drive.remote.diffSize; + stat.drive.remote.decSize = 0; + }); +} + export const meta = { }; @@ -44,6 +69,10 @@ export default (params: any) => new Promise(async (res, rej) => { }), ]); + // 後方互換性のため + migrateStats(statsPerDay); + migrateStats(statsPerHour); + const format = (src: IStats[], span: 'day' | 'hour') => { const chart: Array, 'span'>> = []; @@ -70,17 +99,20 @@ export default (params: any) => new Promise(async (res, rej) => { users: { local: { total: mostRecent.users.local.total, - diff: 0 + inc: 0, + dec: 0 }, remote: { total: mostRecent.users.remote.total, - diff: 0 + inc: 0, + dec: 0 } }, notes: { local: { total: mostRecent.notes.local.total, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -89,7 +121,8 @@ export default (params: any) => new Promise(async (res, rej) => { }, remote: { total: mostRecent.notes.remote.total, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -101,14 +134,18 @@ export default (params: any) => new Promise(async (res, rej) => { local: { totalCount: mostRecent.drive.local.totalCount, totalSize: mostRecent.drive.local.totalSize, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 }, remote: { totalCount: mostRecent.drive.remote.totalCount, totalSize: mostRecent.drive.remote.totalSize, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 } } }); @@ -118,17 +155,20 @@ export default (params: any) => new Promise(async (res, rej) => { users: { local: { total: 0, - diff: 0 + inc: 0, + dec: 0 }, remote: { total: 0, - diff: 0 + inc: 0, + dec: 0 } }, notes: { local: { total: 0, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -137,7 +177,8 @@ export default (params: any) => new Promise(async (res, rej) => { }, remote: { total: 0, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -149,14 +190,18 @@ export default (params: any) => new Promise(async (res, rej) => { local: { totalCount: 0, totalSize: 0, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 }, remote: { totalCount: 0, totalSize: 0, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 } } }); diff --git a/src/services/update-chart.ts b/src/services/update-chart.ts index 0a0f58bb92..1f8da6be9f 100644 --- a/src/services/update-chart.ts +++ b/src/services/update-chart.ts @@ -48,17 +48,20 @@ async function getCurrentStats(span: 'day' | 'hour'): Promise { users: { local: { total: mostRecentStats.users.local.total, - diff: 0 + inc: 0, + dec: 0 }, remote: { total: mostRecentStats.users.remote.total, - diff: 0 + inc: 0, + dec: 0 } }, notes: { local: { total: mostRecentStats.notes.local.total, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -67,7 +70,8 @@ async function getCurrentStats(span: 'day' | 'hour'): Promise { }, remote: { total: mostRecentStats.notes.remote.total, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -79,14 +83,18 @@ async function getCurrentStats(span: 'day' | 'hour'): Promise { local: { totalCount: mostRecentStats.drive.local.totalCount, totalSize: mostRecentStats.drive.local.totalSize, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 }, remote: { totalCount: mostRecentStats.drive.remote.totalCount, totalSize: mostRecentStats.drive.remote.totalSize, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 } } }; @@ -105,17 +113,20 @@ async function getCurrentStats(span: 'day' | 'hour'): Promise { users: { local: { total: 0, - diff: 0 + inc: 0, + dec: 0 }, remote: { total: 0, - diff: 0 + inc: 0, + dec: 0 } }, notes: { local: { total: 0, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -124,7 +135,8 @@ async function getCurrentStats(span: 'day' | 'hour'): Promise { }, remote: { total: 0, - diff: 0, + inc: 0, + dec: 0, diffs: { normal: 0, reply: 0, @@ -136,14 +148,18 @@ async function getCurrentStats(span: 'day' | 'hour'): Promise { local: { totalCount: 0, totalSize: 0, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 }, remote: { totalCount: 0, totalSize: 0, - diffCount: 0, - diffSize: 0 + incCount: 0, + incSize: 0, + decCount: 0, + decSize: 0 } } }; @@ -174,46 +190,56 @@ function update(inc: any) { } export async function updateUserStats(user: IUser, isAdditional: boolean) { - const amount = isAdditional ? 1 : -1; const origin = isLocalUser(user) ? 'local' : 'remote'; const inc = {} as any; - inc[`users.${origin}.total`] = amount; - inc[`users.${origin}.diff`] = amount; + inc[`users.${origin}.total`] = isAdditional ? 1 : -1; + if (isAdditional) { + inc[`users.${origin}.inc`] = 1; + } else { + inc[`users.${origin}.dec`] = 1; + } await update(inc); } export async function updateNoteStats(note: INote, isAdditional: boolean) { - const amount = isAdditional ? 1 : -1; const origin = isLocalUser(note._user) ? 'local' : 'remote'; const inc = {} as any; - inc[`notes.${origin}.total`] = amount; - inc[`notes.${origin}.diff`] = amount; + inc[`notes.${origin}.total`] = isAdditional ? 1 : -1; + + if (isAdditional) { + inc[`notes.${origin}.inc`] = 1; + } else { + inc[`notes.${origin}.dec`] = 1; + } if (note.replyId != null) { - inc[`notes.${origin}.diffs.reply`] = amount; + inc[`notes.${origin}.diffs.reply`] = isAdditional ? 1 : -1; } else if (note.renoteId != null) { - inc[`notes.${origin}.diffs.renote`] = amount; + inc[`notes.${origin}.diffs.renote`] = isAdditional ? 1 : -1; } else { - inc[`notes.${origin}.diffs.normal`] = amount; + inc[`notes.${origin}.diffs.normal`] = isAdditional ? 1 : -1; } await update(inc); } export async function updateDriveStats(file: IDriveFile, isAdditional: boolean) { - const amount = isAdditional ? 1 : -1; - const size = isAdditional ? file.length : -file.length; const origin = isLocalUser(file.metadata._user) ? 'local' : 'remote'; const inc = {} as any; - inc[`drive.${origin}.totalCount`] = amount; - inc[`drive.${origin}.diffCount`] = amount; - inc[`drive.${origin}.totalSize`] = size; - inc[`drive.${origin}.diffSize`] = size; + inc[`drive.${origin}.totalCount`] = isAdditional ? 1 : -1; + inc[`drive.${origin}.totalSize`] = isAdditional ? file.length : -file.length; + if (isAdditional) { + inc[`drive.${origin}.incCount`] = 1; + inc[`drive.${origin}.incSize`] = file.length; + } else { + inc[`drive.${origin}.decCount`] = 1; + inc[`drive.${origin}.decSize`] = file.length; + } await update(inc); } -- cgit v1.2.3-freya From ef57f5907b115b8047e798f7486bb9ee73d465aa Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 25 Aug 2018 11:10:27 +0900 Subject: Fix bug --- src/server/api/endpoints/chart.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/server/api/endpoints') diff --git a/src/server/api/endpoints/chart.ts b/src/server/api/endpoints/chart.ts index 514bacaa84..406ad39946 100644 --- a/src/server/api/endpoints/chart.ts +++ b/src/server/api/endpoints/chart.ts @@ -4,7 +4,23 @@ type Omit = Pick>; function migrateStats(stats: IStats[]) { stats.forEach(stat => { - const isOldData = stat.users.local.inc == null; + const isOldData = + stat.users.local.inc == null || + stat.users.local.dec == null || + stat.users.remote.inc == null || + stat.users.remote.dec == null || + stat.notes.local.inc == null || + stat.notes.local.dec == null || + stat.notes.remote.inc == null || + stat.notes.remote.dec == null || + stat.drive.local.incCount == null || + stat.drive.local.decCount == null || + stat.drive.local.incSize == null || + stat.drive.local.decSize == null || + stat.drive.remote.incCount == null || + stat.drive.remote.decCount == null || + stat.drive.remote.incSize == null || + stat.drive.remote.decSize == null; if (!isOldData) return; -- cgit v1.2.3-freya From 08754609747266b0c24037860b44e11c662ea885 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 25 Aug 2018 19:44:47 +0900 Subject: ユーザーのアイコンにサムネイルを使うように MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #2365 --- src/remote/activitypub/models/person.ts | 6 +++--- src/server/api/endpoints/i/update.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/server/api/endpoints') diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts index 61bcf77c43..4a7b505a9f 100644 --- a/src/remote/activitypub/models/person.ts +++ b/src/remote/activitypub/models/person.ts @@ -166,8 +166,8 @@ export async function createPerson(value: any, resolver?: Resolver): Promise new Promise(a if (avatar == null) return rej('avatar not found'); - updates.avatarUrl = avatar.metadata.url || `${config.drive_url}/${avatar._id}`; + updates.avatarUrl = avatar.metadata.thumbnailUrl || avatar.metadata.url || `${config.drive_url}/${avatar._id}`; if (avatar.metadata.properties.avgColor) { updates.avatarColor = avatar.metadata.properties.avgColor; -- cgit v1.2.3-freya From 2de8e8c35803d77af1d6eae78d619f9b57c86bd7 Mon Sep 17 00:00:00 2001 From: syuilo Date: Wed, 29 Aug 2018 06:59:43 +0900 Subject: Fix bug --- src/client/app/init.ts | 4 +- src/docs/about.en-US.md | 3 + src/docs/about.en.md | 3 - src/docs/about.ja-JP.md | 3 + src/docs/about.ja.md | 3 - src/docs/api.ja-JP.md | 80 +++++++++ src/docs/api.ja.md | 80 --------- src/docs/api/endpoints/view.pug | 2 +- src/docs/api/entities/drive-file.yaml | 52 +++--- src/docs/api/entities/drive-folder.yaml | 24 +-- src/docs/api/entities/note.yaml | 98 +++++------ src/docs/api/entities/user.yaml | 96 +++++------ src/docs/api/entities/view.pug | 2 +- src/docs/api/mixins.pug | 2 +- src/docs/base.pug | 2 +- src/docs/follow.ja-JP.md | 8 + src/docs/follow.ja.md | 8 - src/docs/mute.ja-JP.md | 13 ++ src/docs/mute.ja.md | 13 -- src/docs/reversi-bot.ja-JP.md | 177 ++++++++++++++++++++ src/docs/reversi-bot.ja.md | 177 -------------------- src/docs/stream.ja-JP.md | 183 +++++++++++++++++++++ src/docs/stream.ja.md | 183 --------------------- src/docs/timelines.ja-JP.md | 15 ++ src/docs/timelines.ja.md | 15 -- src/server/api/endpoints/admin/invite.ts | 2 +- src/server/api/endpoints/admin/suspend-user.ts | 8 +- src/server/api/endpoints/admin/unsuspend-user.ts | 8 +- src/server/api/endpoints/admin/unverify-user.ts | 8 +- src/server/api/endpoints/admin/update-meta.ts | 4 +- src/server/api/endpoints/admin/verify-user.ts | 8 +- src/server/api/endpoints/drive.ts | 4 +- src/server/api/endpoints/drive/files.ts | 4 +- src/server/api/endpoints/drive/files/create.ts | 10 +- src/server/api/endpoints/drive/files/delete.ts | 4 +- src/server/api/endpoints/drive/files/show.ts | 4 +- src/server/api/endpoints/drive/files/update.ts | 16 +- .../api/endpoints/drive/files/upload_from_url.ts | 2 +- src/server/api/endpoints/drive/folders.ts | 4 +- src/server/api/endpoints/drive/folders/create.ts | 4 +- src/server/api/endpoints/drive/folders/show.ts | 2 +- src/server/api/endpoints/drive/folders/update.ts | 4 +- src/server/api/endpoints/following/create.ts | 4 +- src/server/api/endpoints/following/delete.ts | 4 +- .../api/endpoints/following/requests/accept.ts | 4 +- .../api/endpoints/following/requests/cancel.ts | 4 +- .../api/endpoints/following/requests/list.ts | 4 +- .../api/endpoints/following/requests/reject.ts | 4 +- src/server/api/endpoints/following/stalk.ts | 4 +- src/server/api/endpoints/following/unstalk.ts | 4 +- .../api/endpoints/games/reversi/games/surrender.ts | 4 +- src/server/api/endpoints/hashtags/search.ts | 8 +- src/server/api/endpoints/i.ts | 2 +- src/server/api/endpoints/i/favorites.ts | 4 +- src/server/api/endpoints/i/update.ts | 4 +- src/server/api/endpoints/messaging/history.ts | 4 +- src/server/api/endpoints/messaging/messages.ts | 4 +- .../api/endpoints/messaging/messages/create.ts | 4 +- .../api/endpoints/messaging/messages/read.ts | 8 +- src/server/api/endpoints/mute/create.ts | 4 +- src/server/api/endpoints/mute/delete.ts | 4 +- src/server/api/endpoints/mute/list.ts | 4 +- src/server/api/endpoints/my/apps.ts | 4 +- src/server/api/endpoints/notes/create.ts | 22 +-- src/server/api/endpoints/notes/delete.ts | 4 +- src/server/api/endpoints/notes/favorites/create.ts | 4 +- src/server/api/endpoints/notes/favorites/delete.ts | 4 +- src/server/api/endpoints/notes/hybrid-timeline.ts | 20 +-- src/server/api/endpoints/notes/mentions.ts | 4 +- .../api/endpoints/notes/polls/recommendation.ts | 4 +- src/server/api/endpoints/notes/polls/vote.ts | 4 +- src/server/api/endpoints/notes/reactions.ts | 4 +- src/server/api/endpoints/notes/reactions/create.ts | 8 +- src/server/api/endpoints/notes/reactions/delete.ts | 4 +- src/server/api/endpoints/notes/timeline.ts | 22 +-- src/server/api/endpoints/notes/trend.ts | 4 +- .../api/endpoints/notes/user-list-timeline.ts | 24 +-- .../endpoints/notifications/mark_all_as_read.ts | 4 +- src/server/api/endpoints/users/lists/create.ts | 4 +- src/server/api/endpoints/users/lists/list.ts | 2 +- src/server/api/endpoints/users/lists/push.ts | 4 +- src/server/api/endpoints/users/lists/show.ts | 4 +- src/server/api/endpoints/users/recommendation.ts | 2 +- src/server/api/endpoints/users/search.ts | 10 +- 84 files changed, 797 insertions(+), 797 deletions(-) create mode 100644 src/docs/about.en-US.md delete mode 100644 src/docs/about.en.md create mode 100644 src/docs/about.ja-JP.md delete mode 100644 src/docs/about.ja.md create mode 100644 src/docs/api.ja-JP.md delete mode 100644 src/docs/api.ja.md create mode 100644 src/docs/follow.ja-JP.md delete mode 100644 src/docs/follow.ja.md create mode 100644 src/docs/mute.ja-JP.md delete mode 100644 src/docs/mute.ja.md create mode 100644 src/docs/reversi-bot.ja-JP.md delete mode 100644 src/docs/reversi-bot.ja.md create mode 100644 src/docs/stream.ja-JP.md delete mode 100644 src/docs/stream.ja.md create mode 100644 src/docs/timelines.ja-JP.md delete mode 100644 src/docs/timelines.ja.md (limited to 'src/server/api/endpoints') diff --git a/src/client/app/init.ts b/src/client/app/init.ts index 18f510ea24..cf97957400 100644 --- a/src/client/app/init.ts +++ b/src/client/app/init.ts @@ -19,8 +19,8 @@ import { version, codename, lang } from './config'; let elementLocale; switch (lang) { - case 'ja': elementLocale = ElementLocaleJa; break; - case 'en': elementLocale = ElementLocaleEn; break; + case 'ja-JP': elementLocale = ElementLocaleJa; break; + case 'en-US': elementLocale = ElementLocaleEn; break; default: elementLocale = ElementLocaleEn; break; } diff --git a/src/docs/about.en-US.md b/src/docs/about.en-US.md new file mode 100644 index 0000000000..bb1c51927b --- /dev/null +++ b/src/docs/about.en-US.md @@ -0,0 +1,3 @@ +# About Misskey + +Misskey is a mini blog SNS. diff --git a/src/docs/about.en.md b/src/docs/about.en.md deleted file mode 100644 index bb1c51927b..0000000000 --- a/src/docs/about.en.md +++ /dev/null @@ -1,3 +0,0 @@ -# About Misskey - -Misskey is a mini blog SNS. diff --git a/src/docs/about.ja-JP.md b/src/docs/about.ja-JP.md new file mode 100644 index 0000000000..1b06361f0f --- /dev/null +++ b/src/docs/about.ja-JP.md @@ -0,0 +1,3 @@ +# Misskeyについて + +MisskeyはミニブログSNSです。 diff --git a/src/docs/about.ja.md b/src/docs/about.ja.md deleted file mode 100644 index 1b06361f0f..0000000000 --- a/src/docs/about.ja.md +++ /dev/null @@ -1,3 +0,0 @@ -# Misskeyについて - -MisskeyはミニブログSNSです。 diff --git a/src/docs/api.ja-JP.md b/src/docs/api.ja-JP.md new file mode 100644 index 0000000000..ecc80cc05e --- /dev/null +++ b/src/docs/api.ja-JP.md @@ -0,0 +1,80 @@ +# Misskey API + +MisskeyのWeb APIを使って、プログラムからMisskeyの様々な機能にアクセスすることができます。 +APIを自分のアカウントから利用する場合(自分のアカウントのみ操作したい場合)と、アプリケーションから利用する場合(不特定のアカウントを操作したい場合)とで利用手順が異なりますので、それぞれのケースについて説明します。 + +## 自分の所有するアカウントからAPIにアクセスする場合 +「設定 > API」で、APIにアクセスするのに必要なAPIキーを取得してください。 +APIにアクセスする際には、リクエストにAPIキーを「i」というパラメータ名で含めます。 + +
+

アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。

+
+ +APIの詳しい使用法は「Misskey APIの利用」セクションをご覧ください。 + +## アプリケーションからAPIにアクセスする場合 +直接ユーザーのAPIキーをアプリケーションが扱うのは危険なので、 +アプリケーションからAPIを利用する際には、アプリケーションとアプリケーションを利用するユーザーが結び付けられた専用のトークン(アクセストークン)をMisskeyに発行してもらい、 +そのトークンをリクエストのパラメータに含める必要があります。 + +
+

アクセストークンは、ユーザーが自分のアカウントにあなたのアプリケーションがアクセスすることを許可した場合のみ発行されます

+
+ +### 1.アプリケーションを登録する +まず、あなたのアプリケーションやWebサービス(以後、あなたのアプリと呼びます)をMisskeyに登録します。 +[デベロッパーセンター](/dev)にアクセスし、「アプリ > アプリ作成」からアプリを作成してください。 +フォームの記入欄の説明は以下の通りです: + +| 名前 | 説明 | +|---|---| +| アプリケーション名 | あなたのアプリの名称。 | +| アプリの概要 | あなたのアプリの簡単な説明や紹介。 | +| コールバックURL | ユーザーが後述する認証フォームで認証を終えた際にリダイレクトするURLを設定できます。あなたのアプリがWebサービスである場合に有用です。 | +| 権限 | あなたのアプリが要求する権限。ここで要求した機能だけがAPIからアクセスできます。 | + +登録が済むとあなたのアプリのシークレットキーが入手できます。このシークレットキーは後で使用します。 + +
+

アプリに成りすまされる可能性があるため、極力このシークレットキーは公開しないようにしてください。

+
+ +### 2.ユーザーに認証させる +アプリを使ってもらうには、ユーザーにアカウントへのアクセスの許可をもらう必要があります。 + +認証セッションを開始するには、%API_URL%/auth/session/generate へパラメータに appSecret としてシークレットキーを含めたリクエストを送信します。 +リクエスト形式はJSONで、メソッドはPOSTです。 +レスポンスとして認証セッションのトークンや認証フォームのURLが取得できるので、認証フォームのURLをブラウザで表示し、ユーザーにフォームを提示してください。 + +あなたのアプリがコールバックURLを設定している場合、 +ユーザーがあなたのアプリの連携を許可すると設定しているコールバックURLに token という名前でセッションのトークンが含まれたクエリを付けてリダイレクトします。 + +あなたのアプリがコールバックURLを設定していない場合、ユーザーがあなたのアプリの連携を許可したことを(何らかの方法で(たとえばボタンを押させるなど))確認出来るようにしてください。 + +### 3.ユーザーのアクセストークンを取得する +ユーザーが連携を許可したら、%API_URL%/auth/session/userkey へ次のパラメータを含むリクエストを送信します: + +| 名前 | 型 | 説明 | +|---|---|---| +| appSecret | string | アプリのシークレットキー | +| token | string | セッションのトークン | + +上手くいけば、認証したユーザーのアクセストークンがレスポンスとして取得できます。おめでとうございます! + +アクセストークンが取得できたら、「ユーザーのアクセストークン+あなたのアプリのシークレットキーをsha256したもの」を「i」というパラメータでリクエストに含めると、APIにアクセスすることができます。 + +「i」パラメータの生成方法を擬似コードで表すと次のようになります: +
const i = sha256(accessToken + secretKey);
+ +APIの詳しい使用法は「Misskey APIの利用」セクションをご覧ください。 + +## Misskey APIの利用 +APIはすべてリクエストのパラメータ・レスポンスともにJSON形式です。また、すべてのエンドポイントはPOSTメソッドのみ受け付けます。 + +ストリーミングAPIも提供しています。 + +APIリファレンスもご確認ください。 + +### レートリミット +Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。 diff --git a/src/docs/api.ja.md b/src/docs/api.ja.md deleted file mode 100644 index ecc80cc05e..0000000000 --- a/src/docs/api.ja.md +++ /dev/null @@ -1,80 +0,0 @@ -# Misskey API - -MisskeyのWeb APIを使って、プログラムからMisskeyの様々な機能にアクセスすることができます。 -APIを自分のアカウントから利用する場合(自分のアカウントのみ操作したい場合)と、アプリケーションから利用する場合(不特定のアカウントを操作したい場合)とで利用手順が異なりますので、それぞれのケースについて説明します。 - -## 自分の所有するアカウントからAPIにアクセスする場合 -「設定 > API」で、APIにアクセスするのに必要なAPIキーを取得してください。 -APIにアクセスする際には、リクエストにAPIキーを「i」というパラメータ名で含めます。 - -
-

アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。

-
- -APIの詳しい使用法は「Misskey APIの利用」セクションをご覧ください。 - -## アプリケーションからAPIにアクセスする場合 -直接ユーザーのAPIキーをアプリケーションが扱うのは危険なので、 -アプリケーションからAPIを利用する際には、アプリケーションとアプリケーションを利用するユーザーが結び付けられた専用のトークン(アクセストークン)をMisskeyに発行してもらい、 -そのトークンをリクエストのパラメータに含める必要があります。 - -
-

アクセストークンは、ユーザーが自分のアカウントにあなたのアプリケーションがアクセスすることを許可した場合のみ発行されます

-
- -### 1.アプリケーションを登録する -まず、あなたのアプリケーションやWebサービス(以後、あなたのアプリと呼びます)をMisskeyに登録します。 -[デベロッパーセンター](/dev)にアクセスし、「アプリ > アプリ作成」からアプリを作成してください。 -フォームの記入欄の説明は以下の通りです: - -| 名前 | 説明 | -|---|---| -| アプリケーション名 | あなたのアプリの名称。 | -| アプリの概要 | あなたのアプリの簡単な説明や紹介。 | -| コールバックURL | ユーザーが後述する認証フォームで認証を終えた際にリダイレクトするURLを設定できます。あなたのアプリがWebサービスである場合に有用です。 | -| 権限 | あなたのアプリが要求する権限。ここで要求した機能だけがAPIからアクセスできます。 | - -登録が済むとあなたのアプリのシークレットキーが入手できます。このシークレットキーは後で使用します。 - -
-

アプリに成りすまされる可能性があるため、極力このシークレットキーは公開しないようにしてください。

-
- -### 2.ユーザーに認証させる -アプリを使ってもらうには、ユーザーにアカウントへのアクセスの許可をもらう必要があります。 - -認証セッションを開始するには、%API_URL%/auth/session/generate へパラメータに appSecret としてシークレットキーを含めたリクエストを送信します。 -リクエスト形式はJSONで、メソッドはPOSTです。 -レスポンスとして認証セッションのトークンや認証フォームのURLが取得できるので、認証フォームのURLをブラウザで表示し、ユーザーにフォームを提示してください。 - -あなたのアプリがコールバックURLを設定している場合、 -ユーザーがあなたのアプリの連携を許可すると設定しているコールバックURLに token という名前でセッションのトークンが含まれたクエリを付けてリダイレクトします。 - -あなたのアプリがコールバックURLを設定していない場合、ユーザーがあなたのアプリの連携を許可したことを(何らかの方法で(たとえばボタンを押させるなど))確認出来るようにしてください。 - -### 3.ユーザーのアクセストークンを取得する -ユーザーが連携を許可したら、%API_URL%/auth/session/userkey へ次のパラメータを含むリクエストを送信します: - -| 名前 | 型 | 説明 | -|---|---|---| -| appSecret | string | アプリのシークレットキー | -| token | string | セッションのトークン | - -上手くいけば、認証したユーザーのアクセストークンがレスポンスとして取得できます。おめでとうございます! - -アクセストークンが取得できたら、「ユーザーのアクセストークン+あなたのアプリのシークレットキーをsha256したもの」を「i」というパラメータでリクエストに含めると、APIにアクセスすることができます。 - -「i」パラメータの生成方法を擬似コードで表すと次のようになります: -
const i = sha256(accessToken + secretKey);
- -APIの詳しい使用法は「Misskey APIの利用」セクションをご覧ください。 - -## Misskey APIの利用 -APIはすべてリクエストのパラメータ・レスポンスともにJSON形式です。また、すべてのエンドポイントはPOSTメソッドのみ受け付けます。 - -ストリーミングAPIも提供しています。 - -APIリファレンスもご確認ください。 - -### レートリミット -Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。 diff --git a/src/docs/api/endpoints/view.pug b/src/docs/api/endpoints/view.pug index 76e1183302..be7e84faa1 100644 --- a/src/docs/api/endpoints/view.pug +++ b/src/docs/api/endpoints/view.pug @@ -15,7 +15,7 @@ block main span.path= endpointUrl.path if endpoint.desc - p#desc= endpoint.desc[lang] || endpoint.desc['ja'] + p#desc= endpoint.desc[lang] || endpoint.desc['ja-JP'] if endpoint.requireCredential div.ui.info: p diff --git a/src/docs/api/entities/drive-file.yaml b/src/docs/api/entities/drive-file.yaml index 62dbec363a..0c2195ac08 100644 --- a/src/docs/api/entities/drive-file.yaml +++ b/src/docs/api/entities/drive-file.yaml @@ -1,90 +1,90 @@ name: "DriveFile" desc: - ja: "ドライブのファイル。" - en: "A file of Drive." + ja-JP: "ドライブのファイル。" + en-US: "A file of Drive." props: id: type: "id" optional: false desc: - ja: "ファイルID" - en: "The ID of this file" + ja-JP: "ファイルID" + en-US: "The ID of this file" createdAt: type: "date" optional: false desc: - ja: "アップロード日時" - en: "The upload date of this file" + ja-JP: "アップロード日時" + en-US: "The upload date of this file" userId: type: "id(User)" optional: false desc: - ja: "所有者ID" - en: "The ID of the owner of this file" + ja-JP: "所有者ID" + en-US: "The ID of the owner of this file" user: type: "entity(User)" optional: true desc: - ja: "所有者" - en: "The owner of this file" + ja-JP: "所有者" + en-US: "The owner of this file" name: type: "string" optional: false desc: - ja: "ファイル名" - en: "The name of this file" + ja-JP: "ファイル名" + en-US: "The name of this file" md5: type: "string" optional: false desc: - ja: "ファイルのMD5ハッシュ値" - en: "The md5 hash value of this file" + ja-JP: "ファイルのMD5ハッシュ値" + en-US: "The md5 hash value of this file" type: type: "string" optional: false desc: - ja: "ファイルの種類" - en: "The type of this file" + ja-JP: "ファイルの種類" + en-US: "The type of this file" datasize: type: "number" optional: false desc: - ja: "ファイルサイズ(bytes)" - en: "The size of this file (bytes)" + ja-JP: "ファイルサイズ(bytes)" + en-US: "The size of this file (bytes)" url: type: "string" optional: false desc: - ja: "ファイルのURL" - en: "The URL of this file" + ja-JP: "ファイルのURL" + en-US: "The URL of this file" folderId: type: "id(DriveFolder)" optional: true desc: - ja: "フォルダID" - en: "The ID of the folder of this file" + ja-JP: "フォルダID" + en-US: "The ID of the folder of this file" folder: type: "entity(DriveFolder)" optional: true desc: - ja: "フォルダ" - en: "The folder of this file" + ja-JP: "フォルダ" + en-US: "The folder of this file" isSensitive: type: "boolean" optional: true desc: - ja: "このメディアが「閲覧注意」(NSFW)かどうか" - en: "Whether this media is NSFW" + ja-JP: "このメディアが「閲覧注意」(NSFW)かどうか" + en-US: "Whether this media is NSFW" diff --git a/src/docs/api/entities/drive-folder.yaml b/src/docs/api/entities/drive-folder.yaml index 0fb8308dd4..e3dfd2ca01 100644 --- a/src/docs/api/entities/drive-folder.yaml +++ b/src/docs/api/entities/drive-folder.yaml @@ -1,41 +1,41 @@ name: "DriveFolder" desc: - ja: "ドライブのフォルダを表します。" - en: "A folder of Drive." + ja-JP: "ドライブのフォルダを表します。" + en-US: "A folder of Drive." props: id: type: "id" optional: false desc: - ja: "フォルダID" - en: "The ID of this folder" + ja-JP: "フォルダID" + en-US: "The ID of this folder" createdAt: type: "date" optional: false desc: - ja: "作成日時" - en: "The created date of this folder" + ja-JP: "作成日時" + en-US: "The created date of this folder" userId: type: "id(User)" optional: false desc: - ja: "所有者ID" - en: "The ID of the owner of this folder" + ja-JP: "所有者ID" + en-US: "The ID of the owner of this folder" parentId: type: "entity(DriveFolder)" optional: false desc: - ja: "親フォルダのID (ルートなら null)" - en: "The ID of parent folder" + ja-JP: "親フォルダのID (ルートなら null)" + en-US: "The ID of parent folder" name: type: "string" optional: false desc: - ja: "フォルダ名" - en: "The name of this folder" + ja-JP: "フォルダ名" + en-US: "The name of this folder" diff --git a/src/docs/api/entities/note.yaml b/src/docs/api/entities/note.yaml index 04cb3c9824..cae9a53f82 100644 --- a/src/docs/api/entities/note.yaml +++ b/src/docs/api/entities/note.yaml @@ -1,190 +1,190 @@ name: "Note" desc: - ja: "投稿。" - en: "A note." + ja-JP: "投稿。" + en-US: "A note." props: id: type: "id" optional: false desc: - ja: "投稿ID" - en: "The ID of this note" + ja-JP: "投稿ID" + en-US: "The ID of this note" createdAt: type: "date" optional: false desc: - ja: "投稿日時" - en: "The posted date of this note" + ja-JP: "投稿日時" + en-US: "The posted date of this note" viaMobile: type: "boolean" optional: true desc: - ja: "モバイル端末から投稿したか否か(自己申告であることに留意)" - en: "Whether this note sent via a mobile device" + ja-JP: "モバイル端末から投稿したか否か(自己申告であることに留意)" + en-US: "Whether this note sent via a mobile device" text: type: "string" optional: true desc: - ja: "投稿の本文" - en: "The text of this note" + ja-JP: "投稿の本文" + en-US: "The text of this note" mediaIds: type: "id(DriveFile)[]" optional: true desc: - ja: "添付されているメディアのID (なければレスポンスでは空配列)" - en: "The IDs of the attached media (empty array for response if no media is attached)" + ja-JP: "添付されているメディアのID (なければレスポンスでは空配列)" + en-US: "The IDs of the attached media (empty array for response if no media is attached)" media: type: "entity(DriveFile)[]" optional: true desc: - ja: "添付されているメディア" - en: "The attached media" + ja-JP: "添付されているメディア" + en-US: "The attached media" userId: type: "id(User)" optional: false desc: - ja: "投稿者ID" - en: "The ID of author of this note" + ja-JP: "投稿者ID" + en-US: "The ID of author of this note" user: type: "entity(User)" optional: true desc: - ja: "投稿者" - en: "The author of this note" + ja-JP: "投稿者" + en-US: "The author of this note" myReaction: type: "string" optional: true desc: - ja: "この投稿に対する自分のリアクション" - en: "The your reaction of this note" + ja-JP: "この投稿に対する自分のリアクション" + en-US: "The your reaction of this note" reactionCounts: type: "object" optional: false desc: - ja: "リアクションをキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト" + ja-JP: "リアクションをキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト" replyId: type: "id(Note)" optional: true desc: - ja: "返信した投稿のID" - en: "The ID of the replyed note" + ja-JP: "返信した投稿のID" + en-US: "The ID of the replyed note" reply: type: "entity(Note)" optional: true desc: - ja: "返信した投稿" - en: "The replyed note" + ja-JP: "返信した投稿" + en-US: "The replyed note" renoteId: type: "id(Note)" optional: true desc: - ja: "引用した投稿のID" - en: "The ID of the quoted note" + ja-JP: "引用した投稿のID" + en-US: "The ID of the quoted note" renote: type: "entity(Note)" optional: true desc: - ja: "引用した投稿" - en: "The quoted note" + ja-JP: "引用した投稿" + en-US: "The quoted note" poll: type: "object" optional: true desc: - ja: "投票" - en: "The poll" + ja-JP: "投票" + en-US: "The poll" props: choices: type: "object[]" optional: false desc: - ja: "投票の選択肢" - en: "The choices of this poll" + ja-JP: "投票の選択肢" + en-US: "The choices of this poll" props: id: type: "number" optional: false desc: - ja: "選択肢ID" - en: "The ID of this choice" + ja-JP: "選択肢ID" + en-US: "The ID of this choice" isVoted: type: "boolean" optional: true desc: - ja: "自分がこの選択肢に投票したかどうか" - en: "Whether you voted to this choice" + ja-JP: "自分がこの選択肢に投票したかどうか" + en-US: "Whether you voted to this choice" text: type: "string" optional: false desc: - ja: "選択肢本文" - en: "The text of this choice" + ja-JP: "選択肢本文" + en-US: "The text of this choice" votes: type: "number" optional: false desc: - ja: "この選択肢に投票された数" - en: "The number voted for this choice" + ja-JP: "この選択肢に投票された数" + en-US: "The number voted for this choice" geo: type: "object" optional: true desc: - ja: "位置情報" - en: "Geo location" + ja-JP: "位置情報" + en-US: "Geo location" props: coordinates: type: "number[]" optional: false desc: - ja: "座標。最初に経度:-180〜180で表す。最後に緯度:-90〜90で表す。" + ja-JP: "座標。最初に経度:-180〜180で表す。最後に緯度:-90〜90で表す。" altitude: type: "number" optional: false desc: - ja: "高度。メートル単位で表す。" + ja-JP: "高度。メートル単位で表す。" accuracy: type: "number" optional: false desc: - ja: "緯度、経度の精度。メートル単位で表す。" + ja-JP: "緯度、経度の精度。メートル単位で表す。" altitudeAccuracy: type: "number" optional: false desc: - ja: "高度の精度。メートル単位で表す。" + ja-JP: "高度の精度。メートル単位で表す。" heading: type: "number" optional: false desc: - ja: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。" + ja-JP: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。" speed: type: "number" optional: false desc: - ja: "速度。メートル / 秒数で表す。" + ja-JP: "速度。メートル / 秒数で表す。" diff --git a/src/docs/api/entities/user.yaml b/src/docs/api/entities/user.yaml index c245974568..c90b55ee88 100644 --- a/src/docs/api/entities/user.yaml +++ b/src/docs/api/entities/user.yaml @@ -1,174 +1,174 @@ name: "User" desc: - ja: "ユーザー。" - en: "A user." + ja-JP: "ユーザー。" + en-US: "A user." props: id: type: "id" optional: false desc: - ja: "ユーザーID" - en: "The ID of this user" + ja-JP: "ユーザーID" + en-US: "The ID of this user" createdAt: type: "date" optional: false desc: - ja: "アカウント作成日時" - en: "The registered date of this user" + ja-JP: "アカウント作成日時" + en-US: "The registered date of this user" username: type: "string" optional: false desc: - ja: "ユーザー名" - en: "The username of this user" + ja-JP: "ユーザー名" + en-US: "The username of this user" description: type: "string" optional: false desc: - ja: "アカウントの説明(自己紹介)" - en: "The description of this user" + ja-JP: "アカウントの説明(自己紹介)" + en-US: "The description of this user" avatarId: type: "id(DriveFile)" optional: true desc: - ja: "アバターのID" - en: "The ID of the avatar of this user" + ja-JP: "アバターのID" + en-US: "The ID of the avatar of this user" avatarUrl: type: "string" optional: false desc: - ja: "アバターのURL" - en: "The URL of the avatar of this user" + ja-JP: "アバターのURL" + en-US: "The URL of the avatar of this user" bannerId: type: "id(DriveFile)" optional: true desc: - ja: "バナーのID" - en: "The ID of the banner of this user" + ja-JP: "バナーのID" + en-US: "The ID of the banner of this user" bannerUrl: type: "string" optional: false desc: - ja: "バナーのURL" - en: "The URL of the banner of this user" + ja-JP: "バナーのURL" + en-US: "The URL of the banner of this user" followersCount: type: "number" optional: false desc: - ja: "フォロワーの数" - en: "The number of the followers for this user" + ja-JP: "フォロワーの数" + en-US: "The number of the followers for this user" followingCount: type: "number" optional: false desc: - ja: "フォローしているユーザーの数" - en: "The number of the following users for this user" + ja-JP: "フォローしているユーザーの数" + en-US: "The number of the following users for this user" isFollowing: type: "boolean" optional: true desc: - ja: "自分がこのユーザーをフォローしているか" + ja-JP: "自分がこのユーザーをフォローしているか" isFollowed: type: "boolean" optional: true desc: - ja: "自分がこのユーザーにフォローされているか" + ja-JP: "自分がこのユーザーにフォローされているか" isMuted: type: "boolean" optional: true desc: - ja: "自分がこのユーザーをミュートしているか" - en: "Whether you muted this user" + ja-JP: "自分がこのユーザーをミュートしているか" + en-US: "Whether you muted this user" notesCount: type: "number" optional: false desc: - ja: "投稿の数" - en: "The number of the notes of this user" + ja-JP: "投稿の数" + en-US: "The number of the notes of this user" pinnedNote: type: "entity(Note)" optional: true desc: - ja: "ピン留めされた投稿" - en: "The pinned note of this user" + ja-JP: "ピン留めされた投稿" + en-US: "The pinned note of this user" pinnedNoteId: type: "id(Note)" optional: true desc: - ja: "ピン留めされた投稿のID" - en: "The ID of the pinned note of this user" + ja-JP: "ピン留めされた投稿のID" + en-US: "The ID of the pinned note of this user" host: type: "string | null" optional: false desc: - ja: "ホスト (例: example.com:3000)" - en: "Host (e.g. example.com:3000)" + ja-JP: "ホスト (例: example.com:3000)" + en-US: "Host (e.g. example.com:3000)" twitter: type: "object" optional: true desc: - ja: "連携されているTwitterアカウント情報" - en: "The info of the connected twitter account of this user" + ja-JP: "連携されているTwitterアカウント情報" + en-US: "The info of the connected twitter account of this user" props: userId: type: "string" optional: false desc: - ja: "ユーザーID" - en: "The user ID" + ja-JP: "ユーザーID" + en-US: "The user ID" screenName: type: "string" optional: false desc: - ja: "ユーザー名" - en: "The screen name of this user" + ja-JP: "ユーザー名" + en-US: "The screen name of this user" isBot: type: "boolean" optional: true desc: - ja: "botか否か(自己申告であることに留意)" - en: "Whether is bot or not" + ja-JP: "botか否か(自己申告であることに留意)" + en-US: "Whether is bot or not" profile: type: "object" optional: false desc: - ja: "プロフィール" - en: "The profile of this user" + ja-JP: "プロフィール" + en-US: "The profile of this user" props: location: type: "string" optional: true desc: - ja: "場所" - en: "The location of this user" + ja-JP: "場所" + en-US: "The location of this user" birthday: type: "string" optional: true desc: - ja: "誕生日 (YYYY-MM-DD)" - en: "The birthday of this user (YYYY-MM-DD)" + ja-JP: "誕生日 (YYYY-MM-DD)" + en-US: "The birthday of this user (YYYY-MM-DD)" diff --git a/src/docs/api/entities/view.pug b/src/docs/api/entities/view.pug index d5c192f438..1f166d053c 100644 --- a/src/docs/api/entities/view.pug +++ b/src/docs/api/entities/view.pug @@ -7,7 +7,7 @@ block meta block main h1= name - p#desc= desc[lang] || desc['ja'] + p#desc= desc[lang] || desc['ja-JP'] section h2= i18n('docs.api.entities.properties') diff --git a/src/docs/api/mixins.pug b/src/docs/api/mixins.pug index 925aab2934..563739d52b 100644 --- a/src/docs/api/mixins.pug +++ b/src/docs/api/mixins.pug @@ -31,4 +31,4 @@ mixin propTable(props) td.name= prop.name td.type +type(prop) - td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja'] : null + td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja-JP'] : null diff --git a/src/docs/base.pug b/src/docs/base.pug index aeafaeffff..26f19ddf09 100644 --- a/src/docs/base.pug +++ b/src/docs/base.pug @@ -16,7 +16,7 @@ html(lang= lang) nav ul each doc in docs - li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja'] + li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja-JP'] section h2 API ul diff --git a/src/docs/follow.ja-JP.md b/src/docs/follow.ja-JP.md new file mode 100644 index 0000000000..a883435ab4 --- /dev/null +++ b/src/docs/follow.ja-JP.md @@ -0,0 +1,8 @@ +# フォロー +ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 +ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 + +## ストーキング +ユーザーをフォローしている状態では、さらに「ストーキング」モードをオンにすることができます。ストーキングを行うと、タイムラインにそのユーザーの全ての投稿が表示されるようになります。つまり、他のユーザーに対する返信も含まれることになります。 +ストーキングするには、ユーザーページの「ストークする」をクリックします。ストーキングをやめるには、もう一度クリックします。 +ストーキングしていることは相手に通知されません。 diff --git a/src/docs/follow.ja.md b/src/docs/follow.ja.md deleted file mode 100644 index a883435ab4..0000000000 --- a/src/docs/follow.ja.md +++ /dev/null @@ -1,8 +0,0 @@ -# フォロー -ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 -ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 - -## ストーキング -ユーザーをフォローしている状態では、さらに「ストーキング」モードをオンにすることができます。ストーキングを行うと、タイムラインにそのユーザーの全ての投稿が表示されるようになります。つまり、他のユーザーに対する返信も含まれることになります。 -ストーキングするには、ユーザーページの「ストークする」をクリックします。ストーキングをやめるには、もう一度クリックします。 -ストーキングしていることは相手に通知されません。 diff --git a/src/docs/mute.ja-JP.md b/src/docs/mute.ja-JP.md new file mode 100644 index 0000000000..6a9608662a --- /dev/null +++ b/src/docs/mute.ja-JP.md @@ -0,0 +1,13 @@ +# ミュート + +ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: + +* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) +* そのユーザーからの通知 +* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 + +ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 + +ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 + +設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/mute.ja.md b/src/docs/mute.ja.md deleted file mode 100644 index 6a9608662a..0000000000 --- a/src/docs/mute.ja.md +++ /dev/null @@ -1,13 +0,0 @@ -# ミュート - -ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります: - -* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote) -* そのユーザーからの通知 -* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴 - -ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。 - -ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。 - -設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。 diff --git a/src/docs/reversi-bot.ja-JP.md b/src/docs/reversi-bot.ja-JP.md new file mode 100644 index 0000000000..98b543ca6c --- /dev/null +++ b/src/docs/reversi-bot.ja-JP.md @@ -0,0 +1,177 @@ +# MisskeyリバーシBotの開発 +Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 + +1. `games/reversi`ストリームに以下のパラメータを付けて接続する: + * `i`: botアカウントのAPIキー + +2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる + * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている + +3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する + +4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: + * `i`: botアカウントのAPIキー + * `game`: `game`の`id` + +5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う + +6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する + +7. ゲームが開始すると、`started`イベントが流れてくる + * イベントの中身にはゲーム情報が含まれている + +8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) + +9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる + * `color`として石の色が含まれている + * `pos`として位置情報が含まれている + +## 位置の計算法 +8x8のマップを考える場合、各マスの位置(Posと呼びます)は次のようになっています: +``` ++--+--+--+--+--+--+--+--+ +| 0| 1| 2| 3| 4| 5| 6| 7| ++--+--+--+--+--+--+--+--+ +| 8| 9|10|11|12|13|14|15| ++--+--+--+--+--+--+--+--+ +|16|17|18|19|20|21|22|23| +... +``` + +### X,Y座標 から Pos に変換する +``` +pos = x + (y * mapWidth) +``` +`mapWidth`は、ゲーム情報の`settings.map`から、次のようにして計算できます: +``` +mapWidth = settings.map[0].length +``` + +### Pos から X,Y座標 に変換する +``` +x = pos % mapWidth +y = Math.floor(pos / mapWidth) +``` + +## マップ情報 +マップ情報は、ゲーム情報の`settings.map`に入っています。 +文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 +それをもとにマップのデザインを知る事が出来ます: +* `(スペース)` ... マス無し +* `-` ... マス +* `b` ... 初期配置される黒石 +* `w` ... 初期配置される白石 + +例えば、4*4の次のような単純なマップがあるとします: +```text ++---+---+---+---+ +| | | | | ++---+---+---+---+ +| | ○ | ● | | ++---+---+---+---+ +| | ● | ○ | | ++---+---+---+---+ +| | | | | ++---+---+---+---+ +``` + +この場合、マップデータはこのようになります: +```javascript +['----', '-wb-', '-bw-', '----'] +``` + +## ユーザーにフォームを提示して対話可能Botを作成する +ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 +例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 + +フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: +```javascript +{ + type: 'init-form', + body: [フォームコントロールの配列] +} +``` + +フォームコントロールの配列については今から説明します。 +フォームコントロールは、次のようなオブジェクトです: +```javascript +{ + id: 'switch1', + type: 'switch', + label: 'Enable hoge', + value: false +} +``` +`id` ... コントロールのID。 +`type` ... コントロールの種類。後述します。 +`label` ... コントロールと一緒に表記するテキスト。 +`value` ... コントロールのデフォルト値。 + +### フォームの操作を受け取る +ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 +イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 +例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: +```javascript +{ + id: 'switch1', + value: true +} +``` + +### フォームコントロールの種類 +#### スイッチ +type: `switch` +スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 + +##### プロパティ +`desc` ... スイッチの詳細な説明。 + +#### ラジオボタン +type: `radio` +ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 + +##### プロパティ +`items` ... ラジオボタンの選択肢。例: +```javascript +items: [{ + label: '弱', + value: 1 +}, { + label: '中', + value: 2 +}, { + label: '強', + value: 3 +}] +``` + +#### スライダー +type: `slider` +スライダーを表示します。 + +##### プロパティ +`min` ... スライダーの下限。 +`max` ... スライダーの上限。 +`step` ... 入力欄で刻むステップ値。 + +#### テキストボックス +type: `textbox` +テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 + +## ユーザーにメッセージを表示する +設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 +例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 +メッセージを表示するには、次のメッセージをストリームに送信します: +```javascript +{ + type: 'message', + body: { + text: 'メッセージ内容', + type: 'メッセージの種類' + } +} +``` +メッセージの種類: `success`, `info`, `warning`, `error`。 + +## 投了する +投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/reversi-bot.ja.md b/src/docs/reversi-bot.ja.md deleted file mode 100644 index 98b543ca6c..0000000000 --- a/src/docs/reversi-bot.ja.md +++ /dev/null @@ -1,177 +0,0 @@ -# MisskeyリバーシBotの開発 -Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。 - -1. `games/reversi`ストリームに以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - -2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる - * イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている - -3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する - -4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する: - * `i`: botアカウントのAPIキー - * `game`: `game`の`id` - -5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う - -6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する - -7. ゲームが開始すると、`started`イベントが流れてくる - * イベントの中身にはゲーム情報が含まれている - -8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述) - -9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる - * `color`として石の色が含まれている - * `pos`として位置情報が含まれている - -## 位置の計算法 -8x8のマップを考える場合、各マスの位置(Posと呼びます)は次のようになっています: -``` -+--+--+--+--+--+--+--+--+ -| 0| 1| 2| 3| 4| 5| 6| 7| -+--+--+--+--+--+--+--+--+ -| 8| 9|10|11|12|13|14|15| -+--+--+--+--+--+--+--+--+ -|16|17|18|19|20|21|22|23| -... -``` - -### X,Y座標 から Pos に変換する -``` -pos = x + (y * mapWidth) -``` -`mapWidth`は、ゲーム情報の`settings.map`から、次のようにして計算できます: -``` -mapWidth = settings.map[0].length -``` - -### Pos から X,Y座標 に変換する -``` -x = pos % mapWidth -y = Math.floor(pos / mapWidth) -``` - -## マップ情報 -マップ情報は、ゲーム情報の`settings.map`に入っています。 -文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 -それをもとにマップのデザインを知る事が出来ます: -* `(スペース)` ... マス無し -* `-` ... マス -* `b` ... 初期配置される黒石 -* `w` ... 初期配置される白石 - -例えば、4*4の次のような単純なマップがあるとします: -```text -+---+---+---+---+ -| | | | | -+---+---+---+---+ -| | ○ | ● | | -+---+---+---+---+ -| | ● | ○ | | -+---+---+---+---+ -| | | | | -+---+---+---+---+ -``` - -この場合、マップデータはこのようになります: -```javascript -['----', '-wb-', '-bw-', '----'] -``` - -## ユーザーにフォームを提示して対話可能Botを作成する -ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 -例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。 - -フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します: -```javascript -{ - type: 'init-form', - body: [フォームコントロールの配列] -} -``` - -フォームコントロールの配列については今から説明します。 -フォームコントロールは、次のようなオブジェクトです: -```javascript -{ - id: 'switch1', - type: 'switch', - label: 'Enable hoge', - value: false -} -``` -`id` ... コントロールのID。 -`type` ... コントロールの種類。後述します。 -`label` ... コントロールと一緒に表記するテキスト。 -`value` ... コントロールのデフォルト値。 - -### フォームの操作を受け取る -ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 -イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 -例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます: -```javascript -{ - id: 'switch1', - value: true -} -``` - -### フォームコントロールの種類 -#### スイッチ -type: `switch` -スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。 - -##### プロパティ -`desc` ... スイッチの詳細な説明。 - -#### ラジオボタン -type: `radio` -ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。 - -##### プロパティ -`items` ... ラジオボタンの選択肢。例: -```javascript -items: [{ - label: '弱', - value: 1 -}, { - label: '中', - value: 2 -}, { - label: '強', - value: 3 -}] -``` - -#### スライダー -type: `slider` -スライダーを表示します。 - -##### プロパティ -`min` ... スライダーの下限。 -`max` ... スライダーの上限。 -`step` ... 入力欄で刻むステップ値。 - -#### テキストボックス -type: `textbox` -テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。 - -## ユーザーにメッセージを表示する -設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 -例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 -メッセージを表示するには、次のメッセージをストリームに送信します: -```javascript -{ - type: 'message', - body: { - text: 'メッセージ内容', - type: 'メッセージの種類' - } -} -``` -メッセージの種類: `success`, `info`, `warning`, `error`。 - -## 投了する -投了をするには、このエンドポイントにリクエストします。 diff --git a/src/docs/stream.ja-JP.md b/src/docs/stream.ja-JP.md new file mode 100644 index 0000000000..c720299932 --- /dev/null +++ b/src/docs/stream.ja-JP.md @@ -0,0 +1,183 @@ +# ストリーミングAPI + +ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、HTTPリクエストを発生させることなくAPIにアクセスしたりすることができます。 + +ストリーミングAPIは複数の種類がありますが、ここではメインとなる「ホームストリーム」について説明します。 + +## ストリームに接続する + +以下のURLに**websocket**接続します。 +``` +%URL% +``` + +接続する際は、`i`というパラメータ名で認証情報を含めます。例: +``` +%URL%/?i=xxxxxxxxxxxxxxx +``` + +認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 + +
+

認証情報の取得については、こちらのドキュメントをご確認ください。

+
+ + +## ストリームを経由してAPIリクエストする + +ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 + +ストリームを経由してAPIリクエストするには、次のようなメッセージをストリームに送信します: +```json +{ + type: 'api', + id: 'xxxxxxxxxxxxxxxx', + endpoint: 'notes/create', + data: { + text: 'yee haw!' + } +} +``` + +`id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 + +`endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 + +`data`には、エンドポイントのパラメータを含めます。 + +
+

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

+
+ +### レスポンスの受信 + +APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 + +```json +{ + type: 'api-res:xxxxxxxxxxxxxxxx', + body: { + ... + } +} +``` + +`xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 + +`body`には、レスポンスが含まれています。 + +## 投稿のキャプチャ + +Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 + +例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 + +しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 + +この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 + +### 投稿をキャプチャする + +投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: + +```json +{ + type: 'capture', + id: 'xxxxxxxxxxxxxxxx' +} +``` + +`id`には、キャプチャしたい投稿の`id`を設定します。 + +このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 + +例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: + +```json +{ + type: 'note-updated', + body: { + note: { + ... + } + } +} +``` + +`body`内の`note`には、その投稿の最新の情報が含まれています。 + +--- + +このように、投稿の情報が更新されると、`note-updated`イベントが流れてくるようになります。`note-updated`イベントが発生するのは、以下の場合です: + +- 投稿にリアクションが付いた +- 投稿に添付されたアンケートに投票がされた +- 投稿が削除された + +### 投稿のキャプチャを解除する + +その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 + +次のメッセージを送信します: + +```json +{ + type: 'decapture', + id: 'xxxxxxxxxxxxxxxx' +} +``` + +`id`には、キャプチャを解除したい投稿の`id`を設定します。 + +このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 + +## 流れてくるイベント一覧 + +流れてくるすべてのメッセージはJSON形式で、必ず`type`というプロパティが含まれています。これにより、メッセージの種類(イベント)を判別することができます。 + +### `note` + +タイムラインに新しい投稿が流れてきたときに発生するイベントです。 + +`body`プロパティの中に、投稿情報が含まれています。 + +### `renote` + +自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 + +`body`プロパティの中に、Renoteされた投稿情報が含まれています。 + +### `mention` + +誰かからメンションされたときに発生するイベントです。 + +`body`プロパティの中に、投稿情報が含まれています。 + +### `read_all_notifications` + +自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 + +### `meUpdated` + +自分の情報が更新されたことを表すイベントです。 + +`body`プロパティの中に、最新の自分のアカウントの情報が含まれています。 + +### `follow` + +自分が誰かをフォローしたときに発生するイベントです。 + +`body`プロパティの中に、フォローしたユーザーの情報が含まれています。 + +### `unfollow` + +自分が誰かのフォローを解除したときに発生するイベントです。 + +`body`プロパティの中に、フォロー解除したユーザーの情報が含まれています。 + +### `followed` + +自分が誰かにフォローされたときに発生するイベントです。 + +`body`プロパティの中に、フォローしてきたユーザーの情報が含まれています。 + diff --git a/src/docs/stream.ja.md b/src/docs/stream.ja.md deleted file mode 100644 index c720299932..0000000000 --- a/src/docs/stream.ja.md +++ /dev/null @@ -1,183 +0,0 @@ -# ストリーミングAPI - -ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、HTTPリクエストを発生させることなくAPIにアクセスしたりすることができます。 - -ストリーミングAPIは複数の種類がありますが、ここではメインとなる「ホームストリーム」について説明します。 - -## ストリームに接続する - -以下のURLに**websocket**接続します。 -``` -%URL% -``` - -接続する際は、`i`というパラメータ名で認証情報を含めます。例: -``` -%URL%/?i=xxxxxxxxxxxxxxx -``` - -認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。 - -
-

認証情報の取得については、こちらのドキュメントをご確認ください。

-
- - -## ストリームを経由してAPIリクエストする - -ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。 - -ストリームを経由してAPIリクエストするには、次のようなメッセージをストリームに送信します: -```json -{ - type: 'api', - id: 'xxxxxxxxxxxxxxxx', - endpoint: 'notes/create', - data: { - text: 'yee haw!' - } -} -``` - -`id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。 - -`endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。 - -`data`には、エンドポイントのパラメータを含めます。 - -
-

APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。

-
- -### レスポンスの受信 - -APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。 - -```json -{ - type: 'api-res:xxxxxxxxxxxxxxxx', - body: { - ... - } -} -``` - -`xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。 - -`body`には、レスポンスが含まれています。 - -## 投稿のキャプチャ - -Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。 - -例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。 - -しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。 - -この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。 - -### 投稿をキャプチャする - -投稿をキャプチャするには、ストリームに次のようなメッセージを送信します: - -```json -{ - type: 'capture', - id: 'xxxxxxxxxxxxxxxx' -} -``` - -`id`には、キャプチャしたい投稿の`id`を設定します。 - -このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。 - -例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます: - -```json -{ - type: 'note-updated', - body: { - note: { - ... - } - } -} -``` - -`body`内の`note`には、その投稿の最新の情報が含まれています。 - ---- - -このように、投稿の情報が更新されると、`note-updated`イベントが流れてくるようになります。`note-updated`イベントが発生するのは、以下の場合です: - -- 投稿にリアクションが付いた -- 投稿に添付されたアンケートに投票がされた -- 投稿が削除された - -### 投稿のキャプチャを解除する - -その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。 - -次のメッセージを送信します: - -```json -{ - type: 'decapture', - id: 'xxxxxxxxxxxxxxxx' -} -``` - -`id`には、キャプチャを解除したい投稿の`id`を設定します。 - -このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。 - -## 流れてくるイベント一覧 - -流れてくるすべてのメッセージはJSON形式で、必ず`type`というプロパティが含まれています。これにより、メッセージの種類(イベント)を判別することができます。 - -### `note` - -タイムラインに新しい投稿が流れてきたときに発生するイベントです。 - -`body`プロパティの中に、投稿情報が含まれています。 - -### `renote` - -自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。 - -`body`プロパティの中に、Renoteされた投稿情報が含まれています。 - -### `mention` - -誰かからメンションされたときに発生するイベントです。 - -`body`プロパティの中に、投稿情報が含まれています。 - -### `read_all_notifications` - -自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。 - -### `meUpdated` - -自分の情報が更新されたことを表すイベントです。 - -`body`プロパティの中に、最新の自分のアカウントの情報が含まれています。 - -### `follow` - -自分が誰かをフォローしたときに発生するイベントです。 - -`body`プロパティの中に、フォローしたユーザーの情報が含まれています。 - -### `unfollow` - -自分が誰かのフォローを解除したときに発生するイベントです。 - -`body`プロパティの中に、フォロー解除したユーザーの情報が含まれています。 - -### `followed` - -自分が誰かにフォローされたときに発生するイベントです。 - -`body`プロパティの中に、フォローしてきたユーザーの情報が含まれています。 - diff --git a/src/docs/timelines.ja-JP.md b/src/docs/timelines.ja-JP.md new file mode 100644 index 0000000000..36ba61bd2d --- /dev/null +++ b/src/docs/timelines.ja-JP.md @@ -0,0 +1,15 @@ +# タイムラインの比較 + +https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing + +## ホーム +自分のフォローしているユーザーの投稿 + +## ローカル +全てのローカルユーザーの「ホーム」指定されていない投稿 + +## ソーシャル +自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 + +## グローバル +全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/docs/timelines.ja.md b/src/docs/timelines.ja.md deleted file mode 100644 index 36ba61bd2d..0000000000 --- a/src/docs/timelines.ja.md +++ /dev/null @@ -1,15 +0,0 @@ -# タイムラインの比較 - -https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing - -## ホーム -自分のフォローしているユーザーの投稿 - -## ローカル -全てのローカルユーザーの「ホーム」指定されていない投稿 - -## ソーシャル -自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿 - -## グローバル -全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿 diff --git a/src/server/api/endpoints/admin/invite.ts b/src/server/api/endpoints/admin/invite.ts index 77608e715c..892b2579f2 100644 --- a/src/server/api/endpoints/admin/invite.ts +++ b/src/server/api/endpoints/admin/invite.ts @@ -3,7 +3,7 @@ import RegistrationTicket from '../../../../models/registration-tickets'; export const meta = { desc: { - ja: '招待コードを発行します。' + 'ja-JP': '招待コードを発行します。' }, requireCredential: true, diff --git a/src/server/api/endpoints/admin/suspend-user.ts b/src/server/api/endpoints/admin/suspend-user.ts index 9b492c6e15..32c2416fb5 100644 --- a/src/server/api/endpoints/admin/suspend-user.ts +++ b/src/server/api/endpoints/admin/suspend-user.ts @@ -5,8 +5,8 @@ import User from '../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーを凍結します。', - en: 'Suspend a user.' + 'ja-JP': '指定したユーザーを凍結します。', + 'en-US': 'Suspend a user.' }, requireCredential: true, @@ -15,8 +15,8 @@ export const meta = { params: { userId: $.type(ID).note({ desc: { - ja: '対象のユーザーID', - en: 'The user ID which you want to suspend' + 'ja-JP': '対象のユーザーID', + 'en-US': 'The user ID which you want to suspend' } }), } diff --git a/src/server/api/endpoints/admin/unsuspend-user.ts b/src/server/api/endpoints/admin/unsuspend-user.ts index 8409bd1b76..879c23ab14 100644 --- a/src/server/api/endpoints/admin/unsuspend-user.ts +++ b/src/server/api/endpoints/admin/unsuspend-user.ts @@ -5,8 +5,8 @@ import User from '../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーの凍結を解除します。', - en: 'Unsuspend a user.' + 'ja-JP': '指定したユーザーの凍結を解除します。', + 'en-US': 'Unsuspend a user.' }, requireCredential: true, @@ -15,8 +15,8 @@ export const meta = { params: { userId: $.type(ID).note({ desc: { - ja: '対象のユーザーID', - en: 'The user ID which you want to unsuspend' + 'ja-JP': '対象のユーザーID', + 'en-US': 'The user ID which you want to unsuspend' } }), } diff --git a/src/server/api/endpoints/admin/unverify-user.ts b/src/server/api/endpoints/admin/unverify-user.ts index 34653cd78a..178049fa1d 100644 --- a/src/server/api/endpoints/admin/unverify-user.ts +++ b/src/server/api/endpoints/admin/unverify-user.ts @@ -5,8 +5,8 @@ import User from '../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーの公式アカウントを解除します。', - en: 'Mark a user as unverified.' + 'ja-JP': '指定したユーザーの公式アカウントを解除します。', + 'en-US': 'Mark a user as unverified.' }, requireCredential: true, @@ -15,8 +15,8 @@ export const meta = { params: { userId: $.type(ID).note({ desc: { - ja: '対象のユーザーID', - en: 'The user ID which you want to unverify' + 'ja-JP': '対象のユーザーID', + 'en-US': 'The user ID which you want to unverify' } }), } diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index bfcab9d6a6..2c7929fabe 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -4,7 +4,7 @@ import getParams from '../../get-params'; export const meta = { desc: { - ja: 'インスタンスの設定を更新します。' + 'ja-JP': 'インスタンスの設定を更新します。' }, requireCredential: true, @@ -13,7 +13,7 @@ export const meta = { params: { disableRegistration: $.bool.optional.nullable.note({ desc: { - ja: '招待制か否か' + 'ja-JP': '招待制か否か' } }), } diff --git a/src/server/api/endpoints/admin/verify-user.ts b/src/server/api/endpoints/admin/verify-user.ts index 5b826eb1c3..dd07684ded 100644 --- a/src/server/api/endpoints/admin/verify-user.ts +++ b/src/server/api/endpoints/admin/verify-user.ts @@ -5,8 +5,8 @@ import User from '../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーを公式アカウントにします。', - en: 'Mark a user as verified.' + 'ja-JP': '指定したユーザーを公式アカウントにします。', + 'en-US': 'Mark a user as verified.' }, requireCredential: true, @@ -15,8 +15,8 @@ export const meta = { params: { userId: $.type(ID).note({ desc: { - ja: '対象のユーザーID', - en: 'The user ID which you want to verify' + 'ja-JP': '対象のユーザーID', + 'en-US': 'The user ID which you want to verify' } }), } diff --git a/src/server/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts index 8ad961494f..063cd475d4 100644 --- a/src/server/api/endpoints/drive.ts +++ b/src/server/api/endpoints/drive.ts @@ -4,8 +4,8 @@ import config from '../../../config'; export const meta = { desc: { - ja: 'ドライブの情報を取得します。', - en: 'Get drive information.' + 'ja-JP': 'ドライブの情報を取得します。', + 'en-US': 'Get drive information.' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts index 063b4adde1..dc6a602e10 100644 --- a/src/server/api/endpoints/drive/files.ts +++ b/src/server/api/endpoints/drive/files.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: 'ドライブのファイル一覧を取得します。', - en: 'Get files of drive.' + 'ja-JP': 'ドライブのファイル一覧を取得します。', + 'en-US': 'Get files of drive.' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts index 41b7e04b46..dfbd11d0c2 100644 --- a/src/server/api/endpoints/drive/files/create.ts +++ b/src/server/api/endpoints/drive/files/create.ts @@ -8,8 +8,8 @@ import getParams from '../../../get-params'; export const meta = { desc: { - ja: 'ドライブにファイルをアップロードします。', - en: 'Upload a file to drive.' + 'ja-JP': 'ドライブにファイルをアップロードします。', + 'en-US': 'Upload a file to drive.' }, requireCredential: true, @@ -27,15 +27,15 @@ export const meta = { folderId: $.type(ID).optional.nullable.note({ default: null, desc: { - ja: 'フォルダID' + 'ja-JP': 'フォルダID' } }), isSensitive: $.bool.optional.note({ default: false, desc: { - ja: 'このメディアが「閲覧注意」(NSFW)かどうか', - en: 'Whether this media is NSFW' + 'ja-JP': 'このメディアが「閲覧注意」(NSFW)かどうか', + 'en-US': 'Whether this media is NSFW' } }) } diff --git a/src/server/api/endpoints/drive/files/delete.ts b/src/server/api/endpoints/drive/files/delete.ts index 02cd96dd8f..fb7340df38 100644 --- a/src/server/api/endpoints/drive/files/delete.ts +++ b/src/server/api/endpoints/drive/files/delete.ts @@ -6,8 +6,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: 'ドライブのファイルを削除します。', - en: 'Delete a file of drive.' + 'ja-JP': 'ドライブのファイルを削除します。', + 'en-US': 'Delete a file of drive.' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts index 6a66c7a272..718fb8c2d7 100644 --- a/src/server/api/endpoints/drive/files/show.ts +++ b/src/server/api/endpoints/drive/files/show.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定したドライブのファイルの情報を取得します。', - en: 'Get specified file of drive.' + 'ja-JP': '指定したドライブのファイルの情報を取得します。', + 'en-US': 'Get specified file of drive.' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts index 9ae2719aa7..ba9abfec61 100644 --- a/src/server/api/endpoints/drive/files/update.ts +++ b/src/server/api/endpoints/drive/files/update.ts @@ -7,8 +7,8 @@ import getParams from '../../../get-params'; export const meta = { desc: { - ja: '指定したドライブのファイルの情報を更新します。', - en: 'Update specified file of drive.' + 'ja-JP': '指定したドライブのファイルの情報を更新します。', + 'en-US': 'Update specified file of drive.' }, requireCredential: true, @@ -18,30 +18,30 @@ export const meta = { params: { fileId: $.type(ID).note({ desc: { - ja: '対象のファイルID' + 'ja-JP': '対象のファイルID' } }), folderId: $.type(ID).optional.nullable.note({ default: undefined, desc: { - ja: 'フォルダID' + 'ja-JP': 'フォルダID' } }), name: $.str.optional.pipe(validateFileName).note({ default: undefined, desc: { - ja: 'ファイル名', - en: 'Name of the file' + 'ja-JP': 'ファイル名', + 'en-US': 'Name of the file' } }), isSensitive: $.bool.optional.note({ default: undefined, desc: { - ja: 'このメディアが「閲覧注意」(NSFW)かどうか', - en: 'Whether this media is NSFW' + 'ja-JP': 'このメディアが「閲覧注意」(NSFW)かどうか', + 'en-US': 'Whether this media is NSFW' } }) } diff --git a/src/server/api/endpoints/drive/files/upload_from_url.ts b/src/server/api/endpoints/drive/files/upload_from_url.ts index d634cf46db..783646feb3 100644 --- a/src/server/api/endpoints/drive/files/upload_from_url.ts +++ b/src/server/api/endpoints/drive/files/upload_from_url.ts @@ -6,7 +6,7 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: 'ドライブに指定されたURLに存在するファイルをアップロードします。' + 'ja-JP': 'ドライブに指定されたURLに存在するファイルをアップロードします。' }, limit: { diff --git a/src/server/api/endpoints/drive/folders.ts b/src/server/api/endpoints/drive/folders.ts index de398eb720..19c2ef7aca 100644 --- a/src/server/api/endpoints/drive/folders.ts +++ b/src/server/api/endpoints/drive/folders.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: 'ドライブのフォルダ一覧を取得します。', - en: 'Get folders of drive.' + 'ja-JP': 'ドライブのフォルダ一覧を取得します。', + 'en-US': 'Get folders of drive.' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/folders/create.ts b/src/server/api/endpoints/drive/folders/create.ts index 03f9504774..5997dedf0f 100644 --- a/src/server/api/endpoints/drive/folders/create.ts +++ b/src/server/api/endpoints/drive/folders/create.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: 'ドライブのフォルダを作成します。', - en: 'Create a folder of drive.' + 'ja-JP': 'ドライブのフォルダを作成します。', + 'en-US': 'Create a folder of drive.' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/folders/show.ts b/src/server/api/endpoints/drive/folders/show.ts index 6a6c879a01..bb25bcba3c 100644 --- a/src/server/api/endpoints/drive/folders/show.ts +++ b/src/server/api/endpoints/drive/folders/show.ts @@ -4,7 +4,7 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定したドライブのフォルダの情報を取得します。' + 'ja-JP': '指定したドライブのフォルダの情報を取得します。' }, requireCredential: true, diff --git a/src/server/api/endpoints/drive/folders/update.ts b/src/server/api/endpoints/drive/folders/update.ts index 1b449428a6..259f373bfc 100644 --- a/src/server/api/endpoints/drive/folders/update.ts +++ b/src/server/api/endpoints/drive/folders/update.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定したドライブのフォルダの情報を更新します。', - en: 'Update specified folder of drive.' + 'ja-JP': '指定したドライブのフォルダの情報を更新します。', + 'en-US': 'Update specified folder of drive.' }, requireCredential: true, diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts index ebe319e0cf..c9bea0e3d2 100644 --- a/src/server/api/endpoints/following/create.ts +++ b/src/server/api/endpoints/following/create.ts @@ -6,8 +6,8 @@ import create from '../../../../services/following/create'; export const meta = { desc: { - ja: '指定したユーザーをフォローします。', - en: 'Follow a user.' + 'ja-JP': '指定したユーザーをフォローします。', + 'en-US': 'Follow a user.' }, limit: { diff --git a/src/server/api/endpoints/following/delete.ts b/src/server/api/endpoints/following/delete.ts index 4806fe4e39..f3b4a73ae8 100644 --- a/src/server/api/endpoints/following/delete.ts +++ b/src/server/api/endpoints/following/delete.ts @@ -6,8 +6,8 @@ import deleteFollowing from '../../../../services/following/delete'; export const meta = { desc: { - ja: '指定したユーザーのフォローを解除します。', - en: 'Unfollow a user.' + 'ja-JP': '指定したユーザーのフォローを解除します。', + 'en-US': 'Unfollow a user.' }, limit: { diff --git a/src/server/api/endpoints/following/requests/accept.ts b/src/server/api/endpoints/following/requests/accept.ts index b3bf2dd667..f6a7dcf120 100644 --- a/src/server/api/endpoints/following/requests/accept.ts +++ b/src/server/api/endpoints/following/requests/accept.ts @@ -4,8 +4,8 @@ import User, { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '自分に届いた、指定したフォローリクエストを承認します。', - en: 'Accept a follow request.' + 'ja-JP': '自分に届いた、指定したフォローリクエストを承認します。', + 'en-US': 'Accept a follow request.' }, requireCredential: true, diff --git a/src/server/api/endpoints/following/requests/cancel.ts b/src/server/api/endpoints/following/requests/cancel.ts index c46b948d29..3da4f4734f 100644 --- a/src/server/api/endpoints/following/requests/cancel.ts +++ b/src/server/api/endpoints/following/requests/cancel.ts @@ -4,8 +4,8 @@ import User, { pack, ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '自分が作成した、指定したフォローリクエストをキャンセルします。', - en: 'Cancel a follow request.' + 'ja-JP': '自分が作成した、指定したフォローリクエストをキャンセルします。', + 'en-US': 'Cancel a follow request.' }, requireCredential: true, diff --git a/src/server/api/endpoints/following/requests/list.ts b/src/server/api/endpoints/following/requests/list.ts index b06a158c08..11a387cf16 100644 --- a/src/server/api/endpoints/following/requests/list.ts +++ b/src/server/api/endpoints/following/requests/list.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '自分に届いたフォローリクエストの一覧を取得します。', - en: 'Get all pending received follow requests.' + 'ja-JP': '自分に届いたフォローリクエストの一覧を取得します。', + 'en-US': 'Get all pending received follow requests.' }, requireCredential: true, diff --git a/src/server/api/endpoints/following/requests/reject.ts b/src/server/api/endpoints/following/requests/reject.ts index a232549bb8..98febe9e9f 100644 --- a/src/server/api/endpoints/following/requests/reject.ts +++ b/src/server/api/endpoints/following/requests/reject.ts @@ -4,8 +4,8 @@ import User, { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '自分に届いた、指定したフォローリクエストを拒否します。', - en: 'Reject a follow request.' + 'ja-JP': '自分に届いた、指定したフォローリクエストを拒否します。', + 'en-US': 'Reject a follow request.' }, requireCredential: true, diff --git a/src/server/api/endpoints/following/stalk.ts b/src/server/api/endpoints/following/stalk.ts index 79a3fb976c..d44cea2cc4 100644 --- a/src/server/api/endpoints/following/stalk.ts +++ b/src/server/api/endpoints/following/stalk.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーをストーキングします。', - en: 'Stalk a user.' + 'ja-JP': '指定したユーザーをストーキングします。', + 'en-US': 'Stalk a user.' }, requireCredential: true, diff --git a/src/server/api/endpoints/following/unstalk.ts b/src/server/api/endpoints/following/unstalk.ts index 71a7a97eeb..8b66f0727e 100644 --- a/src/server/api/endpoints/following/unstalk.ts +++ b/src/server/api/endpoints/following/unstalk.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーのストーキングをやめます。', - en: 'Unstalk a user.' + 'ja-JP': '指定したユーザーのストーキングをやめます。', + 'en-US': 'Unstalk a user.' }, requireCredential: true, diff --git a/src/server/api/endpoints/games/reversi/games/surrender.ts b/src/server/api/endpoints/games/reversi/games/surrender.ts index 49821650ed..8ca0143674 100644 --- a/src/server/api/endpoints/games/reversi/games/surrender.ts +++ b/src/server/api/endpoints/games/reversi/games/surrender.ts @@ -6,7 +6,7 @@ import { publishReversiGameStream } from '../../../../../../stream'; export const meta = { desc: { - ja: '指定したリバーシの対局で投了します。' + 'ja-JP': '指定したリバーシの対局で投了します。' }, requireCredential: true, @@ -14,7 +14,7 @@ export const meta = { params: { gameId: $.type(ID).note({ desc: { - ja: '投了したい対局' + 'ja-JP': '投了したい対局' } }) } diff --git a/src/server/api/endpoints/hashtags/search.ts b/src/server/api/endpoints/hashtags/search.ts index 262370cacc..f6fb35b2ff 100644 --- a/src/server/api/endpoints/hashtags/search.ts +++ b/src/server/api/endpoints/hashtags/search.ts @@ -5,7 +5,7 @@ const escapeRegexp = require('escape-regexp'); export const meta = { desc: { - ja: 'ハッシュタグを検索します。' + 'ja-JP': 'ハッシュタグを検索します。' }, requireCredential: false, @@ -14,20 +14,20 @@ export const meta = { limit: $.num.optional.range(1, 100).note({ default: 10, desc: { - ja: '最大数' + 'ja-JP': '最大数' } }), query: $.str.note({ desc: { - ja: 'クエリ' + 'ja-JP': 'クエリ' } }), offset: $.num.optional.min(0).note({ default: 0, desc: { - ja: 'オフセット' + 'ja-JP': 'オフセット' } }) } diff --git a/src/server/api/endpoints/i.ts b/src/server/api/endpoints/i.ts index 7f25c07957..1f99ef2d8d 100644 --- a/src/server/api/endpoints/i.ts +++ b/src/server/api/endpoints/i.ts @@ -3,7 +3,7 @@ import { IApp } from '../../../models/app'; export const meta = { desc: { - ja: '自分のアカウント情報を取得します。' + 'ja-JP': '自分のアカウント情報を取得します。' }, requireCredential: true, diff --git a/src/server/api/endpoints/i/favorites.ts b/src/server/api/endpoints/i/favorites.ts index 47c8a87fd9..32c1a55fb0 100644 --- a/src/server/api/endpoints/i/favorites.ts +++ b/src/server/api/endpoints/i/favorites.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: 'お気に入りに登録した投稿一覧を取得します。', - en: 'Get favorited notes' + 'ja-JP': 'お気に入りに登録した投稿一覧を取得します。', + 'en-US': 'Get favorited notes' }, requireCredential: true, diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts index 61a6b20c7c..cdb4eb3f56 100644 --- a/src/server/api/endpoints/i/update.ts +++ b/src/server/api/endpoints/i/update.ts @@ -8,8 +8,8 @@ import config from '../../../../config'; export const meta = { desc: { - ja: 'アカウント情報を更新します。', - en: 'Update myself' + 'ja-JP': 'アカウント情報を更新します。', + 'en-US': 'Update myself' }, requireCredential: true, diff --git a/src/server/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts index 43cceacf95..1dd08cd13c 100644 --- a/src/server/api/endpoints/messaging/history.ts +++ b/src/server/api/endpoints/messaging/history.ts @@ -6,8 +6,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: 'Messagingの履歴を取得します。', - en: 'Show messaging history.' + 'ja-JP': 'Messagingの履歴を取得します。', + 'en-US': 'Show messaging history.' }, requireCredential: true, diff --git a/src/server/api/endpoints/messaging/messages.ts b/src/server/api/endpoints/messaging/messages.ts index ae26419bc6..dec0638eed 100644 --- a/src/server/api/endpoints/messaging/messages.ts +++ b/src/server/api/endpoints/messaging/messages.ts @@ -6,8 +6,8 @@ import read from '../../common/read-messaging-message'; export const meta = { desc: { - ja: '指定したユーザーとのMessagingのメッセージ一覧を取得します。', - en: 'Get messages of messaging.' + 'ja-JP': '指定したユーザーとのMessagingのメッセージ一覧を取得します。', + 'en-US': 'Get messages of messaging.' }, requireCredential: true, diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts index d33d9e7e77..a6fabcfa45 100644 --- a/src/server/api/endpoints/messaging/messages/create.ts +++ b/src/server/api/endpoints/messaging/messages/create.ts @@ -12,8 +12,8 @@ import pushSw from '../../../../../push-sw'; export const meta = { desc: { - ja: '指定したユーザーへMessagingのメッセージを送信します。', - en: 'Create a message of messaging.' + 'ja-JP': '指定したユーザーへMessagingのメッセージを送信します。', + 'en-US': 'Create a message of messaging.' }, requireCredential: true, diff --git a/src/server/api/endpoints/messaging/messages/read.ts b/src/server/api/endpoints/messaging/messages/read.ts index f609337523..581b57579b 100644 --- a/src/server/api/endpoints/messaging/messages/read.ts +++ b/src/server/api/endpoints/messaging/messages/read.ts @@ -6,8 +6,8 @@ import getParams from '../../../get-params'; export const meta = { desc: { - ja: '指定した自分宛てのメッセージを既読にします。', - en: 'Mark as read a message of messaging.' + 'ja-JP': '指定した自分宛てのメッセージを既読にします。', + 'en-US': 'Mark as read a message of messaging.' }, requireCredential: true, @@ -17,8 +17,8 @@ export const meta = { params: { messageId: $.type(ID).note({ desc: { - ja: '既読にするメッセージのID', - en: 'The ID of a message that you want to mark as read' + 'ja-JP': '既読にするメッセージのID', + 'en-US': 'The ID of a message that you want to mark as read' } }) } diff --git a/src/server/api/endpoints/mute/create.ts b/src/server/api/endpoints/mute/create.ts index bd70cd62ef..5b2e7a8d71 100644 --- a/src/server/api/endpoints/mute/create.ts +++ b/src/server/api/endpoints/mute/create.ts @@ -4,8 +4,8 @@ import Mute from '../../../../models/mute'; export const meta = { desc: { - ja: 'ユーザーをミュートします。', - en: 'Mute a user' + 'ja-JP': 'ユーザーをミュートします。', + 'en-US': 'Mute a user' }, requireCredential: true, diff --git a/src/server/api/endpoints/mute/delete.ts b/src/server/api/endpoints/mute/delete.ts index 3187c46f83..e8ed75a847 100644 --- a/src/server/api/endpoints/mute/delete.ts +++ b/src/server/api/endpoints/mute/delete.ts @@ -4,8 +4,8 @@ import Mute from '../../../../models/mute'; export const meta = { desc: { - ja: 'ユーザーのミュートを解除します。', - en: 'Unmute a user' + 'ja-JP': 'ユーザーのミュートを解除します。', + 'en-US': 'Unmute a user' }, requireCredential: true, diff --git a/src/server/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts index e297605338..387b2396f5 100644 --- a/src/server/api/endpoints/mute/list.ts +++ b/src/server/api/endpoints/mute/list.ts @@ -5,8 +5,8 @@ import { getFriendIds } from '../../common/get-friends'; export const meta = { desc: { - ja: 'ミュートしているユーザー一覧を取得します。', - en: 'Get muted users.' + 'ja-JP': 'ミュートしているユーザー一覧を取得します。', + 'en-US': 'Get muted users.' }, requireCredential: true, diff --git a/src/server/api/endpoints/my/apps.ts b/src/server/api/endpoints/my/apps.ts index 35185db41d..412dff6164 100644 --- a/src/server/api/endpoints/my/apps.ts +++ b/src/server/api/endpoints/my/apps.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '自分のアプリケーション一覧を取得します。', - en: 'Get my apps' + 'ja-JP': '自分のアプリケーション一覧を取得します。', + 'en-US': 'Get my apps' }, requireCredential: true diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts index 9cdbec5270..04f5f7562e 100644 --- a/src/server/api/endpoints/notes/create.ts +++ b/src/server/api/endpoints/notes/create.ts @@ -9,7 +9,7 @@ import getParams from '../../get-params'; export const meta = { desc: { - ja: '投稿します。' + 'ja-JP': '投稿します。' }, requireCredential: true, @@ -25,33 +25,33 @@ export const meta = { visibility: $.str.optional.or(['public', 'home', 'followers', 'specified', 'private']).note({ default: 'public', desc: { - ja: '投稿の公開範囲' + 'ja-JP': '投稿の公開範囲' } }), visibleUserIds: $.arr($.type(ID)).optional.unique().min(1).note({ desc: { - ja: '(投稿の公開範囲が specified の場合)投稿を閲覧できるユーザー' + 'ja-JP': '(投稿の公開範囲が specified の場合)投稿を閲覧できるユーザー' } }), text: $.str.optional.nullable.pipe(isValidText).note({ default: null, desc: { - ja: '投稿内容' + 'ja-JP': '投稿内容' } }), cw: $.str.optional.nullable.pipe(isValidCw).note({ desc: { - ja: 'コンテンツの警告。このパラメータを指定すると設定したテキストで投稿のコンテンツを隠す事が出来ます。' + 'ja-JP': 'コンテンツの警告。このパラメータを指定すると設定したテキストで投稿のコンテンツを隠す事が出来ます。' } }), viaMobile: $.bool.optional.note({ default: false, desc: { - ja: 'モバイルデバイスからの投稿か否か。' + 'ja-JP': 'モバイルデバイスからの投稿か否か。' } }), @@ -66,20 +66,20 @@ export const meta = { speed: $.num.nullable }).optional.nullable.strict().note({ desc: { - ja: '位置情報' + 'ja-JP': '位置情報' }, ref: 'geo' }), mediaIds: $.arr($.type(ID)).optional.unique().range(1, 4).note({ desc: { - ja: '添付するメディア' + 'ja-JP': '添付するメディア' } }), renoteId: $.type(ID).optional.note({ desc: { - ja: 'Renote対象' + 'ja-JP': 'Renote対象' } }), @@ -90,7 +90,7 @@ export const meta = { .each(c => c.length > 0 && c.length < 50) }).optional.strict().note({ desc: { - ja: 'アンケート' + 'ja-JP': 'アンケート' }, ref: 'poll' }) @@ -102,7 +102,7 @@ export const meta = { createdNote: { type: 'entity(Note)', desc: { - ja: '作成した投稿' + 'ja-JP': '作成した投稿' } } } diff --git a/src/server/api/endpoints/notes/delete.ts b/src/server/api/endpoints/notes/delete.ts index 22c6101e14..6d9826cf7b 100644 --- a/src/server/api/endpoints/notes/delete.ts +++ b/src/server/api/endpoints/notes/delete.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '指定した投稿を削除します。', - en: 'Delete a note.' + 'ja-JP': '指定した投稿を削除します。', + 'en-US': 'Delete a note.' }, requireCredential: true, diff --git a/src/server/api/endpoints/notes/favorites/create.ts b/src/server/api/endpoints/notes/favorites/create.ts index 87f6cf1f08..daf7780abc 100644 --- a/src/server/api/endpoints/notes/favorites/create.ts +++ b/src/server/api/endpoints/notes/favorites/create.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定した投稿をお気に入りに登録します。', - en: 'Favorite a note.' + 'ja-JP': '指定した投稿をお気に入りに登録します。', + 'en-US': 'Favorite a note.' }, requireCredential: true, diff --git a/src/server/api/endpoints/notes/favorites/delete.ts b/src/server/api/endpoints/notes/favorites/delete.ts index 3906fe99bb..e42b24d324 100644 --- a/src/server/api/endpoints/notes/favorites/delete.ts +++ b/src/server/api/endpoints/notes/favorites/delete.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定した投稿のお気に入りを解除します。', - en: 'Unfavorite a note.' + 'ja-JP': '指定した投稿のお気に入りを解除します。', + 'en-US': 'Unfavorite a note.' }, requireCredential: true, diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts index 3fce4fb9af..2dbb1190c1 100644 --- a/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -10,65 +10,65 @@ export const meta = { name: 'notes/hybrid-timeline', desc: { - ja: 'ハイブリッドタイムラインを取得します。' + 'ja-JP': 'ハイブリッドタイムラインを取得します。' }, params: { limit: $.num.optional.range(1, 100).note({ default: 10, desc: { - ja: '最大数' + 'ja-JP': '最大数' } }), sinceId: $.type(ID).optional.note({ desc: { - ja: '指定すると、この投稿を基点としてより新しい投稿を取得します' + 'ja-JP': '指定すると、この投稿を基点としてより新しい投稿を取得します' } }), untilId: $.type(ID).optional.note({ desc: { - ja: '指定すると、この投稿を基点としてより古い投稿を取得します' + 'ja-JP': '指定すると、この投稿を基点としてより古い投稿を取得します' } }), sinceDate: $.num.optional.note({ desc: { - ja: '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + 'ja-JP': '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' } }), untilDate: $.num.optional.note({ desc: { - ja: '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + 'ja-JP': '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' } }), includeMyRenotes: $.bool.optional.note({ default: true, desc: { - ja: '自分の行ったRenoteを含めるかどうか' + 'ja-JP': '自分の行ったRenoteを含めるかどうか' } }), includeRenotedMyNotes: $.bool.optional.note({ default: true, desc: { - ja: 'Renoteされた自分の投稿を含めるかどうか' + 'ja-JP': 'Renoteされた自分の投稿を含めるかどうか' } }), includeLocalRenotes: $.bool.optional.note({ default: true, desc: { - ja: 'Renoteされたローカルの投稿を含めるかどうか' + 'ja-JP': 'Renoteされたローカルの投稿を含めるかどうか' } }), mediaOnly: $.bool.optional.note({ desc: { - ja: 'true にすると、メディアが添付された投稿だけ取得します' + 'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します' } }), } diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts index db91230a81..a7fb14d8a9 100644 --- a/src/server/api/endpoints/notes/mentions.ts +++ b/src/server/api/endpoints/notes/mentions.ts @@ -6,8 +6,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '自分に言及している投稿の一覧を取得します。', - en: 'Get mentions of myself.' + 'ja-JP': '自分に言及している投稿の一覧を取得します。', + 'en-US': 'Get mentions of myself.' }, requireCredential: true diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/src/server/api/endpoints/notes/polls/recommendation.ts index a0469d1870..9af223c010 100644 --- a/src/server/api/endpoints/notes/polls/recommendation.ts +++ b/src/server/api/endpoints/notes/polls/recommendation.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: 'おすすめのアンケート一覧を取得します。', - en: 'Get recommended polls.' + 'ja-JP': 'おすすめのアンケート一覧を取得します。', + 'en-US': 'Get recommended polls.' }, requireCredential: true, diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts index 568c187f8a..ab80e7f5d0 100644 --- a/src/server/api/endpoints/notes/polls/vote.ts +++ b/src/server/api/endpoints/notes/polls/vote.ts @@ -9,8 +9,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定した投稿のアンケートに投票します。', - en: 'Vote poll of a note.' + 'ja-JP': '指定した投稿のアンケートに投票します。', + 'en-US': 'Vote poll of a note.' }, requireCredential: true, diff --git a/src/server/api/endpoints/notes/reactions.ts b/src/server/api/endpoints/notes/reactions.ts index 8921c55916..6e7d60e0f0 100644 --- a/src/server/api/endpoints/notes/reactions.ts +++ b/src/server/api/endpoints/notes/reactions.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '指定した投稿のリアクション一覧を取得します。', - en: 'Show reactions of a note.' + 'ja-JP': '指定した投稿のリアクション一覧を取得します。', + 'en-US': 'Show reactions of a note.' }, requireCredential: true diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/src/server/api/endpoints/notes/reactions/create.ts index 65e24e7c06..0781db16c5 100644 --- a/src/server/api/endpoints/notes/reactions/create.ts +++ b/src/server/api/endpoints/notes/reactions/create.ts @@ -7,8 +7,8 @@ import getParams from '../../../get-params'; export const meta = { desc: { - ja: '指定した投稿にリアクションします。', - en: 'React to a note.' + 'ja-JP': '指定した投稿にリアクションします。', + 'en-US': 'React to a note.' }, requireCredential: true, @@ -18,13 +18,13 @@ export const meta = { params: { noteId: $.type(ID).note({ desc: { - ja: '対象の投稿' + 'ja-JP': '対象の投稿' } }), reaction: $.str.pipe(validateReaction.ok).note({ desc: { - ja: 'リアクションの種類' + 'ja-JP': 'リアクションの種類' } }) } diff --git a/src/server/api/endpoints/notes/reactions/delete.ts b/src/server/api/endpoints/notes/reactions/delete.ts index 62af0407bc..598eb65364 100644 --- a/src/server/api/endpoints/notes/reactions/delete.ts +++ b/src/server/api/endpoints/notes/reactions/delete.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定した投稿へのリアクションを取り消します。', - en: 'Unreact to a note.' + 'ja-JP': '指定した投稿へのリアクションを取り消します。', + 'en-US': 'Unreact to a note.' }, requireCredential: true, diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts index 3e3fa8c4aa..099bf2010b 100644 --- a/src/server/api/endpoints/notes/timeline.ts +++ b/src/server/api/endpoints/notes/timeline.ts @@ -8,8 +8,8 @@ import getParams from '../../get-params'; export const meta = { desc: { - ja: 'タイムラインを取得します。', - en: 'Get timeline of myself.' + 'ja-JP': 'タイムラインを取得します。', + 'en-US': 'Get timeline of myself.' }, requireCredential: true, @@ -18,58 +18,58 @@ export const meta = { limit: $.num.optional.range(1, 100).note({ default: 10, desc: { - ja: '最大数' + 'ja-JP': '最大数' } }), sinceId: $.type(ID).optional.note({ desc: { - ja: '指定すると、この投稿を基点としてより新しい投稿を取得します' + 'ja-JP': '指定すると、この投稿を基点としてより新しい投稿を取得します' } }), untilId: $.type(ID).optional.note({ desc: { - ja: '指定すると、この投稿を基点としてより古い投稿を取得します' + 'ja-JP': '指定すると、この投稿を基点としてより古い投稿を取得します' } }), sinceDate: $.num.optional.note({ desc: { - ja: '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + 'ja-JP': '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' } }), untilDate: $.num.optional.note({ desc: { - ja: '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + 'ja-JP': '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' } }), includeMyRenotes: $.bool.optional.note({ default: true, desc: { - ja: '自分の行ったRenoteを含めるかどうか' + 'ja-JP': '自分の行ったRenoteを含めるかどうか' } }), includeRenotedMyNotes: $.bool.optional.note({ default: true, desc: { - ja: 'Renoteされた自分の投稿を含めるかどうか' + 'ja-JP': 'Renoteされた自分の投稿を含めるかどうか' } }), includeLocalRenotes: $.bool.optional.note({ default: true, desc: { - ja: 'Renoteされたローカルの投稿を含めるかどうか' + 'ja-JP': 'Renoteされたローカルの投稿を含めるかどうか' } }), mediaOnly: $.bool.optional.note({ desc: { - ja: 'true にすると、メディアが添付された投稿だけ取得します' + 'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します' } }), } diff --git a/src/server/api/endpoints/notes/trend.ts b/src/server/api/endpoints/notes/trend.ts index 1cbbfacadc..7a0a098f28 100644 --- a/src/server/api/endpoints/notes/trend.ts +++ b/src/server/api/endpoints/notes/trend.ts @@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '人気の投稿の一覧を取得します。', - en: 'Get trend notes.' + 'ja-JP': '人気の投稿の一覧を取得します。', + 'en-US': 'Get trend notes.' }, requireCredential: true diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts index dcef548666..a7b43014ed 100644 --- a/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/src/server/api/endpoints/notes/user-list-timeline.ts @@ -8,8 +8,8 @@ import getParams from '../../get-params'; export const meta = { desc: { - ja: '指定したユーザーリストのタイムラインを取得します。', - en: 'Get timeline of a user list.' + 'ja-JP': '指定したユーザーリストのタイムラインを取得します。', + 'en-US': 'Get timeline of a user list.' }, requireCredential: true, @@ -17,65 +17,65 @@ export const meta = { params: { listId: $.type(ID).note({ desc: { - ja: 'リストのID' + 'ja-JP': 'リストのID' } }), limit: $.num.optional.range(1, 100).note({ default: 10, desc: { - ja: '最大数' + 'ja-JP': '最大数' } }), sinceId: $.type(ID).optional.note({ desc: { - ja: '指定すると、この投稿を基点としてより新しい投稿を取得します' + 'ja-JP': '指定すると、この投稿を基点としてより新しい投稿を取得します' } }), untilId: $.type(ID).optional.note({ desc: { - ja: '指定すると、この投稿を基点としてより古い投稿を取得します' + 'ja-JP': '指定すると、この投稿を基点としてより古い投稿を取得します' } }), sinceDate: $.num.optional.note({ desc: { - ja: '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + 'ja-JP': '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' } }), untilDate: $.num.optional.note({ desc: { - ja: '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' + 'ja-JP': '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' } }), includeMyRenotes: $.bool.optional.note({ default: true, desc: { - ja: '自分の行ったRenoteを含めるかどうか' + 'ja-JP': '自分の行ったRenoteを含めるかどうか' } }), includeRenotedMyNotes: $.bool.optional.note({ default: true, desc: { - ja: 'Renoteされた自分の投稿を含めるかどうか' + 'ja-JP': 'Renoteされた自分の投稿を含めるかどうか' } }), includeLocalRenotes: $.bool.optional.note({ default: true, desc: { - ja: 'Renoteされたローカルの投稿を含めるかどうか' + 'ja-JP': 'Renoteされたローカルの投稿を含めるかどうか' } }), mediaOnly: $.bool.optional.note({ desc: { - ja: 'true にすると、メディアが添付された投稿だけ取得します' + 'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します' } }), } diff --git a/src/server/api/endpoints/notifications/mark_all_as_read.ts b/src/server/api/endpoints/notifications/mark_all_as_read.ts index a9875ebb01..e2bde777b3 100644 --- a/src/server/api/endpoints/notifications/mark_all_as_read.ts +++ b/src/server/api/endpoints/notifications/mark_all_as_read.ts @@ -4,8 +4,8 @@ import User, { ILocalUser } from '../../../../models/user'; export const meta = { desc: { - ja: '全ての通知を既読にします。', - en: 'Mark all notifications as read.' + 'ja-JP': '全ての通知を既読にします。', + 'en-US': 'Mark all notifications as read.' }, requireCredential: true, diff --git a/src/server/api/endpoints/users/lists/create.ts b/src/server/api/endpoints/users/lists/create.ts index d7dc2a5f70..ac4f957a0d 100644 --- a/src/server/api/endpoints/users/lists/create.ts +++ b/src/server/api/endpoints/users/lists/create.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: 'ユーザーリストを作成します。', - en: 'Create a user list' + 'ja-JP': 'ユーザーリストを作成します。', + 'en-US': 'Create a user list' }, requireCredential: true, diff --git a/src/server/api/endpoints/users/lists/list.ts b/src/server/api/endpoints/users/lists/list.ts index 31fef26bdc..966e1d3ad9 100644 --- a/src/server/api/endpoints/users/lists/list.ts +++ b/src/server/api/endpoints/users/lists/list.ts @@ -3,7 +3,7 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '自分の作成したユーザーリスト一覧を取得します。' + 'ja-JP': '自分の作成したユーザーリスト一覧を取得します。' }, requireCredential: true, diff --git a/src/server/api/endpoints/users/lists/push.ts b/src/server/api/endpoints/users/lists/push.ts index bd4e201bde..2d68ec7458 100644 --- a/src/server/api/endpoints/users/lists/push.ts +++ b/src/server/api/endpoints/users/lists/push.ts @@ -8,8 +8,8 @@ import { deliver } from '../../../../../queue'; export const meta = { desc: { - ja: '指定したユーザーリストに指定したユーザーを追加します。', - en: 'Add a user to a user list.' + 'ja-JP': '指定したユーザーリストに指定したユーザーを追加します。', + 'en-US': 'Add a user to a user list.' }, requireCredential: true, diff --git a/src/server/api/endpoints/users/lists/show.ts b/src/server/api/endpoints/users/lists/show.ts index 2fd142a609..a2dd00c6e1 100644 --- a/src/server/api/endpoints/users/lists/show.ts +++ b/src/server/api/endpoints/users/lists/show.ts @@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../../models/user'; export const meta = { desc: { - ja: '指定したユーザーリストの情報を取得します。', - en: 'Show a user list.' + 'ja-JP': '指定したユーザーリストの情報を取得します。', + 'en-US': 'Show a user list.' }, requireCredential: true, diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts index 13377e6fff..e0a5cb9e36 100644 --- a/src/server/api/endpoints/users/recommendation.ts +++ b/src/server/api/endpoints/users/recommendation.ts @@ -6,7 +6,7 @@ import Mute from '../../../../models/mute'; export const meta = { desc: { - ja: 'おすすめのユーザー一覧を取得します。' + 'ja-JP': 'おすすめのユーザー一覧を取得します。' }, requireCredential: true, diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts index eda3f95728..307a8f6894 100644 --- a/src/server/api/endpoints/users/search.ts +++ b/src/server/api/endpoints/users/search.ts @@ -5,7 +5,7 @@ import getParams from '../../get-params'; export const meta = { desc: { - ja: 'ユーザーを検索します。' + 'ja-JP': 'ユーザーを検索します。' }, requireCredential: false, @@ -13,28 +13,28 @@ export const meta = { params: { query: $.str.note({ desc: { - ja: 'クエリ' + 'ja-JP': 'クエリ' } }), offset: $.num.optional.min(0).note({ default: 0, desc: { - ja: 'オフセット' + 'ja-JP': 'オフセット' } }), limit: $.num.optional.range(1, 100).note({ default: 10, desc: { - ja: '取得する数' + 'ja-JP': '取得する数' } }), localOnly: $.bool.optional.note({ default: false, desc: { - ja: 'ローカルユーザーのみ検索対象にするか否か' + 'ja-JP': 'ローカルユーザーのみ検索対象にするか否か' } }), }, -- cgit v1.2.3-freya From 117ab633a151d5d006f5c9dceead4bde1ddea8a1 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 30 Aug 2018 03:49:52 +0900 Subject: Improve API --- src/server/api/endpoints/chart.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/server/api/endpoints') diff --git a/src/server/api/endpoints/chart.ts b/src/server/api/endpoints/chart.ts index 406ad39946..521fc42c98 100644 --- a/src/server/api/endpoints/chart.ts +++ b/src/server/api/endpoints/chart.ts @@ -1,4 +1,6 @@ +import $ from 'cafy'; import Stats, { IStats } from '../../../models/stats'; +import getParams from '../../get-params'; type Omit = Pick>; @@ -44,11 +46,26 @@ function migrateStats(stats: IStats[]) { } export const meta = { + desc: { + 'ja-JP': 'インスタンスの統計を取得します。' + }, + + params: { + limit: $.num.optional.range(1, 100).note({ + default: 30, + desc: { + 'ja-JP': '最大数' + } + }), + } }; export default (params: any) => new Promise(async (res, rej) => { - const daysRange = 30; - const hoursRange = 30; + const [ps, psErr] = getParams(meta, params); + if (psErr) throw psErr; + + const daysRange = ps.limit; + const hoursRange = ps.limit; const now = new Date(); const y = now.getFullYear(); -- cgit v1.2.3-freya From 3038434712077cedd92a6cd68d74513f9dbd62bd Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 30 Aug 2018 03:53:26 +0900 Subject: Fix bug --- src/server/api/endpoints/chart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/api/endpoints') diff --git a/src/server/api/endpoints/chart.ts b/src/server/api/endpoints/chart.ts index 521fc42c98..7da970131e 100644 --- a/src/server/api/endpoints/chart.ts +++ b/src/server/api/endpoints/chart.ts @@ -1,6 +1,6 @@ import $ from 'cafy'; import Stats, { IStats } from '../../../models/stats'; -import getParams from '../../get-params'; +import getParams from '../get-params'; type Omit = Pick>; -- cgit v1.2.3-freya