Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Piper ONNX Converter</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> | |
<script src="https://cdn.tailwindcss.com"></script> | |
</head> | |
<body class="bg-gray-100 min-h-screen flex items-center justify-center"> | |
<div class="container mx-auto px-4"> | |
<h1 class="text-3xl font-bold mb-8 text-center">Piper ONNX Converter</h1> | |
<form id="converterForm" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"> | |
<div class="mb-4"> | |
<label class="block text-gray-700 text-sm font-bold mb-2" for="repo_id"> | |
Hugging Face Repository ID: | |
</label> | |
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="repo_id" name="repo_id" type="text" required> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-gray-700 text-sm font-bold mb-2" for="token"> | |
Hugging Face Token: | |
</label> | |
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="token" name="token" type="password" required> | |
</div> | |
<div class="mb-6"> | |
<label class="block text-gray-700 text-sm font-bold mb-2" for="model_name"> | |
Model Name: | |
</label> | |
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="model_name" name="model_name" type="text" required> | |
</div> | |
<div class="flex items-center justify-between"> | |
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="submit"> | |
Convert and Download | |
</button> | |
</div> | |
</form> | |
<div id="progress" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" style="display: none;"> | |
<h2 class="text-2xl font-bold mb-4">Processing...</h2> | |
<div id="log" class="bg-gray-100 p-4 rounded-lg h-64 overflow-y-auto mb-4"></div> | |
<a id="downloadLink" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" style="display: none;">Download Converted Model</a> | |
<button id="convertAnotherButton" class="bg-yellow-500 hover:bg-yellow-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" style="display: none;">Convert Another Model</button> | |
</div> | |
</div> | |
<script> | |
const form = document.getElementById('converterForm'); | |
const progress = document.getElementById('progress'); | |
const log = document.getElementById('log'); | |
const downloadLink = document.getElementById('downloadLink'); | |
const convertAnotherButton = document.getElementById('convertAnotherButton'); | |
const socket = io(); | |
socket.on('task_update', function(data) { | |
const logEntry = document.createElement('p'); | |
logEntry.textContent = data.message; | |
log.appendChild(logEntry); | |
log.scrollTop = log.scrollHeight; | |
// Check if the message contains the download URL | |
if (data.message.includes("Processing completed. Download URL:")) { | |
const url = data.message.split("Download URL: ")[1]; | |
downloadLink.href = url; | |
downloadLink.style.display = 'inline-block'; | |
convertAnotherButton.style.display = 'inline-block'; | |
} | |
}); | |
form.addEventListener('submit', async (e) => { | |
e.preventDefault(); | |
const formData = new FormData(form); | |
try { | |
const response = await fetch('/', { | |
method: 'POST', | |
body: formData | |
}); | |
const data = await response.json(); | |
if (data.task_id) { | |
form.style.display = 'none'; | |
progress.style.display = 'block'; | |
pollStatus(data.task_id); | |
} | |
} catch (error) { | |
console.error('Error:', error); | |
} | |
}); | |
async function pollStatus(taskId) { | |
while (true) { | |
try { | |
const response = await fetch(`/status/${taskId}`); | |
const data = await response.json(); | |
if (data.status === 'completed') { | |
// We don't need to set the download link here anymore | |
// as it's now handled in the socket.on('task_update') function | |
break; | |
} else if (data.status === 'error') { | |
const errorMsg = document.createElement('p'); | |
errorMsg.textContent = 'An error occurred during processing.'; | |
errorMsg.classList.add('text-red-500', 'font-bold'); | |
log.appendChild(errorMsg); | |
break; | |
} | |
await new Promise(resolve => setTimeout(resolve, 5000)); // Poll every 5 seconds | |
} catch (error) { | |
console.error('Error polling status:', error); | |
break; | |
} | |
} | |
} | |
convertAnotherButton.addEventListener('click', () => { | |
form.style.display = 'block'; | |
progress.style.display = 'none'; | |
downloadLink.style.display = 'none'; | |
convertAnotherButton.style.display = 'none'; | |
log.innerHTML = ''; // Clear the log | |
}); | |
</script> | |
</body> | |
</html> | |