This commit is contained in:
syuilo 2020-03-07 01:04:36 +09:00
parent c7c537c8b8
commit 1947835c51
16 changed files with 167 additions and 64 deletions

View file

@ -1,6 +1,6 @@
const dateTimeIntervals = {
'days': 86400000,
'hours': 3600000,
'day': 86400000,
'hour': 3600000,
};
export function DateUTC(time: number[]): Date {

View file

@ -25,11 +25,16 @@ export const meta = {
'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。'
}
},
offset: {
validator: $.optional.num,
default: 0,
},
},
res: convertLog(activeUsersChart.schema),
};
export default define(meta, async (ps) => {
return await activeUsersChart.getChart(ps.span as any, ps.limit!);
return await activeUsersChart.getChart(ps.span as any, ps.limit!, ps.offset!);
});

View file

@ -25,11 +25,16 @@ export const meta = {
'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。'
}
},
offset: {
validator: $.optional.num,
default: 0,
},
},
res: convertLog(driveChart.schema),
};
export default define(meta, async (ps) => {
return await driveChart.getChart(ps.span as any, ps.limit!);
return await driveChart.getChart(ps.span as any, ps.limit!, ps.offset!);
});

View file

@ -25,11 +25,16 @@ export const meta = {
'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。'
}
},
offset: {
validator: $.optional.num,
default: 0,
},
},
res: convertLog(federationChart.schema),
};
export default define(meta, async (ps) => {
return await federationChart.getChart(ps.span as any, ps.limit!);
return await federationChart.getChart(ps.span as any, ps.limit!, ps.offset!);
});

View file

@ -26,6 +26,11 @@ export const meta = {
}
},
offset: {
validator: $.optional.num,
default: 0,
},
tag: {
validator: $.str,
desc: {
@ -38,5 +43,5 @@ export const meta = {
};
export default define(meta, async (ps) => {
return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.tag);
return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.tag);
});

View file

@ -26,6 +26,11 @@ export const meta = {
}
},
offset: {
validator: $.optional.num,
default: 0,
},
host: {
validator: $.str,
desc: {
@ -39,5 +44,5 @@ export const meta = {
};
export default define(meta, async (ps) => {
return await instanceChart.getChart(ps.span as any, ps.limit!, ps.host);
return await instanceChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.host);
});

View file

@ -25,11 +25,16 @@ export const meta = {
'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。'
}
},
offset: {
validator: $.optional.num,
default: 0,
},
},
res: convertLog(networkChart.schema),
};
export default define(meta, async (ps) => {
return await networkChart.getChart(ps.span as any, ps.limit!);
return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset!);
});

View file

@ -25,11 +25,16 @@ export const meta = {
'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。'
}
},
offset: {
validator: $.optional.num,
default: 0,
},
},
res: convertLog(notesChart.schema),
};
export default define(meta, async (ps) => {
return await notesChart.getChart(ps.span as any, ps.limit!);
return await notesChart.getChart(ps.span as any, ps.limit!, ps.offset!);
});

View file

@ -27,6 +27,11 @@ export const meta = {
}
},
offset: {
validator: $.optional.num,
default: 0,
},
userId: {
validator: $.type(ID),
desc: {
@ -40,5 +45,5 @@ export const meta = {
};
export default define(meta, async (ps) => {
return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.userId);
return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
});

View file

@ -27,6 +27,11 @@ export const meta = {
}
},
offset: {
validator: $.optional.num,
default: 0,
},
userId: {
validator: $.type(ID),
desc: {
@ -40,5 +45,5 @@ export const meta = {
};
export default define(meta, async (ps) => {
return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.userId);
return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
});

View file

@ -27,6 +27,11 @@ export const meta = {
}
},
offset: {
validator: $.optional.num,
default: 0,
},
userId: {
validator: $.type(ID),
desc: {
@ -40,5 +45,5 @@ export const meta = {
};
export default define(meta, async (ps) => {
return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.userId);
return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
});

View file

@ -27,6 +27,11 @@ export const meta = {
}
},
offset: {
validator: $.optional.num,
default: 0,
},
userId: {
validator: $.type(ID),
desc: {
@ -40,5 +45,5 @@ export const meta = {
};
export default define(meta, async (ps) => {
return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.userId);
return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
});

View file

@ -25,11 +25,16 @@ export const meta = {
'ja-JP': '最大数。例えば 30 を指定したとすると、スパンが"day"の場合は30日分のデータが、スパンが"hour"の場合は30時間分のデータが返ります。'
}
},
offset: {
validator: $.optional.num,
default: 0,
},
},
res: convertLog(usersChart.schema),
};
export default define(meta, async (ps) => {
return await usersChart.getChart(ps.span as any, ps.limit!);
return await usersChart.getChart(ps.span as any, ps.limit!, ps.offset!);
});

