feat: welcome page

This commit is contained in:
DIYgod 2024-01-21 15:18:42 +08:00
parent 847724cad1
commit 8e0154552c
No known key found for this signature in database
8 changed files with 135 additions and 58 deletions

View File

@ -13,7 +13,6 @@ type Config = {
chromiumExecutablePath?: string;
connect: {
port: number;
socket: string | null;
};
listenInaddrAny: boolean;
requestRetry: number;
@ -347,7 +346,6 @@ const calculateValue = () => {
// network
connect: {
port: toInt(envs.PORT, 1200), // 监听端口
socket: envs.SOCKET || null, // 监听 Unix Socket, null 为禁用
},
listenInaddrAny: toBoolean(envs.LISTEN_INADDR_ANY, true), // 是否允许公网连接,取值 0 1
requestRetry: toInt(envs.REQUEST_RETRY, 2), // 请求失败重试次数

View File

@ -1,35 +0,0 @@
const app = require('./app');
const config = require('./config').value;
const fs = require('fs');
const logger = require('./utils/logger');
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (config.enableCluster && cluster.isMaster && process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'dev') {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
let server;
if (config.connect.socket) {
if (fs.existsSync(config.connect.socket)) {
fs.unlinkSync(config.connect.socket);
}
server = app.listen(config.connect.socket, Number.parseInt(config.listenInaddrAny) ? null : '127.0.0.1');
logger.info('Listening Unix Socket ' + config.connect.socket);
process.on('SIGINT', () => {
fs.unlinkSync(config.connect.socket);
process.exit();
});
}
if (config.connect.port) {
server = app.listen(config.connect.port, Number.parseInt(config.listenInaddrAny) ? null : '127.0.0.1');
logger.info('Listening Port ' + config.connect.port);
}
logger.info('🎉 RSSHub start! Cheers!');
logger.info('💖 Can you help keep this open source project alive? Please sponsor 👉 https://docs.rsshub.app/support');
module.exports = server;
}

View File

@ -9,10 +9,16 @@ import debug from '@/middleware/debug'
import header from '@/middleware/header'
import antiHotlink from '@/middleware/anti-hotlink'
import parameter from '@/middleware/parameter'
import logger from '@/utils/logger'
import routes from '@/routes'
import index from '@/v3/index'
import { config } from '@/config'
process.on('uncaughtException', (e) => {
logger.error('uncaughtException: ' + e);
});
const app = new Hono()
app.use('*', onerror);
@ -38,12 +44,14 @@ for (const name in routes) {
})
}
app.get('/', (c) => {
return c.text('Hello Hono!')
})
app.get('/', index)
console.log(app)
const port = config.connect.port
console.log(`Server is running on port ${port}`)
logger.info(`🎉 RSSHub is running on port ${port}! Cheers!`)
logger.info('💖 Can you help keep this open source project alive? Please sponsor 👉 https://docs.rsshub.app/support');
serve({
fetch: app.fetch,

View File

@ -1,17 +1,17 @@
import { MiddlewareHandler } from "hono";
import { getRouteNameFromPath } from '@/utils/helpers';
const middleware: MiddlewareHandler = async (ctx, next) => {
const debug = Object.assign({
hitCache: 0,
request: 0,
etag: 0,
paths: [],
routes: [],
errorPaths: [],
errorRoutes: [],
}, ctx.get('debug'));
const debug = {
hitCache: 0,
request: 0,
etag: 0,
paths: [],
routes: [],
errorPaths: [],
errorRoutes: [],
}
const middleware: MiddlewareHandler = async (ctx, next) => {
if (!debug.paths[ctx.req.path]) {
debug.paths[ctx.req.path] = 0;
}
@ -33,11 +33,11 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
debug.hitCache++;
}
ctx.set('debuged', true);
if (ctx.res.status === 304) {
debug.etag++;
}
};
export default middleware;
export default middleware;
export const getDebugInfo = () => debug

View File

@ -56,7 +56,7 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
const data = ctx.get('data') as Data;
if (!data) {
throw new Error('wrong path');
// throw new Error('wrong path');
} else {
if ((!data.item || data.item.length === 0) && !data.allowEmpty) {
throw new Error('this route is empty, please check the original site or <a href="https://github.com/DIYgod/RSSHub/issues/new/choose">create an issue</a>');
@ -194,7 +194,7 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
regex instanceof RE2JS
? regex.matcher(title).find() || regex.matcher(description).find() || regex.matcher(author).find() || category.some((c) => regex.matcher(c).find())
: title.match(regex) || description.match(regex) || author.match(regex) || category.some((c) => c.match(regex));
return isFilter;
});
}
@ -377,4 +377,4 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
}
};
export default middleware;
export default middleware;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 12 KiB

