mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
vjudge: move ddoc.mount to vjudge.mount (#945)
This commit is contained in:
1 parent
44581e8b16
commit
71b14d42d8
2 files changed
+29
-20
No files matched your search
@@ -10,6 +10,7 @@ import { BasicProvider, IBasicProvider, RemoteAccount } from './interface';
|
|||||||
import providers from './providers/index';
|
import providers from './providers/index';
|
||||||
|
|
||||||
const coll = db.collection('vjudge');
|
const coll = db.collection('vjudge');
|
||||||
|
const collMount = db.collection('vjudge.mount');
|
||||||
const logger = new Logger('vjudge');
|
const logger = new Logger('vjudge');
|
||||||
const syncing = {};
|
const syncing = {};
|
||||||
|
|
||||||
@@ -77,9 +78,10 @@ class AccountService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async sync(domainId: string, resync = false, list: string) {
|
async sync(target: string, resync = false, list: string) {
|
||||||
let page = 1;
|
let page = 1;
|
||||||
let pids = await this.api.listProblem(page, resync, list);
|
let pids = await this.api.listProblem(page, resync, list);
|
||||||
|
const [domainId, namespaceId] = target.split('.');
|
||||||
while (pids.length) {
|
while (pids.length) {
|
||||||
logger.info(`${domainId}: Syncing page ${page}`);
|
logger.info(`${domainId}: Syncing page ${page}`);
|
||||||
for (const id of pids) {
|
for (const id of pids) {
|
||||||
@@ -91,12 +93,13 @@ class AccountService {
|
|||||||
const [pid, metastr = '{}'] = id.split('#');
|
const [pid, metastr = '{}'] = id.split('#');
|
||||||
const normalizedPid = pid.replace(/[_-]/g, '');
|
const normalizedPid = pid.replace(/[_-]/g, '');
|
||||||
const meta = JSON.parse(metastr);
|
const meta = JSON.parse(metastr);
|
||||||
if (await ProblemModel.get(domainId, normalizedPid) || syncing[`${domainId}/${pid}`]) continue;
|
const targetPid = namespaceId ? `${namespaceId}-${normalizedPid}` : normalizedPid;
|
||||||
|
if (await ProblemModel.get(domainId, targetPid) || syncing[`${domainId}/${pid}`]) continue;
|
||||||
syncing[`${domainId}/${pid}`] = true;
|
syncing[`${domainId}/${pid}`] = true;
|
||||||
try {
|
try {
|
||||||
const res = await this.api.getProblem(pid, meta);
|
const res = await this.api.getProblem(pid, meta);
|
||||||
if (!res) continue;
|
if (!res) continue;
|
||||||
const docId = await ProblemModel.add(domainId, normalizedPid, res.title, res.content, 1, res.tag);
|
const docId = await ProblemModel.add(domainId, targetPid, res.title, res.content, 1, res.tag);
|
||||||
if (res.difficulty) await ProblemModel.edit(domainId, docId, { difficulty: res.difficulty });
|
if (res.difficulty) await ProblemModel.edit(domainId, docId, { difficulty: res.difficulty });
|
||||||
for (const key in res.files) {
|
for (const key in res.files) {
|
||||||
await ProblemModel.addAdditionalFile(domainId, docId, key, res.files[key]);
|
await ProblemModel.addAdditionalFile(domainId, docId, key, res.files[key]);
|
||||||
@@ -104,7 +107,7 @@ class AccountService {
|
|||||||
for (const key in res.data) {
|
for (const key in res.data) {
|
||||||
await ProblemModel.addTestdata(domainId, docId, key, res.data[key]);
|
await ProblemModel.addTestdata(domainId, docId, key, res.data[key]);
|
||||||
}
|
}
|
||||||
logger.info(`${domainId}: problem ${docId}(${pid}) sync done`);
|
logger.info(`${domainId}: problem ${docId}(${pid}) sync done -> ${targetPid}(${docId})`);
|
||||||
} finally {
|
} finally {
|
||||||
delete syncing[`${domainId}/${pid}`];
|
delete syncing[`${domainId}/${pid}`];
|
||||||
}
|
}
|
||||||
@@ -129,20 +132,16 @@ class AccountService {
|
|||||||
if (this.syncing) return;
|
if (this.syncing) return;
|
||||||
this.syncing = true;
|
this.syncing = true;
|
||||||
try {
|
try {
|
||||||
const ddocs = await DomainModel.getMulti({ mount: this.account.type.split('.')[0] }).toArray();
|
const mounts = await collMount.find({ mount: this.account.type.split('.')[0] }).toArray();
|
||||||
do {
|
do {
|
||||||
this.listUpdated = false;
|
this.listUpdated = false;
|
||||||
for (const listName of this.problemLists) {
|
for (const listName of this.problemLists) {
|
||||||
for (const ddoc of ddocs) {
|
for (const mount of mounts) {
|
||||||
if (ddoc.syncDone === true) {
|
if (!mount.syncDone?.[listName]) await this.sync(mount._id, false, listName);
|
||||||
await DomainModel.edit(ddoc._id, { syncDone: { main: true } });
|
else await this.sync(mount._id, true, listName);
|
||||||
ddoc.syncDone = { main: true };
|
await collMount.updateOne({ _id: mount._id }, { $set: { [`syncDone.${listName}`]: true } });
|
||||||
}
|
mount.syncDone ||= {};
|
||||||
if (!ddoc.syncDone?.[listName]) await this.sync(ddoc._id, false, listName);
|
mount.syncDone[listName] = true;
|
||||||
else await this.sync(ddoc._id, true, listName);
|
|
||||||
await DomainModel.edit(ddoc._id, { [`syncDone.${listName}`]: true });
|
|
||||||
ddoc.syncDone ||= {};
|
|
||||||
ddoc.syncDone[listName] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (this.listUpdated);
|
} while (this.listUpdated);
|
||||||
@@ -256,6 +255,15 @@ export async function apply(ctx: Context) {
|
|||||||
rewrite(['poj.0', 'poj.4'], 'cc.cc98'),
|
rewrite(['poj.0', 'poj.4'], 'cc.cc98'),
|
||||||
]);
|
]);
|
||||||
}, 'update csgoj and poj langs in record collection'),
|
}, 'update csgoj and poj langs in record collection'),
|
||||||
|
async () => {
|
||||||
|
const ddocs = await DomainModel.coll.find({ mount: { $exists: true, $ne: null } }).toArray();
|
||||||
|
for (const ddoc of ddocs) {
|
||||||
|
const syncDone = typeof ddoc.syncDone === 'object' ? ddoc.syncDone : { main: !!ddoc.syncDone };
|
||||||
|
await collMount.updateOne({ _id: ddoc._id }, { $set: { mount: ddoc.mount, syncDone } }, { upsert: true });
|
||||||
|
}
|
||||||
|
await DomainModel.coll.updateMany({}, { $unset: { mount: '', mountInfo: '', syncDone: '' } });
|
||||||
|
return true;
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
ctx.inject(['vjudge'], async (c) => {
|
ctx.inject(['vjudge'], async (c) => {
|
||||||
|
|||||||
@@ -14,14 +14,15 @@ export interface RemoteAccount {
|
|||||||
enableOn?: string[];
|
enableOn?: string[];
|
||||||
UA?: string;
|
UA?: string;
|
||||||
}
|
}
|
||||||
|
export interface VjudgeMount {
|
||||||
|
_id: string; // domainId, or `${domainId}.${namespace}`
|
||||||
|
mount: string;
|
||||||
|
syncDone: Record<string, boolean>;
|
||||||
|
}
|
||||||
declare module 'hydrooj' {
|
declare module 'hydrooj' {
|
||||||
interface Collections {
|
interface Collections {
|
||||||
vjudge: RemoteAccount;
|
vjudge: RemoteAccount;
|
||||||
}
|
'vjudge.mount': VjudgeMount;
|
||||||
|
|
||||||
interface DomainDoc {
|
|
||||||
mount?: string;
|
|
||||||
mountInfo?: any;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type NextFunction = (body: Partial<JudgeResultBody>) => void;
|
type NextFunction = (body: Partial<JudgeResultBody>) => void;
|
||||||
|
|||||||
Reference in new issue
Block a user