mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 17:36:08 +08:00
better types & use attend instead of enroll
This commit is contained in:
1 parent
e7428c8f79
commit
3dd4c1c994
17 files changed
+141
-82
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "2.13.4",
|
||||
"version": "2.13.5",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"main": "dist/loader.js",
|
||||
"typings": "dist/loader.d.ts",
|
||||
|
||||
@@ -159,7 +159,7 @@ class HomeSecurityHandler extends Handler {
|
||||
if (udoc) throw new UserAlreadyExistError(email);
|
||||
const [code] = await token.add(
|
||||
token.TYPE_CHANGEMAIL,
|
||||
await system.get('changemail_token_expire_seconds'),
|
||||
await system.get('changemail_token_expire_seconds') as number,
|
||||
{ uid: this.user._id, email },
|
||||
);
|
||||
const m = await this.renderHTML('user_changemail_mail.html', {
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
} from '../service/server';
|
||||
import { Tdoc } from '../interface';
|
||||
|
||||
async function _parseDagJson(domainId, dag) {
|
||||
async function _parseDagJson(domainId: string, _dag: string): Promise<Tdoc['dag']> {
|
||||
const parsed = [];
|
||||
try {
|
||||
dag = JSON.parse(dag);
|
||||
const dag = JSON.parse(_dag);
|
||||
assert(dag instanceof Array, 'dag must be an array');
|
||||
const ids = new Set(dag.map((s) => s._id));
|
||||
assert(dag.length === ids.size, '_id must be unique');
|
||||
@@ -177,16 +177,6 @@ class TrainingCreateHandler extends Handler {
|
||||
const pids = training.getPids(dag);
|
||||
assert(pids.length, new ValidationError('dag'));
|
||||
const pdocs = await problem.getMulti(domainId, { docId: { $in: pids } }).sort('_id', 1).toArray();
|
||||
const existPids = pdocs.map((pdoc) => pdoc.docId);
|
||||
const existPnames = pdocs.map((pdoc) => pdoc.pid);
|
||||
if (pids.length !== existPids.length) {
|
||||
for (const pid of pids) {
|
||||
assert(
|
||||
existPids.includes(pid) || existPnames.includes(pid),
|
||||
new ProblemNotFoundError(pid),
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const pdoc of pdocs) {
|
||||
if (pdoc.hidden) this.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN);
|
||||
}
|
||||
@@ -242,11 +232,10 @@ class TrainingEditHandler extends Handler {
|
||||
],
|
||||
}).sort('_id', 1).toArray();
|
||||
const existPids = pdocs.map((pdoc) => pdoc.docId);
|
||||
const existPnames = pdocs.map((pdoc) => pdoc.pid);
|
||||
if (pids.length !== existPids.length) {
|
||||
for (const pid in pids) {
|
||||
assert(
|
||||
existPids.includes(pid) || existPnames.includes(pid),
|
||||
existPids.includes(parseInt(pid, 10)),
|
||||
new ProblemNotFoundError(pid),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class UserRegisterHandler extends Handler {
|
||||
this.limitRate('send_mail', 3600, 30);
|
||||
const t = await token.add(
|
||||
token.TYPE_REGISTRATION,
|
||||
await system.get('registration_token_expire_seconds'),
|
||||
await system.get('registration_token_expire_seconds') as number,
|
||||
{ mail },
|
||||
);
|
||||
if (await system.get('smtp.user')) {
|
||||
@@ -118,7 +118,7 @@ class UserLostPassHandler extends Handler {
|
||||
if (!udoc) throw new UserNotFoundError(mail);
|
||||
const [tid] = await token.add(
|
||||
token.TYPE_LOSTPASS,
|
||||
await system.get('lostpass_token_expire_seconds'),
|
||||
await system.get('lostpass_token_expire_seconds') as number,
|
||||
{ uid: udoc._id },
|
||||
);
|
||||
const m = await this.renderHTML('user_lostpass_mail', { url: `lostpass/${tid}`, uname: udoc.uname });
|
||||
|
||||
@@ -3,6 +3,15 @@ import { ObjectID, GridFSBucket } from 'mongodb';
|
||||
import fs from 'fs';
|
||||
import { Dictionary, NumericDictionary } from 'lodash';
|
||||
|
||||
export type NumberKeys<O> = {
|
||||
[K in keyof O]: number extends O[K] ? K : never
|
||||
}[keyof O]
|
||||
|
||||
export interface System {
|
||||
_id: string,
|
||||
value: string | number,
|
||||
}
|
||||
|
||||
export interface Setting {
|
||||
family: string,
|
||||
key: string,
|
||||
@@ -175,7 +184,7 @@ export interface PretestConfig {
|
||||
}
|
||||
|
||||
export interface ContestInfo {
|
||||
type: number,
|
||||
type: 30 | 60,
|
||||
tid: ObjectID,
|
||||
}
|
||||
|
||||
@@ -293,6 +302,8 @@ export interface Ddoc {
|
||||
ip: string,
|
||||
pin: boolean,
|
||||
highlight: boolean,
|
||||
updateAt: Date,
|
||||
nReply: number,
|
||||
}
|
||||
|
||||
// Discussion reply
|
||||
@@ -379,6 +390,29 @@ export interface JudgeResultBody {
|
||||
|
||||
export type PathComponent = [string, string, Dictionary<any>?, boolean?];
|
||||
|
||||
export interface Collections {
|
||||
'blacklist': Bdoc,
|
||||
'contest': Tdoc,
|
||||
'domain': DomainDoc,
|
||||
'domain.user': any,
|
||||
'record': Rdoc,
|
||||
'document': any,
|
||||
'problem': Pdoc,
|
||||
'user': Udoc,
|
||||
'check': any,
|
||||
'message': Mdoc,
|
||||
'token': TokenDoc,
|
||||
'file': Ufdoc,
|
||||
'status': any,
|
||||
'oauth': any,
|
||||
'system': System,
|
||||
'task': any,
|
||||
'opcount': any,
|
||||
'fs.chunks': any,
|
||||
'fs.files': any,
|
||||
'document.status': any,
|
||||
}
|
||||
|
||||
export interface Model {
|
||||
blacklist: typeof import('./model/blacklist'),
|
||||
builtin: typeof import('./model/builtin'),
|
||||
|
||||
@@ -12,7 +12,7 @@ export async function sendMail(to: string, subject: string, text: string, html:
|
||||
system.get('smtp.user'),
|
||||
system.get('smtp.pass'),
|
||||
system.get('smtp.from'),
|
||||
]);
|
||||
]) as unknown as [string, number, boolean, string, string, string];
|
||||
const transporter = nodemailer.createTransport({
|
||||
host, port, secure, auth: { user, pass },
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ObjectID } from 'mongodb';
|
||||
import { ObjectID, FilterQuery } from 'mongodb';
|
||||
import * as user from './user';
|
||||
import * as problem from './problem';
|
||||
import * as document from './document';
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
import * as misc from '../lib/misc';
|
||||
import ranked from '../lib/rank';
|
||||
|
||||
type Type = 30 | 60;
|
||||
|
||||
const acm: ContestRule = {
|
||||
TEXT: 'ACM/ICPC',
|
||||
check: () => { },
|
||||
@@ -356,7 +358,7 @@ function _getStatusJournal(tsdoc) {
|
||||
export function add(
|
||||
domainId: string, title: string, content: string, owner: number,
|
||||
rule: string, beginAt = new Date(), endAt = new Date(), pids = [],
|
||||
rated = false, data = {}, type = document.TYPE_CONTEST,
|
||||
rated = false, data: Partial<Tdoc> = {}, type: Type = document.TYPE_CONTEST,
|
||||
) {
|
||||
if (!this.RULES[rule]) throw new ValidationError('rule');
|
||||
if (beginAt >= endAt) throw new ValidationError('beginAt', 'endAt');
|
||||
@@ -371,7 +373,7 @@ export function add(
|
||||
|
||||
export async function edit(
|
||||
domainId: string, tid: ObjectID,
|
||||
$set: any, type = document.TYPE_CONTEST,
|
||||
$set: any, type: Type = document.TYPE_CONTEST,
|
||||
) {
|
||||
if ($set.rule) {
|
||||
if (!this.RULES[$set.rule]) throw new ValidationError('rule');
|
||||
@@ -383,7 +385,7 @@ export async function edit(
|
||||
}
|
||||
|
||||
export async function get(
|
||||
domainId: string, tid: ObjectID, type = document.TYPE_CONTEST,
|
||||
domainId: string, tid: ObjectID, type: Type | -1 = document.TYPE_CONTEST,
|
||||
) {
|
||||
let tdoc: Tdoc;
|
||||
if (type === -1) {
|
||||
@@ -396,7 +398,7 @@ export async function get(
|
||||
|
||||
export async function updateStatus(
|
||||
domainId: string, tid: ObjectID, uid: number, rid: ObjectID, pid: number,
|
||||
accept = false, score = 0, type = document.TYPE_CONTEST,
|
||||
accept = false, score = 0, type: 30 | 60 = document.TYPE_CONTEST,
|
||||
) {
|
||||
const tdoc = await get(domainId, tid, type);
|
||||
const tsdoc = await document.revPushStatus(domainId, type, tid, uid, 'journal', {
|
||||
@@ -427,7 +429,7 @@ export async function getListStatus(
|
||||
|
||||
export async function attend(
|
||||
domainId: string, tid: ObjectID, uid: number,
|
||||
type = document.TYPE_CONTEST,
|
||||
type: Type = document.TYPE_CONTEST,
|
||||
) {
|
||||
try {
|
||||
await document.cappedIncStatus(domainId, type, tid, uid, 'attend', 1, 0, 1);
|
||||
@@ -491,7 +493,7 @@ export const ContestHandlerMixin = (c) => class extends c {
|
||||
|
||||
async getScoreboard(
|
||||
domainId: string, tid: ObjectID,
|
||||
isExport = false, docType = document.TYPE_CONTEST,
|
||||
isExport = false, docType: 30 | 60 = document.TYPE_CONTEST,
|
||||
): Promise<[Tdoc, ScoreboardNode[][], Udict]> {
|
||||
const tdoc = await get(domainId, tid, docType);
|
||||
if (!this.canShowScoreboard(tdoc)) throw new ContestScoreboardHiddenError(tid);
|
||||
@@ -522,16 +524,18 @@ export function setStatus(domainId: string, tid: ObjectID, uid: number, $set: an
|
||||
return document.setStatus(domainId, document.TYPE_CONTEST, tid, uid, $set);
|
||||
}
|
||||
|
||||
export function count(domainId: string, query: any, type = document.TYPE_CONTEST) {
|
||||
export function count(domainId: string, query: any, type: Type = document.TYPE_CONTEST) {
|
||||
return document.count(domainId, type, query);
|
||||
}
|
||||
|
||||
export function getMulti(domainId: string, query = {}, type = document.TYPE_CONTEST) {
|
||||
return document.getMulti(domainId, type, query);
|
||||
export function getMulti<K extends Type & keyof document.DocumentType>(
|
||||
domainId: string, query: FilterQuery<document.DocumentType[K]> = {}, type?: K,
|
||||
) {
|
||||
return document.getMulti(domainId, type || document.TYPE_CONTEST, query);
|
||||
}
|
||||
|
||||
export async function getAndListStatus(
|
||||
domainId: string, tid: ObjectID, docType = document.TYPE_CONTEST,
|
||||
domainId: string, tid: ObjectID, docType: Type | -1 = document.TYPE_CONTEST,
|
||||
): Promise<[Tdoc, any[]]> {
|
||||
// TODO(iceboy): projection, pagination.
|
||||
const tdoc = await get(domainId, tid, docType);
|
||||
@@ -540,7 +544,7 @@ export async function getAndListStatus(
|
||||
return [tdoc, tsdocs];
|
||||
}
|
||||
|
||||
export async function recalcStatus(domainId: string, tid: ObjectID, type = document.TYPE_CONTEST) {
|
||||
export async function recalcStatus(domainId: string, tid: ObjectID, type: Type = document.TYPE_CONTEST) {
|
||||
const [tdoc, tsdocs] = await Promise.all([
|
||||
document.get(domainId, type, tid),
|
||||
document.getMultiStatus(domainId, type, { docId: tid }).toArray(),
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import assert from 'assert';
|
||||
import { ObjectID } from 'mongodb';
|
||||
import { ObjectID, Cursor, FilterQuery } from 'mongodb';
|
||||
import * as db from '../service/db';
|
||||
import * as bus from '../service/bus';
|
||||
import {
|
||||
Pdoc, Ddoc, Ufdoc, Drdoc, Tdoc, TrainingDoc, NumberKeys,
|
||||
} from '../interface';
|
||||
|
||||
type DocID = ObjectID | string | number;
|
||||
|
||||
@@ -19,15 +22,28 @@ export const TYPE_TRAINING = 40;
|
||||
export const TYPE_FILE = 50;
|
||||
export const TYPE_HOMEWORK = 60;
|
||||
|
||||
export async function add<T extends DocID>(
|
||||
export interface DocumentType {
|
||||
[TYPE_PROBLEM]: Pdoc,
|
||||
[TYPE_PROBLEM_SOLUTION]: any,
|
||||
[TYPE_PROBLEM_LIST]: any,
|
||||
[TYPE_DISCUSSION_NODE]: any,
|
||||
[TYPE_DISCUSSION]: Ddoc,
|
||||
[TYPE_DISCUSSION_REPLY]: Drdoc,
|
||||
[TYPE_CONTEST]: Tdoc,
|
||||
[TYPE_TRAINING]: TrainingDoc,
|
||||
[TYPE_FILE]: Ufdoc,
|
||||
[TYPE_HOMEWORK]: Tdoc,
|
||||
}
|
||||
|
||||
export async function add<T extends DocID, K extends keyof DocumentType>(
|
||||
domainId: string, content: string, owner: number,
|
||||
docType: number, docId: T,
|
||||
docType: K, docId: DocumentType[K]['docId'],
|
||||
parentType?: number | null, parentId?: DocID,
|
||||
args?: any,
|
||||
): Promise<T>
|
||||
export async function add(
|
||||
export async function add<K extends keyof DocumentType>(
|
||||
domainId: string, content: string, owner: number,
|
||||
docType: number, docId: null,
|
||||
docType: K, docId: null,
|
||||
parentType?: number, parentId?: DocID,
|
||||
args?: any,
|
||||
): Promise<ObjectID>
|
||||
@@ -57,11 +73,13 @@ export async function add(
|
||||
return docId || res.insertedId;
|
||||
}
|
||||
|
||||
export function get(domainId: string, docType: number, docId: DocID) {
|
||||
export function get<K extends keyof DocumentType>(domainId: string, docType: K, docId: DocumentType[K]['docId']) {
|
||||
return coll.findOne({ domainId, docType, docId });
|
||||
}
|
||||
|
||||
export async function set(domainId: string, docType: number, docId: DocID, $set: any) {
|
||||
export async function set<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, docId: DocumentType[K]['docId'], $set: Partial<DocumentType[K]>,
|
||||
): Promise<DocumentType[K]> {
|
||||
await bus.parallel('document/set', domainId, docType, docId, $set);
|
||||
const res = await coll.findOneAndUpdate(
|
||||
{ domainId, docType, docId },
|
||||
@@ -71,28 +89,36 @@ export async function set(domainId: string, docType: number, docId: DocID, $set:
|
||||
return res.value;
|
||||
}
|
||||
|
||||
export function deleteOne(domainId: string, docType: number, docId: DocID) {
|
||||
export function deleteOne<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, docId: DocumentType[K]['docId'],
|
||||
) {
|
||||
return Promise.all([
|
||||
collStatus.deleteMany({ domainId, docType, docId }),
|
||||
coll.deleteOne({ domainId, docType, docId }),
|
||||
]);
|
||||
}
|
||||
|
||||
export function deleteMulti(domainId: string, docType: number, args: any = {}) {
|
||||
return coll.deleteMany({ ...args, domainId, docType });
|
||||
export function deleteMulti<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, query?: FilterQuery<DocumentType[K]>,
|
||||
) {
|
||||
return coll.deleteMany({ ...query, domainId, docType });
|
||||
}
|
||||
|
||||
export function deleteMultiStatus(domainId: string, docType: number, args: any = {}) {
|
||||
return collStatus.deleteMany({ ...args, domainId, docType });
|
||||
export function deleteMultiStatus<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, query?: FilterQuery<DocumentType[K]>,
|
||||
) {
|
||||
return collStatus.deleteMany({ ...query, domainId, docType });
|
||||
}
|
||||
|
||||
export function getMulti(domainId: string, docType: number, args: any = {}) {
|
||||
return coll.find({ ...args, docType, domainId });
|
||||
export function getMulti<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, query?: FilterQuery<DocumentType[K]>,
|
||||
): Cursor<DocumentType[K]> {
|
||||
return coll.find({ ...query, docType, domainId });
|
||||
}
|
||||
|
||||
export async function inc(
|
||||
domainId: string, docType: number, docId: DocID,
|
||||
key: string, value: number,
|
||||
export async function inc<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, docId: DocumentType[K]['docId'],
|
||||
key: NumberKeys<DocumentType[K]>, value: number,
|
||||
) {
|
||||
const res = await coll.findOneAndUpdate(
|
||||
{ domainId, docType, docId },
|
||||
@@ -102,9 +128,11 @@ export async function inc(
|
||||
return res.value;
|
||||
}
|
||||
|
||||
export async function incAndSet(
|
||||
domainId: string, docType: number, docId: DocID,
|
||||
key: string, value: number, args: any,
|
||||
type Q = NumberKeys<DocumentType[10]>
|
||||
|
||||
export async function incAndSet<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, docId: DocumentType[K]['docId'],
|
||||
key: NumberKeys<DocumentType[K]>, value: number, args: Partial<DocumentType[K]>,
|
||||
) {
|
||||
const res = await coll.findOneAndUpdate(
|
||||
{ domainId, docType, docId },
|
||||
@@ -114,13 +142,15 @@ export async function incAndSet(
|
||||
return res.value;
|
||||
}
|
||||
|
||||
export function count(domainId: string, docType: number, query: any) {
|
||||
export function count<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, query?: FilterQuery<DocumentType[K]>,
|
||||
) {
|
||||
return coll.find({ ...query, docType, domainId }).count();
|
||||
}
|
||||
|
||||
export async function push(
|
||||
domainId: string, docType: number, docId: DocID,
|
||||
key: string, content: string, owner: number, args: any = {},
|
||||
export async function push<K extends keyof DocumentType, T extends keyof DocumentType[K]>(
|
||||
domainId: string, docType: K, docId: DocumentType[K]['docId'],
|
||||
key: keyof DocumentType[K], content: string, owner: number, args: DocumentType[K][T][0] = {},
|
||||
) {
|
||||
const _id = new ObjectID();
|
||||
const doc = await coll.findOneAndUpdate(
|
||||
@@ -137,10 +167,10 @@ export async function push(
|
||||
return [doc.value, _id];
|
||||
}
|
||||
|
||||
export async function pull(
|
||||
domainId: string, docType: number, docId: DocID,
|
||||
export async function pull<K extends keyof DocumentType>(
|
||||
domainId: string, docType: K, docId: DocumentType[K]['docId'],
|
||||
setKey: string, contents: string[],
|
||||
) {
|
||||
): Promise<DocumentType[K]> {
|
||||
const res = await coll.findOneAndUpdate(
|
||||
{ domainId, docType, docId },
|
||||
{ $pull: { [setKey]: { $in: contents } } },
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Dictionary } from 'lodash';
|
||||
import { Collection } from 'mongodb';
|
||||
import { BUILTIN_ROLES, PRIV } from './builtin';
|
||||
import { DomainDoc } from '../interface';
|
||||
import * as db from '../service/db';
|
||||
|
||||
const coll: Collection<DomainDoc> = db.collection('domain');
|
||||
const coll = db.collection('domain');
|
||||
const collUser = db.collection('domain.user');
|
||||
|
||||
export const JOIN_METHOD_NONE = 0;
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as file from './file';
|
||||
import * as document from './document';
|
||||
import * as domain from './domain';
|
||||
import {
|
||||
Pdoc, Pdict, ProblemDataSource, ProblemStatusDoc,
|
||||
Pdoc, Pdict, ProblemDataSource, ProblemStatusDoc, NumberKeys,
|
||||
} from '../interface';
|
||||
import { ProblemNotFoundError } from '../error';
|
||||
import * as testdataConfig from '../lib/testdataConfig';
|
||||
@@ -63,7 +63,7 @@ export async function get(
|
||||
if (typeof pid !== 'number') {
|
||||
if (Number.isSafeInteger(parseInt(pid, 10))) pid = parseInt(pid, 10);
|
||||
}
|
||||
const pdoc = Number.isInteger(pid)
|
||||
const pdoc = typeof pid === 'number'
|
||||
? await document.get(domainId, document.TYPE_PROBLEM, pid)
|
||||
: (await document.getMulti(domainId, document.TYPE_PROBLEM, { pid }).toArray())[0];
|
||||
if (!pdoc) return null;
|
||||
@@ -85,7 +85,7 @@ export function edit(domainId: string, _id: number, $set: Partial<Pdoc>): Promis
|
||||
return document.set(domainId, document.TYPE_PROBLEM, _id, $set);
|
||||
}
|
||||
|
||||
export function inc(domainId: string, _id: number, field: string, n: number): Promise<Pdoc> {
|
||||
export function inc(domainId: string, _id: number, field: NumberKeys<Pdoc>, n: number): Promise<Pdoc> {
|
||||
return document.inc(domainId, document.TYPE_PROBLEM, _id, field, n);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ import Lru from 'lru-cache';
|
||||
import * as db from '../service/db';
|
||||
|
||||
const coll = db.collection('system');
|
||||
const cache = new Lru({
|
||||
const cache = new Lru<string, string | number>({
|
||||
maxAge: 5000,
|
||||
});
|
||||
|
||||
export async function get(_id: string) {
|
||||
export async function get(_id: string): Promise<string | number> {
|
||||
const res = cache.get(_id);
|
||||
if (res !== undefined) return res;
|
||||
const doc = await coll.findOne({ _id });
|
||||
@@ -51,11 +51,13 @@ export async function set(_id: string, value: any) {
|
||||
export async function inc(_id: string) {
|
||||
const res = await coll.findOneAndUpdate(
|
||||
{ _id },
|
||||
// FIXME NumberKeys<>
|
||||
// @ts-ignore
|
||||
{ $inc: { value: 1 } },
|
||||
{ upsert: true, returnOriginal: false },
|
||||
);
|
||||
cache.set(_id, res.value.value);
|
||||
return res.value.value;
|
||||
return res.value.value as number;
|
||||
}
|
||||
|
||||
global.Hydro.model.system = {
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function enroll(domainId: string, tid: ObjectID, uid: number) {
|
||||
} catch (e) {
|
||||
throw new TrainingAlreadyEnrollError(tid, uid);
|
||||
}
|
||||
return await document.inc(domainId, document.TYPE_TRAINING, tid, 'enroll', 1);
|
||||
return await document.inc(domainId, document.TYPE_TRAINING, tid, 'attend', 1);
|
||||
}
|
||||
|
||||
export function setStatus(domainId: string, tid: ObjectID, uid: number, $set: any) {
|
||||
@@ -42,7 +42,7 @@ export function add(
|
||||
dag,
|
||||
title,
|
||||
description,
|
||||
enroll: 0,
|
||||
attend: 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ async function runInDomain(domainId: string, isSub: boolean, report: Function) {
|
||||
for (const dudoc of dudocs) {
|
||||
deltaudict[dudoc.uid] = dudoc.rpdelta || 0;
|
||||
}
|
||||
const contests = await contest.getMulti(domainId, { rated: true }, -1).sort('endAt', -1).toArray();
|
||||
const contests = await contest.getMulti(domainId, { rated: true }).sort('endAt', -1).toArray();
|
||||
await report({ message: `Found ${contests.length} contests in ${domainId}` });
|
||||
for (const i in contests) {
|
||||
const tdoc = contests[i];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import mongodb from 'mongodb';
|
||||
import mongodb, { Collection } from 'mongodb';
|
||||
import * as bus from './bus';
|
||||
import options from '../options';
|
||||
import { Collections } from '../interface';
|
||||
|
||||
const opts = options();
|
||||
|
||||
@@ -25,7 +26,7 @@ mongodb.MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopolog
|
||||
});
|
||||
});
|
||||
|
||||
export function collection(c: string) {
|
||||
export function collection<K extends keyof Collections>(c: K): Collection<Collections[K]> {
|
||||
if (opts.prefix) return db.collection(`${opts.prefix}.${c}`);
|
||||
return db.collection(c);
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ export function requireCsrfToken(target: any, funcName: string, obj: any) {
|
||||
}
|
||||
|
||||
export async function prepare() {
|
||||
app.keys = await system.get('session.keys');
|
||||
app.keys = await system.get('session.keys') as unknown as string[];
|
||||
if (argv.public) {
|
||||
app.use(cache(argv.public, {
|
||||
maxAge: 0,
|
||||
@@ -402,7 +402,7 @@ export class Handler {
|
||||
}
|
||||
|
||||
async init({ domainId }) {
|
||||
const xff = await system.get('server.xff');
|
||||
const xff = await system.get('server.xff') as string;
|
||||
if (xff) this.request.ip = this.request.headers[xff.toLowerCase()];
|
||||
[this.domain] = await Promise.all([
|
||||
domain.get(domainId),
|
||||
@@ -498,8 +498,8 @@ export class Handler {
|
||||
|
||||
async saveCookie() {
|
||||
const expireSeconds = this.session.save
|
||||
? await system.get('session.expire_seconds')
|
||||
: await system.get('session.unsaved_expire_seconds');
|
||||
? await system.get('session.expire_seconds') as number
|
||||
: await system.get('session.unsaved_expire_seconds') as number;
|
||||
if (this.session._id) {
|
||||
await token.update(
|
||||
this.session._id,
|
||||
@@ -525,7 +525,7 @@ export class Handler {
|
||||
);
|
||||
}
|
||||
const cookie: SetOption = {
|
||||
secure: await system.get('session.secure'),
|
||||
secure: !!await system.get('session.secure'),
|
||||
httpOnly: false,
|
||||
};
|
||||
if (this.session.save) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/migrate-vijos",
|
||||
"version": "1.3.7",
|
||||
"version": "1.3.8",
|
||||
"main": "package.json",
|
||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||
"author": "undefined <masnn0@outlook.com>",
|
||||
@@ -14,7 +14,7 @@
|
||||
"@types/mongodb": "^3.5.27"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hydrooj": "^2.13.0"
|
||||
"hydrooj": "^2.13.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-yaml": "^3.14.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import {
|
||||
Rdoc, TestCase, Mdoc, Drrdoc,
|
||||
Rdoc, TestCase, Mdoc, Drrdoc, TrainingNode,
|
||||
} from 'hydrooj';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
@@ -126,12 +126,12 @@ const tasks = {
|
||||
},
|
||||
attend: 'attend',
|
||||
desc: 'description',
|
||||
enroll: 'enroll',
|
||||
enroll: 'attend',
|
||||
rated: 'rated',
|
||||
dag: {
|
||||
field: 'dag',
|
||||
processer: (dag) => {
|
||||
const r = [];
|
||||
const r: TrainingNode[] = [];
|
||||
for (const t of dag) {
|
||||
r.push({
|
||||
_id: t._id,
|
||||
|
||||
Reference in new issue
Block a user