Skip to content

Commit

Permalink
- route /status that was originally introduced in 2019: 3460ecc and…
Browse files Browse the repository at this point in the history
… broken after migrated crawler to c# in June 2022

- route `/stats` that broken as of renaming field `postTime` to `postedAt` in 429de6a
@ `be/routes/api.php`

- unused exports `throwIfApiError()`, `useApiStatus()` & `useApiStatsForumsPostCount()` @ index.ts
- unused exports `ApiStatus` & `ApiStatsForumPostCount`, and interface `TimeCountPair` @ index.d.ts
@ api
- route `/status` & `/stats` @ router/index.ts & `<GlobalNavBar>`
- unused exports `commonToolboxFeatures`, `extendCommonToolbox()` & `emptyChartSeriesData()` @ shared/echarts.ts
$ rm views/Stat{,u}s.vue shared/groupByTimeGranularityUtcPlus8.d.ts
@ fe
  • Loading branch information
n0099 committed Mar 10, 2024
1 parent a870c10 commit c81b81d
Show file tree
Hide file tree
Showing 9 changed files with 2 additions and 533 deletions.
69 changes: 0 additions & 69 deletions be/routes/api.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
<?php

use App\Eloquent\Model\Post\PostFactory;
use App\Helper;
use App\Http\Controllers\PostsQuery;
use App\Http\Controllers\UsersQuery;
use App\Http\Middleware\ReCAPTCHACheck;
use Illuminate\Database\Query\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\Rule;

/*
|--------------------------------------------------------------------------
Expand All @@ -26,68 +21,4 @@
Route::middleware(ReCAPTCHACheck::class)->group(static function () {
Route::get('/posts', [PostsQuery::class, 'query']);
Route::get('/users', [UsersQuery::class, 'query']);
Route::get('/status', static function (Request $request): string {
$groupByTimeGranularity = [
'minute' => 'FROM_UNIXTIME(startTime, "%Y-%m-%d %H:%i") AS startTime',
'hour' => 'FROM_UNIXTIME(startTime, "%Y-%m-%d %H:00") AS startTime',
'day' => 'FROM_UNIXTIME(startTime, "%Y-%m-%d") AS startTime',
];

/** @var array{timeGranularity: string, startTime: string, endTime: string} $queryParams */
$queryParams = $request->validate([
'timeGranularity' => ['required', 'string', Rule::in(array_keys($groupByTimeGranularity))],
'startTime' => 'required|integer|numeric',
'endTime' => 'required|integer|numeric'
]);

return DB::query()
->selectRaw('
CAST(UNIX_TIMESTAMP(startTime) AS UNSIGNED) AS startTime,
SUM(queueTiming) AS queueTiming,
SUM(webRequestTiming) AS webRequestTiming,
SUM(savePostsTiming) AS savePostsTiming,
CAST(SUM(webRequestTimes) AS UNSIGNED) AS webRequestTimes,
CAST(SUM(parsedPostTimes) AS UNSIGNED) AS parsedPostTimes,
CAST(SUM(parsedUserTimes) AS UNSIGNED) AS parsedUserTimes
')
->fromSub(static fn (Builder $query) =>
$query->from('tbm_crawledPosts')
->selectRaw($groupByTimeGranularity[$queryParams['timeGranularity']])
->selectRaw('
queueTiming,
webRequestTiming,
savePostsTiming,
webRequestTimes,
parsedPostTimes,
parsedUserTimes
')
->whereBetween('startTime', [$queryParams['startTime'], $queryParams['endTime']])
->orderBy('id', 'DESC'), 'T')
->groupBy('startTime')
->get()->toJson();
});
Route::get('/stats/forums/postCount', static function (Request $request): array {
$groupByTimeGranularity = Helper::rawSqlGroupByTimeGranularity('postTime');
$queryParams = $request->validate([
'fid' => 'required|integer',
'timeGranularity' => ['required', 'string', Rule::in(array_keys($groupByTimeGranularity))],
'startTime' => 'required|integer|numeric',
'endTime' => 'required|integer|numeric'
]);

$forumsPostCount = [];
foreach (PostFactory::getPostModelsByFid($queryParams['fid']) as $postType => $forumPostModel) {
/** @var \Illuminate\Database\Eloquent\Model $forumPostModel */
$forumsPostCount[$postType] = $forumPostModel
->selectRaw($groupByTimeGranularity[$queryParams['timeGranularity']])
->selectRaw('COUNT(*) AS count')
->whereBetween('postTime', [Helper::timestampToLocalDateTime($queryParams['startTime']), Helper::timestampToLocalDateTime($queryParams['endTime'])])
->groupBy('time')
->orderBy('time')
->get()->toArray();
}
Helper::abortAPIIf(40403, collect($forumsPostCount)->every(fn ($i) => $i === []));

return $forumsPostCount;
});
});
29 changes: 1 addition & 28 deletions fe/src/api/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Reply, SubReply, Thread } from './post';
import type { User, UserGenderQueryParam } from './user';
import type { SelectUserParams } from '@/components/widgets/selectUser';
import type { BoolInt, Fid, Float, PostType, UInt, UnixTimestamp } from '@/shared';
import type { Mix } from '@/shared/groupBytimeGranularityUtcPlus8';
import type { BoolInt, Fid, PostType, UInt } from '@/shared';

