diff --git a/web/app.py b/web/app.py index 18c4cf7..1a156df 100644 --- a/web/app.py +++ b/web/app.py @@ -1,46 +1,44 @@ -from fastapi import FastAPI, Form, Request -from fastapi.responses import FileResponse, HTMLResponse -from fastapi.templating import Jinja2Templates import os +import subprocess +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +import uvicorn +# +class RunScriptRequest(BaseModel): + config: str + userId: str + +# FastAPI app = FastAPI() -# Указываем директории для статических файлов и шаблонов -templates = Jinja2Templates(directory=os.path.dirname(os.path.realpath(__file__))) -app.mount("/static", StaticFiles(directory="static"), name="static") - -@app.get("/") -async def get_form(request: Request): - # Загружаем HTML шаблон (index.html) и передаем в него данные - return templates.TemplateResponse("index.html", {"request": request}) - @app.post("/run") -async def run_dns_resolver( - services: list[str] = Form(...), - dns_servers: list[str] = Form(...), - cloudflare: str = Form(...), - aggregation: str = Form(...), - format: str = Form(...), - gateway: str = Form(None), - commentary: str = Form(None) -): - # Генерация config.ini - config_path = "config.ini" - with open(config_path, "w") as config: - config.write("[DomainMapper]\n") - config.write(f"service={','.join(services)}\n") - config.write(f"dnsserver={','.join(dns_servers)}\n") - config.write(f"cloudflare={cloudflare}\n") - config.write(f"subnet={aggregation}\n") - config.write(f"filetype={format}\n") - if gateway: - config.write(f"gateway={gateway}\n") - if commentary: - config.write(f"commentary={commentary}\n") +async def run_script(request: RunScriptRequest): + config_content = request.config + user_id = request.userId - # Запуск скрипта - result_file = "output.txt" - os.system(f"python3 main.py -c {config_path}") + # + config_filename = f"config-id_{user_id}.ini" + try: + # + with open(config_filename, 'w') as f: + f.write(config_content) - # Возвращаем файл результата - return FileResponse(path=result_file, filename="output.txt", media_type="text/plain") + # subprocess + result = subprocess.run( + ['python3', 'main.py', '-c', config_filename], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True + ) + + # + return {"stdout": result.stdout, "stderr": result.stderr} + + except Exception as e: + raise HTTPException(status_code=500, detail=f": {str(e)}") + +# ( Uvicorn) +if __name__ == "__main__": + # FastAPI Uvicorn + uvicorn.run(app, host="0.0.0.0", port=5000) diff --git a/web/index.html b/web/index.html index c7bc1bb..3da7a8e 100644 --- a/web/index.html +++ b/web/index.html @@ -38,7 +38,63 @@ return true; } - // Загрузка сервисов из файла и добавление их в форму + function generateConfig(event) { + event.preventDefault(); + + if (!validateForm(event)) { + return; + } + + const services = Array.from(document.querySelectorAll('input[name="services"]:checked')).map(el => el.value).join(','); + const dnsServers = Array.from(document.querySelectorAll('input[name="dns_servers"]:checked')).map(el => el.value).join(' '); + const format = document.querySelector('input[name="format"]:checked').value; + const gateway = document.getElementById('gateway')?.value || ''; + const commentary = document.getElementById('commentary')?.value || ''; + const cloudflare = document.querySelector('input[name="cloudflare"]:checked') ? 'yes' : 'no'; + const aggregation = document.querySelector('input[name="aggregation"]:checked').value; + + const userId = Math.floor(Math.random() * 100000); // Случайный ID пользователя + const filename = `out-id_${userId}.txt`; + + const config = ` +[DomainMapper] +localplatform = no +localdns = no +service = ${services} +dnsserver = ${dnsServers} +cloudflare = ${cloudflare} +subnet = ${aggregation} +filename = ${filename} +filetype = ${format} +gateway = ${gateway} +keenetic = ${gateway} +listname = ${commentary} +mk_comment = off +cfginfo = no +run = +`; + + sendConfigToServer(config, userId); + } + + function sendConfigToServer(config, userId) { + fetch('/run', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ config: config, userId: userId }) + }) + .then(response => response.text()) + .then(data => { + document.getElementById('progress').innerText = `Конфигурация создана и скрипт запущен. Результат: ${data}`; + }) + .catch(error => { + console.error('Ошибка при отправке конфигурации:', error); + document.getElementById('progress').innerText = 'Ошибка при выполнении.'; + }); + } + function loadServices() { const serviceUrl = 'https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/refs/heads/main/platformdb'; @@ -67,7 +123,6 @@ .catch(error => console.error('Error loading services:', error)); } - // Загрузка DNS серверов из файла и добавление их в форму function loadDNSServers() { const dnsUrl = 'https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/refs/heads/main/dnsdb'; @@ -96,12 +151,9 @@ .catch(error => console.error('Error loading DNS servers:', error)); } - // Функция для отображения/скрытия поля ввода IP шлюза function toggleGatewayField() { const format = document.querySelector('input[name="format"]:checked'); const gatewayField = document.getElementById('gatewayField'); - - // Показываем поле, если выбран формат Unix Route, Windows Route или Keenetic CLI if (format && (format.value === 'unix' || format.value === 'win' || format.value === 'keenetic')) { gatewayField.style.display = 'block'; } else { @@ -109,12 +161,9 @@ } } - // Функция для отображения/скрытия поля комментария (для Mikrotik и Keenetic) function toggleCommentField() { const format = document.querySelector('input[name="format"]:checked'); const commentField = document.getElementById('commentaryField'); - - // Показываем поле, если выбран формат Mikrotik firewall или Keenetic CLI if (format && (format.value === 'mikrotik' || format.value === 'keenetic')) { commentField.style.display = 'block'; } else { @@ -126,12 +175,10 @@ loadServices(); loadDNSServers(); - // Инициализировать отображение полей для шлюза и комментария при загрузке toggleGatewayField(); toggleCommentField(); }; - // Добавляем слушатель событий для изменения выбора формата document.addEventListener('change', function(event) { if (event.target.name === 'format') { toggleGatewayField(); @@ -142,7 +189,7 @@