/* eslint-disable no-await-in-loop */ /* eslint-disable no-eval */ import fs from 'fs'; import path from 'path'; import yaml from 'js-yaml'; export const builtinLib = [ 'jwt', 'download', 'i18n', 'mail', 'markdown', 'md5', 'misc', 'paginate', 'hash.hydro', 'rank', 'template', 'validator', 'nav', 'sysinfo', 'testdata.convert.ini', 'readConfig', 'logger', 'useragent', ]; export const builtinModel = [ 'builtin', 'document', 'domain', 'blacklist', 'opcount', 'setting', 'token', 'user', 'problem', 'record', 'contest', 'message', 'solution', 'training', 'file', 'discussion', 'system', ]; export const builtinHandler = [ 'home', 'problem', 'record', 'judge', 'user', 'contest', 'training', 'discussion', 'manage', 'import', 'misc', 'homework', 'domain', 'wiki', ]; export const builtinScript = [ 'install', 'rating', 'recalcRating', 'register', 'problemStat', 'blacklist', 'setSuperadmin', 'deleteUser', ]; function getFiles(folder: string, base = ''): string[] { const files = []; const f = fs.readdirSync(folder); for (const i of f) { if (fs.statSync(path.join(folder, i)).isDirectory()) { files.push(...getFiles(path.join(folder, i), path.join(base, i))); } else files.push(path.join(base, i)); } return files.map((item) => item.replace(/\\/gmi, '/')); } export async function handler(pending: string[], fail: string[]) { for (const i of pending) { const p = path.resolve(i, 'handler.js'); if (fs.existsSync(p) && !fail.includes(i)) { try { console.log(`Handler init: ${i}`); console.time(`Handler init: ${i}`); eval('require')(p); console.timeEnd(`Handler init: ${i}`); } catch (e) { fail.push(i); console.error(`Handler Load Fail: ${i}`); } } } } export async function locale(pending: string[], fail: string[]) { for (const i of pending) { let p = path.resolve(i, 'locales'); if (!fs.existsSync(p)) p = path.resolve(i, 'locale'); if (fs.existsSync(p) && fs.statSync(p).isDirectory() && !fail.includes(i)) { try { const files = fs.readdirSync(p); const locales = {}; for (const file of files) { const content = fs.readFileSync(path.resolve(p, file)).toString(); locales[file.split('.')[0]] = yaml.safeLoad(content); } global.Hydro.lib.i18n(locales); console.log(`Locale init: ${i}`); } catch (e) { fail.push(i); console.error(`Locale Load Fail: ${i}`); } } } } export async function setting(pending: string[], fail: string[], modelSetting: typeof import('../model/setting')) { const map = { system: modelSetting.SystemSetting, account: modelSetting.AccountSetting, preference: modelSetting.PreferenceSetting, }; for (const i of pending) { let p = path.resolve(i, 'setting.yaml'); const t = i.split(path.sep); const name = t[t.length - 1]; if (!fs.existsSync(p)) p = path.resolve(i, 'settings.yaml'); if (fs.existsSync(p) && !fail.includes(i)) { try { const cfg: any = yaml.safeLoad(fs.readFileSync(p).toString()); for (const key in cfg) { map[cfg[key].category || 'system']( modelSetting.Setting( name, `${name}.${key}`, cfg[key].range, cfg[key].default, cfg[key].type || 'text', cfg[key].name || key, cfg[key].desc || '', ), ); } } catch (e) { console.error(`Config Load Fail: ${i}`); } } } } export async function template(pending: string[], fail: string[]) { for (const i of pending) { let p = path.resolve(i, 'templates'); if (!fs.existsSync(p)) p = path.resolve(i, 'template'); if (fs.existsSync(p) && fs.statSync(p).isDirectory() && !fail.includes(i)) { try { const files = getFiles(p); for (const file of files) { global.Hydro.ui.template[file] = fs.readFileSync( path.resolve(p, file), ).toString(); } console.log(`Template init: ${i}`); } catch (e) { fail.push(i); console.error(`Template Load Fail: ${i}`); } } } } export async function uistatic(pending: string[], fail: string[]) { for (const i of pending) { const p = path.resolve(i, 'public', 'static-manifest.json'); if (fs.existsSync(p) && fs.statSync(p).isFile() && !fail.includes(i)) { try { Object.assign(global.Hydro.ui.manifest, eval('require')(p)); } catch (e) { fail.push(i); } } } } export async function model(pending: string[], fail: string[]) { for (const i of pending) { const p = path.resolve(i, 'model.js'); if (fs.existsSync(p) && !fail.includes(i)) { try { console.log(`Model init: ${i}`); console.time(`Model init: ${i}`); eval('require')(p); console.timeEnd(`Model init: ${i}`); } catch (e) { fail.push(i); console.error(`Model Load Fail: ${i}`); } } } } export async function lib(pending: string[], fail: string[]) { for (const i of pending) { const p = path.resolve(i, 'lib.js'); if (fs.existsSync(p) && !fail.includes(i)) { try { console.log(`Lib init: ${i}`); console.time(`Lib init: ${i}`); eval('require')(p); console.timeEnd(`Lib init: ${i}`); } catch (e) { fail.push(i); console.error(`Lib Load Fail: ${i}`); console.error(e); } } } } export async function service(pending: string[], fail: string[]) { for (const i of pending) { const p = path.resolve(i, 'service.js'); if (fs.existsSync(p) && !fail.includes(i)) { try { console.log(`Service init: ${i}`); console.time(`Service init: ${i}`); eval('require')(p); console.timeEnd(`Service init: ${i}`); } catch (e) { fail.push(i); console.error(`Service Load Fail: ${i}`); console.error(e); } } } } export async function script(pending: string[], fail: string[], active: string[]) { for (const i of pending) { const p = path.resolve(i, 'script.js'); if (fs.existsSync(p) && !fail.includes(i)) { try { console.time(`Script init: ${i}`); eval('require')(p); console.timeEnd(`Script init: ${i}`); } catch (e) { fail.push(i); console.error(`Script Load Fail: ${i}`); console.error(e); } } active.push(i); } } export async function wiki(pending: string[], fail: string[]) { for (const i of pending) { const p = path.resolve(i, 'wiki'); if (fs.existsSync(p) && fs.statSync(p).isDirectory() && !fail.includes(i)) { try { const categories = fs.readdirSync(p); for (const category of categories) { console.log('category', category); if (!fs.statSync(p).isDirectory()) return; const pages = fs.readdirSync(path.join(p, category)); if (!global.Hydro.wiki[category]) global.Hydro.wiki[category] = {}; console.log(pages); for (const page of pages) { const c = fs.readFileSync(path.join(p, category, page)).toString().split('\n'); const pagename = page.split('.')[0]; global.Hydro.wiki[category][pagename] = []; let content = null; for (let j = 0; j < c.length; j++) { const line = c[j]; if (line.startsWith('# ')) { if (content) global.Hydro.wiki[category][pagename].push(content); content = {}; const t = line.split('# ')[1].split('|'); [content.title, content.id] = t.map((q) => q.trim()); content.content = ''; } else { content.content = `${content.content}${line}\n`; } } } } console.log(`Wiki init: ${i}`); } catch (e) { fail.push(i); console.error(`Wiki Load Fail: ${i}`); } } } }