|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<style> |
|
body { |
|
font-family: Arial, sans-serif; |
|
} |
|
input, button, progress { |
|
display: block; |
|
margin-top: 10px; |
|
} |
|
#message { |
|
margin-top: 20px; |
|
color: blue; |
|
} |
|
#error { |
|
color: red; |
|
} |
|
#drop_zone { |
|
width: 300px; |
|
height: 200px; |
|
border: 2px dashed #aaa; |
|
line-height: 200px; |
|
text-align: center; |
|
margin-top: 10px; |
|
} |
|
#file_list { |
|
margin-top: 10px; |
|
} |
|
#fileUpload { |
|
display: none; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<label for="tokenInput">Hugging Face Token:</label> |
|
<input type="password" id="tokenInput" name="tokenInput"> |
|
<label for="repoInput">Repository ID:</label> |
|
<input type="text" id="repoInput" name="repoInput" placeholder="my-user/nlp-model"> |
|
<div id="drop_zone">Drag files/folders here or click to browse from your computer.</div> |
|
<ul id="file_list"></ul> |
|
<input type="file" id="fileUpload" multiple> |
|
<button id="uploadButton">Upload Files</button> |
|
<div id="processingMessage"></div> |
|
<progress id="progressBar" value="0" max="100"></progress> |
|
<div id="message"></div> |
|
<div id="error"></div> |
|
|
|
<script type="module"> |
|
import { createRepo, uploadFiles } from "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]/+esm"; |
|
|
|
class FileUploader { |
|
constructor() { |
|
this.files = []; |
|
this.fileInput = document.getElementById('fileUpload'); |
|
this.dropZone = document.getElementById('drop_zone'); |
|
this.fileList = document.getElementById('file_list'); |
|
this.uploadButton = document.getElementById('uploadButton'); |
|
|
|
this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e)); |
|
this.dropZone.addEventListener('click', () => this.fileInput.click()); |
|
this.dropZone.addEventListener('dragover', event => event.preventDefault()); |
|
this.dropZone.addEventListener('drop', (e) => this.handleFileDrop(e)); |
|
this.uploadButton.addEventListener('click', () => this.upload()); |
|
} |
|
|
|
handleFileSelect(event) { |
|
const newFiles = Array.from(event.target.files).map(file => ({ path: file.name, content: file })); |
|
this.files = this.files.concat(newFiles); |
|
this.updateFileList(); |
|
} |
|
|
|
handleFileDrop(event) { |
|
event.preventDefault(); |
|
let items = event.dataTransfer.items; |
|
for (let i = 0; i < items.length; i++) { |
|
let item = items[i].webkitGetAsEntry(); |
|
if (item) { |
|
this.traverseFileTree(item); |
|
} |
|
} |
|
} |
|
|
|
traverseFileTree(item, path = '') { |
|
if (item.isFile) { |
|
item.file((file) => { |
|
this.files.push({ path: path + file.name, content: file }); |
|
this.updateFileList(); |
|
}); |
|
} else if (item.isDirectory) { |
|
let dirReader = item.createReader(); |
|
dirReader.readEntries((entries) => { |
|
for (let i = 0; i < entries.length; i++) { |
|
this.traverseFileTree(entries[i], path + item.name + "/"); |
|
} |
|
}); |
|
} |
|
} |
|
|
|
updateFileList() { |
|
this.fileList.innerHTML = ''; |
|
for (let file of this.files) { |
|
let listItem = document.createElement('li'); |
|
listItem.textContent = file.path; |
|
this.fileList.appendChild(listItem); |
|
} |
|
} |
|
|
|
async upload() { |
|
const tokenInput = document.getElementById('tokenInput'); |
|
const HF_ACCESS_TOKEN = tokenInput.value; |
|
const repoInput = document.getElementById('repoInput'); |
|
const REPO_ID = repoInput.value; |
|
const progressBar = document.getElementById('progressBar'); |
|
const messageDiv = document.getElementById('message'); |
|
const errorDiv = document.getElementById('error'); |
|
const processingMessage = document.getElementById('processingMessage'); |
|
|
|
progressBar.value = 0; |
|
messageDiv.textContent = ''; |
|
errorDiv.textContent = ''; |
|
processingMessage.textContent = ''; |
|
|
|
if (this.files.length > 0) { |
|
const totalSize = this.files.reduce((total, file) => total + file.content.size, 0) / (1024 * 1024); |
|
const startTime = Date.now(); |
|
|
|
try { |
|
await createRepo({ repo: REPO_ID, credentials: { accessToken: HF_ACCESS_TOKEN } }); |
|
} catch (error) { |
|
if (error.message !== 'You already created this model repo') { |
|
console.error('Error creating repository', error); |
|
errorDiv.textContent = 'Error creating repository'; |
|
return; |
|
} |
|
console.log('Repository already exists, proceeding to upload files'); |
|
} |
|
|
|
try { |
|
await uploadFiles({ repo: REPO_ID, credentials: { accessToken: HF_ACCESS_TOKEN }, files: this.files }); |
|
console.log('All files uploaded successfully'); |
|
progressBar.value = 100; |
|
} catch (error) { |
|
console.error('Error uploading files', error); |
|
errorDiv.textContent = 'Error uploading files'; |
|
return; |
|
} |
|
|
|
const elapsedTime = (Date.now() - startTime) / 1000; |
|
const speed = totalSize / elapsedTime; |
|
|
|
messageDiv.textContent = `All files uploaded successfully in ${elapsedTime.toFixed(2)} seconds, for all ${totalSize.toFixed(2)} MB in the ${this.files.length} files, speed ${speed.toFixed(2)} MB/s.`; |
|
processingMessage.textContent = "All files processed"; |
|
this.files = []; |
|
this.updateFileList(); |
|
} else { |
|
messageDiv.textContent = 'Please select files to upload'; |
|
} |
|
} |
|
} |
|
|
|
new FileUploader(); |
|
</script> |
|
</body> |
|
</html> |