mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
eslint: add github/array-foreach rule
This commit is contained in:
21 files changed
+59
-51
No files matched your search
@@ -12,6 +12,7 @@ plugins:
|
|||||||
- '@typescript-eslint'
|
- '@typescript-eslint'
|
||||||
- simple-import-sort
|
- simple-import-sort
|
||||||
- eslint-plugin-import
|
- eslint-plugin-import
|
||||||
|
- eslint-plugin-github
|
||||||
rules:
|
rules:
|
||||||
'@typescript-eslint/no-shadow': 1
|
'@typescript-eslint/no-shadow': 1
|
||||||
|
|
||||||
@@ -146,6 +147,8 @@ rules:
|
|||||||
- selector: WithStatement
|
- selector: WithStatement
|
||||||
message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.'
|
message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.'
|
||||||
|
|
||||||
|
github/array-foreach: 1
|
||||||
|
|
||||||
simple-import-sort/imports:
|
simple-import-sort/imports:
|
||||||
- warn
|
- warn
|
||||||
- groups:
|
- groups:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"@typescript-eslint/parser": "^6.8.0",
|
"@typescript-eslint/parser": "^6.8.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||||
|
"eslint-plugin-github": "^4.10.1",
|
||||||
"eslint-plugin-import": "2.28.1",
|
"eslint-plugin-import": "2.28.1",
|
||||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
|
|||||||
@@ -637,9 +637,9 @@ export class ContestUserHandler extends ContestManagementBaseHandler {
|
|||||||
const tsdocs = await contest.getMultiStatus(domainId, { docId: tid }).project({
|
const tsdocs = await contest.getMultiStatus(domainId, { docId: tid }).project({
|
||||||
uid: 1, attend: 1, startAt: 1, unrank: 1,
|
uid: 1, attend: 1, startAt: 1, unrank: 1,
|
||||||
}).toArray();
|
}).toArray();
|
||||||
tsdocs.forEach((i) => {
|
for (const tsdoc of tsdocs) {
|
||||||
i.endAt = (this.tdoc.duration && i.startAt) ? moment(i.startAt).add(this.tdoc.duration, 'hours').toDate() : null;
|
tsdoc.endAt = (this.tdoc.duration && tsdoc.startAt) ? moment(tsdoc.startAt).add(this.tdoc.duration, 'hours').toDate() : null;
|
||||||
});
|
}
|
||||||
const udict = await user.getListForRender(domainId, [this.tdoc.owner, ...tsdocs.map((i) => i.uid)]);
|
const udict = await user.getListForRender(domainId, [this.tdoc.owner, ...tsdocs.map((i) => i.uid)]);
|
||||||
this.response.body = { tdoc: this.tdoc, tsdocs, udict };
|
this.response.body = { tdoc: this.tdoc, tsdocs, udict };
|
||||||
this.response.pjax = 'partials/contest_user.html';
|
this.response.pjax = 'partials/contest_user.html';
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export class HomeHandler extends Handler {
|
|||||||
uids = new Set<number>();
|
uids = new Set<number>();
|
||||||
|
|
||||||
collectUser(uids: number[]) {
|
collectUser(uids: number[]) {
|
||||||
uids.forEach((uid) => this.uids.add(uid));
|
for (const uid of uids) this.uids.add(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHomework(domainId: string, limit = 5) {
|
async getHomework(domainId: string, limit = 5) {
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class DomainModel {
|
|||||||
const affected = await UserModel.getMulti({ _id: { $in: uid } })
|
const affected = await UserModel.getMulti({ _id: { $in: uid } })
|
||||||
.project<{ _id: number, mail: string, uname: string }>({ mail: 1, uname: 1 })
|
.project<{ _id: number, mail: string, uname: string }>({ mail: 1, uname: 1 })
|
||||||
.toArray();
|
.toArray();
|
||||||
affected.forEach((udoc) => deleteUserCache(udoc));
|
for (const udoc of affected) deleteUserCache(udoc);
|
||||||
return await collUser.updateMany({ domainId, uid: { $in: uid } }, { $set: { role } }, { upsert: true });
|
return await collUser.updateMany({ domainId, uid: { $in: uid } }, { $set: { role } }, { upsert: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export async function add(data: Partial<OplogDoc> & { type: string }): Promise<O
|
|||||||
|
|
||||||
function safeKeys(data: any) {
|
function safeKeys(data: any) {
|
||||||
if (['string', 'number', 'boolean'].includes(typeof data)) return data;
|
if (['string', 'number', 'boolean'].includes(typeof data)) return data;
|
||||||
if (data instanceof Array) data.forEach(safeKeys);
|
if (data instanceof Array) for (const d of data) safeKeys(d);
|
||||||
else if (data instanceof ObjectId) return data;
|
else if (data instanceof ObjectId) return data;
|
||||||
else if (data instanceof Object) {
|
else if (data instanceof Object) {
|
||||||
for (const key in data) {
|
for (const key in data) {
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ export function Connection(
|
|||||||
closed = true;
|
closed = true;
|
||||||
bus.emit('connection/close', h);
|
bus.emit('connection/close', h);
|
||||||
if (interval) clearInterval(interval);
|
if (interval) clearInterval(interval);
|
||||||
disposables.forEach((d) => d());
|
for (const d of disposables) d();
|
||||||
h.cleanup?.(args);
|
h.cleanup?.(args);
|
||||||
};
|
};
|
||||||
interval = setInterval(() => {
|
interval = setInterval(() => {
|
||||||
@@ -555,8 +555,10 @@ ${ctx.response.status} ${endTime - startTime}ms ${ctx.response.length}`);
|
|||||||
const layers = [baseLayer, rendererLayer(router, logger), responseLayer(logger), userLayer];
|
const layers = [baseLayer, rendererLayer(router, logger), responseLayer(logger), userLayer];
|
||||||
app.use(async (ctx, next) => await next().catch(console.error)).use(domainLayer);
|
app.use(async (ctx, next) => await next().catch(console.error)).use(domainLayer);
|
||||||
app.use(router.routes()).use(router.allowedMethods());
|
app.use(router.routes()).use(router.allowedMethods());
|
||||||
layers.forEach((layer) => router.use(layer as any));
|
for (const layer of layers) {
|
||||||
layers.forEach((layer) => app.use(layer as any));
|
router.use(layer as any);
|
||||||
|
app.use(layer);
|
||||||
|
}
|
||||||
app.use((ctx) => handle(ctx, NotFoundHandler, () => true));
|
app.use((ctx) => handle(ctx, NotFoundHandler, () => true));
|
||||||
wsServer.on('connection', async (socket, request) => {
|
wsServer.on('connection', async (socket, request) => {
|
||||||
socket.on('error', (err) => {
|
socket.on('error', (err) => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// This file was adapted from @koishijs, MIT licensed.
|
||||||
/* eslint-disable consistent-return */
|
/* eslint-disable consistent-return */
|
||||||
/* eslint-disable import/no-dynamic-require */
|
/* eslint-disable import/no-dynamic-require */
|
||||||
/* eslint-disable @typescript-eslint/no-shadow */
|
/* eslint-disable @typescript-eslint/no-shadow */
|
||||||
@@ -13,7 +14,7 @@ function loadDependencies(filename: string, ignored: Set<string>) {
|
|||||||
function traverse({ filename, children }: NodeJS.Module) {
|
function traverse({ filename, children }: NodeJS.Module) {
|
||||||
if (ignored.has(filename) || dependencies.has(filename) || filename.includes('/node_modules/')) return;
|
if (ignored.has(filename) || dependencies.has(filename) || filename.includes('/node_modules/')) return;
|
||||||
dependencies.add(filename);
|
dependencies.add(filename);
|
||||||
children.forEach(traverse);
|
for (const c of children) traverse(c);
|
||||||
}
|
}
|
||||||
traverse(require.cache[filename]);
|
traverse(require.cache[filename]);
|
||||||
return dependencies;
|
return dependencies;
|
||||||
@@ -87,13 +88,13 @@ export default class Watcher extends Service {
|
|||||||
this.accepted = new Set(this.stashed);
|
this.accepted = new Set(this.stashed);
|
||||||
this.declined = new Set(this.externals);
|
this.declined = new Set(this.externals);
|
||||||
|
|
||||||
this.stashed.forEach((filename) => {
|
for (const filename of this.stashed) {
|
||||||
const { children } = require.cache[filename];
|
const { children } = require.cache[filename];
|
||||||
for (const { filename } of children) {
|
for (const { filename } of children) {
|
||||||
if (this.accepted.has(filename) || this.declined.has(filename) || filename.includes('/node_modules/')) continue;
|
if (this.accepted.has(filename) || this.declined.has(filename) || filename.includes('/node_modules/')) continue;
|
||||||
pending.push(filename);
|
pending.push(filename);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
while (pending.length) {
|
while (pending.length) {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
@@ -168,7 +169,7 @@ export default class Watcher extends Service {
|
|||||||
// we only detect reloads at plugin level
|
// we only detect reloads at plugin level
|
||||||
// a plugin will be reloaded if any of its dependencies are accepted
|
// a plugin will be reloaded if any of its dependencies are accepted
|
||||||
if (!dependencies.some((dep) => this.accepted.has(dep))) continue;
|
if (!dependencies.some((dep) => this.accepted.has(dep))) continue;
|
||||||
dependencies.forEach((dep) => this.accepted.add(dep));
|
for (const dep of dependencies) this.accepted.add(dep);
|
||||||
|
|
||||||
// prepare for reload
|
// prepare for reload
|
||||||
let isMarked = false;
|
let isMarked = false;
|
||||||
|
|||||||
@@ -434,10 +434,10 @@ const scripts: UpgradeScript[] = [
|
|||||||
null,
|
null,
|
||||||
async function _65_66() {
|
async function _65_66() {
|
||||||
return await iterateAllDomain(async (ddoc) => {
|
return await iterateAllDomain(async (ddoc) => {
|
||||||
Object.keys(ddoc.roles).forEach((role) => {
|
for (const role of Object.keys(ddoc.roles)) {
|
||||||
if (['guest', 'root'].includes(role)) return;
|
if (['guest', 'root'].includes(role)) return;
|
||||||
ddoc.roles[role] = (BigInt(ddoc.roles[role]) | PERM.PREM_VIEW_DISPLAYNAME).toString();
|
ddoc.roles[role] = (BigInt(ddoc.roles[role]) | PERM.PREM_VIEW_DISPLAYNAME).toString();
|
||||||
});
|
}
|
||||||
await domain.setRoles(ddoc._id, ddoc.roles);
|
await domain.setRoles(ddoc._id, ddoc.roles);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -331,19 +331,21 @@ export async function run({
|
|||||||
if (judgeState) {
|
if (judgeState) {
|
||||||
if (judgeState.compile?.message) data.compilerTexts.push(judgeState.compile.message.replace(/<.+?>/g, ''));
|
if (judgeState.compile?.message) data.compilerTexts.push(judgeState.compile.message.replace(/<.+?>/g, ''));
|
||||||
if (judgeState.judge) {
|
if (judgeState.judge) {
|
||||||
judgeState.judge.subtasks.forEach((subtask, index) => {
|
for (let i = 0; i < judgeState.judge.subtasks.length; i++) {
|
||||||
subtask.cases.forEach((curCase, caseIndex) => {
|
const subtask = judgeState.judge.subtasks.length[i];
|
||||||
|
for (let j = 0; j < subtask.cases.length; j++) {
|
||||||
|
const curCase = subtask.cases[j];
|
||||||
data.testCases.push({
|
data.testCases.push({
|
||||||
subtaskId: index + 1,
|
subtaskId: i + 1,
|
||||||
id: caseIndex + 1,
|
id: j + 1,
|
||||||
score: Math.trunc((curCase.result?.scoringRate || 0) * 100),
|
score: Math.trunc((curCase.result?.scoringRate || 0) * 100),
|
||||||
time: curCase.result?.time || 0,
|
time: curCase.result?.time || 0,
|
||||||
memory: curCase.result?.memory || 0,
|
memory: curCase.result?.memory || 0,
|
||||||
message: curCase.result?.spjMessage || curCase.result?.systemMessage || curCase.result?.userError || '',
|
message: curCase.result?.spjMessage || curCase.result?.systemMessage || curCase.result?.userError || '',
|
||||||
status: curCase.status === 2 ? TestcaseJudgeStatusMap[curCase.result.type] : TestcaseStatusMap[curCase.status],
|
status: curCase.status === 2 ? TestcaseJudgeStatusMap[curCase.result.type] : TestcaseStatusMap[curCase.status],
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rdoc.type) {
|
if (rdoc.type) {
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ export async function run({
|
|||||||
try {
|
try {
|
||||||
const details = await xml2js.parseStringPromise(result.details);
|
const details = await xml2js.parseStringPromise(result.details);
|
||||||
if (details.tests.subtask) {
|
if (details.tests.subtask) {
|
||||||
details.tests.subtask.forEach((subtask) => {
|
for (const subtask of details.tests.subtask) {
|
||||||
if (!subtask.test) {
|
if (!subtask.test) {
|
||||||
data.testCases.push({
|
data.testCases.push({
|
||||||
subtaskId: subtask.$.num,
|
subtaskId: subtask.$.num,
|
||||||
@@ -409,7 +409,7 @@ export async function run({
|
|||||||
message: 'Skipped',
|
message: 'Skipped',
|
||||||
status: STATUS.STATUS_CANCELED,
|
status: STATUS.STATUS_CANCELED,
|
||||||
});
|
});
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
data.testCases.push(...subtask.test.map((curCase, caseIndex) => ({
|
data.testCases.push(...subtask.test.map((curCase, caseIndex) => ({
|
||||||
subtaskId: subtask.$.num,
|
subtaskId: subtask.$.num,
|
||||||
@@ -420,7 +420,7 @@ export async function run({
|
|||||||
message: curCase.res[0] || '',
|
message: curCase.res[0] || '',
|
||||||
status: statusMap[curCase.$.info] || STATUS.STATUS_WAITING,
|
status: statusMap[curCase.$.info] || STATUS.STATUS_WAITING,
|
||||||
})));
|
})));
|
||||||
});
|
}
|
||||||
} else if (details.tests.test) {
|
} else if (details.tests.test) {
|
||||||
data.testCases.push(...details.tests.test.map((curCase) => ({
|
data.testCases.push(...details.tests.test.map((curCase) => ({
|
||||||
subtaskId: 1,
|
subtaskId: 1,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable github/array-foreach */
|
||||||
import { $, addPage, AutoloadPage } from '@hydrooj/ui-default';
|
import { $, addPage, AutoloadPage } from '@hydrooj/ui-default';
|
||||||
|
|
||||||
/* global DocsAPI */
|
/* global DocsAPI */
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ export default async function readYamlCases(cfg: Record<string, any> = {}, check
|
|||||||
}
|
}
|
||||||
if (cfg.interactor) config.interactor = checkFile(cfg.interactor, 'Cannot find interactor {0}.');
|
if (cfg.interactor) config.interactor = checkFile(cfg.interactor, 'Cannot find interactor {0}.');
|
||||||
if (cfg.validator) config.validator = checkFile(cfg.validator, 'Cannot find validator {0}.');
|
if (cfg.validator) config.validator = checkFile(cfg.validator, 'Cannot find validator {0}.');
|
||||||
['judge', 'user'].forEach((n) => {
|
for (const n of ['judge', 'user']) {
|
||||||
const conf = cfg[`${n}_extra_files`];
|
const conf = cfg[`${n}_extra_files`];
|
||||||
if (!conf) return;
|
if (!conf) continue;
|
||||||
if (conf instanceof Array) {
|
if (conf instanceof Array) {
|
||||||
config[`${n}_extra_files`] = conf.map((file) => checkFile(file, `Cannot find ${n} extra file {0}.`));
|
config[`${n}_extra_files`] = conf.map((file) => checkFile(file, `Cannot find ${n} extra file {0}.`));
|
||||||
} else throw new Error(`Invalid ${n}_extra_files config.`);
|
} else throw new Error(`Invalid ${n}_extra_files config.`);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
if (cfg.cases?.length) {
|
if (cfg.cases?.length) {
|
||||||
config.subtasks = [{
|
config.subtasks = [{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export interface LangConfig {
|
|||||||
export function parseLang(config: string): Record<string, LangConfig> {
|
export function parseLang(config: string): Record<string, LangConfig> {
|
||||||
const file = yaml.load(config) as Record<string, LangConfig>;
|
const file = yaml.load(config) as Record<string, LangConfig>;
|
||||||
if (typeof file === 'undefined' || typeof file === 'string' || typeof file === 'number') throw new Error();
|
if (typeof file === 'undefined' || typeof file === 'string' || typeof file === 'number') throw new Error();
|
||||||
Object.keys(file).filter((i) => i.startsWith('_')).forEach((k) => delete file[k]);
|
for (const key of Object.keys(file)) if (key.startsWith('_')) delete file[key];
|
||||||
for (const key in file) {
|
for (const key in file) {
|
||||||
const entry = file[key];
|
const entry = file[key];
|
||||||
if (key.includes('.')) {
|
if (key.includes('.')) {
|
||||||
|
|||||||
@@ -36,9 +36,7 @@ export function folderSize(folderPath: string) {
|
|||||||
size += stats.size;
|
size += stats.size;
|
||||||
const files = fs.readdirSync(p);
|
const files = fs.readdirSync(p);
|
||||||
if (Array.isArray(files)) {
|
if (Array.isArray(files)) {
|
||||||
files.forEach((file) => {
|
for (const file of files) _next(path.join(p, file));
|
||||||
_next(path.join(p, file));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,9 +245,9 @@ export function CallableInstance(property = '__call__') {
|
|||||||
else func = this.constructor.prototype[property];
|
else func = this.constructor.prototype[property];
|
||||||
const apply = function __call__(...args) { return func.apply(apply, ...args); };
|
const apply = function __call__(...args) { return func.apply(apply, ...args); };
|
||||||
Object.setPrototypeOf(apply, this.constructor.prototype);
|
Object.setPrototypeOf(apply, this.constructor.prototype);
|
||||||
Object.getOwnPropertyNames(func).forEach((p) => {
|
for (const p of Object.getOwnPropertyNames(func)) {
|
||||||
Object.defineProperty(apply, p, Object.getOwnPropertyDescriptor(func, p));
|
Object.defineProperty(apply, p, Object.getOwnPropertyDescriptor(func, p));
|
||||||
});
|
}
|
||||||
return apply;
|
return apply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class AccountService {
|
|||||||
await next({ status: STATUS.STATUS_JUDGING, message: `ID = ${rid}` });
|
await next({ status: STATUS.STATUS_JUDGING, message: `ID = ${rid}` });
|
||||||
const nextFunction = (data) => {
|
const nextFunction = (data) => {
|
||||||
if (data.case) delete data.case.message;
|
if (data.case) delete data.case.message;
|
||||||
if (data.cases) data.cases.forEach((x) => delete x.message);
|
if (data.cases) for (const x of data.cases) delete x.message;
|
||||||
return next(data);
|
return next(data);
|
||||||
};
|
};
|
||||||
await this.api.waitForSubmission(rid, task.config?.detail === false ? nextFunction : next, end);
|
await this.api.waitForSubmission(rid, task.config?.detail === false ? nextFunction : next, end);
|
||||||
|
|||||||
@@ -177,15 +177,15 @@ export default class CodeforcesProvider extends BasicFetcher implements IBasicPr
|
|||||||
const text = $dom.window.document.querySelector('.problem-statement').innerHTML;
|
const text = $dom.window.document.querySelector('.problem-statement').innerHTML;
|
||||||
const { window: { document } } = new JSDOM(text);
|
const { window: { document } } = new JSDOM(text);
|
||||||
const files = {};
|
const files = {};
|
||||||
document.querySelectorAll('img[src]').forEach((ele) => {
|
for (const ele of document.querySelectorAll('img[src]')) {
|
||||||
const src = ele.getAttribute('src');
|
const src = ele.getAttribute('src');
|
||||||
if (!src.startsWith('http')) return;
|
if (!src.startsWith('http')) continue;
|
||||||
const file = new PassThrough();
|
const file = new PassThrough();
|
||||||
this.get(src).pipe(file);
|
this.get(src).pipe(file);
|
||||||
const fid = String.random(8);
|
const fid = String.random(8);
|
||||||
files[`${fid}.png`] = file;
|
files[`${fid}.png`] = file;
|
||||||
ele.setAttribute('src', `file://${fid}.png`);
|
ele.setAttribute('src', `file://${fid}.png`);
|
||||||
});
|
}
|
||||||
const title = document.querySelector('.title').innerHTML.trim().split('. ')[1];
|
const title = document.querySelector('.title').innerHTML.trim().split('. ')[1];
|
||||||
const time = parseInt(document.querySelector('.time-limit').innerHTML.substr(53, 2), 10);
|
const time = parseInt(document.querySelector('.time-limit').innerHTML.substr(53, 2), 10);
|
||||||
const memory = parseInt(document.querySelector('.memory-limit').innerHTML.substr(55, 4), 10);
|
const memory = parseInt(document.querySelector('.memory-limit').innerHTML.substr(55, 4), 10);
|
||||||
@@ -200,11 +200,11 @@ export default class CodeforcesProvider extends BasicFetcher implements IBasicPr
|
|||||||
const note = document.querySelector('.note')?.innerHTML.trim();
|
const note = document.querySelector('.note')?.innerHTML.trim();
|
||||||
document.querySelector('.note')?.remove();
|
document.querySelector('.note')?.remove();
|
||||||
document.querySelector('.sample-tests')?.remove();
|
document.querySelector('.sample-tests')?.remove();
|
||||||
document.querySelectorAll('.section-title').forEach((ele) => {
|
for (const ele of document.querySelectorAll('.section-title')) {
|
||||||
const e = document.createElement('h2');
|
const e = document.createElement('h2');
|
||||||
e.innerHTML = ele.innerHTML;
|
e.innerHTML = ele.innerHTML;
|
||||||
ele.replaceWith(e);
|
ele.replaceWith(e);
|
||||||
});
|
}
|
||||||
const description = document.body.innerHTML.trim();
|
const description = document.body.innerHTML.trim();
|
||||||
return {
|
return {
|
||||||
title: id.startsWith('P921') ? title.replace('1', id.split('P921')[1]) : title,
|
title: id.startsWith('P921') ? title.replace('1', id.split('P921')[1]) : title,
|
||||||
|
|||||||
@@ -93,12 +93,12 @@ export default class CSGOJProvider extends BasicFetcher implements IBasicProvide
|
|||||||
const pDescription = document.querySelector('div[name="Description"]');
|
const pDescription = document.querySelector('div[name="Description"]');
|
||||||
const files = {};
|
const files = {};
|
||||||
const images = {};
|
const images = {};
|
||||||
pDescription.querySelectorAll('img[src]').forEach((ele) => {
|
for (const ele of pDescription.querySelectorAll('img[src]')) {
|
||||||
let src = ele.getAttribute('src').replace('.svg', '.png');
|
let src = ele.getAttribute('src').replace('.svg', '.png');
|
||||||
src = new URL(src, 'https://cpc.csgrandeur.cn').toString();
|
src = new URL(src, 'https://cpc.csgrandeur.cn').toString();
|
||||||
if (images[src]) {
|
if (images[src]) {
|
||||||
ele.setAttribute('src', `file://${images[src]}.png`);
|
ele.setAttribute('src', `file://${images[src]}.png`);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
const file = new PassThrough();
|
const file = new PassThrough();
|
||||||
this.get(src).pipe(file);
|
this.get(src).pipe(file);
|
||||||
@@ -106,7 +106,7 @@ export default class CSGOJProvider extends BasicFetcher implements IBasicProvide
|
|||||||
images[src] = fid;
|
images[src] = fid;
|
||||||
files[`${fid}.png`] = file;
|
files[`${fid}.png`] = file;
|
||||||
ele.setAttribute('src', `file://${fid}.png`);
|
ele.setAttribute('src', `file://${fid}.png`);
|
||||||
});
|
}
|
||||||
const description = [...pDescription.children].map((i) => i.outerHTML).join('');
|
const description = [...pDescription.children].map((i) => i.outerHTML).join('');
|
||||||
const input = [...document.querySelector('div[name="Input"]').children].map((i) => i.outerHTML).join('');
|
const input = [...document.querySelector('div[name="Input"]').children].map((i) => i.outerHTML).join('');
|
||||||
const output = [...document.querySelector('div[name="Output"]').children].map((i) => i.outerHTML).join('');
|
const output = [...document.querySelector('div[name="Output"]').children].map((i) => i.outerHTML).join('');
|
||||||
|
|||||||
@@ -113,11 +113,11 @@ export default class POJProvider extends BasicFetcher implements IBasicProvider
|
|||||||
content.children[0].remove();
|
content.children[0].remove();
|
||||||
content.children[0].remove();
|
content.children[0].remove();
|
||||||
content.children[0].remove();
|
content.children[0].remove();
|
||||||
content.querySelectorAll('img[src]').forEach((ele) => {
|
for (const ele of content.querySelectorAll('img[src]')) {
|
||||||
const src = ele.getAttribute('src');
|
const src = ele.getAttribute('src');
|
||||||
if (images[src]) {
|
if (images[src]) {
|
||||||
ele.setAttribute('src', `file://${images[src]}.png`);
|
ele.setAttribute('src', `file://${images[src]}.png`);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
const file = new PassThrough();
|
const file = new PassThrough();
|
||||||
this.get(src).pipe(file);
|
this.get(src).pipe(file);
|
||||||
@@ -125,7 +125,7 @@ export default class POJProvider extends BasicFetcher implements IBasicProvider
|
|||||||
images[src] = fid;
|
images[src] = fid;
|
||||||
files[`${fid}.png`] = file;
|
files[`${fid}.png`] = file;
|
||||||
ele.setAttribute('src', `file://${fid}.png`);
|
ele.setAttribute('src', `file://${fid}.png`);
|
||||||
});
|
}
|
||||||
let lastId = 0;
|
let lastId = 0;
|
||||||
let markNext = '';
|
let markNext = '';
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|||||||
@@ -52,15 +52,15 @@ export default class SPOJProvider extends BasicFetcher implements IBasicProvider
|
|||||||
logger.info(id);
|
logger.info(id);
|
||||||
const { document } = await this.html(`/problems/${id}/`);
|
const { document } = await this.html(`/problems/${id}/`);
|
||||||
const files = {};
|
const files = {};
|
||||||
document.querySelector('#problem-body').querySelectorAll('img[src]').forEach((ele) => {
|
for (const ele of document.querySelector('#problem-body').querySelectorAll('img[src]')) {
|
||||||
const src = ele.getAttribute('src');
|
const src = ele.getAttribute('src');
|
||||||
if (!src.startsWith('http')) return;
|
if (!src.startsWith('http')) continue;
|
||||||
const file = new PassThrough();
|
const file = new PassThrough();
|
||||||
this.get(src).pipe(file);
|
this.get(src).pipe(file);
|
||||||
const fid = String.random(8);
|
const fid = String.random(8);
|
||||||
files[`${fid}.png`] = file;
|
files[`${fid}.png`] = file;
|
||||||
ele.setAttribute('src', `file://${fid}.png`);
|
ele.setAttribute('src', `file://${fid}.png`);
|
||||||
});
|
}
|
||||||
const meta = document.querySelector('#problem-meta').children[1];
|
const meta = document.querySelector('#problem-meta').children[1];
|
||||||
const window = await this.html(`/submit/${id}/`);
|
const window = await this.html(`/submit/${id}/`);
|
||||||
const langs = Array.from(window.document.querySelector('#lang').querySelectorAll('option'))
|
const langs = Array.from(window.document.querySelector('#lang').querySelectorAll('option'))
|
||||||
|
|||||||
@@ -71,15 +71,15 @@ export default class UOJProvider extends BasicFetcher implements IBasicProvider
|
|||||||
const res = await this.get(`/problem/${id.split('P')[1]}`);
|
const res = await this.get(`/problem/${id.split('P')[1]}`);
|
||||||
const { window: { document } } = new JSDOM(res.text);
|
const { window: { document } } = new JSDOM(res.text);
|
||||||
const files = {};
|
const files = {};
|
||||||
document.querySelectorAll('article>img[src]').forEach((ele) => {
|
for (const ele of document.querySelectorAll('article>img[src]')) {
|
||||||
const src = ele.getAttribute('src');
|
const src = ele.getAttribute('src');
|
||||||
if (!src.startsWith('http')) return;
|
if (!src.startsWith('http')) continue;
|
||||||
const file = new PassThrough();
|
const file = new PassThrough();
|
||||||
this.get(src).pipe(file);
|
this.get(src).pipe(file);
|
||||||
const fid = String.random(8);
|
const fid = String.random(8);
|
||||||
files[`${fid}.png`] = file;
|
files[`${fid}.png`] = file;
|
||||||
ele.setAttribute('src', `file://${fid}.png`);
|
ele.setAttribute('src', `file://${fid}.png`);
|
||||||
});
|
}
|
||||||
const contentNode = document.querySelector('article');
|
const contentNode = document.querySelector('article');
|
||||||
const titles = contentNode.querySelectorAll('h3');
|
const titles = contentNode.querySelectorAll('h3');
|
||||||
for (const title of titles) {
|
for (const title of titles) {
|
||||||
|
|||||||
Reference in new issue
Block a user