106
lib/v3/index.ts Normal file
View File

@ -0,0 +1,106 @@
import type { Handler } from 'hono';
import { config } from '@/config';
import art from 'art-template';
import * as path from 'node:path';
import gitRevSync from 'git-rev-sync';
import { getDebugInfo } from '@/middleware/debug';
let gitHash = process.env.HEROKU_SLUG_COMMIT?.slice(0, 7) || process.env.VERCEL_GIT_COMMIT_SHA?.slice(0, 7)
if (!gitHash) {
try {
gitHash = gitRevSync.short();
} catch {
gitHash = 'unknown';
}
}
const startTime = Date.now();
const handler: Handler = (ctx) => {
ctx.header('Content-Type', 'text/html; charset=UTF-8')
ctx.header('Cache-Control', 'no-cache')
const debug = getDebugInfo();
const routes = Object.keys(debug.routes).sort((a, b) => debug.routes[b] - debug.routes[a]);
const hotRoutes = routes.slice(0, 30);
const hotRoutesValue = hotRoutes.map((item) => `${debug.routes[item]} ${item}<br>`).join('');
const paths = Object.keys(debug.paths).sort((a, b) => debug.paths[b] - debug.paths[a]);
const hotPaths = paths.slice(0, 30);
const hotPathsValue = hotPaths.map((item) => `${debug.paths[item]} ${item}<br>`).join('');
let hotErrorRoutesValue = '';
if (debug.errorRoutes) {
const errorRoutes = Object.keys(debug.errorRoutes).sort((a, b) => debug.errorRoutes[b] - debug.errorRoutes[a]);
const hotErrorRoutes = errorRoutes.slice(0, 30);
hotErrorRoutesValue = hotErrorRoutes.map((item) => `${debug.errorRoutes[item]} ${item}<br>`).join('');
}
let hotErrorPathsValue = '';
if (debug.errorPaths) {
const errorPaths = Object.keys(debug.errorPaths).sort((a, b) => debug.errorPaths[b] - debug.errorPaths[a]);
const hotErrorPaths = errorPaths.slice(0, 30);
hotErrorPathsValue = hotErrorPaths.map((item) => `${debug.errorPaths[item]} ${item}<br>`).join('');
}
const showDebug = !config.debugInfo || config.debugInfo === 'false' ? false : config.debugInfo === 'true' || config.debugInfo === ctx.req.query('debug');
const { disallowRobot, nodeName } = config;
const duration = Date.now() - startTime;
return ctx.body(art(path.resolve(__dirname, '../views/welcome.art'), {
showDebug,
disallowRobot,
debug: [
nodeName
? {
name: 'Node Name',
value: nodeName,
}
: null,
{
name: 'Git Hash',
value: gitHash,
},
{
name: 'Request Amount',
value: debug.request,
},
{
name: 'Request Frequency',
value: ((debug.request / (duration / 1000)) * 60).toFixed(3) + ' times/minute',
},
{
name: 'Cache Hit Ratio',
value: debug.request ? (debug.hitCache / debug.request).toFixed(3) : 0,
},
{
name: 'ETag Matched',
value: debug.etag,
},
{
name: 'Run Time',
value: (duration / 3_600_000).toFixed(2) + ' hour(s)',
},
{
name: 'Hot Routes',
value: hotRoutesValue,
},
{
name: 'Hot Paths',
value: hotPathsValue,
},
{
name: 'Hot Error Routes',
value: hotErrorRoutesValue,
},
{
name: 'Hot Error Paths',
value: hotErrorPathsValue,
},
],
}));
};
export default handler;

View File

@ -79,7 +79,7 @@
<body>
<div class="content">
<p>
<img src="./logo.png" alt="RSSHub" width="100" loading="lazy" />
<img src="https://i.imgur.com/KmgWkHm.png" alt="RSSHub" width="100" loading="lazy" />
</p>
<h1>Welcome to