ups / templates /index.html
samfred2's picture
Update templates/index.html
3dc3878 verified
Raw
History Blame Contribute Delete
6.17 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Downloadwella to Hugging Face Frame Extractor</title>
<style>
body { font-family: sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; }
.container { max-width: 800px; margin: auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
h1 { color: #0056b3; }
form { margin-top: 20px; display: flex; flex-direction: column; gap: 10px; }
input[type="text"] { padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
button { padding: 10px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
button:hover { background-color: #0056b3; }
.status-box { background-color: #e9ecef; border: 1px solid #ced4da; padding: 15px; border-radius: 4px; margin-top: 20px; }
.log-entry { margin-bottom: 5px; border-bottom: 1px dotted #ccc; padding-bottom: 3px; }
.error { color: red; font-weight: bold; }
.success { color: green; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>Downloadwella to Hugging Face Frame Extractor</h1>
<p>Enter a Downloadwella URL to download the video, extract frames, and upload them as a zip to Hugging Face.</p>
<form id="processForm">
<input type="text" id="videoUrl" name="video_url" placeholder="Enter Downloadwella URL (e.g., https://downloadwella.com/some-video-id)" required>
<button type="submit">Start Processing</button>
</form>
<div class="status-box">
<h2>Processing Status</h2>
<p><strong>Is Running:</strong> <span id="isRunning">{{ status.is_running }}</span></p>
<p><strong>Current Action:</strong> <span id="currentAction">{{ status.current_action }}</span></p>
<p><strong>Last Processed URL:</strong> <span id="lastProcessedUrl">{{ status.last_processed_url if status.last_processed_url else 'N/A' }}</span></p>
<p><strong>Processed Count:</strong> <span id="processedCount">{{ status.processed_count }}</span></p>
<h3>Logs:</h3>
<div id="logs" style="max-height: 300px; overflow-y: scroll; background-color: #fff; padding: 10px; border-radius: 4px;">
{% for log in status.logs %}
<div class="log-entry">{{ log }}</div>
{% endfor %}
</div>
</div>
</div>
<script>
const processForm = document.getElementById('processForm');
const videoUrlInput = document.getElementById('videoUrl');
const isRunningSpan = document.getElementById('isRunning');
const currentActionSpan = document.getElementById('currentAction');
const lastProcessedUrlSpan = document.getElementById('lastProcessedUrl');
const processedCountSpan = document.getElementById('processedCount');
const logsDiv = document.getElementById('logs');
processForm.addEventListener('submit', async (event) => {
event.preventDefault();
const videoUrl = videoUrlInput.value;
if (!videoUrl) return;
logsDiv.innerHTML = ''; // Clear previous logs
addLog('Initiating processing...');
try {
const response = await fetch('/start', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `video_url=${encodeURIComponent(videoUrl)}`
});
const data = await response.json();
addLog(data.message);
if (data.message === "Processor started") {
// Start polling for status updates
pollStatus();
}
} catch (error) {
addLog(`Error starting process: ${error}`, true);
}
});
async function fetchStatus() {
try {
const response = await fetch('/stats');
const status = await response.json();
isRunningSpan.textContent = status.is_running;
currentActionSpan.textContent = status.current_action;
lastProcessedUrlSpan.textContent = status.last_processed_url || 'N/A';
processedCountSpan.textContent = status.processed_count;
// Only update logs if there are new entries or status changed
if (status.logs.length !== logsDiv.children.length) {
logsDiv.innerHTML = '';
status.logs.forEach(log => addLog(log));
}
return status.is_running;
} catch (error) {
addLog(`Error fetching status: ${error}`, true);
return false;
}
}
function addLog(message, isError = false) {
const logEntry = document.createElement('div');
logEntry.classList.add('log-entry');
if (isError) {
logEntry.classList.add('error');
}
logEntry.textContent = message;
logsDiv.appendChild(logEntry);
logsDiv.scrollTop = logsDiv.scrollHeight; // Auto-scroll to bottom
}
let pollingInterval;
function pollStatus() {
if (pollingInterval) clearInterval(pollingInterval);
pollingInterval = setInterval(async () => {
const running = await fetchStatus();
if (!running && currentActionSpan.textContent !== "Idle" && currentActionSpan.textContent !== "Error") {
addLog("Processing finished or stopped.");
clearInterval(pollingInterval);
}
}, 3000); // Poll every 3 seconds
}
// Initial status fetch on page load
fetchStatus();
pollStatus(); // Start polling immediately
</script>
</body>
</html>