mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-21 01:46:28 +08:00
core: make API a service
This commit is contained in:
8 files changed
+388
-357
No files matched your search
@@ -8,6 +8,7 @@ import { nanoid } from 'nanoid';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import parser from '@hydrooj/utils/lib/search';
|
||||
import { sortFiles, streamToBuffer } from '@hydrooj/utils/lib/utils';
|
||||
import type { Context } from '../context';
|
||||
import {
|
||||
BadRequestError, ContestNotAttendedError, ContestNotEndedError, ContestNotFoundError, ContestNotLiveError,
|
||||
FileLimitExceededError, HackFailedError, NoProblemError, NotFoundError,
|
||||
@@ -34,72 +35,10 @@ import {
|
||||
Handler, param, post, query, route, Types,
|
||||
} from '../service/server';
|
||||
import { buildProjection } from '../utils';
|
||||
import { registerResolver, registerValue } from './api';
|
||||
import { ContestDetailBaseHandler } from './contest';
|
||||
|
||||
export const parseCategory = (value: string) => value.replace(/,/g, ',').split(',').map((e) => e.trim());
|
||||
|
||||
registerValue('FileInfo', [
|
||||
['_id', 'String!'],
|
||||
['name', 'String!'],
|
||||
['size', 'Int'],
|
||||
['lastModified', 'Date'],
|
||||
]);
|
||||
registerValue('Problem', [
|
||||
['_id', 'ObjectID!'],
|
||||
['owner', 'Int!'],
|
||||
['domainId', 'String!'],
|
||||
['docId', 'Int!'],
|
||||
['docType', 'Int!'],
|
||||
['pid', 'String'],
|
||||
['title', 'String!'],
|
||||
['content', 'String!'],
|
||||
['data', '[FileInfo]'],
|
||||
['additional_file', '[FileInfo]'],
|
||||
['nSubmit', 'Int'],
|
||||
['nAccept', 'Int'],
|
||||
['difficulty', 'Int'],
|
||||
['tag', '[String]'],
|
||||
['hidden', 'Boolean'],
|
||||
]);
|
||||
|
||||
registerResolver(
|
||||
'Query', 'problem(id: Int, pid: String)', 'Problem',
|
||||
async (arg, ctx) => {
|
||||
ctx.checkPerm(PERM.PERM_VIEW);
|
||||
const pdoc = await problem.get(ctx.args.domainId, arg.pid || arg.id);
|
||||
if (!pdoc) return null;
|
||||
if (pdoc.hidden) ctx.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN);
|
||||
ctx.pdoc = pdoc;
|
||||
return pdoc;
|
||||
},
|
||||
);
|
||||
registerResolver('Query', 'problems(ids: [Int])', '[Problem]', async (arg, ctx) => {
|
||||
ctx.checkPerm(PERM.PERM_VIEW);
|
||||
const res = await problem.getList(ctx.args.domainId, arg.ids, ctx.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN) || ctx.user._id,
|
||||
undefined, undefined, true);
|
||||
return Object.keys(res).map((id) => res[+id]);
|
||||
}, 'Get a list of problem by ids');
|
||||
registerResolver(
|
||||
'Problem', 'manage', 'ProblemManage',
|
||||
(arg, ctx) => {
|
||||
if (!ctx.user.own(ctx.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) ctx.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
||||
return {};
|
||||
},
|
||||
);
|
||||
registerResolver(
|
||||
'ProblemManage', 'delete', 'Boolean!',
|
||||
async (arg, ctx) => {
|
||||
const tdocs = await contest.getRelated(ctx.args.domainId, ctx.pdoc.docId);
|
||||
if (tdocs.length) throw new ProblemAlreadyUsedByContestError(ctx.pdoc.docId, tdocs[0]._id);
|
||||
return problem.del(ctx.pdoc.domainId, ctx.pdoc.docId);
|
||||
},
|
||||
);
|
||||
registerResolver(
|
||||
'ProblemManage', 'edit(title: String, content: String, tag: [String], hidden: Boolean)', 'Problem!',
|
||||
(arg, ctx) => problem.edit(ctx.args.domainId, ctx.pdoc.docId, arg),
|
||||
);
|
||||
|
||||
function buildQuery(udoc: User) {
|
||||
const q: Filter<ProblemDoc> = {};
|
||||
if (!udoc.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)) {
|
||||
@@ -1078,7 +1017,7 @@ export class ProblemPrefixListHandler extends Handler {
|
||||
}
|
||||
}
|
||||
|
||||
export async function apply(ctx) {
|
||||
export async function apply(ctx: Context) {
|
||||
ctx.Route('problem_main', '/p', ProblemMainHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.Route('problem_random', '/problem/random', ProblemRandomHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.Route('problem_detail', '/p/:pid', ProblemDetailHandler);
|
||||
@@ -1095,4 +1034,65 @@ export async function apply(ctx) {
|
||||
ctx.Route('problem_statistics', '/p/:pid/stat', ProblemStatisticsHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.Route('problem_create', '/problem/create', ProblemCreateHandler, PERM.PERM_CREATE_PROBLEM);
|
||||
ctx.Route('problem_prefix_list', '/problem/list', ProblemPrefixListHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.inject(['api'], ({ api }) => {
|
||||
api.value('FileInfo', [
|
||||
['_id', 'String!'],
|
||||
['name', 'String!'],
|
||||
['size', 'Int'],
|
||||
['lastModified', 'Date'],
|
||||
]);
|
||||
api.value('Problem', [
|
||||
['_id', 'ObjectID!'],
|
||||
['owner', 'Int!'],
|
||||
['domainId', 'String!'],
|
||||
['docId', 'Int!'],
|
||||
['docType', 'Int!'],
|
||||
['pid', 'String'],
|
||||
['title', 'String!'],
|
||||
['content', 'String!'],
|
||||
['data', '[FileInfo]'],
|
||||
['additional_file', '[FileInfo]'],
|
||||
['nSubmit', 'Int'],
|
||||
['nAccept', 'Int'],
|
||||
['difficulty', 'Int'],
|
||||
['tag', '[String]'],
|
||||
['hidden', 'Boolean'],
|
||||
]);
|
||||
api.resolver(
|
||||
'Query', 'problem(id: Int, pid: String)', 'Problem',
|
||||
async (arg, c) => {
|
||||
c.checkPerm(PERM.PERM_VIEW);
|
||||
const pdoc = await problem.get(c.args.domainId, arg.pid || arg.id);
|
||||
if (!pdoc) return null;
|
||||
if (pdoc.hidden) c.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN);
|
||||
c.pdoc = pdoc;
|
||||
return pdoc;
|
||||
},
|
||||
);
|
||||
api.resolver('Query', 'problems(ids: [Int])', '[Problem]', async (arg, c) => {
|
||||
c.checkPerm(PERM.PERM_VIEW);
|
||||
const res = await problem.getList(c.args.domainId, arg.ids, c.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN) || c.user._id,
|
||||
undefined, undefined, true);
|
||||
return Object.keys(res).map((id) => res[+id]);
|
||||
}, 'Get a list of problem by ids');
|
||||
api.resolver(
|
||||
'Problem', 'manage', 'ProblemManage',
|
||||
(arg, c) => {
|
||||
if (!c.user.own(c.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) c.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
||||
return {};
|
||||
},
|
||||
);
|
||||
api.resolver(
|
||||
'ProblemManage', 'delete', 'Boolean!',
|
||||
async (arg, c) => {
|
||||
const tdocs = await contest.getRelated(c.args.domainId, c.pdoc.docId);
|
||||
if (tdocs.length) throw new ProblemAlreadyUsedByContestError(c.pdoc.docId, tdocs[0]._id);
|
||||
return problem.del(c.pdoc.domainId, c.pdoc.docId);
|
||||
},
|
||||
);
|
||||
api.resolver(
|
||||
'ProblemManage', 'edit(title: String, content: String, tag: [String], hidden: Boolean)', 'Problem!',
|
||||
(arg, c) => problem.edit(c.args.domainId, c.pdoc.docId, arg),
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user