V-1488abed / src /info-page.ts
krazyxki's picture
Duplicate from neurokun/V-1488
29ce54a
import { Request, Response } from "express";
import * as textToImage from 'text-to-image';
import showdown from "showdown";
import { config, listConfig } from "./config";
import { keys } from "./keys";
import { proxies } from "./proxies";
import { captchas } from './proxy/captchas';
import { proxyKeys } from './proxy/proxy-keys';
import { getUniqueIps } from "./proxy/rate-limit";
export const handleInfoPage = async (req: Request, res: Response) => {
// Huggingface puts spaces behind some cloudflare ssl proxy, so `req.protocol` is `http` but the correct URL is actually `https`
const host = req.get("host");
const isHuggingface = host?.includes("hf.space");
const protocol = isHuggingface ? "https" : req.protocol;
res.send(await getInfoPageHtml(protocol + "://" + host, req.body));
};
const ms = require('ms');
async function getInfoPageHtml(host: string, body: any) {
const keylist = keys.list();
const proxylist = proxies.list();
const rateLimitInfo = { proompters: getUniqueIps() };
const usage = keys.getUsage();
const now = Date.now();
const uptimeDays = Math.floor(process.uptime() / 86400);
const info = {
uptime: uptimeDays > 0 ? `${uptimeDays} день или дня или дней` : 'меньше дня',
timestamp: new Date(now).toLocaleString('ru-RU', { timeZone: 'Europe/Moscow' }),
api: host + "/proxy/openai/v1",
proompts: keylist.reduce((acc, k) => acc + k.promptCount, 0) + proxylist.reduce((acc, k) => acc + k.promptCount, 0),
...(config.modelRateLimit ? rateLimitInfo : {}),
'gpt-3.5-turbo': {
all: keylist.length,
active: keylist.filter((k) => !k.isDisabled).length,
trial: keylist.filter((k) => k.isTrial && !k.isDisabled).length,
remaining: usage.gpt3.remaining,
usage: `${usage.gpt3.usage.toFixed(2)}/${Math.round(usage.gpt3.limit)}`,
},
'gpt-4': {
all: keylist.filter((k) => k.isGpt4).length,
active: keylist.filter((k) => k.isGpt4 && !k.isDisabled).length,
trial: keylist.filter((k) => k.isGpt4 && k.isTrial && !k.isDisabled).length,
remaining: usage.gpt4.remaining,
usage: `${usage.gpt4.usage.toFixed(2)}/${Math.round(usage.gpt4.limit)}`,
},
config: listConfig(),
};
const readme = require("fs").readFileSync("README.md", "utf8");
const readmeBody = readme.split("---")[2] || readme;
const converter = new showdown.Converter();
const html = converter.makeHtml(readmeBody);
let captchaHTML = '';
if (config.proxyCaptcha) {
if (captchas.check(body?.key, body?.value)) {
const key = proxyKeys.generate();
captchaHTML = `
<p style="text-align: center;color: #fff;">
Твой ключ от прокси - <code>${key}</code><br />
Писать его в поле API Key в таверне и не забудь после этого нажать Connect. <br />
Учти, если превысишь лимит в ${config.modelRateLimit} запросов в минуту - ключ превратится в тыкву и придётся идти за новым.
</p>
`;
} else {
const captcha = await captchas.generate();
captchaHTML = `
<img src="${captcha.instructionImg}"/><br />
<img src="${captcha.img}"/><br />
<div style="display: grid;width: 33%;">
<input type="hidden" name="key" value="${captcha.key}" />
<input type="text" name="value" autocomplete="off" />
<input type="submit" value="${captchas.encodeString('Нажатием этой кнопки вы поддерживаете СВО')}" />
</div>
<script>
const form = document.getElementById("captchaForm");
document.addEventListener('keyup', (e) => {
if (e.ctrlKey) form?.reset();
});
document.addEventListener('mousedown', (e) => {
if (e.button === 2) form?.reset();
});
</script>
`;
}
}
const pageBody = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>2ch proxy.</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>
<body style="padding: 1em;">
<main>
${html}
<div style="width: 100%;height: 47px;content: &quot;Z&quot;;margin-left: auto;margin-right: auto;color: #f9f946;font-size: 36px;background: linear-gradient(to bottom, #000 33.333%, #0039A6 33.333%, #0039A6 66.667%, #D52B1E 66.667%);text-shadow: 1px 2px 1px black;font-family: initial;text-align: center;margin-bottom: 9px;">Z</div>
<form action="" method="POST" style="margin-left:auto;margin-right:auto;" id="captchaForm">
${captchaHTML}
<pre>${JSON.stringify(info, null, 2)}</pre>
</form>
<div style="width: 100%;height: 47px;content: &quot;Z&quot;;margin-left: auto;margin-right: auto;color: #f9f946;font-size: 36px;background: linear-gradient(to bottom, #64C8FF 33.333%, #0039A6 33.333%, #0039A6 66.667%, #D52B1E 66.667%);text-shadow: 1px 2px 1px black;font-family: initial;text-align: center;margin-top: 9px;">V</div>
<div style="position:absolute; top:-9999px; left:-9999px;">
<div id="player"></div>
</div>
</main>
</body>
<script>
var player;
var videoIds = ['nClPPq2s-XQ', 'I8EMtklElRE', 'paZxfm8dhG0', 'OcdZtfuSt_A', 'AcTnMR_boys', 'i-DeuCQqgkM', '5qNtOryEVc0', 'pvq1NQz-I5E', 'm7FKzjmeg8U', 'mzaf8ExJ2hg', 'wOTD2KaAVjc', '5d1HWklOlN8', 'sYMZtGsDzss' ];
// Замените VIDEO_ID на реальные ID видео, которые вы хотите проигрывать
function onYouTubeIframeAPIReady() {
var randomIndex = Math.floor(Math.random() * videoIds.length);
var randomVideoId = videoIds[randomIndex];
player = new YT.Player('player', {
videoId: randomVideoId,
playerVars: {
autoplay: 1,
loop: 1,
controls: 1,
showinfo: 1,
modestbranding: 1,
iv_load_policy: 3,
start: 1,
autohide: 0,
mute: 0
},
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
<style>
pre{
border-radius: 8px;
background: #222;
width: 31%;
margin-left: auto;
margin-right: auto;
overflow: auto;
padding: 11px;
border: double;
text-align: start;
font-size: 11px;
color: #fff;
user-select: text;
}
body {
background-color: #222!important;
display: block;
margin-left: auto;
margin-right: auto;
}
#captchaForm {
display: flex;
flex-direction: column;
align-items: center;
margin: 6px;
margin-left: auto;
margin-right: auto;
border-radius: 6px;
width: 66%;
}
img {
margin: 5px;
margin-left:auto;
margin-right:auto;
height: 40px;
}
input[type="text"]{
border-top-left-radius: 6px;
border: 0px;
border-top-right-radius: 6px;
background-color: #333;
color: #fff;
padding: 7px;
text-align: center;
}
input[type="submit"]{
border-bottom-left-radius: 6px;
border: 0px;
border-bottom-right-radius: 6px;
background-color: #373636;
color: #fff;
padding: 7px;
text-align: center;
}
form {
user-select: text;
display: grid;
border: #fff 2px double;
margin: 5px;
margin-right: 5px;
margin-left: 5px;
padding: 11px;
border-radius: 6px;
margin-left: auto;
margin-right: auto;
}
input:hover {
background-color: #242424!important;
cursor: pointer;
}
</style>
</html>`;
return pageBody;
}