Spaces:
Sleeping
Sleeping
<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: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background-color: #f4f7f9; color: #333; margin: 0; padding: 20px; } | |
.container { max-width: 900px; margin: 0 auto; } | |
header { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px; text-align: center; } | |
h1 { margin: 0; color: #2c3e50; } | |
#solve-btn { background-color: #3498db; color: white; border: none; padding: 12px 24px; font-size: 16px; border-radius: 5px; cursor: pointer; transition: background-color 0.3s; } | |
#solve-btn:disabled { background-color: #bdc3c7; cursor: not-allowed; } | |
#spinner { display: none; margin-left: 15px; border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 24px; height: 24px; animation: spin 1s linear infinite; vertical-align: middle; } | |
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } | |
.captcha-history { display: flex; flex-direction: column; gap: 20px; } | |
.captcha-card { background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); padding: 20px; } | |
.captcha-card h3 { margin-top: 0; border-bottom: 1px solid #ecf0f1; padding-bottom: 10px; } | |
.images-container { display: flex; justify-content: space-around; flex-wrap: wrap; gap: 20px; margin-top: 15px; } | |
.image-wrapper { text-align: center; } | |
.image-wrapper img { max-width: 100%; height: auto; border: 1px solid #ddd; border-radius: 4px; } | |
.image-wrapper p { font-size: 14px; color: #7f8c8d; margin-top: 5px; } | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<header> | |
<h1>Распознаватель Капчи EGE</h1> | |
<button id="solve-btn">Распознать новую капчу</button> | |
<div id="spinner"></div> | |
</header> | |
<div class="captcha-history" id="captcha-history"> | |
{% for captcha in captchas %} | |
<div class="captcha-card"> | |
<h3>Распознано: {{ captcha.text }}</h3> | |
<div class="images-container"> | |
<div class="image-wrapper"> | |
<p>Оригинал</p> | |
<img src="data:image/png;base64,{{ captcha.original_b64 }}" alt="Original Captcha"> | |
</div> | |
<div class="image-wrapper"> | |
<p>Обработанное</p> | |
<img src="data:image/png;base64,{{ captcha.processed_b64 }}" alt="Processed Captcha"> | |
</div> | |
</div> | |
</div> | |
{% endfor %} | |
</div> | |
</div> | |
<script> | |
const solveBtn = document.getElementById('solve-btn'); | |
const historyContainer = document.getElementById('captcha-history'); | |
const spinner = document.getElementById('spinner'); | |
solveBtn.addEventListener('click', async () => { | |
solveBtn.disabled = true; | |
spinner.style.display = 'inline-block'; | |
try { | |
const response = await fetch('/solve', { method: 'POST' }); | |
if (!response.ok) { | |
throw new Error('Ошибка сети или сервера'); | |
} | |
const data = await response.json(); | |
if (data.error) { | |
alert(data.error); | |
} else { | |
const newCaptchaCard = ` | |
<div class="captcha-card"> | |
<h3>Распознано: ${data.text}</h3> | |
<div class="images-container"> | |
<div class="image-wrapper"> | |
<p>Оригинал</p> | |
<img src="data:image/png;base64,${data.original_b64}" alt="Original Captcha"> | |
</div> | |
<div class="image-wrapper"> | |
<p>Обработанное</p> | |
<img src="data:image/png;base64,${data.processed_b64}" alt="Processed Captcha"> | |
</div> | |
</div> | |
</div> | |
`; | |
historyContainer.insertAdjacentHTML('afterbegin', newCaptchaCard); | |
} | |
} catch (error) { | |
console.error('Ошибка при запросе новой капчи:', error); | |
alert('Не удалось получить новую капчу. Попробуйте снова.'); | |
} finally { | |
solveBtn.disabled = false; | |
spinner.style.display = 'none'; | |
} | |
}); | |
</script> | |
</body> | |
</html> | |