View file

@ -60,9 +60,9 @@ export default define(meta, async () => {
Notes.count({ where: { userHost: null }, cache: 3600000 }),
Users.count({ cache: 3600000 }),
Users.count({ where: { host: null }, cache: 3600000 }),
federationChart.getChart('hour', 1).then(chart => chart.instance.total[0]),
driveChart.getChart('hour', 1).then(chart => chart.local.totalSize[0]),
driveChart.getChart('hour', 1).then(chart => chart.remote.totalSize[0]),
federationChart.getChart('hour', 1, 0).then(chart => chart.instance.total[0]),
driveChart.getChart('hour', 1, 0).then(chart => chart.local.totalSize[0]),
driveChart.getChart('hour', 1, 0).then(chart => chart.remote.totalSize[0]),
]);
return {

View file

@ -8,7 +8,7 @@ import * as nestedProperty from 'nested-property';
import autobind from 'autobind-decorator';
import Logger from '../logger';
import { Schema } from '../../misc/schema';
import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual } from 'typeorm';
import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual, Between } from 'typeorm';
import { DateUTC, isTimeSame, isTimeBefore, subtractTimespan } from '../../prelude/time';
import { getChartInsertLock } from '../../misc/app-lock';
@ -133,6 +133,21 @@ export default abstract class Chart<T extends Record<string, any>> {
return Math.floor(x.getTime() / 1000);
}
@autobind
private static dateToYMDH(date: Date): [number, number, number, number] {
const y = date.getUTCFullYear();
const m = date.getUTCMonth();
const d = date.getUTCDate();
const h = date.getUTCHours();
return [y, m, d, h];
}
@autobind
private static getCurrentDate(): [number, number, number, number] {
return Chart.dateToYMDH(new Date());
}
@autobind
public static schemaToEntity(name: string, schema: Schema): EntitySchema {
return new EntitySchema({
@ -211,18 +226,6 @@ export default abstract class Chart<T extends Record<string, any>> {
return log as T;
}
@autobind
private getCurrentDate(): [number, number, number, number] {
const now = new Date();
const y = now.getUTCFullYear();
const m = now.getUTCMonth();
const d = now.getUTCDate();
const h = now.getUTCHours();
return [y, m, d, h];
}
@autobind
private getLatestLog(span: Span, group: string | null = null): Promise<Log | null> {
return this.repository.findOne({
@ -237,7 +240,7 @@ export default abstract class Chart<T extends Record<string, any>> {
@autobind
private async getCurrentLog(span: Span, group: string | null = null): Promise<Log> {
const [y, m, d, h] = this.getCurrentDate();
const [y, m, d, h] = Chart.getCurrentDate();
const current =
span == 'day' ? DateUTC([y, m, d]) :
@ -378,12 +381,23 @@ export default abstract class Chart<T extends Record<string, any>> {
}
@autobind
public async getChart(span: Span, range: number, group: string | null = null): Promise<ArrayValue<T>> {
const [y, m, d, h] = this.getCurrentDate();
public async getChart(span: Span, range: number, offset: number, group: string | null = null): Promise<ArrayValue<T>> {
let [y, m, d, h] = Chart.getCurrentDate();
let lt: Date = null as never;
if (offset > 0) {
[y, m, d, h] = Chart.dateToYMDH(subtractTimespan(DateUTC([y, m, d, h]), offset, span));
lt =
span === 'day' ? DateUTC([y, m, d]) :
span === 'hour' ? DateUTC([y, m, d, h]) :
null as never;
}
const gt =
span === 'day' ? subtractTimespan(DateUTC([y, m, d]), range - 1, 'days') :
span === 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), range - 1, 'hours') :
span === 'day' ? subtractTimespan(DateUTC([y, m, d]), range - 1, 'day') :
span === 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), range - 1, 'hour') :
null as never;
// ログ取得
@ -391,7 +405,9 @@ export default abstract class Chart<T extends Record<string, any>> {
where: {
group: group,
span: span,
date: MoreThanOrEqual(Chart.dateToTimestamp(gt))
date: offset === 0
? MoreThanOrEqual(Chart.dateToTimestamp(gt))
: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt))
},
order: {
date: -1
@ -439,8 +455,8 @@ export default abstract class Chart<T extends Record<string, any>> {
// 整形
for (let i = (range - 1); i >= 0; i--) {
const current =
span == 'day' ? subtractTimespan(DateUTC([y, m, d]), i, 'days') :
span == 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), i, 'hours') :
span == 'day' ? subtractTimespan(DateUTC([y, m, d]), i, 'day') :
span == 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), i, 'hour') :
null as never;
const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current));

View file

@ -86,8 +86,8 @@ describe('Chart', () => {
it('Can updates', async(async () => {
await testChart.increment();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -109,8 +109,8 @@ describe('Chart', () => {
it('Can updates (dec)', async(async () => {
await testChart.decrement();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -130,8 +130,8 @@ describe('Chart', () => {
}));
it('Empty chart', async(async () => {
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -155,8 +155,8 @@ describe('Chart', () => {
await testChart.increment();
await testChart.increment();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -182,8 +182,8 @@ describe('Chart', () => {
await testChart.increment();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -209,8 +209,8 @@ describe('Chart', () => {
await testChart.increment();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -235,8 +235,8 @@ describe('Chart', () => {
clock.tick('05:00:00');
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -262,8 +262,8 @@ describe('Chart', () => {
clock.tick('05:00:00');
await testChart.increment();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -282,14 +282,41 @@ describe('Chart', () => {
});
}));
it('Can specify offset', async(async () => {
await testChart.increment();
clock.tick('01:00:00');
await testChart.increment();
const chartHours = await testChart.getChart('hour', 3, 1);
const chartDays = await testChart.getChart('day', 3, 1);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0]
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [0, 0, 0]
},
});
}));
describe('Grouped', () => {
it('Can updates', async(async () => {
await testGroupedChart.increment('alice');
const aliceChartHours = await testGroupedChart.getChart('hour', 3, 'alice');
const aliceChartDays = await testGroupedChart.getChart('day', 3, 'alice');
const bobChartHours = await testGroupedChart.getChart('hour', 3, 'bob');
const bobChartDays = await testGroupedChart.getChart('day', 3, 'bob');
const aliceChartHours = await testGroupedChart.getChart('hour', 3, 0, 'alice');
const aliceChartDays = await testGroupedChart.getChart('day', 3, 0, 'alice');
const bobChartHours = await testGroupedChart.getChart('hour', 3, 0, 'bob');
const bobChartDays = await testGroupedChart.getChart('day', 3, 0, 'bob');
assert.deepStrictEqual(aliceChartHours, {
foo: {
@ -331,8 +358,8 @@ describe('Chart', () => {
await testUniqueChart.uniqueIncrement('alice');
await testUniqueChart.uniqueIncrement('bob');
const chartHours = await testUniqueChart.getChart('hour', 3);
const chartDays = await testUniqueChart.getChart('day', 3);
const chartHours = await testUniqueChart.getChart('hour', 3, 0);
const chartDays = await testUniqueChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: [2, 0, 0],
@ -350,8 +377,8 @@ describe('Chart', () => {
await testChart.resync();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {
@ -379,8 +406,8 @@ describe('Chart', () => {
await testChart.resync();
const chartHours = await testChart.getChart('hour', 3);
const chartDays = await testChart.getChart('day', 3);
const chartHours = await testChart.getChart('hour', 3, 0);
const chartDays = await testChart.getChart('day', 3, 0);
assert.deepStrictEqual(chartHours, {
foo: {