You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/packages/hydrojudge/src/utils.ts

93 lines
2.8 KiB
TypeScript

import fs from 'fs-extra';
import path from 'path';
import { parse } from 'shell-quote';
import _ from 'lodash';
import { EventEmitter } from 'events';
import { FormatError } from './error';
const EMPTY_STR = /^[ \r\n\t]*$/i;
export const cmd = parse;
export function parseFilename(filePath: string) {
const t = filePath.split('/');
return t[t.length - 1];
}
export class Queue<T> extends EventEmitter {
queue: T[] = [];
waiting: any[] = [];
get(count = 1) {
if (this.queue.length < count) {
return new Promise<T[]>((resolve) => {
this.waiting.push({ count, resolve });
});
}
const items = [];
for (let i = 0; i < count; i++) { items.push(this.queue[i]); }
this.queue = _.drop(this.queue, count);
return items as T[];
}
push(value: T) {
this.queue.push(value);
if (this.waiting.length && this.waiting[0].count <= this.queue.length) {
const items = [];
for (let i = 0; i < this.waiting[0].count; i++) { items.push(this.queue[i]); }
this.queue = _.drop(this.queue, this.waiting[0].count);
this.waiting[0].resolve(items);
this.waiting.shift();
}
}
}
export function compilerText(stdout: string, stderr: string) {
const ret = [];
if (!EMPTY_STR.test(stdout)) ret.push(stdout.substr(0, 1024 * 1024));
if (!EMPTY_STR.test(stderr)) ret.push(stderr.substr(0, 1024 * 1024));
return ret.join('\n');
}
export function copyInDir(dir: string) {
const files = {};
if (fs.existsSync(dir)) {
fs.readdirSync(dir).forEach((f1) => {
const p1 = `${dir}/${f1}`;
if (fs.statSync(p1).isDirectory()) {
fs.readdirSync(p1).forEach((f2) => {
files[`${f1}/${f2}`] = { src: `${dir}/${f1}/${f2}` };
});
} else files[f1] = { src: `${dir}/${f1}` };
});
}
return files;
}
export function restrictFile(p: string) {
if (!p) return '/';
if (p[0] === '/') p = '';
return p.replace(/\.\./gmi, '');
}
export function ensureFile(folder: string) {
return (file: string, message: string) => {
3 years ago
if (file === '/dev/null') return file;
4 years ago
// Historical issue
if (file.includes('/')) {
const f = path.join(folder, restrictFile(file.split('/')[1]));
if (fs.existsSync(f)) {
const stat = fs.statSync(f);
if (stat.isFile()) return f;
}
}
const f = path.join(folder, restrictFile(file));
if (!fs.existsSync(f)) throw new FormatError(message, [file]);
const stat = fs.statSync(f);
if (!stat.isFile()) throw new FormatError(message, [file]);
return f;
};
}
export * from '@hydrooj/utils/lib/utils';