Files
hotels/simple_web.py

174 lines
7.1 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
Упрощенный веб-интерфейс без сложных БД запросов
"""
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import uvicorn
app = FastAPI(title="Система аудита отелей")
@app.get("/")
async def root():
return HTMLResponse("""
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Аудит Отелей - Общественный Контроль</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
.container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 10px; }
h1 { color: #2c3e50; text-align: center; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; }
.stat-card { background: #3498db; color: white; padding: 20px; border-radius: 8px; text-align: center; }
.stat-number { font-size: 2em; font-weight: bold; }
.stat-label { font-size: 0.9em; opacity: 0.9; }
.regions { margin-top: 30px; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }
th { background: #34495e; color: white; }
.btn { background: #e74c3c; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; }
.btn:hover { background: #c0392b; }
.btn-small { background: #27ae60; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; font-size: 0.8em; }
.btn-small:hover { background: #229954; }
</style>
</head>
<body>
<div class="container">
<h1>🏨 Система аудита отелей</h1>
<div class="stats">
<div class="stat-card">
<div class="stat-number" id="total-hotels">33,773</div>
<div class="stat-label">Всего отелей</div>
</div>
<div class="stat-card">
<div class="stat-number" id="crawled-sites">115</div>
<div class="stat-label">Спарсено сайтов</div>
</div>
<div class="stat-card">
<div class="stat-number" id="audited-hotels">239</div>
<div class="stat-label">Проведено аудитов</div>
</div>
<div class="stat-card">
<div class="stat-number" id="avg-score">11.0</div>
<div class="stat-label">Средний балл</div>
</div>
</div>
<div class="regions">
<h2>📊 Статус по регионам</h2>
<table>
<thead>
<tr>
<th>Регион</th>
<th>Отелей</th>
<th>Спарсено</th>
<th>Проверено</th>
<th>Средний балл</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
<tr>
<td>Камчатский край</td>
<td>159</td>
<td>82</td>
<td>159</td>
<td>10.8/20</td>
<td><button class="btn-small" onclick="downloadAudit('Камчатский край')">📥 Скачать</button></td>
</tr>
<tr>
<td>Орловская область</td>
<td>68</td>
<td>29</td>
<td>68</td>
<td>10.6/20</td>
<td><button class="btn-small" onclick="downloadAudit('Орловская область')">📥 Скачать</button></td>
</tr>
<tr>
<td>Чукотский автономный округ</td>
<td>12</td>
<td>4</td>
<td>12</td>
<td>11.7/20</td>
<td><span style="color: #999;">Старый аудит</span></td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top: 30px; text-align: center;">
<button class="btn" onclick="location.reload()">🔄 Обновить</button>
<button class="btn" onclick="alert('Полная версия: http://localhost:8888')">🔗 Полная версия</button>
</div>
</div>
<script>
function downloadAudit(regionName) {
const url = `/api/audit/download/${encodeURIComponent(regionName)}`;
const link = document.createElement('a');
link.href = url;
link.download = `audit_${regionName.replace(/\\s+/g, '_')}.xlsx`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
</script>
</body>
</html>
""")
@app.get("/api/stats")
async def get_stats():
"""Упрощенная статистика"""
return {
"total_hotels": 33773,
"crawled_sites": 115,
"audited_hotels": 239,
"avg_score": 11.0,
"regions": [
{"region_name": "Камчатский край", "total_hotels": 159, "crawled": 82, "audited": 159, "avg_score": 10.8},
{"region_name": "Орловская область", "total_hotels": 68, "crawled": 29, "audited": 68, "avg_score": 10.6},
{"region_name": "Чукотский автономный округ", "total_hotels": 12, "crawled": 4, "audited": 12, "avg_score": 11.7}
]
}
@app.get("/api/audit/download/{region}")
async def download_audit(region: str):
"""Скачать Excel отчет по аудиту"""
import os
from fastapi.responses import FileResponse
# Ищем последний файл аудита для региона
region_safe = region.replace(' ', '_')
audit_dir = '/root/engine/public_oversight/hotels'
try:
files = [f for f in os.listdir(audit_dir) if f.startswith(f'audit_{region_safe}') and f.endswith('.xlsx')]
if not files:
return {"error": f"Файл аудита для региона '{region}' не найден. Сначала запустите аудит."}
# Берем последний файл (по дате в имени)
files.sort(reverse=True)
latest_file = files[0]
file_path = os.path.join(audit_dir, latest_file)
return FileResponse(
path=file_path,
filename=latest_file,
media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
except Exception as e:
return {"error": str(e)}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8889)