export interface ApiError { errorCode: number, errorInfo: Record<string, unknown[]> | string }
export interface Api<TResponse, TQueryParam = never> {
Expand All @@ -17,32 +16,6 @@ export type ApiForums = Api<Array<{
isCrawling: BoolInt
}>>;

export type ApiStatus = Api<Array<{
startTime: UnixTimestamp,
queueTiming: Float,
webRequestTiming: Float,
savePostsTiming: Float,
webRequestTimes: UInt,
parsedPostTimes: UInt,
parsedUserTimes: UInt
}>, {
timeGranularity: 'day' | 'hour' | 'minute',
startTime: UnixTimestamp,
endTime: UnixTimestamp
}>;

interface TimeCountPair { time: Mix, count: UInt }
export type ApiStatsForumPostCount = Api<{
thread: TimeCountPair[],
reply: TimeCountPair[],
subReply: TimeCountPair[]
}, {
fid: Fid,
timeGranularity: 'day' | 'hour' | 'minute' | 'month' | 'week' | 'year',
startTime: UnixTimestamp,
endTime: UnixTimestamp
}>;

export type Cursor = string;
interface CursorPagination {
pages: {
Expand Down
10 changes: 1 addition & 9 deletions fe/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Api, ApiError, ApiForums, ApiPosts, ApiStatsForumPostCount, ApiStatus, ApiUsers, Cursor, CursorPagination } from '@/api/index.d';
import type { Api, ApiError, ApiForums, ApiPosts, ApiUsers, Cursor, CursorPagination } from '@/api/index.d';
import type { Ref } from 'vue';
import type { InfiniteData, QueryKey, UseInfiniteQueryOptions, UseQueryOptions } from '@tanstack/vue-query';
import { useInfiniteQuery, useQuery } from '@tanstack/vue-query';
Expand All @@ -23,12 +23,6 @@ export class FetchResponseError extends Error {
export const isApiError = (response: ApiError | unknown): response is ApiError => _.isObject(response)
&& 'errorCode' in response && _.isNumber(response.errorCode)
&& 'errorInfo' in response && (_.isObject(response.errorInfo) || _.isString(response.errorInfo));
export const throwIfApiError = <TResponse>(response: ApiError | TResponse): TResponse => {
if (isApiError(response))
throw new Error(JSON.stringify(response));

return response;
};
export const queryFunction = async <TResponse, TQueryParam>
(endpoint: string, queryParam?: TQueryParam, signal?: AbortSignal): Promise<TResponse> => {
nprogress.start();
Expand Down Expand Up @@ -119,7 +113,5 @@ const useApiWithCursor = <
});

export const useApiForums = () => useApi<ApiForums>('forums', queryFunction)();
export const useApiStatus = useApi<ApiStatus>('status', queryFunctionWithReCAPTCHA);
export const useApiStatsForumsPostCount = useApi<ApiStatsForumPostCount>('stats/forums/postCount', queryFunctionWithReCAPTCHA);
export const useApiUsers = useApi<ApiUsers>('users', queryFunctionWithReCAPTCHA);
export const useApiPosts = useApiWithCursor<ApiPosts>('posts', queryFunctionWithReCAPTCHA);
2 changes: 0 additions & 2 deletions fe/src/components/GlobalNavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ const navs = reactive<Array<DropDown | Route>>([
{ route: 'user', title: '用户', icon: 'users' }
]
},
{ route: 'stats', title: '统计', icon: 'chart-pie' },
{ route: 'status', title: '状态', icon: 'satellite-dish' },
{
title: '专题',
icon: 'paper-plane',
Expand Down
2 changes: 0 additions & 2 deletions fe/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ export default createRouter({
withCursorRoute(userRoute, 'displayName/:displayName', 'user/displayName')
]
}),
withViewRoute(import('@/views/Status.vue'), 'status'),
withViewRoute(import('@/views/Stats.vue'), 'stats'),
withViewRoute(import('@/views/BilibiliVote.vue'), 'bilibiliVote')
],
linkActiveClass: 'active',
Expand Down
26 changes: 0 additions & 26 deletions fe/src/shared/echarts.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { DateTime } from 'luxon';
import * as _ from 'lodash-es';

import type { BarSeriesOption, LineSeriesOption } from 'echarts/charts';
import type { ToolboxComponentOption } from 'echarts/components';
import * as echarts from 'echarts/core';
// eslint-disable-next-line import/extensions
import type { ColorPaletteOptionMixin } from 'echarts/types/src/util/types.d.ts';
Expand All @@ -28,29 +25,6 @@ export const echarts4ColorTheme: ColorPaletteOptionMixin = {
]
};

export const commonToolboxFeatures: echarts.ComposeOption<ToolboxComponentOption> = {
toolbox: {
feature: {
dataZoom: { show: true, yAxisIndex: 'none' },
saveAsImage: { show: true }
}
}
};
export const extendCommonToolbox = (extend: echarts.ComposeOption<ToolboxComponentOption>)
: echarts.ComposeOption<ToolboxComponentOption> =>
_.merge(commonToolboxFeatures, extend);

export const emptyChartSeriesData = (chart: echarts.ECharts) => {
chart.setOption({
series: _.map(chart.getOption().series as BarSeriesOption | LineSeriesOption, series => {
if (_.isObject(series) && 'data' in series)
series.data = [];

return series;
})
});
};

export const timeGranularities = ['minute', 'hour', 'day', 'week', 'month', 'year'] as const;
export type TimeGranularity = typeof timeGranularities[number];
export type TimeGranularityStringMap = { [P in TimeGranularity]?: string };
Expand Down
7 changes: 0 additions & 7 deletions fe/src/shared/groupByTimeGranularityUtcPlus8.d.ts

This file was deleted.

172 changes: 0 additions & 172 deletions fe/src/views/Stats.vue

This file was deleted.

Loading

0 comments on commit c81b81d

Please sign in to comment.