mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +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 os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import cac from 'cac';
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import type { Context } from 'koa';
|
|
||||||
import { MongoClient, WriteConcern } from 'mongodb';
|
import { MongoClient, WriteConcern } from 'mongodb';
|
||||||
import mongoUri from 'mongodb-uri';
|
import mongoUri from 'mongodb-uri';
|
||||||
import { Context as PluginContext } from '../context';
|
import { readline } from '../ui';
|
||||||
|
|
||||||
const listenPort = cac().parse().options.port || 8888;
|
export async function load() {
|
||||||
let resolve;
|
console.error('Config file not found.');
|
||||||
|
if (!process.stdin.isTTY) {
|
||||||
async function get(ctx: Context) {
|
console.error('Please fill in ~/.hydro/config.json with MongoDB connection string in the following format:');
|
||||||
ctx.body = `<!DOCTYPE html>
|
console.error('{"url":"mongodb://localhost:27017/hydro"}');
|
||||||
<html data-page="setup" data-layout="immersive" class="layout--immersive page--setup nojs">
|
process.exit(1);
|
||||||
<head>
|
}
|
||||||
<meta charset="UTF-8">
|
// eslint-disable-next-line no-constant-condition
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
while (true) {
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
console.error('Please type your MongoDB connection string below:');
|
||||||
<link rel="stylesheet" media="all" href="/default.theme.css">
|
console.error('Example: mongodb://localhost:27017/hydro');
|
||||||
<title>Setup</title>
|
try {
|
||||||
</head>
|
const uri = await readline();
|
||||||
<body>
|
if (!uri) throw new Error('no url found');
|
||||||
<div class="slideout-panel" id="panel">
|
const url = mongoUri.parse(uri);
|
||||||
<div class="main">
|
const Database = await MongoClient.connect(uri, {
|
||||||
<div class="row"><div class="columns">
|
readPreference: 'nearest',
|
||||||
<div class="immersive--content immersive--center">
|
writeConcern: new WriteConcern('majority'),
|
||||||
<h1>Setup</h1>
|
});
|
||||||
<form method="POST">
|
const db = Database.db(url.database);
|
||||||
<div class="row"><div class="columns">
|
const coll = db.collection<any>('system');
|
||||||
<label class="inverse material textbox">
|
await coll.updateOne({ _id: '_test' }, { $set: { value: 1 } }, { upsert: true });
|
||||||
MongoDB Connection URI
|
await coll.deleteOne({ _id: '_test' });
|
||||||
<input name="url" type="text" value="mongodb://user:pass@127.0.0.1:27017/hydro" autofocus>
|
fs.ensureDirSync(path.resolve(os.homedir(), '.hydro'));
|
||||||
</label>
|
fs.writeFileSync(path.resolve(os.homedir(), '.hydro', 'config.json'), JSON.stringify({ url: uri }));
|
||||||
</div></div>
|
break;
|
||||||
<div class="row"><div class="columns">
|
} catch (e) {
|
||||||
<div class="text-center">
|
console.error(e);
|
||||||
<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 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');
|
const shell = new Logger('shell');
|
||||||
async function executeCommand(input: string) {
|
async function executeCommand(input: string) {
|
||||||
input = input.trim();
|
|
||||||
// Clear the stack
|
// Clear the stack
|
||||||
setImmediate(async () => {
|
setImmediate(async () => {
|
||||||
if (input === 'exit' || input === 'quit' || input === 'shutdown') {
|
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.setEncoding('utf-8');
|
||||||
process.stdin.setRawMode?.(false);
|
process.stdin.setRawMode?.(false);
|
||||||
process.stdin.on('data', (buf) => {
|
process.stdin.on('data', (buf) => {
|
||||||
const input = buf.toString();
|
const input = buf.toString().trim();
|
||||||
executeCommand(input);
|
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",
|
"name": "@hydrooj/ui-default",
|
||||||
"version": "4.51.2",
|
"version": "4.51.3",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ browserUpdate({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// monaco-editor requires this polyfill
|
// monaco-editor requires this polyfill
|
||||||
if (window.MediaQueryList) {
|
if (window.MediaQueryList && !MediaQueryList.prototype.addEventListener) {
|
||||||
MediaQueryList.prototype.addEventListener = (k, listener) => {
|
MediaQueryList.prototype.addEventListener = (k, listener) => {
|
||||||
MediaQueryList.prototype.addListener(listener);
|
MediaQueryList.prototype.addListener(listener);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user