mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
ui: fix
This commit is contained in:
4 files changed
+46
-99
No files matched your search
@@ -1,102 +1,39 @@
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import cac from 'cac';
|
||||
import fs from 'fs-extra';
|
||||
import type { Context } from 'koa';
|
||||
import { MongoClient, WriteConcern } from 'mongodb';
|
||||
import mongoUri from 'mongodb-uri';
|
||||
import { Context as PluginContext } from '../context';
|
||||
import { readline } from '../ui';
|
||||
|
||||
const listenPort = cac().parse().options.port || 8888;
|
||||
let resolve;
|
||||
|
||||
async function get(ctx: Context) {
|
||||
ctx.body = `<!DOCTYPE html>
|
||||
<html data-page="setup" data-layout="immersive" class="layout--immersive page--setup nojs">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<link rel="stylesheet" media="all" href="/default.theme.css">
|
||||
<title>Setup</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="slideout-panel" id="panel">
|
||||
<div class="main">
|
||||
<div class="row"><div class="columns">
|
||||
<div class="immersive--content immersive--center">
|
||||
<h1>Setup</h1>
|
||||
<form method="POST">
|
||||
<div class="row"><div class="columns">
|
||||
<label class="inverse material textbox">
|
||||
MongoDB Connection URI
|
||||
<input name="url" type="text" value="mongodb://user:pass@127.0.0.1:27017/hydro" autofocus>
|
||||
</label>
|
||||
</div></div>
|
||||
<div class="row"><div class="columns">
|
||||
<div class="text-center">
|
||||
<input type="submit" value="Confirm" class="inverse expanded rounded primary button">
|
||||
</div>
|
||||
</div></div>
|
||||
</form>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`;
|
||||
ctx.response.type = 'text/html';
|
||||
}
|
||||
|
||||
async function post(ctx: Context) {
|
||||
try {
|
||||
if (!ctx.request.body?.url) throw new Error('no url found');
|
||||
const url = mongoUri.parse(ctx.request.body.url);
|
||||
const Database = await MongoClient.connect(ctx.request.body.url, {
|
||||
readPreference: 'nearest',
|
||||
writeConcern: new WriteConcern('majority'),
|
||||
});
|
||||
const db = Database.db(url.database);
|
||||
const coll = db.collection<any>('system');
|
||||
await Promise.all([
|
||||
coll.updateOne(
|
||||
{ _id: 'server.url' },
|
||||
{ $set: { value: ctx.request.href } },
|
||||
{ upsert: true },
|
||||
),
|
||||
coll.updateOne(
|
||||
{ _id: 'server.port' },
|
||||
{ $set: { value: parseInt(listenPort as string, 10) } },
|
||||
{ upsert: true },
|
||||
),
|
||||
]);
|
||||
fs.ensureDirSync(path.resolve(os.homedir(), '.hydro'));
|
||||
fs.writeFileSync(path.resolve(os.homedir(), '.hydro', 'config.json'), JSON.stringify({ url: ctx.request.body.url }));
|
||||
ctx.body = '<h1>Done! Hydro is now starting.</h1>';
|
||||
resolve?.();
|
||||
} catch (e) {
|
||||
ctx.body = `Error connecting to database: ${e.message}\n${e.stack}`;
|
||||
export async function load() {
|
||||
console.error('Config file not found.');
|
||||
if (!process.stdin.isTTY) {
|
||||
console.error('Please fill in ~/.hydro/config.json with MongoDB connection string in the following format:');
|
||||
console.error('{"url":"mongodb://localhost:27017/hydro"}');
|
||||
process.exit(1);
|
||||
}
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
console.error('Please type your MongoDB connection string below:');
|
||||
console.error('Example: mongodb://localhost:27017/hydro');
|
||||
try {
|
||||
const uri = await readline();
|
||||
if (!uri) throw new Error('no url found');
|
||||
const url = mongoUri.parse(uri);
|
||||
const Database = await MongoClient.connect(uri, {
|
||||
readPreference: 'nearest',
|
||||
writeConcern: new WriteConcern('majority'),
|
||||
});
|
||||
const db = Database.db(url.database);
|
||||
const coll = db.collection<any>('system');
|
||||
await coll.updateOne({ _id: '_test' }, { $set: { value: 1 } }, { upsert: true });
|
||||
await coll.deleteOne({ _id: '_test' });
|
||||
fs.ensureDirSync(path.resolve(os.homedir(), '.hydro'));
|
||||
fs.writeFileSync(path.resolve(os.homedir(), '.hydro', 'config.json'), JSON.stringify({ url: uri }));
|
||||
break;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function load(ctx: PluginContext) {
|
||||
let dispose;
|
||||
ctx.plugin(require('@hydrooj/framework'), {
|
||||
keys: [Math.random()],
|
||||
proxy: false,
|
||||
upload: false,
|
||||
port: listenPort,
|
||||
});
|
||||
ctx.inject(['server'], ({ server }) => {
|
||||
dispose = server.addServerLayer('setup', (c) => {
|
||||
if (c.request.method.toLowerCase() === 'post') return post(c);
|
||||
return get(c);
|
||||
});
|
||||
});
|
||||
return new Promise((r) => {
|
||||
resolve = () => {
|
||||
dispose?.();
|
||||
r(null);
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -22,7 +22,6 @@ process.on('SIGTERM', terminate);
|
||||
|
||||
const shell = new Logger('shell');
|
||||
async function executeCommand(input: string) {
|
||||
input = input.trim();
|
||||
// Clear the stack
|
||||
setImmediate(async () => {
|
||||
if (input === 'exit' || input === 'quit' || input === 'shutdown') {
|
||||
@@ -39,9 +38,20 @@ async function executeCommand(input: string) {
|
||||
});
|
||||
}
|
||||
|
||||
let readlineCallback;
|
||||
|
||||
process.stdin.setEncoding('utf-8');
|
||||
process.stdin.setRawMode?.(false);
|
||||
process.stdin.on('data', (buf) => {
|
||||
const input = buf.toString();
|
||||
executeCommand(input);
|
||||
const input = buf.toString().trim();
|
||||
if (readlineCallback) {
|
||||
readlineCallback(input);
|
||||
readlineCallback = null;
|
||||
} else executeCommand(input);
|
||||
});
|
||||
|
||||
export const useReadline = (callback: (string) => any) => {
|
||||
if (readlineCallback) throw new Error('Already waiting for input.');
|
||||
readlineCallback = callback;
|
||||
};
|
||||
export const readline = () => new Promise<string>((resolve) => { useReadline(resolve); });
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/ui-default",
|
||||
"version": "4.51.2",
|
||||
"version": "4.51.3",
|
||||
"author": "undefined <i@undefined.moe>",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "index.ts",
|
||||
|
||||
@@ -12,7 +12,7 @@ browserUpdate({
|
||||
});
|
||||
|
||||
// monaco-editor requires this polyfill
|
||||
if (window.MediaQueryList) {
|
||||
if (window.MediaQueryList && !MediaQueryList.prototype.addEventListener) {
|
||||
MediaQueryList.prototype.addEventListener = (k, listener) => {
|
||||
MediaQueryList.prototype.addListener(listener);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user