refactor: Move GAS Pravosudie scraper into standalone page 'Жатва ГАС'
This commit is contained in:
parent
48b23f5980
commit
2f92e81ec5
4 changed files with 131 additions and 79 deletions
|
|
@ -842,6 +842,10 @@ async def get_infra_page(request: Request, username: str = Depends(get_current_a
|
||||||
|
|
||||||
return templates.TemplateResponse(request=request, name="infra.html", context={"username": username, "speedtests": speedtests})
|
return templates.TemplateResponse(request=request, name="infra.html", context={"username": username, "speedtests": speedtests})
|
||||||
|
|
||||||
|
@app.get("/sudrf")
|
||||||
|
async def sudrf_page(request: Request, username: str = Depends(get_current_admin)):
|
||||||
|
return templates.TemplateResponse(request=request, name="sudrf.html", context={"username": username})
|
||||||
|
|
||||||
@app.post("/api/infra/run_speedtest")
|
@app.post("/api/infra/run_speedtest")
|
||||||
async def api_run_speedtest(username: str = Depends(get_current_admin)):
|
async def api_run_speedtest(username: str = Depends(get_current_admin)):
|
||||||
script_path = "/app/infra/speedtest_monitor.py" if os.path.exists("/app/infra/speedtest_monitor.py") else "/home/matrixhasyou/infra/speedtest_monitor.py"
|
script_path = "/app/infra/speedtest_monitor.py" if os.path.exists("/app/infra/speedtest_monitor.py") else "/home/matrixhasyou/infra/speedtest_monitor.py"
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,11 @@
|
||||||
<i class="bi bi-calendar3"></i> СОБЫТИЯ
|
<i class="bi bi-calendar3"></i> СОБЫТИЯ
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div class="mt-3 px-3"><small class="text-success opacity-50 text-uppercase" style="font-size: 0.6em;">Юрист</small></div>
|
||||||
|
<a class="nav-link {% block nav_sudrf %}{% endblock %}" href="/sudrf">
|
||||||
|
<i class="bi bi-bank text-danger"></i> ЖАТВА ГАС
|
||||||
|
</a>
|
||||||
|
|
||||||
<div class="mt-3 px-3"><small class="text-success opacity-50 text-uppercase" style="font-size: 0.6em;">Система</small></div>
|
<div class="mt-3 px-3"><small class="text-success opacity-50 text-uppercase" style="font-size: 0.6em;">Система</small></div>
|
||||||
<a class="nav-link {% block nav_infra %}{% endblock %}" href="/infra">
|
<a class="nav-link {% block nav_infra %}{% endblock %}" href="/infra">
|
||||||
<i class="bi bi-cpu"></i> ИНФРАСТРУКТУРА
|
<i class="bi bi-cpu"></i> ИНФРАСТРУКТУРА
|
||||||
|
|
|
||||||
|
|
@ -78,30 +78,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="card bg-dark border-danger">
|
|
||||||
<div class="card-header text-danger">ГАС ПРАВОСУДИЕ (СУДЕБНЫЙ АРХИВ)</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
||||||
<button id="runSudrfParserBtn" class="btn btn-outline-danger flex-grow-1 me-2">
|
|
||||||
<i class="bi bi-play-circle"></i> ЗАПУСТИТЬ ЖАТВУ СУДОВ
|
|
||||||
</button>
|
|
||||||
<div id="sudrfStatusBadge" class="badge bg-secondary p-2">СТАТУС: НЕИЗВЕСТНО</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
||||||
<a href="http://192.168.10.116:6080/vnc.html" target="_blank" class="btn btn-outline-info w-100">
|
|
||||||
<i class="bi bi-window"></i> ОТКРЫТЬ VNC БРАУЗЕР (ДЛЯ ЕСИА)
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="mb-2 d-flex justify-content-between">
|
|
||||||
<span class="small text-muted">ПОСЛЕДНИЕ ЛОГИ:</span>
|
|
||||||
<button id="refreshSudrfStatusBtn" class="btn btn-sm btn-link p-0 text-danger">ОБНОВИТЬ СТАТУС</button>
|
|
||||||
</div>
|
|
||||||
<pre id="sudrfLogs" class="bg-black text-danger p-2 small border border-secondary" style="height: 200px; overflow-y: scroll; font-size: 0.7rem;"></pre>
|
|
||||||
<div class="small opacity-50 mt-2">Выполняет: Открытие сессии -> Ввод 2FA пользователем -> Парсинг ej.sudrf.ru -> Сборка PDF -> Google Drive</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="card bg-dark border-warning">
|
<div class="card bg-dark border-warning">
|
||||||
<div class="card-header text-warning">ДЕЙСТВИЯ</div>
|
<div class="card-header text-warning">ДЕЙСТВИЯ</div>
|
||||||
|
|
@ -179,62 +155,9 @@ async function refreshGisStatus() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('runSudrfParserBtn').addEventListener('click', async function() {
|
|
||||||
const btn = this;
|
|
||||||
if (!confirm('Запустить сборку судебного архива ГАС Правосудие? Потребуется войти через Госуслуги во VNC.')) return;
|
|
||||||
|
|
||||||
btn.disabled = true;
|
|
||||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> СЕССИЯ СУДОВ...';
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('/api/infra/run_sudrf_parser', { method: 'POST' });
|
|
||||||
const result = await response.json();
|
|
||||||
alert(result.message);
|
|
||||||
} catch (e) {
|
|
||||||
alert('Ошибка: ' + e);
|
|
||||||
} finally {
|
|
||||||
btn.disabled = false;
|
|
||||||
btn.innerHTML = '<i class="bi bi-play-circle"></i> ЗАПУСТИТЬ ЖАТВУ СУДОВ';
|
|
||||||
refreshSudrfStatus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function refreshSudrfStatus() {
|
|
||||||
const badge = document.getElementById('sudrfStatusBadge');
|
|
||||||
const logs = document.getElementById('sudrfLogs');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('/api/infra/sudrf_status');
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (data.alive) {
|
|
||||||
badge.className = 'badge bg-success p-2';
|
|
||||||
badge.innerText = 'СТАТУС: РАБОТАЕТ';
|
|
||||||
} else {
|
|
||||||
badge.className = 'badge bg-danger p-2';
|
|
||||||
badge.innerText = 'СТАТУС: ОСТАНОВЛЕН';
|
|
||||||
}
|
|
||||||
|
|
||||||
logs.innerText = data.log;
|
|
||||||
logs.scrollTop = logs.scrollHeight;
|
|
||||||
} catch (e) {
|
|
||||||
badge.className = 'badge bg-warning p-2';
|
|
||||||
badge.innerText = 'ОШИБКА API';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('refreshGisStatusBtn').addEventListener('click', refreshGisStatus);
|
document.getElementById('refreshGisStatusBtn').addEventListener('click', refreshGisStatus);
|
||||||
document.getElementById('refreshSudrfStatusBtn').addEventListener('click', refreshSudrfStatus);
|
window.addEventListener('load', refreshGisStatus);
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
refreshGisStatus();
|
|
||||||
refreshSudrfStatus();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Авто-обновление раз в 30 секунд
|
// Авто-обновление раз в 30 секунд
|
||||||
setInterval(() => {
|
setInterval(refreshGisStatus, 30000);
|
||||||
refreshGisStatus();
|
|
||||||
refreshSudrfStatus();
|
|
||||||
}, 30000);
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
120
web/templates/sudrf.html
Normal file
120
web/templates/sudrf.html
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Жатва ГАС Правосудие - LKM37{% endblock %}
|
||||||
|
{% block nav_sudrf %}active{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2 class="mb-4"><i class="bi bi-bank text-danger"></i> Жатва ГАС Правосудие</h2>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Инструкция и Статус -->
|
||||||
|
<div class="col-md-6 mb-4">
|
||||||
|
<div class="card bg-dark border-danger h-100">
|
||||||
|
<div class="card-header border-danger text-danger">
|
||||||
|
<i class="bi bi-info-circle"></i> ИНСТРУКЦИЯ И УПРАВЛЕНИЕ
|
||||||
|
</div>
|
||||||
|
<div class="card-body d-flex flex-column justify-content-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-white">Этот модуль предназначен для автоматизированного сбора поданных обращений, заявлений и ответов судов с портала ГАС «Правосудие» (ej.sudrf.ru) для последующей склейки в PDF и загрузки в Google Drive (NotebookLM).</p>
|
||||||
|
|
||||||
|
<h5 class="text-danger mt-4"><i class="bi bi-1-circle"></i> Шаг 1: Подготовка сессии</h5>
|
||||||
|
<p class="small text-muted">Нажмите кнопку «Запустить Жатву ГАС Правосудие» ниже. Система откроет скрытый браузер Chromium на виртуальном рабочем столе.</p>
|
||||||
|
|
||||||
|
<h5 class="text-danger mt-3"><i class="bi bi-2-circle"></i> Шаг 2: Авторизация ЕСИА</h5>
|
||||||
|
<p class="small text-muted">Откройте VNC-браузер по ссылке справа и войдите в свой личный кабинет ГАС «Правосудие» через Госуслуги (потребуется пройти 2FA/SMS).</p>
|
||||||
|
|
||||||
|
<h5 class="text-danger mt-3"><i class="bi bi-3-circle"></i> Шаг 3: Автоматический парсинг</h5>
|
||||||
|
<p class="small text-muted">Как только вход будет обнаружен, скрипт перехватит сессию, соберет список дел, сделает скриншоты, скачает вложения и загрузит сводные PDF на Google Drive.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4 pt-3 border-top border-secondary">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<span class="text-white">Статус парсера:</span>
|
||||||
|
<div id="sudrfStatusBadge" class="badge bg-secondary p-2">НЕИЗВЕСТНО</div>
|
||||||
|
</div>
|
||||||
|
<button id="runSudrfParserBtn" class="btn btn-danger w-100 py-2">
|
||||||
|
<i class="bi bi-play-circle-fill"></i> ЗАПУСТИТЬ ЖАТВУ ГАС ПРАВОСУДИЕ
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- VNC и Логи -->
|
||||||
|
<div class="col-md-6 mb-4">
|
||||||
|
<div class="card bg-dark border-info h-100">
|
||||||
|
<div class="card-header border-info text-info">
|
||||||
|
<i class="bi bi-display"></i> СЕССИЯ И ЛОГИ СКАНИРОВАНИЯ
|
||||||
|
</div>
|
||||||
|
<div class="card-body d-flex flex-column">
|
||||||
|
<a href="http://192.168.10.116:6080/vnc.html" target="_blank" class="btn btn-outline-info w-100 py-3 mb-3">
|
||||||
|
<i class="bi bi-window-fullscreen"></i> ОТКРЫТЬ VNC ЭКРАН (noVNC)
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
|
<span class="small text-muted">ЛОГИ В РЕАЛЬНОМ ВРЕМЕНИ:</span>
|
||||||
|
<button id="refreshSudrfStatusBtn" class="btn btn-sm btn-outline-secondary py-0 px-2" style="font-size: 0.75rem;">
|
||||||
|
<i class="bi bi-arrow-clockwise"></i> ОБНОВИТЬ
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre id="sudrfLogs" class="bg-black text-danger p-3 small border border-secondary flex-grow-1" style="min-height: 250px; overflow-y: scroll; font-family: monospace; font-size: 0.75rem;"></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_script %}
|
||||||
|
<script>
|
||||||
|
document.getElementById('runSudrfParserBtn').addEventListener('click', async function() {
|
||||||
|
const btn = this;
|
||||||
|
if (!confirm('Запустить сборку судебного архива ГАС Правосудие? Потребуется войти через Госуслуги во VNC.')) return;
|
||||||
|
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> СЕССИЯ ЗАПУЩЕНА...';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/infra/run_sudrf_parser', { method: 'POST' });
|
||||||
|
const result = await response.json();
|
||||||
|
alert(result.message);
|
||||||
|
} catch (e) {
|
||||||
|
alert('Ошибка при запуске: ' + e);
|
||||||
|
} finally {
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.innerHTML = '<i class="bi bi-play-circle-fill"></i> ЗАПУСТИТЬ ЖАТВУ ГАС ПРАВОСУДИЕ';
|
||||||
|
refreshSudrfStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function refreshSudrfStatus() {
|
||||||
|
const badge = document.getElementById('sudrfStatusBadge');
|
||||||
|
const logs = document.getElementById('sudrfLogs');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/infra/sudrf_status');
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.alive) {
|
||||||
|
badge.className = 'badge bg-success p-2';
|
||||||
|
badge.innerText = 'СТАТУС: РАБОТАЕТ';
|
||||||
|
} else {
|
||||||
|
badge.className = 'badge bg-danger p-2';
|
||||||
|
badge.innerText = 'СТАТУС: ОСТАНОВЛЕН';
|
||||||
|
}
|
||||||
|
|
||||||
|
logs.innerText = data.log || "Лог пуст или еще не создан.";
|
||||||
|
logs.scrollTop = logs.scrollHeight;
|
||||||
|
} catch (e) {
|
||||||
|
badge.className = 'badge bg-warning p-2';
|
||||||
|
badge.innerText = 'ОШИБКА API';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('refreshSudrfStatusBtn').addEventListener('click', refreshSudrfStatus);
|
||||||
|
|
||||||
|
window.addEventListener('load', refreshSudrfStatus);
|
||||||
|
// Автообновление логов каждые 15 секунд
|
||||||
|
setInterval(refreshSudrfStatus, 15000);
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
Loading…
Reference in a new issue