mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 17:36:08 +08:00
remove server.log setting item
This commit is contained in:
1 parent
e62e7b49a3
commit
ee78271a84
27 files changed
+159
-114
No files matched your search
+20
-17
@@ -1,21 +1,24 @@
|
||||
/* eslint-disable func-names */
|
||||
const { isClass } = require('./utils');
|
||||
import { isClass } from './utils';
|
||||
|
||||
interface IHydroError {
|
||||
new(...args: any[]): HydroError
|
||||
new(...args: any[]): HydroError
|
||||
}
|
||||
|
||||
const Err = (name: string, ...info: Array<IHydroError | Function | string | number>) => {
|
||||
function isHydroError(item: any): item is IHydroError {
|
||||
return isClass(item);
|
||||
}
|
||||
|
||||
const Err = (name: string, ...info: Array<IHydroError | (() => string) | string | number>) => {
|
||||
let Class: IHydroError;
|
||||
let msg;
|
||||
let code;
|
||||
let msg: () => string;
|
||||
let code: number;
|
||||
for (const item of info) {
|
||||
if (typeof item === 'number') {
|
||||
code = item;
|
||||
} else if (typeof item === 'string') {
|
||||
msg = function () { return item; };
|
||||
} else if (isClass(item)) {
|
||||
// @ts-ignore
|
||||
} else if (isHydroError(item)) {
|
||||
Class = item;
|
||||
} else if (typeof item === 'function') {
|
||||
msg = item;
|
||||
@@ -29,19 +32,19 @@ const Err = (name: string, ...info: Array<IHydroError | Function | string | numb
|
||||
};
|
||||
|
||||
export class HydroError extends Error {
|
||||
params: any[];
|
||||
params: any[];
|
||||
|
||||
code: number;
|
||||
code: number;
|
||||
|
||||
constructor(...params: any[]) {
|
||||
super();
|
||||
this.params = params;
|
||||
}
|
||||
constructor(...params: any[]) {
|
||||
super();
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
msg() {
|
||||
return 'HydroError';
|
||||
}
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
msg() {
|
||||
return 'HydroError';
|
||||
}
|
||||
}
|
||||
|
||||
export const UserFacingError = Err('UserFacingError', HydroError, 'UserFacingError', 400);
|
||||
|
||||
@@ -106,7 +106,9 @@ class DomainUserHandler extends ManageHandler {
|
||||
};
|
||||
}
|
||||
|
||||
async postSetUser({ domainId, uid, role }) {
|
||||
@param('uid', Types.Int)
|
||||
@param('role', Types.String)
|
||||
async postSetUser(domainId: string, uid: number, role: string) {
|
||||
await domain.setUserRole(domainId, uid, role);
|
||||
this.back();
|
||||
}
|
||||
@@ -161,7 +163,8 @@ class DomainRoleHandler extends ManageHandler {
|
||||
this.response.body = { roles, domain: this.domain, path };
|
||||
}
|
||||
|
||||
async postAdd({ domainId, role }) {
|
||||
@param('role', Types.String)
|
||||
async postAdd(domainId: string, role: string) {
|
||||
const roles = await domain.getRoles(this.domain);
|
||||
const rdict: any = {};
|
||||
for (const r of roles) rdict[r._id] = r.perm;
|
||||
@@ -183,7 +186,7 @@ class DomainRoleHandler extends ManageHandler {
|
||||
|
||||
class DomainSearchHandler extends Handler {
|
||||
@param('q', Types.String)
|
||||
async get(q: string) {
|
||||
async get(domainId: string, q: string) {
|
||||
const ddocs = await domain.getPrefixSearch(q, 20);
|
||||
for (let i = 0; i < ddocs.length; i++) {
|
||||
ddocs[i].gravatar = ddocs[i].gravatar ? gravatar(ddocs[i].gravatar) : '/img/team_avatar.png';
|
||||
|
||||
@@ -150,9 +150,9 @@ class HomeSecurityHandler extends Handler {
|
||||
|
||||
@param('currentPassword', Types.String)
|
||||
@param('mail', Types.String, isEmail)
|
||||
async postChangeMail(domainId: string, currentPassword: string, email: string) {
|
||||
async postChangeMail(domainId: string, current: string, email: string) {
|
||||
this.limitRate('send_mail', 3600, 30);
|
||||
this.user.checkPassword(currentPassword);
|
||||
this.user.checkPassword(current);
|
||||
const udoc = await user.getByEmail(domainId, email);
|
||||
if (udoc) throw new UserAlreadyExistError(email);
|
||||
const [code] = await token.add(
|
||||
|
||||
@@ -158,13 +158,4 @@ export async function apply() {
|
||||
Route('ui', '/extra.css', UiSettingsHandler);
|
||||
}
|
||||
|
||||
apply.updateStatus = function updateStatus(args) {
|
||||
args.type = 'judger';
|
||||
return coll.updateOne(
|
||||
{ mid: args.mid, type: 'judger' },
|
||||
{ $set: args },
|
||||
{ upsert: true },
|
||||
);
|
||||
};
|
||||
|
||||
global.Hydro.handler.misc = apply;
|
||||
@@ -15,8 +15,8 @@ import { sendMail } from '../lib/mail';
|
||||
import * as misc from '../lib/misc';
|
||||
import {
|
||||
UserAlreadyExistError, InvalidTokenError, VerifyPasswordError,
|
||||
UserNotFoundError, LoginError, SystemError,
|
||||
BlacklistedError, UserFacingError,
|
||||
UserNotFoundError, SystemError, BlacklistedError,
|
||||
UserFacingError,
|
||||
} from '../error';
|
||||
|
||||
class UserLoginHandler extends Handler {
|
||||
@@ -35,7 +35,7 @@ class UserLoginHandler extends Handler {
|
||||
@param('rememberme', Types.Boolean, true)
|
||||
async post(domainId: string, uname: string, password: string, rememberme = false) {
|
||||
const udoc = await user.getByUname(domainId, uname);
|
||||
if (!udoc) throw new LoginError(uname);
|
||||
if (!udoc) throw new UserNotFoundError(uname);
|
||||
udoc.checkPassword(password);
|
||||
await user.setById(udoc._id, { loginat: new Date(), loginip: this.request.ip });
|
||||
if (udoc.priv === PRIV.PRIV_NONE) throw new BlacklistedError(uname);
|
||||
|
||||
+36
-4
@@ -141,7 +141,7 @@ export interface Pdoc {
|
||||
acMsg?: string,
|
||||
}
|
||||
|
||||
export type Pdict = Dictionary<Pdoc>;
|
||||
export type Pdict = NumericDictionary<Pdoc>;
|
||||
|
||||
export interface TestCase {
|
||||
time: number,
|
||||
@@ -245,7 +245,38 @@ export interface Bdoc {
|
||||
expireAt: Date,
|
||||
}
|
||||
|
||||
interface ContestStat extends Dictionary<any> {
|
||||
// Discussion
|
||||
export interface Ddoc {
|
||||
_id: ObjectID,
|
||||
docType: number,
|
||||
docId: ObjectID,
|
||||
owner: number,
|
||||
title: string,
|
||||
content: string,
|
||||
ip: string,
|
||||
}
|
||||
|
||||
// Discussion reply
|
||||
export interface Drdoc {
|
||||
_id: ObjectID,
|
||||
docType: number,
|
||||
docId: ObjectID,
|
||||
parentType: number,
|
||||
parentId: ObjectID,
|
||||
owner: number,
|
||||
ip: string,
|
||||
reply: Drrdoc[],
|
||||
}
|
||||
|
||||
// Discussion Tail Reply
|
||||
export interface Drrdoc {
|
||||
_id: ObjectID,
|
||||
owner: number,
|
||||
content: string,
|
||||
ip: string,
|
||||
}
|
||||
|
||||
export interface ContestStat extends Dictionary<any> {
|
||||
detail: any,
|
||||
}
|
||||
|
||||
@@ -330,6 +361,7 @@ declare global {
|
||||
gridfs: GridFSBucket,
|
||||
monitor: typeof import('./service/monitor'),
|
||||
server: typeof import('./service/server'),
|
||||
[key: string]: any,
|
||||
},
|
||||
lib: {
|
||||
download: typeof import('./lib/download').default,
|
||||
@@ -363,9 +395,9 @@ declare global {
|
||||
},
|
||||
error: typeof import('./error'),
|
||||
locales: Dict<Dict<string>>,
|
||||
postInit: Function[],
|
||||
postInit: Array<() => Promise<any>>,
|
||||
},
|
||||
onDestory: Function[],
|
||||
onDestory: Array<() => void>,
|
||||
addons: string[],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ function decodeJWT(idToken: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export function decode(idToken: string) {
|
||||
const decodedJWT = decodeJWT(idToken);
|
||||
return decodedJWT.payload;
|
||||
|
||||
@@ -6,12 +6,6 @@ function wrap(func: Function, type: string) {
|
||||
func(...args);
|
||||
if (global.Hydro.model.message) {
|
||||
try {
|
||||
for (let i = 0; i <= args.length; i++) {
|
||||
if (args[i] instanceof Error) {
|
||||
// js-yaml cannot dump [object Error]
|
||||
args[i] = `${args[i].message}\n${args[i].stack}`;
|
||||
}
|
||||
}
|
||||
global.Hydro.model.message.send(1, 1, serialize({ time, type, args }), 0);
|
||||
} catch (e) {
|
||||
func(e.message);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import nodemailer from 'nodemailer';
|
||||
import { SendMailError } from '../error';
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export async function sendMail(to: string, subject: string, text: string, html: string) {
|
||||
let t: unknown;
|
||||
try {
|
||||
|
||||
+12
-11
@@ -1,19 +1,20 @@
|
||||
import AnsiUp from 'ansi_up';
|
||||
import { ObjectID } from 'mongodb';
|
||||
import md5 from './md5';
|
||||
|
||||
const AU = new AnsiUp();
|
||||
|
||||
export function ansiToHtml(str) {
|
||||
export function ansiToHtml(str: string) {
|
||||
return AU.ansi_to_html(str);
|
||||
}
|
||||
|
||||
export function gravatar(email, s = 32) {
|
||||
export function gravatar(email: string, s = 32) {
|
||||
return `//gravatar.loli.net/avatar/${md5((email || '').toString().trim().toLowerCase())}?d=mm&s=${s}`;
|
||||
}
|
||||
|
||||
export function datetimeSpan(dt, relative = true, format = '%Y-%m-%d %H:%M:%S') {
|
||||
export function datetimeSpan(dt: Date | ObjectID, relative = true, format = '%Y-%m-%d %H:%M:%S') {
|
||||
if (!dt) return 'DATETIME_SPAN_ERROR';
|
||||
if (dt.generationTime) dt = new Date(dt.generationTime * 1000);
|
||||
if (dt instanceof ObjectID) dt = new Date(dt.generationTime * 1000);
|
||||
else if (typeof dt === 'number' || typeof dt === 'string') dt = new Date(dt);
|
||||
return '<span class="time{0}" data-timestamp="{1}">{2}</span>'.format(
|
||||
relative ? ' relative' : '',
|
||||
@@ -22,9 +23,10 @@ export function datetimeSpan(dt, relative = true, format = '%Y-%m-%d %H:%M:%S')
|
||||
);
|
||||
}
|
||||
|
||||
export function* paginate(page, numPages) {
|
||||
const radius = 2; let first; let
|
||||
last;
|
||||
export function* paginate(page: number, numPages: number) {
|
||||
const radius = 2;
|
||||
let first: number;
|
||||
let last: number;
|
||||
if (page > 1) {
|
||||
yield ['first', 1];
|
||||
yield ['previous', page - 1];
|
||||
@@ -45,7 +47,7 @@ export function* paginate(page, numPages) {
|
||||
yield ['last', numPages];
|
||||
}
|
||||
|
||||
export function size(s, base = 1) {
|
||||
export function size(s: number, base = 1) {
|
||||
s *= base;
|
||||
const unit = 1024;
|
||||
const unitNames = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
||||
@@ -53,12 +55,11 @@ export function size(s, base = 1) {
|
||||
if (s < unit) return '{0} {1}'.format(Math.round(s * 10) / 10, unitName);
|
||||
s /= unit;
|
||||
}
|
||||
return '{0} {1}'.format(Math.round(s * unit), unitNames[unitNames.length - 1]);
|
||||
return `${Math.round(s * unit)} ${unitNames[unitNames.length - 1]}`;
|
||||
}
|
||||
|
||||
function _digit2(number: number) {
|
||||
if (number < 10) return `0${number}`;
|
||||
return number.toString();
|
||||
return number < 10 ? `0${number}` : number.toString();
|
||||
}
|
||||
|
||||
export function formatSeconds(_seconds = '0') {
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ const Checker = (perm: bigint, priv: number, checker: Function = trueChecker) =>
|
||||
|
||||
const Item = (
|
||||
name: string, args: any, prefix: string,
|
||||
...permPrivChecker: Array<number | bigint | Function | Array<bigint | string>>
|
||||
...permPrivChecker: Array<number | bigint | Function>
|
||||
) => {
|
||||
let _priv: number;
|
||||
let _perm: bigint;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Cursor } from 'mongodb';
|
||||
import { ValidationError } from '../error';
|
||||
|
||||
async function paginate(cursor: import('mongodb').Cursor, page: number, pageSize: number): Promise<[any[], number, number]> {
|
||||
export default async function paginate(
|
||||
cursor: Cursor, page: number, pageSize: number,
|
||||
): Promise<[any[], number, number]> {
|
||||
if (page <= 0) throw new ValidationError('page');
|
||||
const [count, pageDocs] = await Promise.all([
|
||||
cursor.count(),
|
||||
@@ -11,4 +14,3 @@ async function paginate(cursor: import('mongodb').Cursor, page: number, pageSize
|
||||
}
|
||||
|
||||
global.Hydro.lib.paginate = paginate;
|
||||
export default paginate;
|
||||
+11
-8
@@ -1,12 +1,16 @@
|
||||
class User {
|
||||
rank: any;
|
||||
rank: number;
|
||||
|
||||
old: any;
|
||||
old: number;
|
||||
|
||||
seed: number;
|
||||
|
||||
uid: number;
|
||||
|
||||
delta?: number;
|
||||
|
||||
new: number;
|
||||
|
||||
constructor(rank: number, old: number, uid = 0) {
|
||||
this.rank = rank;
|
||||
this.old = old;
|
||||
@@ -16,7 +20,7 @@ class User {
|
||||
}
|
||||
|
||||
class RatingCalculator {
|
||||
users: any;
|
||||
users: User[];
|
||||
|
||||
constructor(users) {
|
||||
this.users = [];
|
||||
@@ -26,11 +30,11 @@ class RatingCalculator {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
calP(a, b) {
|
||||
calP(a: User, b: User) {
|
||||
return 1 / (1 + 10 ** ((b.old - a.old) / 400));
|
||||
}
|
||||
|
||||
getExSeed(rating, ownUser) {
|
||||
getExSeed(rating: number, ownUser: User) {
|
||||
const exUser = new User(0.0, rating);
|
||||
let result = 1;
|
||||
for (const user of this.users) {
|
||||
@@ -39,7 +43,7 @@ class RatingCalculator {
|
||||
return result;
|
||||
}
|
||||
|
||||
calRating(rank, user) {
|
||||
calRating(rank: number, user: User) {
|
||||
let left = 1;
|
||||
let right = 8000;
|
||||
while (right - left > 1) {
|
||||
@@ -101,10 +105,9 @@ interface RatingOutputUser {
|
||||
uid: number,
|
||||
}
|
||||
|
||||
function calculate(users: RatingInputUser[]): RatingOutputUser[] {
|
||||
export default function calculate(users: RatingInputUser[]): RatingOutputUser[] {
|
||||
const calculator = new RatingCalculator(users);
|
||||
return calculator.calculate();
|
||||
}
|
||||
|
||||
global.Hydro.lib.rating = calculate;
|
||||
export default calculate;
|
||||
+2
-16
@@ -67,22 +67,8 @@ function _validate(scheme: any, arg: any, base: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
function descriptor(scheme: any): Function {
|
||||
return function desc(target: any, name: string, obj: any) {
|
||||
const originalMethod = obj.value;
|
||||
obj.value = function func(...args: any[]) {
|
||||
_validate(scheme, args[0], '');
|
||||
return originalMethod.call(this, ...args);
|
||||
};
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
export function validate(scheme: any): Function;
|
||||
export function validate(scheme: any, arg: any): void;
|
||||
export function validate(...args: any[]): any {
|
||||
if (args.length === 1) return descriptor(args[0]);
|
||||
return _validate(args[0], args[1], '');
|
||||
export function validate(scheme: any, arg: any) {
|
||||
return _validate(scheme, arg, '');
|
||||
}
|
||||
|
||||
export const isTitle = (s) => s && s.length < 64;
|
||||
|
||||
@@ -4,6 +4,11 @@ import { Bdoc } from '../interface';
|
||||
const coll = db.collection('blacklist');
|
||||
|
||||
export async function add(ip: string): Promise<Bdoc> {
|
||||
/**
|
||||
* Add a ip into blacklist.
|
||||
* @param {string} ip
|
||||
* @returns {Promise<Bdoc>}
|
||||
*/
|
||||
const expireAt = new Date(new Date().getTime() + 365 * 24 * 60 * 60 * 1000);
|
||||
const res = await coll.findOneAndUpdate(
|
||||
{ _id: ip },
|
||||
@@ -13,7 +18,12 @@ export async function add(ip: string): Promise<Bdoc> {
|
||||
return res.value;
|
||||
}
|
||||
|
||||
export function get(ip: string): Promise<Bdoc> {
|
||||
export function get(ip: string): Promise<Bdoc | null> {
|
||||
/**
|
||||
* Get a ip, return null if not.
|
||||
* @param {string} ip
|
||||
* @returns {Promise<Bdoc>}
|
||||
*/
|
||||
return coll.findOne({ _id: ip });
|
||||
}
|
||||
|
||||
|
||||
+18
-10
@@ -5,6 +5,7 @@ import * as training from './training';
|
||||
import * as document from './document';
|
||||
import { PERM } from './builtin';
|
||||
import { DocumentNotFoundError } from '../error';
|
||||
import { Ddoc, Drdoc, Drrdoc } from '../interface';
|
||||
|
||||
export const typeDisplay = {
|
||||
[document.TYPE_PROBLEM]: 'problem',
|
||||
@@ -18,7 +19,7 @@ export function add(
|
||||
domainId: string, parentType: number, parentId: ObjectID | number | string,
|
||||
owner: number, title: string, content: string,
|
||||
ip: string | null = null, highlight: boolean = false,
|
||||
) {
|
||||
): Promise<ObjectID> {
|
||||
return document.add(
|
||||
domainId, content, owner, document.TYPE_DISCUSSION,
|
||||
null, parentType, parentId,
|
||||
@@ -33,14 +34,14 @@ export function add(
|
||||
);
|
||||
}
|
||||
|
||||
export function get(domainId: string, did: ObjectID) {
|
||||
export function get(domainId: string, did: ObjectID): Promise<Ddoc | null> {
|
||||
return document.get(domainId, document.TYPE_DISCUSSION, did);
|
||||
}
|
||||
|
||||
export function edit(
|
||||
domainId: string, did: ObjectID,
|
||||
title: string, content: string, highlight: boolean,
|
||||
) {
|
||||
): Promise<Ddoc | null> {
|
||||
return document.set(domainId, document.TYPE_DISCUSSION, did, { title, content, highlight });
|
||||
}
|
||||
|
||||
@@ -65,7 +66,7 @@ export function getMulti(domainId: string, query: any = {}) {
|
||||
export async function addReply(
|
||||
domainId: string, did: ObjectID, owner: number,
|
||||
content: string, ip: string,
|
||||
) {
|
||||
): Promise<Drdoc> {
|
||||
const [drdoc] = await Promise.all([
|
||||
document.add(
|
||||
domainId, content, owner, document.TYPE_DISCUSSION_REPLY,
|
||||
@@ -76,11 +77,13 @@ export async function addReply(
|
||||
return drdoc;
|
||||
}
|
||||
|
||||
export function getReply(domainId: string, drid: ObjectID) {
|
||||
export function getReply(domainId: string, drid: ObjectID): Promise<Drdoc | null> {
|
||||
return document.get(domainId, document.TYPE_DISCUSSION_REPLY, drid);
|
||||
}
|
||||
|
||||
export async function editReply(domainId: string, drid: ObjectID, content: string) {
|
||||
export async function editReply(
|
||||
domainId: string, drid: ObjectID, content: string,
|
||||
): Promise<Drdoc | null> {
|
||||
return document.set(domainId, document.TYPE_DISCUSSION_REPLY, drid, { content });
|
||||
}
|
||||
|
||||
@@ -100,14 +103,14 @@ export function getMultiReply(domainId: string, did: ObjectID) {
|
||||
).sort('_id', -1);
|
||||
}
|
||||
|
||||
export function getListReply(domainId: string, did: ObjectID) {
|
||||
export function getListReply(domainId: string, did: ObjectID): Promise<Drdoc[]> {
|
||||
return getMultiReply(domainId, did).toArray();
|
||||
}
|
||||
|
||||
export async function addTailReply(
|
||||
domainId: string, drid: ObjectID,
|
||||
owner: number, content: string, ip: string,
|
||||
) {
|
||||
): Promise<[Drdoc, ObjectID]> {
|
||||
let drdoc = await document.get(domainId, document.TYPE_DISCUSSION_REPLY, drid);
|
||||
const sid = new ObjectID();
|
||||
[drdoc] = await Promise.all([
|
||||
@@ -117,11 +120,16 @@ export async function addTailReply(
|
||||
return [drdoc, sid];
|
||||
}
|
||||
|
||||
export function getTailReply(domainId: string, drid: ObjectID, drrid: ObjectID) {
|
||||
export function getTailReply(
|
||||
domainId: string, drid: ObjectID, drrid: ObjectID,
|
||||
): Promise<[Drdoc, Drrdoc] | [null, null]> {
|
||||
// @ts-ignore
|
||||
return document.getSub(domainId, document.TYPE_DISCUSSION_REPLY, drid, 'reply', drrid);
|
||||
}
|
||||
|
||||
export function editTailReply(domainId: string, drid: ObjectID, drrid: ObjectID, content: string) {
|
||||
export function editTailReply(
|
||||
domainId: string, drid: ObjectID, drrid: ObjectID, content: string,
|
||||
): Promise<Drrdoc> {
|
||||
return document.setSub(domainId, document.TYPE_DISCUSSION_REPLY, drid, 'reply', drrid, { content });
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function send(
|
||||
return mdoc;
|
||||
}
|
||||
|
||||
export async function get(_id: ObjectID): Promise<Mdoc> {
|
||||
export async function get(_id: ObjectID): Promise<Mdoc | null> {
|
||||
return await coll.findOne({ _id });
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export async function getMany(query: any, sort: any, page: number, limit: number
|
||||
.toArray();
|
||||
}
|
||||
|
||||
export async function setFlag(messageId: ObjectID, flag: number) {
|
||||
export async function setFlag(messageId: ObjectID, flag: number): Promise<Mdoc | null> {
|
||||
const result = await coll.findOneAndUpdate(
|
||||
{ _id: messageId },
|
||||
{ $bit: { flag: { xor: flag } } },
|
||||
|
||||
@@ -77,7 +77,7 @@ export function edit(domainId: string, _id: number, $set: any): Promise<Pdoc> {
|
||||
return document.set(domainId, document.TYPE_PROBLEM, _id, $set);
|
||||
}
|
||||
|
||||
export function inc(domainId: string, _id: number, field: string, n: number) {
|
||||
export function inc(domainId: string, _id: number, field: string, n: number): Promise<Pdoc> {
|
||||
return document.inc(domainId, document.TYPE_PROBLEM, _id, field, n);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ export function count(domainId: string, query: any) {
|
||||
return document.count(domainId, document.TYPE_PROBLEM, query);
|
||||
}
|
||||
|
||||
export async function random(domainId: string, query: any) {
|
||||
export async function random(domainId: string, query: any): Promise<string | null> {
|
||||
const cursor = document.getMulti(domainId, document.TYPE_PROBLEM, query);
|
||||
const pcount = await cursor.count();
|
||||
if (pcount) {
|
||||
@@ -100,16 +100,18 @@ export async function getList(
|
||||
): Promise<Pdict> {
|
||||
pids = Array.from(new Set(pids));
|
||||
const r = {};
|
||||
const l = {};
|
||||
const q: any = { $or: [{ docId: { $in: pids } }, { pid: { $in: pids } }] };
|
||||
if (!getHidden) q.hidden = false;
|
||||
const pdocs = await document.getMulti(domainId, document.TYPE_PROBLEM, q).toArray();
|
||||
for (const pdoc of pdocs) {
|
||||
r[pdoc.docId] = pdoc;
|
||||
r[pdoc.pid] = pdoc;
|
||||
l[pdoc.pid] = pdoc;
|
||||
}
|
||||
// TODO enhance
|
||||
if (pdocs.length !== pids.length) {
|
||||
for (const pid of pids) {
|
||||
if (!r[pid]) {
|
||||
if (!(r[pid] || l[pid])) {
|
||||
if (doThrow) {
|
||||
throw new ProblemNotFoundError(domainId, pid);
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import _ from 'lodash';
|
||||
import yaml from 'js-yaml';
|
||||
import { ObjectID } from 'mongodb';
|
||||
import { STATUS } from './builtin';
|
||||
import * as task from './task';
|
||||
|
||||
@@ -121,7 +121,6 @@ SystemSetting(
|
||||
Setting('setting_server', 'server.cdn', null, '/', 'text', 'CDN Prefix', 'Ends with /'),
|
||||
Setting('setting_server', 'server.port', null, 8888, 'number', 'Server Port'),
|
||||
Setting('setting_server', 'server.xff', null, null, 'text', 'IP Header', 'e.g. x-forwarded-for (lowercase)'),
|
||||
Setting('setting_server', 'server.log', null, false, 'boolean', 'Disable Access Log'),
|
||||
Setting('setting_session', 'session.keys', null, [String.random(32)], 'text', 'session.keys', null, FLAG_DISABLED | FLAG_HIDDEN),
|
||||
Setting('setting_session', 'session.secure', null, false, 'boolean', 'session.secure'),
|
||||
Setting('setting_session', 'session.saved_expire_seconds', null, 3600 * 24 * 30, 'number', 'Saved session expire seconds'),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ValidationError } from '../error';
|
||||
import * as db from '../service/db';
|
||||
|
||||
const coll = db.collection('token');
|
||||
|
||||
+8
-1
@@ -8,5 +8,12 @@ export default function load() {
|
||||
if (!fs.existsSync(f)) f = path.resolve(os.homedir(), '.config', 'hydro', 'config.json');
|
||||
if (!fs.existsSync(f)) f = path.resolve(os.homedir(), '.hydro', 'config.json');
|
||||
if (!fs.existsSync(f)) f = path.resolve('/config/config.json');
|
||||
return JSON.parse(fs.readFileSync(f).toString());
|
||||
let result: any = {};
|
||||
try {
|
||||
result = JSON.parse(fs.readFileSync(f).toString());
|
||||
} catch (e) {
|
||||
console.error('Cannot read config file', e);
|
||||
result = {};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ type ND = NumericDictionary<number>
|
||||
function calc(udict: ND, rankedDocs: [number, number][]) {
|
||||
const users = [];
|
||||
for (const [rank, uid] of rankedDocs) {
|
||||
users.push({ uid, rank, old: users[uid] || 1500 });
|
||||
users.push({ uid, rank, old: udict[uid] || 1500 });
|
||||
}
|
||||
const rated = rating(users);
|
||||
for (const udoc of rated) {
|
||||
|
||||
@@ -13,6 +13,15 @@ export async function update() {
|
||||
global.Hydro.stat.reqCount = 0;
|
||||
}
|
||||
|
||||
export function updateJudger(args) {
|
||||
args.type = 'judger';
|
||||
return coll.updateOne(
|
||||
{ mid: args.mid, type: 'judger' },
|
||||
{ $set: args },
|
||||
{ upsert: true },
|
||||
);
|
||||
}
|
||||
|
||||
global.Hydro.postInit.push(
|
||||
async () => {
|
||||
const info = await sysinfo.get();
|
||||
@@ -25,4 +34,4 @@ global.Hydro.postInit.push(
|
||||
},
|
||||
);
|
||||
|
||||
global.Hydro.service.monitor = { update };
|
||||
global.Hydro.service.monitor = { update, updateJudger };
|
||||
@@ -743,8 +743,8 @@ export function Connection(
|
||||
|
||||
// TODO use postInit?
|
||||
export async function start() {
|
||||
const [disableLog, port] = await system.getMany(['server.log', 'server.port']);
|
||||
if (!disableLog) {
|
||||
const port = await system.get('server.port');
|
||||
if (!argv.debug) {
|
||||
app.use(morgan(':method :url :status :res[content-length] - :response-time ms', {
|
||||
skip: (req, res) => res.hasHeader('nolog'),
|
||||
}));
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import fs from 'fs';
|
||||
import { serialize } from 'v8';
|
||||
import cluster from 'cluster';
|
||||
import path from 'path';
|
||||
import * as superagent from 'superagent';
|
||||
import serialize from 'serialize-javascript';
|
||||
import proxy from 'superagent-proxy';
|
||||
import Lru from 'lru-cache';
|
||||
|
||||
@@ -147,13 +147,13 @@ const TIME_UNITS = { '': 1000, m: 1, u: 0.001 };
|
||||
const MEMORY_RE = /^([0-9]+(?:\.[0-9]*)?)([kmg])b?$/i;
|
||||
const MEMORY_UNITS = { k: 0.1, m: 1, g: 1024 };
|
||||
|
||||
export function parseTimeMS(str) {
|
||||
export function parseTimeMS(str: string) {
|
||||
const match = TIME_RE.exec(str);
|
||||
if (!match) throw new Error(`${str} error parsing time`);
|
||||
return Math.floor(parseFloat(match[1]) * TIME_UNITS[match[2]]);
|
||||
}
|
||||
|
||||
export function parseMemoryMB(str) {
|
||||
export function parseMemoryMB(str: string) {
|
||||
const match = MEMORY_RE.exec(str);
|
||||
if (!match) throw new Error(`${str} error parsing memory`);
|
||||
return Math.floor(parseFloat(match[1]) * MEMORY_UNITS[match[2]]);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "2.10.7",
|
||||
"version": "2.10.8",
|
||||
"main": "dist/loader.js",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||
|
||||
Reference in new issue
Block a user