multimodalart HF staff commited on
Commit
367dacb
1 Parent(s): ad155f6

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +171 -58
index.html CHANGED
@@ -16,6 +16,20 @@
16
  #error {
17
  color: red;
18
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </style>
20
  </head>
21
  <body>
@@ -23,6 +37,8 @@
23
  <input type="password" id="tokenInput" name="tokenInput">
24
  <label for="repoInput">Repository ID:</label>
25
  <input type="text" id="repoInput" name="repoInput" placeholder="my-user/nlp-model">
 
 
26
  <input type="file" id="fileUpload" multiple>
27
  <button id="uploadButton">Upload Files</button>
28
  <div id="processingMessage"></div>
@@ -32,101 +48,198 @@
32
 
33
  <script type="module">
34
  import { createRepo, uploadFiles } from "https://cdn.jsdelivr.net/npm/@huggingface/hub@0.8.3/+esm";
35
-
36
  class FileUploader {
37
  constructor() {
 
 
 
 
 
38
  this.fileInput = document.getElementById('fileUpload');
 
 
39
  this.uploadButton = document.getElementById('uploadButton');
40
- this.tokenInput = document.getElementById('tokenInput');
41
- this.repoInput = document.getElementById('repoInput');
42
  this.progressBar = document.getElementById('progressBar');
43
  this.messageDiv = document.getElementById('message');
44
  this.errorDiv = document.getElementById('error');
45
  this.processingMessage = document.getElementById('processingMessage');
46
-
 
 
47
  this.hijackFetch();
48
- this.uploadButton.addEventListener('click', this.upload);
 
 
 
 
 
49
  }
50
-
51
- hijackFetch = () => {
52
  const originalFetch = fetch;
53
- this.totalUploaded = 0;
54
- this.progressMap = new Map();
55
-
56
- fetch = (url, init) => init.method !== 'PUT' ? originalFetch(url, init) : this.handleFetch(url, init);
57
- };
58
-
59
- handleFetch = (url, init) => new Promise((resolve, reject) => {
60
- const xhr = new XMLHttpRequest();
61
- xhr.open(init.method, url);
62
- for (let header in init.headers) xhr.setRequestHeader(header, init.headers[header]);
63
- xhr.onload = () => resolve({ok: xhr.status >= 200 && xhr.status < 300, status: xhr.status, statusText: xhr.statusText, text: () => Promise.resolve(xhr.responseText), json: () => Promise.resolve(JSON.parse(xhr.responseText)), headers: {get: (header) => xhr.getResponseHeader(header)}});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  xhr.onerror = () => reject(new TypeError('Network request failed'));
65
  xhr.ontimeout = () => reject(new TypeError('Network request failed due to timeout'));
66
  xhr.upload.onprogress = (event) => this.updateUploadProgress(event, url);
67
  xhr.send(init.body);
68
- });
69
-
70
- updateUploadProgress = (event, url) => {
71
  if (event.lengthComputable) {
72
  this.progressMap.set(url, event.loaded);
73
  this.totalUploaded = Array.from(this.progressMap.values()).reduce((a, b) => a + b, 0);
 
 
 
74
  this.progressBar.value = this.totalUploaded;
75
- this.processingMessage.textContent = this.totalUploaded === 0 ? 'Preparing your upload' : this.totalUploaded === this.progressBar.max ? 'Processing your upload' : '';
 
 
 
 
 
76
  }
77
- };
78
-
79
- upload = async () => {
80
- const files = Array.from(this.fileInput.files);
81
- const HF_ACCESS_TOKEN = this.tokenInput.value;
82
- const REPO_ID = this.repoInput.value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  this.progressBar.value = 0;
84
  this.messageDiv.textContent = '';
85
  this.errorDiv.textContent = '';
86
  this.processingMessage.textContent = '';
87
-
88
- if (files.length > 0) {
89
- this.progressBar.max = files.reduce((total, file) => total + file.size, 0);
90
- this.totalUploaded = 0;
91
- this.startTime = Date.now();
92
-
93
  try {
94
  await this.createRepository(REPO_ID, HF_ACCESS_TOKEN);
95
- await this.uploadFilesToRepo(REPO_ID, HF_ACCESS_TOKEN, files);
96
- this.handleUploadSuccess(files);
97
  } catch (error) {
98
  this.handleErrorDuringUpload(error);
99
  }
100
  } else {
101
- this.messageDiv.textContent = 'Please select files to upload';
102
  }
103
- };
104
-
105
- createRepository = async (REPO_ID, HF_ACCESS_TOKEN) => {
 
 
 
 
 
 
 
106
  try {
107
- await createRepo({repo: REPO_ID, credentials: { accessToken: HF_ACCESS_TOKEN }});
 
 
 
108
  } catch (error) {
109
- if (error.message !== 'You already created this model repo') throw error;
 
 
110
  }
111
- };
112
-
113
- uploadFilesToRepo = (REPO_ID, HF_ACCESS_TOKEN, files) => uploadFiles({repo: REPO_ID, credentials: { accessToken: HF_ACCESS_TOKEN }, files: files.map(file => ({path: file.name, content: file}))});
114
-
115
- handleUploadSuccess = (files) => {
116
- const elapsedTime = (Date.now() - this.startTime) / 1000;
117
- let totalSizeMB = this.progressBar.max / (1024 * 1024)
118
- let speed = totalSizeMB / elapsedTime;
119
- this.messageDiv.innerHTML = `All files uploaded successfully in ${elapsedTime.toFixed(2)} seconds, for all ${totalSizeMB.toFixed(2)} MB in the ${files.length} files, speed ${speed.toFixed(2)} MB/s.`;
120
- this.processingMessage.textContent = "All files processed";
121
- };
122
-
123
- handleErrorDuringUpload = (error) => {
 
 
 
 
 
124
  console.error('Error during upload', error);
125
  this.errorDiv.textContent = 'Error during upload: ' + error.message;
126
- };
127
  }
