管理画面からアラートワーカーを起動できるように
This commit is contained in:
parent
81c2dcb35a
commit
f64c0d0bd5
@ -1,10 +1,13 @@
|
||||
/**
|
||||
* バージョン情報など、サーバーのメタデータを返すAPI
|
||||
* Admin API
|
||||
* @author Xeltica
|
||||
*/
|
||||
|
||||
import { Get, JsonController } from 'routing-controllers';
|
||||
import { BadRequestError, CurrentUser, Get, JsonController, OnUndefined, Post } from 'routing-controllers';
|
||||
import { IUser } from '../../common/types/user';
|
||||
import { config } from '../../config';
|
||||
import { work } from '../services/worker';
|
||||
import * as Store from '../store';
|
||||
|
||||
@JsonController('/admin')
|
||||
export class AdminController {
|
||||
@ -15,4 +18,24 @@ export class AdminController {
|
||||
acct: `@${username}@${host}`,
|
||||
};
|
||||
}
|
||||
|
||||
@Get('/misshai/error') getMisshaiError(@CurrentUser({ required: true }) user: IUser) {
|
||||
if (!user.isAdmin) {
|
||||
throw new BadRequestError('Not an Admin');
|
||||
}
|
||||
|
||||
return Store.getState().misshaiWorkerRecentError;
|
||||
}
|
||||
|
||||
@OnUndefined(204)
|
||||
@Post('/misshai/start') startMisshai(@CurrentUser({ required: true }) user: IUser) {
|
||||
if (!user.isAdmin) {
|
||||
throw new BadRequestError('Not an Admin');
|
||||
}
|
||||
if (Store.getState().nowCalculating) {
|
||||
throw new BadRequestError('Already started');
|
||||
}
|
||||
|
||||
work();
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,13 @@ import * as Store from '../store';
|
||||
import { User } from '../models/entities/user';
|
||||
|
||||
export default (): void => {
|
||||
cron.schedule('0 0 0 * * *', async () => {
|
||||
Store.dispatch({ nowCalculating: true });
|
||||
cron.schedule('0 0 0 * * *', work);
|
||||
};
|
||||
|
||||
export const work = async () => {
|
||||
Store.dispatch({ nowCalculating: true });
|
||||
|
||||
try {
|
||||
const users = await Users.find({ alertMode: Not<AlertMode>('nothing') });
|
||||
for (const user of users) {
|
||||
await update(user).catch(e => handleError(user, e));
|
||||
@ -24,9 +28,13 @@ export default (): void => {
|
||||
return delay(3000);
|
||||
}
|
||||
}
|
||||
|
||||
Store.dispatch({ misshaiWorkerRecentError: null });
|
||||
} catch (e) {
|
||||
const msg = String(e instanceof Error ? e.stack : e);
|
||||
Store.dispatch({ misshaiWorkerRecentError: msg });
|
||||
} finally {
|
||||
Store.dispatch({ nowCalculating: false });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
const defaultState: State = {
|
||||
nowCalculating: false,
|
||||
misshaiWorkerRecentError: null,
|
||||
};
|
||||
|
||||
let _state: Readonly<State> = defaultState;
|
||||
@ -16,6 +17,7 @@ let _state: Readonly<State> = defaultState;
|
||||
*/
|
||||
export type State = {
|
||||
nowCalculating: boolean,
|
||||
misshaiWorkerRecentError: string | null,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,7 @@ import { Skeleton } from './Skeleton';
|
||||
import { IAnnouncement } from '../../common/types/announcement';
|
||||
import { $delete, $get, $post, $put } from '../misc/api';
|
||||
import { Card } from './Card';
|
||||
import { showModal } from '../store/slices/screen';
|
||||
|
||||
|
||||
export const AdminPage: React.VFC = () => {
|
||||
@ -19,6 +20,8 @@ export const AdminPage: React.VFC = () => {
|
||||
const [draftTitle, setDraftTitle] = useState('');
|
||||
const [draftBody, setDraftBody] = useState('');
|
||||
|
||||
const [misshaiError, setMisshaiError] = useState<string | null>(null);
|
||||
|
||||
const submitAnnouncement = async () => {
|
||||
if (selectedAnnouncement) {
|
||||
await $put('announcements', {
|
||||
@ -52,6 +55,22 @@ export const AdminPage: React.VFC = () => {
|
||||
setAnnouncements(announcements ?? []);
|
||||
setAnnouncementsLoaded(true);
|
||||
});
|
||||
$get<string | null>('admin/misshai/error').then(setMisshaiError);
|
||||
};
|
||||
|
||||
const onClickStartMisshaiAlertWorkerButton = () => {
|
||||
$post('admin/misshai/start').then(() => {
|
||||
dispatch(showModal({
|
||||
type: 'dialog',
|
||||
message: '開始',
|
||||
}));
|
||||
}).catch((e) => {
|
||||
dispatch(showModal({
|
||||
type: 'dialog',
|
||||
icon: 'error',
|
||||
message: e.message,
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -166,6 +185,16 @@ export const AdminPage: React.VFC = () => {
|
||||
)}
|
||||
</Card>
|
||||
</article>
|
||||
<article>
|
||||
<h2>Misshai</h2>
|
||||
<div className="vstack">
|
||||
<button className="btn danger" onClick={onClickStartMisshaiAlertWorkerButton}>
|
||||
ミス廃アラートワーカーを強制起動する
|
||||
</button>
|
||||
<h3>直近のワーカーエラー</h3>
|
||||
<pre><code>{misshaiError ?? 'なし'}</code></pre>
|
||||
</div>
|
||||
</article>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -174,3 +203,7 @@ export const AdminPage: React.VFC = () => {
|
||||
};
|
||||
|
||||
|
||||
function dispatch(arg0: any) {
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user