gewei20 commited on
Commit
d1b5e4b
Β·
verified Β·
1 Parent(s): 327641e

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +518 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Upload R2
3
- emoji: πŸƒ
4
- colorFrom: blue
5
- colorTo: pink
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: upload-r2
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,518 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CloudSync - S3 File Uploader</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .dropzone {
11
+ border: 2px dashed #3b82f6;
12
+ transition: all 0.3s ease;
13
+ }
14
+ .dropzone.active {
15
+ border-color: #10b981;
16
+ background-color: #f0f9ff;
17
+ }
18
+ .progress-bar {
19
+ transition: width 0.3s ease;
20
+ }
21
+ .file-item:hover {
22
+ background-color: #f8fafc;
23
+ }
24
+ .rotate {
25
+ animation: spin 1s linear infinite;
26
+ }
27
+ @keyframes spin {
28
+ from { transform: rotate(0deg); }
29
+ to { transform: rotate(360deg); }
30
+ }
31
+ </style>
32
+ </head>
33
+ <body class="bg-gray-50 min-h-screen">
34
+ <div class="container mx-auto px-4 py-8 max-w-4xl">
35
+ <!-- Header -->
36
+ <header class="mb-8 text-center">
37
+ <h1 class="text-4xl font-bold text-blue-600 mb-2">CloudSync</h1>
38
+ <p class="text-gray-600">Efficient S3 File Uploader with Real-time Monitoring</p>
39
+ </header>
40
+
41
+ <!-- Connection Settings Card -->
42
+ <div class="bg-white rounded-lg shadow-md p-6 mb-6">
43
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
44
+ <i class="fas fa-cloud-upload-alt text-blue-500 mr-2"></i>
45
+ S3 Connection Settings
46
+ </h2>
47
+
48
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
49
+ <div>
50
+ <label class="block text-sm font-medium text-gray-700 mb-1">Endpoint URL</label>
51
+ <input type="text" id="endpointUrl" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" value="https://75f5ed467c14e39214f3a6f2a169f3d0.r2.cloudflarestorage.com/scrapydocs">
52
+ </div>
53
+ <div>
54
+ <label class="block text-sm font-medium text-gray-700 mb-1">Bucket Name</label>
55
+ <input type="text" id="bucketName" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" value="scrapydocs">
56
+ </div>
57
+ </div>
58
+
59
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
60
+ <div>
61
+ <label class="block text-sm font-medium text-gray-700 mb-1">Access Key</label>
62
+ <input type="password" id="accessKey" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter your access key">
63
+ </div>
64
+ <div>
65
+ <label class="block text-sm font-medium text-gray-700 mb-1">Secret Key</label>
66
+ <input type="password" id="secretKey" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter your secret key">
67
+ </div>
68
+ </div>
69
+
70
+ <div class="mt-6 flex justify-end">
71
+ <button id="testConnectionBtn" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 flex items-center">
72
+ <i class="fas fa-plug mr-2"></i> Test Connection
73
+ </button>
74
+ </div>
75
+
76
+ <div id="connectionStatus" class="mt-4 hidden">
77
+ <div class="flex items-center p-3 rounded-md">
78
+ <i class="fas fa-circle mr-2 text-gray-400"></i>
79
+ <span class="text-sm">Connection status will appear here</span>
80
+ </div>
81
+ </div>
82
+ </div>
83
+
84
+ <!-- File Upload Card -->
85
+ <div class="bg-white rounded-lg shadow-md p-6 mb-6">
86
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
87
+ <i class="fas fa-folder-open text-blue-500 mr-2"></i>
88
+ Folder Upload
89
+ </h2>
90
+
91
+ <div class="mb-4">
92
+ <label class="block text-sm font-medium text-gray-700 mb-1">Folder Path</label>
93
+ <div class="flex">
94
+ <input type="text" id="folderPath" class="flex-1 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter folder path or drag & drop">
95
+ <button id="browseBtn" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-r-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
96
+ <i class="fas fa-folder-open mr-1"></i> Browse
97
+ </button>
98
+ </div>
99
+ </div>
100
+
101
+ <div id="dropzone" class="dropzone p-8 rounded-md mb-4 text-center cursor-pointer">
102
+ <i class="fas fa-cloud-upload-alt text-4xl text-blue-400 mb-3"></i>
103
+ <p class="text-gray-600 mb-2">Drag & drop files here or click to select</p>
104
+ <p class="text-sm text-gray-500">Supports multiple files and folders</p>
105
+ </div>
106
+
107
+ <div class="flex justify-between">
108
+ <div>
109
+ <label class="block text-sm font-medium text-gray-700 mb-1">Prefix (optional)</label>
110
+ <input type="text" id="prefix" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="e.g., docs/2023">
111
+ </div>
112
+ <div class="flex items-end">
113
+ <button id="uploadBtn" class="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 flex items-center">
114
+ <i class="fas fa-upload mr-2"></i> Upload Files
115
+ </button>
116
+ </div>
117
+ </div>
118
+ </div>
119
+
120
+ <!-- Upload Progress -->
121
+ <div id="uploadProgress" class="bg-white rounded-lg shadow-md p-6 mb-6 hidden">
122
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
123
+ <i class="fas fa-tasks text-blue-500 mr-2"></i>
124
+ Upload Progress
125
+ </h2>
126
+
127
+ <div class="mb-4">
128
+ <div class="flex justify-between mb-1">
129
+ <span class="text-sm font-medium text-gray-700">Overall Progress</span>
130
+ <span id="overallProgressText" class="text-sm font-medium text-gray-700">0%</span>
131
+ </div>
132
+ <div class="w-full bg-gray-200 rounded-full h-2.5">
133
+ <div id="overallProgressBar" class="bg-blue-600 h-2.5 rounded-full progress-bar" style="width: 0%"></div>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="mb-2 flex justify-between">
138
+ <span class="text-sm font-medium text-gray-700">Files Processed: <span id="filesProcessed">0</span>/<span id="totalFiles">0</span></span>
139
+ <span class="text-sm font-medium text-gray-700">Success: <span id="successCount" class="text-green-600">0</span> | Failed: <span id="failedCount" class="text-red-600">0</span></span>
140
+ </div>
141
+
142
+ <div id="fileList" class="border border-gray-200 rounded-md divide-y divide-gray-200 max-h-64 overflow-y-auto">
143
+ <!-- Files will be listed here -->
144
+ <div class="text-center py-8 text-gray-500">
145
+ <i class="fas fa-file-upload text-3xl mb-2"></i>
146
+ <p>No files selected</p>
147
+ </div>
148
+ </div>
149
+
150
+ <div class="mt-4 flex justify-end">
151
+ <button id="cancelUploadBtn" class="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 flex items-center">
152
+ <i class="fas fa-stop-circle mr-2"></i> Cancel Upload
153
+ </button>
154
+ </div>
155
+ </div>
156
+
157
+ <!-- Log Console -->
158
+ <div class="bg-white rounded-lg shadow-md p-6">
159
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
160
+ <i class="fas fa-terminal text-blue-500 mr-2"></i>
161
+ Activity Log
162
+ </h2>
163
+
164
+ <div id="logConsole" class="bg-gray-900 text-green-400 font-mono text-sm p-4 rounded-md h-48 overflow-y-auto">
165
+ <div>> Welcome to CloudSync S3 Uploader</div>
166
+ <div>> Ready to upload files to your S3 bucket</div>
167
+ </div>
168
+
169
+ <div class="mt-4 flex justify-between">
170
+ <button id="clearLogBtn" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 flex items-center">
171
+ <i class="fas fa-trash-alt mr-2"></i> Clear Log
172
+ </button>
173
+ <div class="flex space-x-2">
174
+ <button id="copyLogBtn" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 flex items-center">
175
+ <i class="fas fa-copy mr-2"></i> Copy Log
176
+ </button>
177
+ <button id="exportLogBtn" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 flex items-center">
178
+ <i class="fas fa-file-export mr-2"></i> Export Log
179
+ </button>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+
185
+ <script>
186
+ // DOM Elements
187
+ const dropzone = document.getElementById('dropzone');
188
+ const folderPathInput = document.getElementById('folderPath');
189
+ const browseBtn = document.getElementById('browseBtn');
190
+ const uploadBtn = document.getElementById('uploadBtn');
191
+ const uploadProgress = document.getElementById('uploadProgress');
192
+ const fileList = document.getElementById('fileList');
193
+ const logConsole = document.getElementById('logConsole');
194
+ const testConnectionBtn = document.getElementById('testConnectionBtn');
195
+ const connectionStatus = document.getElementById('connectionStatus');
196
+
197
+ // State variables
198
+ let filesToUpload = [];
199
+ let isUploading = false;
200
+ let uploadCancelled = false;
201
+
202
+ // Event Listeners
203
+ dropzone.addEventListener('click', () => {
204
+ // In a real app, this would trigger file selection
205
+ addLog("File selection dialog would open here in a real application");
206
+ });
207
+
208
+ dropzone.addEventListener('dragover', (e) => {
209
+ e.preventDefault();
210
+ dropzone.classList.add('active');
211
+ });
212
+
213
+ dropzone.addEventListener('dragleave', () => {
214
+ dropzone.classList.remove('active');
215
+ });
216
+
217
+ dropzone.addEventListener('drop', (e) => {
218
+ e.preventDefault();
219
+ dropzone.classList.remove('active');
220
+
221
+ // In a real app, this would handle dropped files
222
+ const files = []; // Array.from(e.dataTransfer.files);
223
+ if (files.length > 0) {
224
+ filesToUpload = files;
225
+ updateFileList();
226
+ addLog(`Added ${files.length} file(s) from drag & drop`);
227
+ }
228
+ });
229
+
230
+ browseBtn.addEventListener('click', () => {
231
+ // In a real app, this would trigger folder selection
232
+ addLog("Folder selection dialog would open here in a real application");
233
+ folderPathInput.value = "D:/app/JupyterLab/crawl4ai/output/docs_scrapy";
234
+ });
235
+
236
+ uploadBtn.addEventListener('click', () => {
237
+ if (filesToUpload.length === 0 && !folderPathInput.value) {
238
+ addLog("βœ– Error: No files or folder selected for upload", "error");
239
+ return;
240
+ }
241
+
242
+ startUpload();
243
+ });
244
+
245
+ testConnectionBtn.addEventListener('click', () => {
246
+ testConnection();
247
+ });
248
+
249
+ document.getElementById('cancelUploadBtn').addEventListener('click', () => {
250
+ if (isUploading) {
251
+ uploadCancelled = true;
252
+ isUploading = false;
253
+ addLog("Upload cancelled by user", "warning");
254
+ }
255
+ });
256
+
257
+ document.getElementById('clearLogBtn').addEventListener('click', () => {
258
+ logConsole.innerHTML = '';
259
+ addLog("Log cleared");
260
+ });
261
+
262
+ document.getElementById('copyLogBtn').addEventListener('click', () => {
263
+ navigator.clipboard.writeText(logConsole.textContent);
264
+ addLog("Log content copied to clipboard");
265
+ });
266
+
267
+ document.getElementById('exportLogBtn').addEventListener('click', () => {
268
+ // In a real app, this would export the log
269
+ addLog("Log export functionality would be implemented here");
270
+ });
271
+
272
+ // Functions
273
+ function updateFileList() {
274
+ if (filesToUpload.length === 0 && !folderPathInput.value) {
275
+ fileList.innerHTML = `
276
+ <div class="text-center py-8 text-gray-500">
277
+ <i class="fas fa-file-upload text-3xl mb-2"></i>
278
+ <p>No files selected</p>
279
+ </div>
280
+ `;
281
+ return;
282
+ }
283
+
284
+ let html = '';
285
+
286
+ if (folderPathInput.value) {
287
+ html += `
288
+ <div class="file-item p-3 flex items-center bg-blue-50">
289
+ <i class="fas fa-folder text-blue-500 mr-3"></i>
290
+ <div class="flex-1">
291
+ <div class="font-medium">${folderPathInput.value.split('/').pop() || folderPathInput.value.split('\\').pop()}</div>
292
+ <div class="text-xs text-gray-500">Folder (contents will be uploaded)</div>
293
+ </div>
294
+ <div class="text-sm text-gray-500">Pending</div>
295
+ </div>
296
+ `;
297
+ }
298
+
299
+ filesToUpload.forEach((file, index) => {
300
+ html += `
301
+ <div class="file-item p-3 flex items-center" data-index="${index}">
302
+ <i class="fas ${file.type.startsWith('image/') ? 'fa-image' : 'fa-file'} text-gray-500 mr-3"></i>
303
+ <div class="flex-1 truncate">
304
+ <div class="font-medium truncate">${file.name}</div>
305
+ <div class="text-xs text-gray-500">${formatFileSize(file.size)}</div>
306
+ </div>
307
+ <div class="text-sm text-gray-500">Pending</div>
308
+ </div>
309
+ `;
310
+ });
311
+
312
+ fileList.innerHTML = html;
313
+ uploadProgress.classList.remove('hidden');
314
+ }
315
+
316
+ function formatFileSize(bytes) {
317
+ if (bytes === 0) return '0 Bytes';
318
+ const k = 1024;
319
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
320
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
321
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
322
+ }
323
+
324
+ function addLog(message, type = "info") {
325
+ const now = new Date();
326
+ const timestamp = now.toLocaleTimeString();
327
+ let icon = '>';
328
+
329
+ if (type === "error") {
330
+ icon = '<i class="fas fa-times-circle text-red-500"></i>';
331
+ } else if (type === "success") {
332
+ icon = '<i class="fas fa-check-circle text-green-500"></i>';
333
+ } else if (type === "warning") {
334
+ icon = '<i class="fas fa-exclamation-triangle text-yellow-500"></i>';
335
+ }
336
+
337
+ const logEntry = document.createElement('div');
338
+ logEntry.innerHTML = `<span class="text-gray-500">${timestamp}</span> ${icon} ${message}`;
339
+ logConsole.appendChild(logEntry);
340
+ logConsole.scrollTop = logConsole.scrollHeight;
341
+ }
342
+
343
+ function testConnection() {
344
+ const endpointUrl = document.getElementById('endpointUrl').value;
345
+ const accessKey = document.getElementById('accessKey').value;
346
+ const secretKey = document.getElementById('secretKey').value;
347
+
348
+ if (!endpointUrl || !accessKey || !secretKey) {
349
+ addLog("βœ– Error: Please fill all connection fields", "error");
350
+ return;
351
+ }
352
+
353
+ testConnectionBtn.innerHTML = '<i class="fas fa-spinner rotate mr-2"></i> Testing...';
354
+ testConnectionBtn.disabled = true;
355
+
356
+ // Simulate connection test
357
+ setTimeout(() => {
358
+ connectionStatus.classList.remove('hidden');
359
+ connectionStatus.innerHTML = `
360
+ <div class="flex items-center p-3 rounded-md bg-green-50">
361
+ <i class="fas fa-check-circle mr-2 text-green-500"></i>
362
+ <span class="text-sm text-green-800">Successfully connected to S3 bucket</span>
363
+ </div>
364
+ `;
365
+ testConnectionBtn.innerHTML = '<i class="fas fa-plug mr-2"></i> Test Connection';
366
+ testConnectionBtn.disabled = false;
367
+ addLog("βœ” Successfully connected to S3 bucket", "success");
368
+ }, 1500);
369
+ }
370
+
371
+ function startUpload() {
372
+ if (isUploading) return;
373
+
374
+ isUploading = true;
375
+ uploadCancelled = false;
376
+ const prefix = document.getElementById('prefix').value;
377
+
378
+ // Reset counters
379
+ document.getElementById('filesProcessed').textContent = '0';
380
+ document.getElementById('totalFiles').textContent = folderPathInput.value ? 'Calculating...' : filesToUpload.length;
381
+ document.getElementById('successCount').textContent = '0';
382
+ document.getElementById('failedCount').textContent = '0';
383
+ document.getElementById('overallProgressBar').style.width = '0%';
384
+ document.getElementById('overallProgressText').textContent = '0%';
385
+
386
+ // Update UI
387
+ uploadBtn.innerHTML = '<i class="fas fa-spinner rotate mr-2"></i> Uploading...';
388
+ uploadBtn.disabled = true;
389
+
390
+ addLog(`Starting upload to bucket: ${document.getElementById('bucketName').value}`);
391
+ if (prefix) {
392
+ addLog(`Using prefix: ${prefix}`);
393
+ }
394
+
395
+ if (folderPathInput.value) {
396
+ addLog(`Uploading folder: ${folderPathInput.value}`);
397
+ // In a real app, this would scan the folder and upload its contents
398
+ simulateFolderUpload(folderPathInput.value, prefix);
399
+ } else {
400
+ // In a real app, this would upload the selected files
401
+ simulateFileUpload(filesToUpload, prefix);
402
+ }
403
+ }
404
+
405
+ function simulateFolderUpload(folderPath, prefix) {
406
+ // Simulate folder scanning and file counting
407
+ setTimeout(() => {
408
+ const totalFiles = 42; // Simulated file count
409
+ document.getElementById('totalFiles').textContent = totalFiles;
410
+ addLog(`Found ${totalFiles} files in folder`);
411
+
412
+ // Simulate file uploads
413
+ let processed = 0;
414
+ let success = 0;
415
+ let failed = 0;
416
+
417
+ const uploadInterval = setInterval(() => {
418
+ if (uploadCancelled || processed >= totalFiles) {
419
+ clearInterval(uploadInterval);
420
+ finishUpload(processed, success, failed);
421
+ return;
422
+ }
423
+
424
+ processed++;
425
+ const isSuccess = Math.random() > 0.1; // 90% success rate
426
+
427
+ if (isSuccess) {
428
+ success++;
429
+ document.getElementById('successCount').textContent = success;
430
+ addLog(`βœ” Successfully uploaded ${prefix ? prefix + '/' : ''}file${processed}.txt`, "success");
431
+
432
+ // Update file item status
433
+ const fileItems = fileList.querySelectorAll('.file-item');
434
+ if (fileItems.length > 0) {
435
+ const randomIndex = Math.floor(Math.random() * fileItems.length);
436
+ const statusDiv = fileItems[randomIndex].querySelector('div:last-child');
437
+ statusDiv.innerHTML = '<span class="text-green-600"><i class="fas fa-check mr-1"></i>Done</span>';
438
+ }
439
+ } else {
440
+ failed++;
441
+ document.getElementById('failedCount').textContent = failed;
442
+ addLog(`βœ– Failed to upload ${prefix ? prefix + '/' : ''}file${processed}.txt`, "error");
443
+ }
444
+
445
+ document.getElementById('filesProcessed').textContent = processed;
446
+ const progress = Math.floor((processed / totalFiles) * 100);
447
+ document.getElementById('overallProgressBar').style.width = `${progress}%`;
448
+ document.getElementById('overallProgressText').textContent = `${progress}%`;
449
+
450
+ }, 200);
451
+
452
+ }, 1000);
453
+ }
454
+
455
+ function simulateFileUpload(files, prefix) {
456
+ const totalFiles = files.length;
457
+ let processed = 0;
458
+ let success = 0;
459
+ let failed = 0;
460
+
461
+ const uploadInterval = setInterval(() => {
462
+ if (uploadCancelled || processed >= totalFiles) {
463
+ clearInterval(uploadInterval);
464
+ finishUpload(processed, success, failed);
465
+ return;
466
+ }
467
+
468
+ processed++;
469
+ const isSuccess = Math.random() > 0.1; // 90% success rate
470
+
471
+ if (isSuccess) {
472
+ success++;
473
+ document.getElementById('successCount').textContent = success;
474
+ addLog(`βœ” Successfully uploaded ${prefix ? prefix + '/' : ''}${files[processed-1].name}`, "success");
475
+
476
+ // Update file item status
477
+ const fileItem = fileList.querySelector(`.file-item[data-index="${processed-1}"]`);
478
+ if (fileItem) {
479
+ const statusDiv = fileItem.querySelector('div:last-child');
480
+ statusDiv.innerHTML = '<span class="text-green-600"><i class="fas fa-check mr-1"></i>Done</span>';
481
+ }
482
+ } else {
483
+ failed++;
484
+ document.getElementById('failedCount').textContent = failed;
485
+ addLog(`βœ– Failed to upload ${prefix ? prefix + '/' : ''}${files[processed-1].name}`, "error");
486
+ }
487
+
488
+ document.getElementById('filesProcessed').textContent = processed;
489
+ const progress = Math.floor((processed / totalFiles) * 100);
490
+ document.getElementById('overallProgressBar').style.width = `${progress}%`;
491
+ document.getElementById('overallProgressText').textContent = `${progress}%`;
492
+
493
+ }, 500);
494
+ }
495
+
496
+ function finishUpload(processed, success, failed) {
497
+ isUploading = false;
498
+
499
+ uploadBtn.innerHTML = '<i class="fas fa-upload mr-2"></i> Upload Files';
500
+ uploadBtn.disabled = false;
501
+
502
+ if (uploadCancelled) {
503
+ addLog(`Upload cancelled. Processed ${processed} files (${success} success, ${failed} failed)`, "warning");
504
+ } else {
505
+ addLog(`Upload complete. Processed ${processed} files (${success} success, ${failed} failed)`);
506
+
507
+ if (failed > 0) {
508
+ addLog("Some files failed to upload. You can try uploading them again.", "warning");
509
+ }
510
+ }
511
+ }
512
+
513
+ // Initialize
514
+ updateFileList();
515
+ addLog("Application initialized");
516
+ </script>
517
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=gewei20/upload-r2" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
518
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ import os import boto3 from dotenv import load_dotenv # 加载.envζ–‡δ»ΆδΈ­ηš„ηŽ―ε’ƒε˜ι‡ load_dotenv() ACCOUNT_ID = os.getenv("S3_ACCOUNT_ID") ACCESS_KEY = os.getenv("S3_ACCESS_KEY") SECRET_KEY = os.getenv("S3_SECRET_KEY") BUCKET = "scrapydocs" s3 = boto3.client( "s3", endpoint_url=f"https://75f5ed467c14e39214f3a6f2a169f3d0.r2.cloudflarestorage.com/scrapydocs", aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY, region_name="auto", ) def upload_folder_contents(folder_path, bucket, prefix=""): try: file_count = 0 for root, _, files in os.walk(folder_path): for file in files: full_path = os.path.join(root, file) key = f"{prefix}/{file}" if prefix else file try: s3.upload_file(full_path, bucket, key) print(f"βœ” Successfully uploaded {key}") file_count += 1 except Exception as e: print(f"βœ– Failed to upload {key}: {str(e)}") print(f"\nUpload complete. Total files processed: {file_count}") return file_count except Exception as e: print(f"βœ– Fatal error: {str(e)}") return 0 if __name__ == "__main__": print("Starting S3 upload process...") folder_path = "D:/app/JupyterLab/crawl4ai/output/docs_scrapy" if not os.path.exists(folder_path): print(f"βœ– Error: Folder not found at {folder_path}") else: print(f"Testing connection to {s3.meta.endpoint_url}") print(s3.list_buckets()) # θΏ™δΌšιͺŒθ―δ½ ηš„ε‡­θ―ζ˜―ε¦ζœ‰ζ•ˆ upload_folder_contents(folder_path, BUCKET) print("Process completed.")