128
-
129
  new FileUploader();
130
  </script>
 
131
  </body>
132
- </html>
 
16
  #error {
17
  color: red;
18
  }
19
+ #drop_zone {
20
+ width: 300px;
21
+ height: 200px;
22
+ border: 2px dashed #aaa;
23
+ line-height: 200px;
24
+ text-align: center;
25
+ margin-top: 10px;
26
+ }
27
+ #file_list {
28
+ margin-top: 10px;
29
+ }
30
+ #fileUpload {
31
+ display: none;
32
+ }
33
  </style>
34
  </head>
35
  <body>
 
37
  <input type="password" id="tokenInput" name="tokenInput">
38
  <label for="repoInput">Repository ID:</label>
39
  <input type="text" id="repoInput" name="repoInput" placeholder="my-user/nlp-model">
40
+ <div id="drop_zone">Drag files/folders here or click to browse from your computer.</div>
41
+ <ul id="file_list"></ul>
42
  <input type="file" id="fileUpload" multiple>
43
  <button id="uploadButton">Upload Files</button>
44
  <div id="processingMessage"></div>
 
48
 
49
  <script type="module">
50
  import { createRepo, uploadFiles } from "https://cdn.jsdelivr.net/npm/@huggingface/hub@0.8.3/+esm";
51
+
52
  class FileUploader {
53
  constructor() {
54
+ this.files = [];
55
+ this.totalUploaded = 0;
56
+ this.startTime = 0;
57
+ this.progressMap = new Map();
58
+
59
  this.fileInput = document.getElementById('fileUpload');
60
+ this.dropZone = document.getElementById('drop_zone');
61
+ this.fileList = document.getElementById('file_list');
62
  this.uploadButton = document.getElementById('uploadButton');
 
 
63
  this.progressBar = document.getElementById('progressBar');
64
  this.messageDiv = document.getElementById('message');
65
  this.errorDiv = document.getElementById('error');
66
  this.processingMessage = document.getElementById('processingMessage');
67
+ this.tokenInput = document.getElementById('tokenInput');
68
+ this.repoInput = document.getElementById('repoInput');
69
+
70
  this.hijackFetch();
71
+
72
+ this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
73
+ this.dropZone.addEventListener('click', () => this.fileInput.click());
74
+ this.dropZone.addEventListener('dragover', event => event.preventDefault());
75
+ this.dropZone.addEventListener('drop', (e) => this.handleFileDrop(e));
76
+ this.uploadButton.addEventListener('click', () => this.upload());
77
  }
78
+
79
+ hijackFetch() {
80
  const originalFetch = fetch;
81
+
82
+ fetch = (url, init) => {
83
+ if (init.method !== 'PUT') {
84
+ return originalFetch(url, init);
85
+ }
86
+
87
+ return new Promise((resolve, reject) => {
88
+ const xhr = new XMLHttpRequest();
89
+ xhr.open(init.method, url);
90
+
91
+ for (let header in init.headers) {
92
+ xhr.setRequestHeader(header, init.headers[header]);
93
+ }
94
+
95
+ this.handleXHR(xhr, resolve, reject, url, init);
96
+ });
97
+ };
98
+ }
99
+
100
+ handleXHR(xhr, resolve, reject, url, init) {
101
+ xhr.onload = () => {
102
+ resolve({
103
+ ok: xhr.status >= 200 && xhr.status < 300,
104
+ status: xhr.status,
105
+ statusText: xhr.statusText,
106
+ text: () => Promise.resolve(xhr.responseText),
107
+ json: () => Promise.resolve(JSON.parse(xhr.responseText)),
108
+ headers: { get: (header) => xhr.getResponseHeader(header) }
109
+ });
110
+ };
111
+
112
  xhr.onerror = () => reject(new TypeError('Network request failed'));
113
  xhr.ontimeout = () => reject(new TypeError('Network request failed due to timeout'));
114
  xhr.upload.onprogress = (event) => this.updateUploadProgress(event, url);
115
  xhr.send(init.body);
116
+ }
117
+
118
+ updateUploadProgress(event, url) {
119
  if (event.lengthComputable) {
120
  this.progressMap.set(url, event.loaded);
121
  this.totalUploaded = Array.from(this.progressMap.values()).reduce((a, b) => a + b, 0);
122
+
123
+ const elapsedSeconds = (Date.now() - this.startTime) / 1000;
124
+
125
  this.progressBar.value = this.totalUploaded;
126
+
127
+ if (this.totalUploaded === 0) {
128
+ this.processingMessage.textContent = 'Preparing your upload';
129
+ } else if (this.totalUploaded === this.progressBar.max) {
130
+ this.processingMessage.textContent = 'Processing your upload';
131
+ }
132
  }
133
+ }
134
+
135
+ handleFileSelect(event) {
136
+ const newFiles = Array.from(event.target.files).map(file => ({ path: file.name, content: file }));
137
+ this.files = this.files.concat(newFiles);
138
+ this.updateFileList();
139
+ }
140
+
141
+ handleFileDrop(event) {
142
+ event.preventDefault();
143
+ let items = event.dataTransfer.items;
144
+ for (let i = 0; i < items.length; i++) {
145
+ let item = items[i].webkitGetAsEntry();
146
+ if (item) {
147
+ this.traverseFileTree(item);
148
+ }
149
+ }
150
+ }
151
+
152
+ traverseFileTree(item, path = '') {
153
+ if (item.isFile) {
154
+ item.file((file) => {
155
+ this.files.push({ path: path + file.name, content: file });
156
+ this.updateFileList();
157
+ });
158
+ } else if (item.isDirectory) {
159
+ let dirReader = item.createReader();
160
+ dirReader.readEntries((entries) => {
161
+ for (let i = 0; i < entries.length; i++) {
162
+ this.traverseFileTree(entries[i], path + item.name + "/");
163
+ }
164
+ });
165
+ }
166
+ }
167
+
168
+ updateFileList() {
169
+ this.fileList.innerHTML = '';
170
+ for (let file of this.files) {
171
+ let listItem = document.createElement('li');
172
+ listItem.textContent = file.path;
173
+ this.fileList.appendChild(listItem);
174
+ }
175
+ }
176
+
177
+ async upload() {
178
  this.progressBar.value = 0;
179
  this.messageDiv.textContent = '';
180
  this.errorDiv.textContent = '';
181
  this.processingMessage.textContent = '';
182
+ const HF_ACCESS_TOKEN = this.tokenInput.value;
183
+ const REPO_ID = this.repoInput.value;
184
+
185
+ if (this.files.length > 0) {
186
+ this.prepareUpload();
187
+
188
  try {
189
  await this.createRepository(REPO_ID, HF_ACCESS_TOKEN);
190
+ await this.uploadFilesToRepo(REPO_ID, HF_ACCESS_TOKEN);
191
+ this.handleUploadSuccess();
192
  } catch (error) {
193
  this.handleErrorDuringUpload(error);
194
  }
195
  } else {
196
+ this.messageDiv.textContent = 'No files selected for upload.';
197
  }
198
+ }
199
+
200
+ prepareUpload() {
201
+ let totalSize = this.files.reduce((total, file) => total + file.content.size, 0);
202
+ this.progressBar.max = totalSize;
203
+ this.totalUploaded = 0;
204
+ this.startTime = Date.now();
205
+ }
206
+
207
+ async createRepository(REPO_ID, HF_ACCESS_TOKEN) {
208
  try {
209
+ await createRepo({
210
+ repo: REPO_ID,
211
+ credentials: { accessToken: HF_ACCESS_TOKEN },
212
+ });
213
  } catch (error) {
214
+ if (error.message !== 'You already created this model repo') {
215
+ throw error;
216
+ }
217
  }
218
+ }
219
+
220
+ async uploadFilesToRepo(REPO_ID, HF_ACCESS_TOKEN) {
221
+ await uploadFiles({
222
+ repo: REPO_ID,
223
+ credentials: { accessToken: HF_ACCESS_TOKEN },
224
+ files: this.files
225
+ });
226
+ }
227
+
228
+ handleUploadSuccess() {
229
+ this.messageDiv.textContent = 'Upload successful!';
230
+ this.processingMessage.textContent = '';
231
+ this.files = [];
232
+ this.updateFileList();
233
+ }
234
+
235
+ handleErrorDuringUpload(error) {
236
  console.error('Error during upload', error);
237
  this.errorDiv.textContent = 'Error during upload: ' + error.message;
238
+ }
239
  }
240
+
241
  new FileUploader();
242
  </script>
243
+
244
  </body>
245
+ </html>