luigi12345 commited on
Commit
75ef963
β€’
1 Parent(s): 06adc53
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ .aider*
2
+ .env
.gpteng/file_selection.toml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Remove '#' to select a file or turn off linting.
2
+
3
+ # Linting with BLACK (Python) enhances code suggestions from LLMs. To disable linting, uncomment the relevant option in the linting settings.
4
+
5
+ # gpt-engineer can only read selected files. Including irrelevant files will degrade performance, cost additional tokens and potentially overflow token limit.
6
+
7
+ [linting]
8
+ # "linting" = "off"
9
+
10
+ [files]
11
+ "app.py" = "selected"
12
+ # "test_app.py" = "selected"
13
+ # "README.md" = "selected"
14
+ # "requirements.txt" = "selected"
.gpteng/memory/logs/debug_log_file.txt ADDED
@@ -0,0 +1,902 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ 2024-11-23T16:56:57.723744
3
+ UPLOADED FILES:
4
+ File: app.py
5
+ import os
6
+ import gradio as gr
7
+ from huggingface_hub import HfApi, upload_folder, create_repo, login, list_repo_files
8
+ from rich.console import Console
9
+ from rich.logging import RichHandler
10
+ import logging
11
+ import time
12
+ import shutil
13
+ from pathlib import Path
14
+
15
+ # Default values
16
+ DEFAULT_REPO = os.getenv("DEFAULT_REPO", "luigi12345/megacursos-master-999")
17
+ DEFAULT_LOCAL_PATH = os.getenv(
18
+ "DEFAULT_LOCAL_PATH", "/Users/samihalawa/Documents/Megacursos/MEGACURSOS_S3_MASTER"
19
+ )
20
+ token = os.getenv("HF_TOKEN", "")
21
+
22
+ # Initialize Rich console for logging
23
+ console = Console()
24
+ logging.basicConfig(
25
+ level=logging.INFO,
26
+ format="%(message)s",
27
+ datefmt="[%Y-%m-%d %H:%M:%S]",
28
+ handlers=[RichHandler(console=console, rich_tracebacks=True)],
29
+ )
30
+ logger = logging.getLogger("InfiniteStorageFace")
31
+
32
+ # Initialize Hugging Face API client
33
+ api = HfApi()
34
+
35
+ # Centralized ignore patterns mapping
36
+ IGNORE_PATTERNS_MAP = {
37
+ "Ignore __pycache__": "**/__pycache__/**",
38
+ "Ignore .git": ".git/**",
39
+ "Ignore .venv": "venv/**",
40
+ "Ignore *.pyc": "*.pyc",
41
+ "Ignore *.log": "*.log",
42
+ "Ignore *.tmp": "*.tmp",
43
+ "Ignore *.DS_Store": "*.DS_Store",
44
+ }
45
+
46
+ # Shared logs list
47
+ shared_logs = []
48
+
49
+ # Event to cancel upload
50
+ cancel_event = False
51
+
52
+
53
+ # Function to log messages
54
+ def log(message):
55
+ timestamp = time.strftime("[%Y-%m-%d %H:%M:%S]")
56
+ full_message = f"{timestamp} {message}"
57
+ shared_logs.append(full_message)
58
+ logger.info(message)
59
+ return full_message
60
+
61
+
62
+ # Function to authenticate user with Hugging Face token
63
+ def authenticate(token):
64
+ if not token:
65
+ return False, log("❌ Hugging Face Token is required.")
66
+ try:
67
+ login(token)
68
+ return True, log("βœ… Authenticated successfully!")
69
+ except Exception as e:
70
+ return False, log(f"❌ Authentication failed: {e}")
71
+
72
+
73
+ # Function to create repository if it doesn't exist
74
+ def create_repo_if_not_exists(repo_id, token, repo_type, private):
75
+ try:
76
+ api.list_repo_files(repo_id=repo_id, repo_type=repo_type, token=token)
77
+ return True, log(f"βœ… Repository '{repo_id}' exists. Proceeding with upload...")
78
+ except Exception:
79
+ log(f"❌ Repository '{repo_id}' does not exist. Creating it...")
80
+ try:
81
+ create_repo(
82
+ repo_id=repo_id,
83
+ token=token,
84
+ private=private,
85
+ repo_type=repo_type,
86
+ exist_ok=True,
87
+ space_sdk="static" if repo_type == "space" else None,
88
+ )
89
+ return True, log(f"βœ… Created new repository: '{repo_id}'.")
90
+ except Exception as create_err:
91
+ return False, log(
92
+ f"❌ Failed to create repository '{repo_id}': {create_err}"
93
+ )
94
+
95
+
96
+ # Function to clean up ignored folders
97
+ def cleanup_before_upload(folder_path, ignore_patterns):
98
+ for pattern in ignore_patterns:
99
+ for path in Path(folder_path).rglob(pattern):
100
+ if path.is_dir():
101
+ shutil.rmtree(path)
102
+ log(f"πŸ—‘οΈ Removed ignored folder: {path}")
103
+
104
+
105
+ # Function to upload a folder
106
+ def upload_folder_structure(
107
+ folder_path, repo_id, token, repo_type, target_path, ignore_patterns
108
+ ):
109
+ # Clean up ignored folders
110
+ cleanup_before_upload(folder_path, ignore_patterns)
111
+
112
+ upload_params = {
113
+ "folder_path": folder_path,
114
+ "repo_id": repo_id,
115
+ "repo_type": repo_type,
116
+ "token": token,
117
+ "path_in_repo": target_path,
118
+ "multi_commits": True,
119
+ "multi_commits_verbose": True,
120
+ }
121
+ log(
122
+ f"πŸš€ Uploading folder '{folder_path}' to '{target_path}' in repository '{repo_id}'..."
123
+ )
124
+ try:
125
+ upload_folder(**upload_params)
126
+ log(f"βœ… Upload completed for '{folder_path}'!")
127
+ except Exception as upload_err:
128
+ log(f"❌ Upload failed for '{folder_path}': {upload_err}")
129
+
130
+
131
+ # Function to handle uploads, allowing direct folder uploads
132
+ def upload_files(
133
+ files,
134
+ repo_id,
135
+ token,
136
+ private,
137
+ threads,
138
+ subfolder,
139
+ repo_type,
140
+ ignore_patterns_selected,
141
+ ):
142
+ global cancel_event
143
+ cancel_event = False
144
+
145
+ logs = []
146
+
147
+ # Authenticate
148
+ auth_success, auth_message = authenticate(token)
149
+ logs.append(auth_message)
150
+ if not auth_success:
151
+ return "\n".join(logs)
152
+
153
+ # Create repo if not exists
154
+ repo_success, repo_message = create_repo_if_not_exists(
155
+ repo_id, token, repo_type, private
156
+ )
157
+ logs.append(repo_message)
158
+ if not repo_success:
159
+ return "\n".join(logs)
160
+
161
+ # Prepare target path
162
+ target_path = subfolder.replace("\\", "/") if subfolder else ""
163
+
164
+ # Map selected ignore patterns to actual patterns
165
+ ignore_patterns = [
166
+ IGNORE_PATTERNS_MAP[pattern] for pattern in ignore_patterns_selected
167
+ ]
168
+
169
+ # Upload folders directly if provided
170
+ if files:
171
+ for file in files:
172
+ if cancel_event:
173
+ logs.append(log("❌ Upload has been cancelled."))
174
+ return "\n".join(logs)
175
+ file_path = file.name
176
+ if os.path.isdir(file_path): # Check if the file is a directory
177
+ upload_folder_structure(
178
+ file_path, repo_id, token, repo_type, target_path, ignore_patterns
179
+ )
180
+ logs.append(log(f"βœ… Uploaded folder '{file_path}'."))
181
+ else:
182
+ logs.append(
183
+ log(
184
+ f"❌ '{file_path}' is not a folder. Only folders can be uploaded."
185
+ )
186
+ )
187
+ else:
188
+ logs.append(log("❌ No files provided for upload."))
189
+
190
+ if cancel_event:
191
+ logs.append(log("❌ Upload has been cancelled."))
192
+ return "\n".join(logs)
193
+
194
+ logs.append(log("πŸš€ Upload completed. Check the logs for details."))
195
+ return "\n".join(logs)
196
+
197
+
198
+ # Function to cancel upload
199
+ def cancel_upload():
200
+ global cancel_event
201
+ cancel_event = True
202
+ return log("Upload has been cancelled.")
203
+
204
+
205
+ # Function to refresh logs
206
+ def refresh_logs():
207
+ return "\n".join(shared_logs)
208
+
209
+
210
+ # Gradio Interface
211
+ def create_interface():
212
+ with gr.Blocks() as app:
213
+ gr.Markdown("# πŸš€ InfiniteStorageFace")
214
+ gr.Markdown(
215
+ "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
216
+ )
217
+
218
+ with gr.Row():
219
+ with gr.Column(scale=1):
220
+ gr.Markdown("## Upload Section")
221
+
222
+ token = gr.Textbox(
223
+ label="Hugging Face Token",
224
+ type="password",
225
+ placeholder="Enter your Hugging Face API token",
226
+ value=os.getenv("HF_TOKEN", ""),
227
+ interactive=True,
228
+ lines=1,
229
+ )
230
+
231
+ repo_type = gr.Dropdown(
232
+ label="Repository Type",
233
+ choices=["space", "model", "dataset"],
234
+ value="space",
235
+ interactive=True,
236
+ )
237
+
238
+ repo_id = gr.Textbox(
239
+ label="Repository ID",
240
+ placeholder="e.g., username/repo-name",
241
+ value=os.getenv("DEFAULT_REPO", ""),
242
+ interactive=True,
243
+ lines=1,
244
+ )
245
+
246
+ private = gr.Checkbox(
247
+ label="Make Repository Private",
248
+ value=False,
249
+ interactive=True,
250
+ )
251
+
252
+ files = gr.File(
253
+ label="Upload Folders",
254
+ file_count="multiple",
255
+ interactive=True,
256
+ type="directory",
257
+ )
258
+
259
+ subfolder = gr.Textbox(
260
+ label="Subfolder in Repository (Optional)",
261
+ placeholder="e.g., data/uploads",
262
+ value="",
263
+ interactive=True,
264
+ lines=1,
265
+ )
266
+
267
+ threads = gr.Slider(
268
+ label="Number of Threads",
269
+ minimum=1,
270
+ maximum=20,
271
+ step=1,
272
+ value=5,
273
+ interactive=True,
274
+ )
275
+
276
+ ignore_patterns_selected = gr.CheckboxGroup(
277
+ choices=list(IGNORE_PATTERNS_MAP.keys()),
278
+ label="Select Patterns to Ignore",
279
+ value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
280
+ interactive=True,
281
+ )
282
+
283
+ upload_button = gr.Button(
284
+ "Start Upload", variant="primary", interactive=True
285
+ )
286
+ cancel_button = gr.Button(
287
+ "Cancel Upload", variant="secondary", interactive=True
288
+ )
289
+
290
+ with gr.Column(scale=1):
291
+ gr.Markdown("## Status Section")
292
+ upload_status = gr.Textbox(
293
+ label="Upload Status",
294
+ lines=10,
295
+ interactive=False,
296
+ value="Idle",
297
+ )
298
+
299
+ with gr.Tab("Logs"):
300
+ log_output = gr.Textbox(
301
+ label="Upload Logs",
302
+ lines=15,
303
+ interactive=False,
304
+ placeholder="Logs will appear here...",
305
+ value="",
306
+ )
307
+ log_refresh = gr.Button("Refresh Logs", interactive=True)
308
+
309
+ # Define the upload button click event
310
+ upload_button.click(
311
+ fn=upload_files,
312
+ inputs=[
313
+ files,
314
+ repo_id,
315
+ token,
316
+ private,
317
+ threads,
318
+ subfolder,
319
+ repo_type,
320
+ ignore_patterns_selected,
321
+ ],
322
+ outputs=upload_status,
323
+ )
324
+
325
+ # Define the cancel button click event
326
+ cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
327
+
328
+ # Define the log refresh button click event
329
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
330
+
331
+ return app
332
+
333
+
334
+ if __name__ == "__main__":
335
+ app = create_interface()
336
+ app.launch(debug=True, share=True)
337
+
338
+
339
+ PROMPT:
340
+ enhance its experience and make it much more efificnet using th ebest Gradio 5 componnets available a
341
+
342
+ 2024-11-23T16:58:00.413965
343
+
344
+ CONSOLE OUTPUT:
345
+ To enhance the user experience and efficiency of the application using the best Gradio 5 components, we will make several improvements. These include using more interactive and user-friendly components, optimizing the layout, and ensuring that the application is responsive and provides real-time feedback. We will also ensure that the code is clean and follows best practices.
346
+
347
+ Here's a step-by-step breakdown of the changes:
348
+
349
+ 1. **Use Gradio 5 Components**: We'll replace some of the existing components with newer Gradio 5 components that offer better interactivity and user experience.
350
+
351
+ 2. **Optimize Layout**: We'll organize the layout to make it more intuitive and visually appealing.
352
+
353
+ 3. **Improve Feedback Mechanism**: We'll enhance the feedback mechanism to provide real-time updates and clearer status messages.
354
+
355
+ 4. **Code Refactoring**: We'll refactor the code to improve readability and maintainability.
356
+
357
+ Let's implement these changes:
358
+
359
+ ```diff
360
+ --- app.py
361
+ +++ app.py
362
+ @@ -1,11 +1,12 @@
363
+ import os
364
+ import gradio as gr
365
+ from huggingface_hub import HfApi, upload_folder, create_repo, login, list_repo_files
366
+ from rich.console import Console
367
+ from rich.logging import RichHandler
368
+ import logging
369
+ import time
370
+ import shutil
371
+ +import threading
372
+ from pathlib import Path
373
+
374
+ # Default values
375
+ @@ -206,124 +207,134 @@
376
+ # Gradio Interface
377
+ def create_interface():
378
+ with gr.Blocks() as app:
379
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
380
+ - gr.Markdown(
381
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
382
+ - )
383
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
384
+ + gr.Markdown(
385
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
386
+ + elem_id="sub-title"
387
+ + )
388
+
389
+ with gr.Row():
390
+ with gr.Column(scale=1):
391
+ - gr.Markdown("## Upload Section")
392
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
393
+
394
+ - token = gr.Textbox(
395
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
396
+ placeholder="Enter your Hugging Face API token",
397
+ value=os.getenv("HF_TOKEN", ""),
398
+ - interactive=True,
399
+ - lines=1,
400
+ + interactive=True
401
+ )
402
+
403
+ - repo_type = gr.Dropdown(
404
+ - label="Repository Type",
405
+ - choices=["space", "model", "dataset"],
406
+ - value="space",
407
+ - interactive=True,
408
+ + repo_type = gr.Radio(
409
+ + label="Repository Type", choices=["space", "model", "dataset"],
410
+ + value="space", interactive=True
411
+ )
412
+
413
+ - repo_id = gr.Textbox(
414
+ - label="Repository ID",
415
+ - placeholder="e.g., username/repo-name",
416
+ - value=os.getenv("DEFAULT_REPO", ""),
417
+ - interactive=True,
418
+ - lines=1,
419
+ + repo_id = gr.Textbox(label="Repository ID",
420
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
421
+ + interactive=True
422
+ )
423
+
424
+ - private = gr.Checkbox(
425
+ - label="Make Repository Private",
426
+ - value=False,
427
+ - interactive=True,
428
+ + private = gr.Checkbox(label="Make Repository Private",
429
+ + value=False, interactive=True
430
+ )
431
+
432
+ - files = gr.File(
433
+ - label="Upload Folders",
434
+ - file_count="multiple",
435
+ - interactive=True,
436
+ - type="directory",
437
+ + files = gr.Files(label="Upload Folders",
438
+ + file_count="multiple", interactive=True, type="directory"
439
+ )
440
+
441
+ - subfolder = gr.Textbox(
442
+ - label="Subfolder in Repository (Optional)",
443
+ - placeholder="e.g., data/uploads",
444
+ - value="",
445
+ - interactive=True,
446
+ - lines=1,
447
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
448
+ + placeholder="e.g., data/uploads", value="", interactive=True
449
+ )
450
+
451
+ - threads = gr.Slider(
452
+ - label="Number of Threads",
453
+ - minimum=1,
454
+ - maximum=20,
455
+ - step=1,
456
+ - value=5,
457
+ - interactive=True,
458
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
459
+ + step=1, value=5, interactive=True
460
+ )
461
+
462
+ - ignore_patterns_selected = gr.CheckboxGroup(
463
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
464
+ - label="Select Patterns to Ignore",
465
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
466
+ - interactive=True,
467
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
468
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
469
+ + interactive=True
470
+ )
471
+
472
+ - upload_button = gr.Button(
473
+ - "Start Upload", variant="primary", interactive=True
474
+ - )
475
+ - cancel_button = gr.Button(
476
+ - "Cancel Upload", variant="secondary", interactive=True
477
+ - )
478
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
479
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
480
+
481
+ with gr.Column(scale=1):
482
+ - gr.Markdown("## Status Section")
483
+ - upload_status = gr.Textbox(
484
+ - label="Upload Status",
485
+ - lines=10,
486
+ - interactive=False,
487
+ - value="Idle",
488
+ + gr.Markdown("## Status Section", elem_id="status-section")
489
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
490
+ + interactive=False, value="Idle"
491
+ )
492
+
493
+ with gr.Tab("Logs"):
494
+ - log_output = gr.Textbox(
495
+ - label="Upload Logs",
496
+ - lines=15,
497
+ - interactive=False,
498
+ - placeholder="Logs will appear here...",
499
+ - value="",
500
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
501
+ + interactive=False, placeholder="Logs will appear here...", value=""
502
+ )
503
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
504
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
505
+
506
+ # Define the upload button click event
507
+ - upload_button.click(
508
+ - fn=upload_files,
509
+ - inputs=[
510
+ - files,
511
+ - repo_id,
512
+ - token,
513
+ - private,
514
+ - threads,
515
+ - subfolder,
516
+ - repo_type,
517
+ - ignore_patterns_selected,
518
+ - ],
519
+ - outputs=upload_status,
520
+ - )
521
+ + def handle_upload(*args):
522
+ + threading.Thread(target=upload_files, args=args).start()
523
+
524
+ - # Define the cancel button click event
525
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
526
+ + upload_button.click(fn=handle_upload, inputs=[
527
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
528
+ + ], outputs=upload_status)
529
+
530
+ - # Define the log refresh button click event
531
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
532
+ +
533
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
534
+
535
+ return app
536
+
537
+ if __name__ == "__main__":
538
+ app = create_interface()
539
+ - app.launch(debug=True, share=True)
540
+ + app.launch(debug=True, share=True, server_port=7860)
541
+ ```
542
+
543
+ ### Key Changes:
544
+ - **Gradio 5 Components**: Updated components to use `gr.Files` for multiple file selection and `gr.Radio` for repository type selection.
545
+ - **Layout Optimization**: Improved the layout with better sectioning and labeling.
546
+ - **Real-time Feedback**: Introduced threading to handle uploads asynchronously, allowing the UI to remain responsive.
547
+ - **Code Refactoring**: Cleaned up the code for better readability and maintainability.
548
+
549
+ This concludes a fully working implementation.
550
+ Invalid Hunk NO.0---
551
+ In Hunk:@@ -206,124 +207,134 @@
552
+ # Gradio Interface
553
+ def create_interface():
554
+ with gr.Blocks() as app:
555
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
556
+ - gr.Markdown(
557
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
558
+ - )
559
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
560
+ + gr.Markdown(
561
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
562
+ + elem_id="sub-title"
563
+ + )
564
+
565
+ with gr.Row():
566
+ with gr.Column(scale=1):
567
+ - gr.Markdown("## Upload Section")
568
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
569
+
570
+ - token = gr.Textbox(
571
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
572
+ placeholder="Enter your Hugging Face API token",
573
+ value=os.getenv("HF_TOKEN", ""),
574
+ - interactive=True,
575
+ - lines=1,
576
+ + interactive=True
577
+ )
578
+
579
+ - repo_type = gr.Dropdown(
580
+ - label="Repository Type",
581
+ - choices=["space", "model", "dataset"],
582
+ - value="space",
583
+ - interactive=True,
584
+ + repo_type = gr.Radio(
585
+ + label="Repository Type", choices=["space", "model", "dataset"],
586
+ + value="space", interactive=True
587
+ )
588
+
589
+ - repo_id = gr.Textbox(
590
+ - label="Repository ID",
591
+ - placeholder="e.g., username/repo-name",
592
+ - value=os.getenv("DEFAULT_REPO", ""),
593
+ - interactive=True,
594
+ - lines=1,
595
+ + repo_id = gr.Textbox(label="Repository ID",
596
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
597
+ + interactive=True
598
+ )
599
+
600
+ - private = gr.Checkbox(
601
+ - label="Make Repository Private",
602
+ - value=False,
603
+ - interactive=True,
604
+ + private = gr.Checkbox(label="Make Repository Private",
605
+ + value=False, interactive=True
606
+ )
607
+
608
+ - files = gr.File(
609
+ - label="Upload Folders",
610
+ - file_count="multiple",
611
+ - interactive=True,
612
+ - type="directory",
613
+ + files = gr.Files(label="Upload Folders",
614
+ + file_count="multiple", interactive=True, type="directory"
615
+ )
616
+
617
+ - subfolder = gr.Textbox(
618
+ - label="Subfolder in Repository (Optional)",
619
+ - placeholder="e.g., data/uploads",
620
+ - value="",
621
+ - interactive=True,
622
+ - lines=1,
623
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
624
+ + placeholder="e.g., data/uploads", value="", interactive=True
625
+ )
626
+
627
+ - threads = gr.Slider(
628
+ - label="Number of Threads",
629
+ - minimum=1,
630
+ - maximum=20,
631
+ - step=1,
632
+ - value=5,
633
+ - interactive=True,
634
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
635
+ + step=1, value=5, interactive=True
636
+ )
637
+
638
+ - ignore_patterns_selected = gr.CheckboxGroup(
639
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
640
+ - label="Select Patterns to Ignore",
641
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
642
+ - interactive=True,
643
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
644
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
645
+ + interactive=True
646
+ )
647
+
648
+ - upload_button = gr.Button(
649
+ - "Start Upload", variant="primary", interactive=True
650
+ - )
651
+ - cancel_button = gr.Button(
652
+ - "Cancel Upload", variant="secondary", interactive=True
653
+ - )
654
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
655
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
656
+
657
+ with gr.Column(scale=1):
658
+ - gr.Markdown("## Status Section")
659
+ - upload_status = gr.Textbox(
660
+ - label="Upload Status",
661
+ - lines=10,
662
+ - interactive=False,
663
+ - value="Idle",
664
+ + gr.Markdown("## Status Section", elem_id="status-section")
665
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
666
+ + interactive=False, value="Idle"
667
+ )
668
+
669
+ with gr.Tab("Logs"):
670
+ - log_output = gr.Textbox(
671
+ - label="Upload Logs",
672
+ - lines=15,
673
+ - interactive=False,
674
+ - placeholder="Logs will appear here...",
675
+ - value="",
676
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
677
+ + interactive=False, placeholder="Logs will appear here...", value=""
678
+ )
679
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
680
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
681
+
682
+ # Define the upload button click event
683
+ - upload_button.click(
684
+ - fn=upload_files,
685
+ - inputs=[
686
+ - files,
687
+ - repo_id,
688
+ - token,
689
+ - private,
690
+ - threads,
691
+ - subfolder,
692
+ - repo_type,
693
+ - ignore_patterns_selected,
694
+ - ],
695
+ - outputs=upload_status,
696
+ - )
697
+ + def handle_upload(*args):
698
+ + threading.Thread(target=upload_files, args=args).start()
699
+
700
+ - # Define the cancel button click event
701
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
702
+ + upload_button.click(fn=handle_upload, inputs=[
703
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
704
+ + ], outputs=upload_status)
705
+
706
+ - # Define the log refresh button click event
707
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
708
+ +
709
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
710
+
711
+ return app
712
+
713
+ if __name__ == "__main__":
714
+ app = create_interface()
715
+ - app.launch(debug=True, share=True)
716
+ + app.launch(debug=True, share=True, server_port=7860)
717
+ , there was at least one mismatch.
718
+ ---
719
+ Let's address the issues with the previous diff and ensure that the changes are correctly formatted and can be found in the code. We'll focus on the specific section that had issues and correct it.
720
+
721
+ ```diff
722
+ --- app.py
723
+ +++ app.py
724
+ @@ -206,124 +207,134 @@
725
+ # Gradio Interface
726
+ def create_interface():
727
+ with gr.Blocks() as app:
728
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
729
+ - gr.Markdown(
730
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
731
+ - )
732
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
733
+ + gr.Markdown(
734
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
735
+ + elem_id="sub-title"
736
+ + )
737
+
738
+ with gr.Row():
739
+ with gr.Column(scale=1):
740
+ - gr.Markdown("## Upload Section")
741
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
742
+
743
+ - token = gr.Textbox(
744
+ - label="Hugging Face Token",
745
+ - type="password",
746
+ - placeholder="Enter your Hugging Face API token",
747
+ - value=os.getenv("HF_TOKEN", ""),
748
+ - interactive=True,
749
+ - lines=1,
750
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
751
+ + placeholder="Enter your Hugging Face API token",
752
+ + value=os.getenv("HF_TOKEN", ""),
753
+ + interactive=True
754
+ )
755
+
756
+ - repo_type = gr.Dropdown(
757
+ - label="Repository Type",
758
+ - choices=["space", "model", "dataset"],
759
+ - value="space",
760
+ - interactive=True,
761
+ + repo_type = gr.Radio(
762
+ + label="Repository Type", choices=["space", "model", "dataset"],
763
+ + value="space", interactive=True
764
+ )
765
+
766
+ - repo_id = gr.Textbox(
767
+ - label="Repository ID",
768
+ - placeholder="e.g., username/repo-name",
769
+ - value=os.getenv("DEFAULT_REPO", ""),
770
+ - interactive=True,
771
+ - lines=1,
772
+ + repo_id = gr.Textbox(label="Repository ID",
773
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
774
+ + interactive=True
775
+ )
776
+
777
+ - private = gr.Checkbox(
778
+ - label="Make Repository Private",
779
+ - value=False,
780
+ - interactive=True,
781
+ + private = gr.Checkbox(label="Make Repository Private",
782
+ + value=False, interactive=True
783
+ )
784
+
785
+ - files = gr.File(
786
+ - label="Upload Folders",
787
+ - file_count="multiple",
788
+ - interactive=True,
789
+ - type="directory",
790
+ + files = gr.Files(label="Upload Folders",
791
+ + file_count="multiple", interactive=True, type="directory"
792
+ )
793
+
794
+ - subfolder = gr.Textbox(
795
+ - label="Subfolder in Repository (Optional)",
796
+ - placeholder="e.g., data/uploads",
797
+ - value="",
798
+ - interactive=True,
799
+ - lines=1,
800
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
801
+ + placeholder="e.g., data/uploads", value="", interactive=True
802
+ )
803
+
804
+ - threads = gr.Slider(
805
+ - label="Number of Threads",
806
+ - minimum=1,
807
+ - maximum=20,
808
+ - step=1,
809
+ - value=5,
810
+ - interactive=True,
811
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
812
+ + step=1, value=5, interactive=True
813
+ )
814
+
815
+ - ignore_patterns_selected = gr.CheckboxGroup(
816
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
817
+ - label="Select Patterns to Ignore",
818
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
819
+ - interactive=True,
820
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
821
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
822
+ + interactive=True
823
+ )
824
+
825
+ - upload_button = gr.Button(
826
+ - "Start Upload", variant="primary", interactive=True
827
+ - )
828
+ - cancel_button = gr.Button(
829
+ - "Cancel Upload", variant="secondary", interactive=True
830
+ - )
831
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
832
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
833
+
834
+ with gr.Column(scale=1):
835
+ - gr.Markdown("## Status Section")
836
+ - upload_status = gr.Textbox(
837
+ - label="Upload Status",
838
+ - lines=10,
839
+ - interactive=False,
840
+ - value="Idle",
841
+ + gr.Markdown("## Status Section", elem_id="status-section")
842
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
843
+ + interactive=False, value="Idle"
844
+ )
845
+
846
+ with gr.Tab("Logs"):
847
+ - log_output = gr.Textbox(
848
+ - label="Upload Logs",
849
+ - lines=15,
850
+ - interactive=False,
851
+ - placeholder="Logs will appear here...",
852
+ - value="",
853
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
854
+ + interactive=False, placeholder="Logs will appear here...", value=""
855
+ )
856
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
857
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
858
+
859
+ # Define the upload button click event
860
+ - upload_button.click(
861
+ - fn=upload_files,
862
+ - inputs=[
863
+ - files,
864
+ - repo_id,
865
+ - token,
866
+ - private,
867
+ - threads,
868
+ - subfolder,
869
+ - repo_type,
870
+ - ignore_patterns_selected,
871
+ - ],
872
+ - outputs=upload_status,
873
+ - )
874
+ + def handle_upload(*args):
875
+ + threading.Thread(target=upload_files, args=args).start()
876
+
877
+ - # Define the cancel button click event
878
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
879
+ + upload_button.click(fn=handle_upload, inputs=[
880
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
881
+ + ], outputs=upload_status)
882
+
883
+ - # Define the log refresh button click event
884
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
885
+ +
886
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
887
+
888
+ return app
889
+
890
+ if __name__ == "__main__":
891
+ app = create_interface()
892
+ - app.launch(debug=True, share=True)
893
+ + app.launch(debug=True, share=True, server_port=7860)
894
+ ```
895
+
896
+ ### Key Corrections:
897
+ - **Element IDs**: Added `elem_id` attributes to `gr.Markdown` components for better styling and identification.
898
+ - **Component Updates**: Corrected the use of `gr.Files` and `gr.Radio` components.
899
+ - **Threading**: Introduced threading for the upload process to keep the UI responsive.
900
+ - **Launch Parameters**: Added `server_port=7860` to the `app.launch()` method for consistency.
901
+
902
+ This should now be correctly formatted and aligned with the existing code structure.
.gpteng/memory/logs/diff_errors.txt ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ 2024-11-23T16:57:31.917034
3
+ In Hunk:@@ -206,124 +207,134 @@
4
+ # Gradio Interface
5
+ def create_interface():
6
+ with gr.Blocks() as app:
7
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
8
+ - gr.Markdown(
9
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
10
+ - )
11
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
12
+ + gr.Markdown(
13
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
14
+ + elem_id="sub-title"
15
+ + )
16
+
17
+ with gr.Row():
18
+ with gr.Column(scale=1):
19
+ - gr.Markdown("## Upload Section")
20
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
21
+
22
+ - token = gr.Textbox(
23
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
24
+ placeholder="Enter your Hugging Face API token",
25
+ value=os.getenv("HF_TOKEN", ""),
26
+ - interactive=True,
27
+ - lines=1,
28
+ + interactive=True
29
+ )
30
+
31
+ - repo_type = gr.Dropdown(
32
+ - label="Repository Type",
33
+ - choices=["space", "model", "dataset"],
34
+ - value="space",
35
+ - interactive=True,
36
+ + repo_type = gr.Radio(
37
+ + label="Repository Type", choices=["space", "model", "dataset"],
38
+ + value="space", interactive=True
39
+ )
40
+
41
+ - repo_id = gr.Textbox(
42
+ - label="Repository ID",
43
+ - placeholder="e.g., username/repo-name",
44
+ - value=os.getenv("DEFAULT_REPO", ""),
45
+ - interactive=True,
46
+ - lines=1,
47
+ + repo_id = gr.Textbox(label="Repository ID",
48
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
49
+ + interactive=True
50
+ )
51
+
52
+ - private = gr.Checkbox(
53
+ - label="Make Repository Private",
54
+ - value=False,
55
+ - interactive=True,
56
+ + private = gr.Checkbox(label="Make Repository Private",
57
+ + value=False, interactive=True
58
+ )
59
+
60
+ - files = gr.File(
61
+ - label="Upload Folders",
62
+ - file_count="multiple",
63
+ - interactive=True,
64
+ - type="directory",
65
+ + files = gr.Files(label="Upload Folders",
66
+ + file_count="multiple", interactive=True, type="directory"
67
+ )
68
+
69
+ - subfolder = gr.Textbox(
70
+ - label="Subfolder in Repository (Optional)",
71
+ - placeholder="e.g., data/uploads",
72
+ - value="",
73
+ - interactive=True,
74
+ - lines=1,
75
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
76
+ + placeholder="e.g., data/uploads", value="", interactive=True
77
+ )
78
+
79
+ - threads = gr.Slider(
80
+ - label="Number of Threads",
81
+ - minimum=1,
82
+ - maximum=20,
83
+ - step=1,
84
+ - value=5,
85
+ - interactive=True,
86
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
87
+ + step=1, value=5, interactive=True
88
+ )
89
+
90
+ - ignore_patterns_selected = gr.CheckboxGroup(
91
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
92
+ - label="Select Patterns to Ignore",
93
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
94
+ - interactive=True,
95
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
96
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
97
+ + interactive=True
98
+ )
99
+
100
+ - upload_button = gr.Button(
101
+ - "Start Upload", variant="primary", interactive=True
102
+ - )
103
+ - cancel_button = gr.Button(
104
+ - "Cancel Upload", variant="secondary", interactive=True
105
+ - )
106
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
107
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
108
+
109
+ with gr.Column(scale=1):
110
+ - gr.Markdown("## Status Section")
111
+ - upload_status = gr.Textbox(
112
+ - label="Upload Status",
113
+ - lines=10,
114
+ - interactive=False,
115
+ - value="Idle",
116
+ + gr.Markdown("## Status Section", elem_id="status-section")
117
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
118
+ + interactive=False, value="Idle"
119
+ )
120
+
121
+ with gr.Tab("Logs"):
122
+ - log_output = gr.Textbox(
123
+ - label="Upload Logs",
124
+ - lines=15,
125
+ - interactive=False,
126
+ - placeholder="Logs will appear here...",
127
+ - value="",
128
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
129
+ + interactive=False, placeholder="Logs will appear here...", value=""
130
+ )
131
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
132
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
133
+
134
+ # Define the upload button click event
135
+ - upload_button.click(
136
+ - fn=upload_files,
137
+ - inputs=[
138
+ - files,
139
+ - repo_id,
140
+ - token,
141
+ - private,
142
+ - threads,
143
+ - subfolder,
144
+ - repo_type,
145
+ - ignore_patterns_selected,
146
+ - ],
147
+ - outputs=upload_status,
148
+ - )
149
+ + def handle_upload(*args):
150
+ + threading.Thread(target=upload_files, args=args).start()
151
+
152
+ - # Define the cancel button click event
153
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
154
+ + upload_button.click(fn=handle_upload, inputs=[
155
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
156
+ + ], outputs=upload_status)
157
+
158
+ - # Define the log refresh button click event
159
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
160
+ +
161
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
162
+
163
+ return app
164
+
165
+ if __name__ == "__main__":
166
+ app = create_interface()
167
+ - app.launch(debug=True, share=True)
168
+ + app.launch(debug=True, share=True, server_port=7860)
169
+ , there was at least one mismatch.
170
+
171
+ 2024-11-23T16:58:00.412573
172
+
.gpteng/memory/logs/improve.txt ADDED
@@ -0,0 +1,1610 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ 2024-11-23T16:57:31.916770
3
+ ================================ System Message ================================
4
+
5
+ You will get instructions for code to write.
6
+ You will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.
7
+ Think step by step and reason yourself to the correct decisions to make sure we get it right.
8
+ Make changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.
9
+
10
+ You will output the content of each file necessary to achieve the goal, including ALL code.
11
+ Output requested code changes and new code in the unified "git diff" syntax. Example:
12
+
13
+ ```diff
14
+ --- example.txt
15
+ +++ example.txt
16
+ @@ -6,3 +6,4 @@
17
+ line content A
18
+ line content B
19
+ + new line added
20
+ - original line X
21
+ + modified line X with changes
22
+ @@ -26,4 +27,5 @@
23
+ condition check:
24
+ - action for condition A
25
+ + if certain condition is met:
26
+ + alternative action for condition A
27
+ another condition check:
28
+ - action for condition B
29
+ + modified action for condition B
30
+ ```
31
+
32
+ Example of a git diff creating a new file:
33
+
34
+ ```diff
35
+ --- /dev/null
36
+ +++ new_file.txt
37
+ @@ -0,0 +1,3 @@
38
+ +First example line
39
+ +
40
+ +Last example line
41
+ ```
42
+ -A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!
43
+ -Every diff must be fenced with triple backtick ```.
44
+ -The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.
45
+ -LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.
46
+ -EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.
47
+ -AVOID STARTING A HUNK WITH AN EMPTY LINE.
48
+ -ALL DIFFS WILL BE APPLIED SIMULTANEOUSLY, AVOID SEQUENTIAL HUNKS.
49
+
50
+
51
+ As far as compatible with the user request, start with the "entrypoint" file, then go to the ones that are imported by that file, and so on.
52
+ Please note that the code should be fully functional. No placeholders.
53
+
54
+ Follow a language and framework appropriate best practice file naming convention.
55
+ Make sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.
56
+ Ensure to implement all code, if you are unsure, write a plausible implementation.
57
+ Include module dependency or package manager dependency definition file.
58
+ Before you finish, double check that all parts of the architecture is present in the files.
59
+
60
+ When you are done, write finish with "this concludes a fully working implementation".
61
+
62
+ Useful to know:
63
+ Almost always put different classes in different files.
64
+ Always use the programming language the user asks for.
65
+ For Python, you always create an appropriate requirements.txt file.
66
+ For NodeJS, you always create an appropriate package.json file.
67
+ Always add a comment briefly describing the purpose of the function definition.
68
+ Add comments explaining very complex bits of logic.
69
+ Always follow the best practices for the requested languages for folder/file structure and how to package the project.
70
+
71
+
72
+ Python toolbelt preferences:
73
+ - pytest
74
+ - dataclasses
75
+
76
+
77
+ ================================ Human Message =================================
78
+
79
+ ```
80
+ File: app.py
81
+ 1 import os
82
+ 2 import gradio as gr
83
+ 3 from huggingface_hub import HfApi, upload_folder, create_repo, login, list_repo_files
84
+ 4 from rich.console import Console
85
+ 5 from rich.logging import RichHandler
86
+ 6 import logging
87
+ 7 import time
88
+ 8 import shutil
89
+ 9 from pathlib import Path
90
+ 10
91
+ 11 # Default values
92
+ 12 DEFAULT_REPO = os.getenv("DEFAULT_REPO", "luigi12345/megacursos-master-999")
93
+ 13 DEFAULT_LOCAL_PATH = os.getenv(
94
+ 14 "DEFAULT_LOCAL_PATH", "/Users/samihalawa/Documents/Megacursos/MEGACURSOS_S3_MASTER"
95
+ 15 )
96
+ 16 token = os.getenv("HF_TOKEN", "")
97
+ 17
98
+ 18 # Initialize Rich console for logging
99
+ 19 console = Console()
100
+ 20 logging.basicConfig(
101
+ 21 level=logging.INFO,
102
+ 22 format="%(message)s",
103
+ 23 datefmt="[%Y-%m-%d %H:%M:%S]",
104
+ 24 handlers=[RichHandler(console=console, rich_tracebacks=True)],
105
+ 25 )
106
+ 26 logger = logging.getLogger("InfiniteStorageFace")
107
+ 27
108
+ 28 # Initialize Hugging Face API client
109
+ 29 api = HfApi()
110
+ 30
111
+ 31 # Centralized ignore patterns mapping
112
+ 32 IGNORE_PATTERNS_MAP = {
113
+ 33 "Ignore __pycache__": "**/__pycache__/**",
114
+ 34 "Ignore .git": ".git/**",
115
+ 35 "Ignore .venv": "venv/**",
116
+ 36 "Ignore *.pyc": "*.pyc",
117
+ 37 "Ignore *.log": "*.log",
118
+ 38 "Ignore *.tmp": "*.tmp",
119
+ 39 "Ignore *.DS_Store": "*.DS_Store",
120
+ 40 }
121
+ 41
122
+ 42 # Shared logs list
123
+ 43 shared_logs = []
124
+ 44
125
+ 45 # Event to cancel upload
126
+ 46 cancel_event = False
127
+ 47
128
+ 48
129
+ 49 # Function to log messages
130
+ 50 def log(message):
131
+ 51 timestamp = time.strftime("[%Y-%m-%d %H:%M:%S]")
132
+ 52 full_message = f"{timestamp} {message}"
133
+ 53 shared_logs.append(full_message)
134
+ 54 logger.info(message)
135
+ 55 return full_message
136
+ 56
137
+ 57
138
+ 58 # Function to authenticate user with Hugging Face token
139
+ 59 def authenticate(token):
140
+ 60 if not token:
141
+ 61 return False, log("❌ Hugging Face Token is required.")
142
+ 62 try:
143
+ 63 login(token)
144
+ 64 return True, log("βœ… Authenticated successfully!")
145
+ 65 except Exception as e:
146
+ 66 return False, log(f"❌ Authentication failed: {e}")
147
+ 67
148
+ 68
149
+ 69 # Function to create repository if it doesn't exist
150
+ 70 def create_repo_if_not_exists(repo_id, token, repo_type, private):
151
+ 71 try:
152
+ 72 api.list_repo_files(repo_id=repo_id, repo_type=repo_type, token=token)
153
+ 73 return True, log(f"βœ… Repository '{repo_id}' exists. Proceeding with upload...")
154
+ 74 except Exception:
155
+ 75 log(f"❌ Repository '{repo_id}' does not exist. Creating it...")
156
+ 76 try:
157
+ 77 create_repo(
158
+ 78 repo_id=repo_id,
159
+ 79 token=token,
160
+ 80 private=private,
161
+ 81 repo_type=repo_type,
162
+ 82 exist_ok=True,
163
+ 83 space_sdk="static" if repo_type == "space" else None,
164
+ 84 )
165
+ 85 return True, log(f"βœ… Created new repository: '{repo_id}'.")
166
+ 86 except Exception as create_err:
167
+ 87 return False, log(
168
+ 88 f"❌ Failed to create repository '{repo_id}': {create_err}"
169
+ 89 )
170
+ 90
171
+ 91
172
+ 92 # Function to clean up ignored folders
173
+ 93 def cleanup_before_upload(folder_path, ignore_patterns):
174
+ 94 for pattern in ignore_patterns:
175
+ 95 for path in Path(folder_path).rglob(pattern):
176
+ 96 if path.is_dir():
177
+ 97 shutil.rmtree(path)
178
+ 98 log(f"πŸ—‘οΈ Removed ignored folder: {path}")
179
+ 99
180
+ 100
181
+ 101 # Function to upload a folder
182
+ 102 def upload_folder_structure(
183
+ 103 folder_path, repo_id, token, repo_type, target_path, ignore_patterns
184
+ 104 ):
185
+ 105 # Clean up ignored folders
186
+ 106 cleanup_before_upload(folder_path, ignore_patterns)
187
+ 107
188
+ 108 upload_params = {
189
+ 109 "folder_path": folder_path,
190
+ 110 "repo_id": repo_id,
191
+ 111 "repo_type": repo_type,
192
+ 112 "token": token,
193
+ 113 "path_in_repo": target_path,
194
+ 114 "multi_commits": True,
195
+ 115 "multi_commits_verbose": True,
196
+ 116 }
197
+ 117 log(
198
+ 118 f"πŸš€ Uploading folder '{folder_path}' to '{target_path}' in repository '{repo_id}'..."
199
+ 119 )
200
+ 120 try:
201
+ 121 upload_folder(**upload_params)
202
+ 122 log(f"βœ… Upload completed for '{folder_path}'!")
203
+ 123 except Exception as upload_err:
204
+ 124 log(f"❌ Upload failed for '{folder_path}': {upload_err}")
205
+ 125
206
+ 126
207
+ 127 # Function to handle uploads, allowing direct folder uploads
208
+ 128 def upload_files(
209
+ 129 files,
210
+ 130 repo_id,
211
+ 131 token,
212
+ 132 private,
213
+ 133 threads,
214
+ 134 subfolder,
215
+ 135 repo_type,
216
+ 136 ignore_patterns_selected,
217
+ 137 ):
218
+ 138 global cancel_event
219
+ 139 cancel_event = False
220
+ 140
221
+ 141 logs = []
222
+ 142
223
+ 143 # Authenticate
224
+ 144 auth_success, auth_message = authenticate(token)
225
+ 145 logs.append(auth_message)
226
+ 146 if not auth_success:
227
+ 147 return "\n".join(logs)
228
+ 148
229
+ 149 # Create repo if not exists
230
+ 150 repo_success, repo_message = create_repo_if_not_exists(
231
+ 151 repo_id, token, repo_type, private
232
+ 152 )
233
+ 153 logs.append(repo_message)
234
+ 154 if not repo_success:
235
+ 155 return "\n".join(logs)
236
+ 156
237
+ 157 # Prepare target path
238
+ 158 target_path = subfolder.replace("\\", "/") if subfolder else ""
239
+ 159
240
+ 160 # Map selected ignore patterns to actual patterns
241
+ 161 ignore_patterns = [
242
+ 162 IGNORE_PATTERNS_MAP[pattern] for pattern in ignore_patterns_selected
243
+ 163 ]
244
+ 164
245
+ 165 # Upload folders directly if provided
246
+ 166 if files:
247
+ 167 for file in files:
248
+ 168 if cancel_event:
249
+ 169 logs.append(log("❌ Upload has been cancelled."))
250
+ 170 return "\n".join(logs)
251
+ 171 file_path = file.name
252
+ 172 if os.path.isdir(file_path): # Check if the file is a directory
253
+ 173 upload_folder_structure(
254
+ 174 file_path, repo_id, token, repo_type, target_path, ignore_patterns
255
+ 175 )
256
+ 176 logs.append(log(f"βœ… Uploaded folder '{file_path}'."))
257
+ 177 else:
258
+ 178 logs.append(
259
+ 179 log(
260
+ 180 f"❌ '{file_path}' is not a folder. Only folders can be uploaded."
261
+ 181 )
262
+ 182 )
263
+ 183 else:
264
+ 184 logs.append(log("❌ No files provided for upload."))
265
+ 185
266
+ 186 if cancel_event:
267
+ 187 logs.append(log("❌ Upload has been cancelled."))
268
+ 188 return "\n".join(logs)
269
+ 189
270
+ 190 logs.append(log("πŸš€ Upload completed. Check the logs for details."))
271
+ 191 return "\n".join(logs)
272
+ 192
273
+ 193
274
+ 194 # Function to cancel upload
275
+ 195 def cancel_upload():
276
+ 196 global cancel_event
277
+ 197 cancel_event = True
278
+ 198 return log("Upload has been cancelled.")
279
+ 199
280
+ 200
281
+ 201 # Function to refresh logs
282
+ 202 def refresh_logs():
283
+ 203 return "\n".join(shared_logs)
284
+ 204
285
+ 205
286
+ 206 # Gradio Interface
287
+ 207 def create_interface():
288
+ 208 with gr.Blocks() as app:
289
+ 209 gr.Markdown("# πŸš€ InfiniteStorageFace")
290
+ 210 gr.Markdown(
291
+ 211 "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
292
+ 212 )
293
+ 213
294
+ 214 with gr.Row():
295
+ 215 with gr.Column(scale=1):
296
+ 216 gr.Markdown("## Upload Section")
297
+ 217
298
+ 218 token = gr.Textbox(
299
+ 219 label="Hugging Face Token",
300
+ 220 type="password",
301
+ 221 placeholder="Enter your Hugging Face API token",
302
+ 222 value=os.getenv("HF_TOKEN", ""),
303
+ 223 interactive=True,
304
+ 224 lines=1,
305
+ 225 )
306
+ 226
307
+ 227 repo_type = gr.Dropdown(
308
+ 228 label="Repository Type",
309
+ 229 choices=["space", "model", "dataset"],
310
+ 230 value="space",
311
+ 231 interactive=True,
312
+ 232 )
313
+ 233
314
+ 234 repo_id = gr.Textbox(
315
+ 235 label="Repository ID",
316
+ 236 placeholder="e.g., username/repo-name",
317
+ 237 value=os.getenv("DEFAULT_REPO", ""),
318
+ 238 interactive=True,
319
+ 239 lines=1,
320
+ 240 )
321
+ 241
322
+ 242 private = gr.Checkbox(
323
+ 243 label="Make Repository Private",
324
+ 244 value=False,
325
+ 245 interactive=True,
326
+ 246 )
327
+ 247
328
+ 248 files = gr.File(
329
+ 249 label="Upload Folders",
330
+ 250 file_count="multiple",
331
+ 251 interactive=True,
332
+ 252 type="directory",
333
+ 253 )
334
+ 254
335
+ 255 subfolder = gr.Textbox(
336
+ 256 label="Subfolder in Repository (Optional)",
337
+ 257 placeholder="e.g., data/uploads",
338
+ 258 value="",
339
+ 259 interactive=True,
340
+ 260 lines=1,
341
+ 261 )
342
+ 262
343
+ 263 threads = gr.Slider(
344
+ 264 label="Number of Threads",
345
+ 265 minimum=1,
346
+ 266 maximum=20,
347
+ 267 step=1,
348
+ 268 value=5,
349
+ 269 interactive=True,
350
+ 270 )
351
+ 271
352
+ 272 ignore_patterns_selected = gr.CheckboxGroup(
353
+ 273 choices=list(IGNORE_PATTERNS_MAP.keys()),
354
+ 274 label="Select Patterns to Ignore",
355
+ 275 value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
356
+ 276 interactive=True,
357
+ 277 )
358
+ 278
359
+ 279 upload_button = gr.Button(
360
+ 280 "Start Upload", variant="primary", interactive=True
361
+ 281 )
362
+ 282 cancel_button = gr.Button(
363
+ 283 "Cancel Upload", variant="secondary", interactive=True
364
+ 284 )
365
+ 285
366
+ 286 with gr.Column(scale=1):
367
+ 287 gr.Markdown("## Status Section")
368
+ 288 upload_status = gr.Textbox(
369
+ 289 label="Upload Status",
370
+ 290 lines=10,
371
+ 291 interactive=False,
372
+ 292 value="Idle",
373
+ 293 )
374
+ 294
375
+ 295 with gr.Tab("Logs"):
376
+ 296 log_output = gr.Textbox(
377
+ 297 label="Upload Logs",
378
+ 298 lines=15,
379
+ 299 interactive=False,
380
+ 300 placeholder="Logs will appear here...",
381
+ 301 value="",
382
+ 302 )
383
+ 303 log_refresh = gr.Button("Refresh Logs", interactive=True)
384
+ 304
385
+ 305 # Define the upload button click event
386
+ 306 upload_button.click(
387
+ 307 fn=upload_files,
388
+ 308 inputs=[
389
+ 309 files,
390
+ 310 repo_id,
391
+ 311 token,
392
+ 312 private,
393
+ 313 threads,
394
+ 314 subfolder,
395
+ 315 repo_type,
396
+ 316 ignore_patterns_selected,
397
+ 317 ],
398
+ 318 outputs=upload_status,
399
+ 319 )
400
+ 320
401
+ 321 # Define the cancel button click event
402
+ 322 cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
403
+ 323
404
+ 324 # Define the log refresh button click event
405
+ 325 log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
406
+ 326
407
+ 327 return app
408
+ 328
409
+ 329
410
+ 330 if __name__ == "__main__":
411
+ 331 app = create_interface()
412
+ 332 app.launch(debug=True, share=True)
413
+ 333
414
+
415
+ ```
416
+
417
+ Request: enhance its experience and make it much more efificnet using th ebest Gradio 5 componnets available a
418
+
419
+ ================================== Ai Message ==================================
420
+
421
+ To enhance the user experience and efficiency of the application using the best Gradio 5 components, we will make several improvements. These include using more interactive and user-friendly components, optimizing the layout, and ensuring that the application is responsive and provides real-time feedback. We will also ensure that the code is clean and follows best practices.
422
+
423
+ Here's a step-by-step breakdown of the changes:
424
+
425
+ 1. **Use Gradio 5 Components**: We'll replace some of the existing components with newer Gradio 5 components that offer better interactivity and user experience.
426
+
427
+ 2. **Optimize Layout**: We'll organize the layout to make it more intuitive and visually appealing.
428
+
429
+ 3. **Improve Feedback Mechanism**: We'll enhance the feedback mechanism to provide real-time updates and clearer status messages.
430
+
431
+ 4. **Code Refactoring**: We'll refactor the code to improve readability and maintainability.
432
+
433
+ Let's implement these changes:
434
+
435
+ ```diff
436
+ --- app.py
437
+ +++ app.py
438
+ @@ -1,11 +1,12 @@
439
+ import os
440
+ import gradio as gr
441
+ from huggingface_hub import HfApi, upload_folder, create_repo, login, list_repo_files
442
+ from rich.console import Console
443
+ from rich.logging import RichHandler
444
+ import logging
445
+ import time
446
+ import shutil
447
+ +import threading
448
+ from pathlib import Path
449
+
450
+ # Default values
451
+ @@ -206,124 +207,134 @@
452
+ # Gradio Interface
453
+ def create_interface():
454
+ with gr.Blocks() as app:
455
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
456
+ - gr.Markdown(
457
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
458
+ - )
459
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
460
+ + gr.Markdown(
461
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
462
+ + elem_id="sub-title"
463
+ + )
464
+
465
+ with gr.Row():
466
+ with gr.Column(scale=1):
467
+ - gr.Markdown("## Upload Section")
468
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
469
+
470
+ - token = gr.Textbox(
471
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
472
+ placeholder="Enter your Hugging Face API token",
473
+ value=os.getenv("HF_TOKEN", ""),
474
+ - interactive=True,
475
+ - lines=1,
476
+ + interactive=True
477
+ )
478
+
479
+ - repo_type = gr.Dropdown(
480
+ - label="Repository Type",
481
+ - choices=["space", "model", "dataset"],
482
+ - value="space",
483
+ - interactive=True,
484
+ + repo_type = gr.Radio(
485
+ + label="Repository Type", choices=["space", "model", "dataset"],
486
+ + value="space", interactive=True
487
+ )
488
+
489
+ - repo_id = gr.Textbox(
490
+ - label="Repository ID",
491
+ - placeholder="e.g., username/repo-name",
492
+ - value=os.getenv("DEFAULT_REPO", ""),
493
+ - interactive=True,
494
+ - lines=1,
495
+ + repo_id = gr.Textbox(label="Repository ID",
496
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
497
+ + interactive=True
498
+ )
499
+
500
+ - private = gr.Checkbox(
501
+ - label="Make Repository Private",
502
+ - value=False,
503
+ - interactive=True,
504
+ + private = gr.Checkbox(label="Make Repository Private",
505
+ + value=False, interactive=True
506
+ )
507
+
508
+ - files = gr.File(
509
+ - label="Upload Folders",
510
+ - file_count="multiple",
511
+ - interactive=True,
512
+ - type="directory",
513
+ + files = gr.Files(label="Upload Folders",
514
+ + file_count="multiple", interactive=True, type="directory"
515
+ )
516
+
517
+ - subfolder = gr.Textbox(
518
+ - label="Subfolder in Repository (Optional)",
519
+ - placeholder="e.g., data/uploads",
520
+ - value="",
521
+ - interactive=True,
522
+ - lines=1,
523
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
524
+ + placeholder="e.g., data/uploads", value="", interactive=True
525
+ )
526
+
527
+ - threads = gr.Slider(
528
+ - label="Number of Threads",
529
+ - minimum=1,
530
+ - maximum=20,
531
+ - step=1,
532
+ - value=5,
533
+ - interactive=True,
534
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
535
+ + step=1, value=5, interactive=True
536
+ )
537
+
538
+ - ignore_patterns_selected = gr.CheckboxGroup(
539
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
540
+ - label="Select Patterns to Ignore",
541
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
542
+ - interactive=True,
543
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
544
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
545
+ + interactive=True
546
+ )
547
+
548
+ - upload_button = gr.Button(
549
+ - "Start Upload", variant="primary", interactive=True
550
+ - )
551
+ - cancel_button = gr.Button(
552
+ - "Cancel Upload", variant="secondary", interactive=True
553
+ - )
554
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
555
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
556
+
557
+ with gr.Column(scale=1):
558
+ - gr.Markdown("## Status Section")
559
+ - upload_status = gr.Textbox(
560
+ - label="Upload Status",
561
+ - lines=10,
562
+ - interactive=False,
563
+ - value="Idle",
564
+ + gr.Markdown("## Status Section", elem_id="status-section")
565
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
566
+ + interactive=False, value="Idle"
567
+ )
568
+
569
+ with gr.Tab("Logs"):
570
+ - log_output = gr.Textbox(
571
+ - label="Upload Logs",
572
+ - lines=15,
573
+ - interactive=False,
574
+ - placeholder="Logs will appear here...",
575
+ - value="",
576
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
577
+ + interactive=False, placeholder="Logs will appear here...", value=""
578
+ )
579
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
580
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
581
+
582
+ # Define the upload button click event
583
+ - upload_button.click(
584
+ - fn=upload_files,
585
+ - inputs=[
586
+ - files,
587
+ - repo_id,
588
+ - token,
589
+ - private,
590
+ - threads,
591
+ - subfolder,
592
+ - repo_type,
593
+ - ignore_patterns_selected,
594
+ - ],
595
+ - outputs=upload_status,
596
+ - )
597
+ + def handle_upload(*args):
598
+ + threading.Thread(target=upload_files, args=args).start()
599
+
600
+ - # Define the cancel button click event
601
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
602
+ + upload_button.click(fn=handle_upload, inputs=[
603
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
604
+ + ], outputs=upload_status)
605
+
606
+ - # Define the log refresh button click event
607
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
608
+ +
609
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
610
+
611
+ return app
612
+
613
+ if __name__ == "__main__":
614
+ app = create_interface()
615
+ - app.launch(debug=True, share=True)
616
+ + app.launch(debug=True, share=True, server_port=7860)
617
+ ```
618
+
619
+ ### Key Changes:
620
+ - **Gradio 5 Components**: Updated components to use `gr.Files` for multiple file selection and `gr.Radio` for repository type selection.
621
+ - **Layout Optimization**: Improved the layout with better sectioning and labeling.
622
+ - **Real-time Feedback**: Introduced threading to handle uploads asynchronously, allowing the UI to remain responsive.
623
+ - **Code Refactoring**: Cleaned up the code for better readability and maintainability.
624
+
625
+ This concludes a fully working implementation.
626
+
627
+ 2024-11-23T16:58:00.412265
628
+ ================================ System Message ================================
629
+
630
+ You will get instructions for code to write.
631
+ You will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.
632
+ Think step by step and reason yourself to the correct decisions to make sure we get it right.
633
+ Make changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.
634
+
635
+ You will output the content of each file necessary to achieve the goal, including ALL code.
636
+ Output requested code changes and new code in the unified "git diff" syntax. Example:
637
+
638
+ ```diff
639
+ --- example.txt
640
+ +++ example.txt
641
+ @@ -6,3 +6,4 @@
642
+ line content A
643
+ line content B
644
+ + new line added
645
+ - original line X
646
+ + modified line X with changes
647
+ @@ -26,4 +27,5 @@
648
+ condition check:
649
+ - action for condition A
650
+ + if certain condition is met:
651
+ + alternative action for condition A
652
+ another condition check:
653
+ - action for condition B
654
+ + modified action for condition B
655
+ ```
656
+
657
+ Example of a git diff creating a new file:
658
+
659
+ ```diff
660
+ --- /dev/null
661
+ +++ new_file.txt
662
+ @@ -0,0 +1,3 @@
663
+ +First example line
664
+ +
665
+ +Last example line
666
+ ```
667
+ -A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!
668
+ -Every diff must be fenced with triple backtick ```.
669
+ -The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.
670
+ -LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.
671
+ -EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.
672
+ -AVOID STARTING A HUNK WITH AN EMPTY LINE.
673
+ -ALL DIFFS WILL BE APPLIED SIMULTANEOUSLY, AVOID SEQUENTIAL HUNKS.
674
+
675
+
676
+ As far as compatible with the user request, start with the "entrypoint" file, then go to the ones that are imported by that file, and so on.
677
+ Please note that the code should be fully functional. No placeholders.
678
+
679
+ Follow a language and framework appropriate best practice file naming convention.
680
+ Make sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.
681
+ Ensure to implement all code, if you are unsure, write a plausible implementation.
682
+ Include module dependency or package manager dependency definition file.
683
+ Before you finish, double check that all parts of the architecture is present in the files.
684
+
685
+ When you are done, write finish with "this concludes a fully working implementation".
686
+
687
+ Useful to know:
688
+ Almost always put different classes in different files.
689
+ Always use the programming language the user asks for.
690
+ For Python, you always create an appropriate requirements.txt file.
691
+ For NodeJS, you always create an appropriate package.json file.
692
+ Always add a comment briefly describing the purpose of the function definition.
693
+ Add comments explaining very complex bits of logic.
694
+ Always follow the best practices for the requested languages for folder/file structure and how to package the project.
695
+
696
+
697
+ Python toolbelt preferences:
698
+ - pytest
699
+ - dataclasses
700
+
701
+
702
+ ================================ Human Message =================================
703
+
704
+ ```
705
+ File: app.py
706
+ 1 import os
707
+ 2 import gradio as gr
708
+ 3 from huggingface_hub import HfApi, upload_folder, create_repo, login, list_repo_files
709
+ 4 from rich.console import Console
710
+ 5 from rich.logging import RichHandler
711
+ 6 import logging
712
+ 7 import time
713
+ 8 import shutil
714
+ 9 from pathlib import Path
715
+ 10
716
+ 11 # Default values
717
+ 12 DEFAULT_REPO = os.getenv("DEFAULT_REPO", "luigi12345/megacursos-master-999")
718
+ 13 DEFAULT_LOCAL_PATH = os.getenv(
719
+ 14 "DEFAULT_LOCAL_PATH", "/Users/samihalawa/Documents/Megacursos/MEGACURSOS_S3_MASTER"
720
+ 15 )
721
+ 16 token = os.getenv("HF_TOKEN", "")
722
+ 17
723
+ 18 # Initialize Rich console for logging
724
+ 19 console = Console()
725
+ 20 logging.basicConfig(
726
+ 21 level=logging.INFO,
727
+ 22 format="%(message)s",
728
+ 23 datefmt="[%Y-%m-%d %H:%M:%S]",
729
+ 24 handlers=[RichHandler(console=console, rich_tracebacks=True)],
730
+ 25 )
731
+ 26 logger = logging.getLogger("InfiniteStorageFace")
732
+ 27
733
+ 28 # Initialize Hugging Face API client
734
+ 29 api = HfApi()
735
+ 30
736
+ 31 # Centralized ignore patterns mapping
737
+ 32 IGNORE_PATTERNS_MAP = {
738
+ 33 "Ignore __pycache__": "**/__pycache__/**",
739
+ 34 "Ignore .git": ".git/**",
740
+ 35 "Ignore .venv": "venv/**",
741
+ 36 "Ignore *.pyc": "*.pyc",
742
+ 37 "Ignore *.log": "*.log",
743
+ 38 "Ignore *.tmp": "*.tmp",
744
+ 39 "Ignore *.DS_Store": "*.DS_Store",
745
+ 40 }
746
+ 41
747
+ 42 # Shared logs list
748
+ 43 shared_logs = []
749
+ 44
750
+ 45 # Event to cancel upload
751
+ 46 cancel_event = False
752
+ 47
753
+ 48
754
+ 49 # Function to log messages
755
+ 50 def log(message):
756
+ 51 timestamp = time.strftime("[%Y-%m-%d %H:%M:%S]")
757
+ 52 full_message = f"{timestamp} {message}"
758
+ 53 shared_logs.append(full_message)
759
+ 54 logger.info(message)
760
+ 55 return full_message
761
+ 56
762
+ 57
763
+ 58 # Function to authenticate user with Hugging Face token
764
+ 59 def authenticate(token):
765
+ 60 if not token:
766
+ 61 return False, log("❌ Hugging Face Token is required.")
767
+ 62 try:
768
+ 63 login(token)
769
+ 64 return True, log("βœ… Authenticated successfully!")
770
+ 65 except Exception as e:
771
+ 66 return False, log(f"❌ Authentication failed: {e}")
772
+ 67
773
+ 68
774
+ 69 # Function to create repository if it doesn't exist
775
+ 70 def create_repo_if_not_exists(repo_id, token, repo_type, private):
776
+ 71 try:
777
+ 72 api.list_repo_files(repo_id=repo_id, repo_type=repo_type, token=token)
778
+ 73 return True, log(f"βœ… Repository '{repo_id}' exists. Proceeding with upload...")
779
+ 74 except Exception:
780
+ 75 log(f"❌ Repository '{repo_id}' does not exist. Creating it...")
781
+ 76 try:
782
+ 77 create_repo(
783
+ 78 repo_id=repo_id,
784
+ 79 token=token,
785
+ 80 private=private,
786
+ 81 repo_type=repo_type,
787
+ 82 exist_ok=True,
788
+ 83 space_sdk="static" if repo_type == "space" else None,
789
+ 84 )
790
+ 85 return True, log(f"βœ… Created new repository: '{repo_id}'.")
791
+ 86 except Exception as create_err:
792
+ 87 return False, log(
793
+ 88 f"❌ Failed to create repository '{repo_id}': {create_err}"
794
+ 89 )
795
+ 90
796
+ 91
797
+ 92 # Function to clean up ignored folders
798
+ 93 def cleanup_before_upload(folder_path, ignore_patterns):
799
+ 94 for pattern in ignore_patterns:
800
+ 95 for path in Path(folder_path).rglob(pattern):
801
+ 96 if path.is_dir():
802
+ 97 shutil.rmtree(path)
803
+ 98 log(f"πŸ—‘οΈ Removed ignored folder: {path}")
804
+ 99
805
+ 100
806
+ 101 # Function to upload a folder
807
+ 102 def upload_folder_structure(
808
+ 103 folder_path, repo_id, token, repo_type, target_path, ignore_patterns
809
+ 104 ):
810
+ 105 # Clean up ignored folders
811
+ 106 cleanup_before_upload(folder_path, ignore_patterns)
812
+ 107
813
+ 108 upload_params = {
814
+ 109 "folder_path": folder_path,
815
+ 110 "repo_id": repo_id,
816
+ 111 "repo_type": repo_type,
817
+ 112 "token": token,
818
+ 113 "path_in_repo": target_path,
819
+ 114 "multi_commits": True,
820
+ 115 "multi_commits_verbose": True,
821
+ 116 }
822
+ 117 log(
823
+ 118 f"πŸš€ Uploading folder '{folder_path}' to '{target_path}' in repository '{repo_id}'..."
824
+ 119 )
825
+ 120 try:
826
+ 121 upload_folder(**upload_params)
827
+ 122 log(f"βœ… Upload completed for '{folder_path}'!")
828
+ 123 except Exception as upload_err:
829
+ 124 log(f"❌ Upload failed for '{folder_path}': {upload_err}")
830
+ 125
831
+ 126
832
+ 127 # Function to handle uploads, allowing direct folder uploads
833
+ 128 def upload_files(
834
+ 129 files,
835
+ 130 repo_id,
836
+ 131 token,
837
+ 132 private,
838
+ 133 threads,
839
+ 134 subfolder,
840
+ 135 repo_type,
841
+ 136 ignore_patterns_selected,
842
+ 137 ):
843
+ 138 global cancel_event
844
+ 139 cancel_event = False
845
+ 140
846
+ 141 logs = []
847
+ 142
848
+ 143 # Authenticate
849
+ 144 auth_success, auth_message = authenticate(token)
850
+ 145 logs.append(auth_message)
851
+ 146 if not auth_success:
852
+ 147 return "\n".join(logs)
853
+ 148
854
+ 149 # Create repo if not exists
855
+ 150 repo_success, repo_message = create_repo_if_not_exists(
856
+ 151 repo_id, token, repo_type, private
857
+ 152 )
858
+ 153 logs.append(repo_message)
859
+ 154 if not repo_success:
860
+ 155 return "\n".join(logs)
861
+ 156
862
+ 157 # Prepare target path
863
+ 158 target_path = subfolder.replace("\\", "/") if subfolder else ""
864
+ 159
865
+ 160 # Map selected ignore patterns to actual patterns
866
+ 161 ignore_patterns = [
867
+ 162 IGNORE_PATTERNS_MAP[pattern] for pattern in ignore_patterns_selected
868
+ 163 ]
869
+ 164
870
+ 165 # Upload folders directly if provided
871
+ 166 if files:
872
+ 167 for file in files:
873
+ 168 if cancel_event:
874
+ 169 logs.append(log("❌ Upload has been cancelled."))
875
+ 170 return "\n".join(logs)
876
+ 171 file_path = file.name
877
+ 172 if os.path.isdir(file_path): # Check if the file is a directory
878
+ 173 upload_folder_structure(
879
+ 174 file_path, repo_id, token, repo_type, target_path, ignore_patterns
880
+ 175 )
881
+ 176 logs.append(log(f"βœ… Uploaded folder '{file_path}'."))
882
+ 177 else:
883
+ 178 logs.append(
884
+ 179 log(
885
+ 180 f"❌ '{file_path}' is not a folder. Only folders can be uploaded."
886
+ 181 )
887
+ 182 )
888
+ 183 else:
889
+ 184 logs.append(log("❌ No files provided for upload."))
890
+ 185
891
+ 186 if cancel_event:
892
+ 187 logs.append(log("❌ Upload has been cancelled."))
893
+ 188 return "\n".join(logs)
894
+ 189
895
+ 190 logs.append(log("πŸš€ Upload completed. Check the logs for details."))
896
+ 191 return "\n".join(logs)
897
+ 192
898
+ 193
899
+ 194 # Function to cancel upload
900
+ 195 def cancel_upload():
901
+ 196 global cancel_event
902
+ 197 cancel_event = True
903
+ 198 return log("Upload has been cancelled.")
904
+ 199
905
+ 200
906
+ 201 # Function to refresh logs
907
+ 202 def refresh_logs():
908
+ 203 return "\n".join(shared_logs)
909
+ 204
910
+ 205
911
+ 206 # Gradio Interface
912
+ 207 def create_interface():
913
+ 208 with gr.Blocks() as app:
914
+ 209 gr.Markdown("# πŸš€ InfiniteStorageFace")
915
+ 210 gr.Markdown(
916
+ 211 "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
917
+ 212 )
918
+ 213
919
+ 214 with gr.Row():
920
+ 215 with gr.Column(scale=1):
921
+ 216 gr.Markdown("## Upload Section")
922
+ 217
923
+ 218 token = gr.Textbox(
924
+ 219 label="Hugging Face Token",
925
+ 220 type="password",
926
+ 221 placeholder="Enter your Hugging Face API token",
927
+ 222 value=os.getenv("HF_TOKEN", ""),
928
+ 223 interactive=True,
929
+ 224 lines=1,
930
+ 225 )
931
+ 226
932
+ 227 repo_type = gr.Dropdown(
933
+ 228 label="Repository Type",
934
+ 229 choices=["space", "model", "dataset"],
935
+ 230 value="space",
936
+ 231 interactive=True,
937
+ 232 )
938
+ 233
939
+ 234 repo_id = gr.Textbox(
940
+ 235 label="Repository ID",
941
+ 236 placeholder="e.g., username/repo-name",
942
+ 237 value=os.getenv("DEFAULT_REPO", ""),
943
+ 238 interactive=True,
944
+ 239 lines=1,
945
+ 240 )
946
+ 241
947
+ 242 private = gr.Checkbox(
948
+ 243 label="Make Repository Private",
949
+ 244 value=False,
950
+ 245 interactive=True,
951
+ 246 )
952
+ 247
953
+ 248 files = gr.File(
954
+ 249 label="Upload Folders",
955
+ 250 file_count="multiple",
956
+ 251 interactive=True,
957
+ 252 type="directory",
958
+ 253 )
959
+ 254
960
+ 255 subfolder = gr.Textbox(
961
+ 256 label="Subfolder in Repository (Optional)",
962
+ 257 placeholder="e.g., data/uploads",
963
+ 258 value="",
964
+ 259 interactive=True,
965
+ 260 lines=1,
966
+ 261 )
967
+ 262
968
+ 263 threads = gr.Slider(
969
+ 264 label="Number of Threads",
970
+ 265 minimum=1,
971
+ 266 maximum=20,
972
+ 267 step=1,
973
+ 268 value=5,
974
+ 269 interactive=True,
975
+ 270 )
976
+ 271
977
+ 272 ignore_patterns_selected = gr.CheckboxGroup(
978
+ 273 choices=list(IGNORE_PATTERNS_MAP.keys()),
979
+ 274 label="Select Patterns to Ignore",
980
+ 275 value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
981
+ 276 interactive=True,
982
+ 277 )
983
+ 278
984
+ 279 upload_button = gr.Button(
985
+ 280 "Start Upload", variant="primary", interactive=True
986
+ 281 )
987
+ 282 cancel_button = gr.Button(
988
+ 283 "Cancel Upload", variant="secondary", interactive=True
989
+ 284 )
990
+ 285
991
+ 286 with gr.Column(scale=1):
992
+ 287 gr.Markdown("## Status Section")
993
+ 288 upload_status = gr.Textbox(
994
+ 289 label="Upload Status",
995
+ 290 lines=10,
996
+ 291 interactive=False,
997
+ 292 value="Idle",
998
+ 293 )
999
+ 294
1000
+ 295 with gr.Tab("Logs"):
1001
+ 296 log_output = gr.Textbox(
1002
+ 297 label="Upload Logs",
1003
+ 298 lines=15,
1004
+ 299 interactive=False,
1005
+ 300 placeholder="Logs will appear here...",
1006
+ 301 value="",
1007
+ 302 )
1008
+ 303 log_refresh = gr.Button("Refresh Logs", interactive=True)
1009
+ 304
1010
+ 305 # Define the upload button click event
1011
+ 306 upload_button.click(
1012
+ 307 fn=upload_files,
1013
+ 308 inputs=[
1014
+ 309 files,
1015
+ 310 repo_id,
1016
+ 311 token,
1017
+ 312 private,
1018
+ 313 threads,
1019
+ 314 subfolder,
1020
+ 315 repo_type,
1021
+ 316 ignore_patterns_selected,
1022
+ 317 ],
1023
+ 318 outputs=upload_status,
1024
+ 319 )
1025
+ 320
1026
+ 321 # Define the cancel button click event
1027
+ 322 cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1028
+ 323
1029
+ 324 # Define the log refresh button click event
1030
+ 325 log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
1031
+ 326
1032
+ 327 return app
1033
+ 328
1034
+ 329
1035
+ 330 if __name__ == "__main__":
1036
+ 331 app = create_interface()
1037
+ 332 app.launch(debug=True, share=True)
1038
+ 333
1039
+
1040
+ ```
1041
+
1042
+ Request: enhance its experience and make it much more efificnet using th ebest Gradio 5 componnets available a
1043
+
1044
+ ================================== Ai Message ==================================
1045
+
1046
+ To enhance the user experience and efficiency of the application using the best Gradio 5 components, we will make several improvements. These include using more interactive and user-friendly components, optimizing the layout, and ensuring that the application is responsive and provides real-time feedback. We will also ensure that the code is clean and follows best practices.
1047
+
1048
+ Here's a step-by-step breakdown of the changes:
1049
+
1050
+ 1. **Use Gradio 5 Components**: We'll replace some of the existing components with newer Gradio 5 components that offer better interactivity and user experience.
1051
+
1052
+ 2. **Optimize Layout**: We'll organize the layout to make it more intuitive and visually appealing.
1053
+
1054
+ 3. **Improve Feedback Mechanism**: We'll enhance the feedback mechanism to provide real-time updates and clearer status messages.
1055
+
1056
+ 4. **Code Refactoring**: We'll refactor the code to improve readability and maintainability.
1057
+
1058
+ Let's implement these changes:
1059
+
1060
+ ```diff
1061
+ --- app.py
1062
+ +++ app.py
1063
+ @@ -1,11 +1,12 @@
1064
+ import os
1065
+ import gradio as gr
1066
+ from huggingface_hub import HfApi, upload_folder, create_repo, login, list_repo_files
1067
+ from rich.console import Console
1068
+ from rich.logging import RichHandler
1069
+ import logging
1070
+ import time
1071
+ import shutil
1072
+ +import threading
1073
+ from pathlib import Path
1074
+
1075
+ # Default values
1076
+ @@ -206,124 +207,134 @@
1077
+ # Gradio Interface
1078
+ def create_interface():
1079
+ with gr.Blocks() as app:
1080
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
1081
+ - gr.Markdown(
1082
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
1083
+ - )
1084
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
1085
+ + gr.Markdown(
1086
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
1087
+ + elem_id="sub-title"
1088
+ + )
1089
+
1090
+ with gr.Row():
1091
+ with gr.Column(scale=1):
1092
+ - gr.Markdown("## Upload Section")
1093
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
1094
+
1095
+ - token = gr.Textbox(
1096
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
1097
+ placeholder="Enter your Hugging Face API token",
1098
+ value=os.getenv("HF_TOKEN", ""),
1099
+ - interactive=True,
1100
+ - lines=1,
1101
+ + interactive=True
1102
+ )
1103
+
1104
+ - repo_type = gr.Dropdown(
1105
+ - label="Repository Type",
1106
+ - choices=["space", "model", "dataset"],
1107
+ - value="space",
1108
+ - interactive=True,
1109
+ + repo_type = gr.Radio(
1110
+ + label="Repository Type", choices=["space", "model", "dataset"],
1111
+ + value="space", interactive=True
1112
+ )
1113
+
1114
+ - repo_id = gr.Textbox(
1115
+ - label="Repository ID",
1116
+ - placeholder="e.g., username/repo-name",
1117
+ - value=os.getenv("DEFAULT_REPO", ""),
1118
+ - interactive=True,
1119
+ - lines=1,
1120
+ + repo_id = gr.Textbox(label="Repository ID",
1121
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
1122
+ + interactive=True
1123
+ )
1124
+
1125
+ - private = gr.Checkbox(
1126
+ - label="Make Repository Private",
1127
+ - value=False,
1128
+ - interactive=True,
1129
+ + private = gr.Checkbox(label="Make Repository Private",
1130
+ + value=False, interactive=True
1131
+ )
1132
+
1133
+ - files = gr.File(
1134
+ - label="Upload Folders",
1135
+ - file_count="multiple",
1136
+ - interactive=True,
1137
+ - type="directory",
1138
+ + files = gr.Files(label="Upload Folders",
1139
+ + file_count="multiple", interactive=True, type="directory"
1140
+ )
1141
+
1142
+ - subfolder = gr.Textbox(
1143
+ - label="Subfolder in Repository (Optional)",
1144
+ - placeholder="e.g., data/uploads",
1145
+ - value="",
1146
+ - interactive=True,
1147
+ - lines=1,
1148
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
1149
+ + placeholder="e.g., data/uploads", value="", interactive=True
1150
+ )
1151
+
1152
+ - threads = gr.Slider(
1153
+ - label="Number of Threads",
1154
+ - minimum=1,
1155
+ - maximum=20,
1156
+ - step=1,
1157
+ - value=5,
1158
+ - interactive=True,
1159
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
1160
+ + step=1, value=5, interactive=True
1161
+ )
1162
+
1163
+ - ignore_patterns_selected = gr.CheckboxGroup(
1164
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
1165
+ - label="Select Patterns to Ignore",
1166
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
1167
+ - interactive=True,
1168
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
1169
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
1170
+ + interactive=True
1171
+ )
1172
+
1173
+ - upload_button = gr.Button(
1174
+ - "Start Upload", variant="primary", interactive=True
1175
+ - )
1176
+ - cancel_button = gr.Button(
1177
+ - "Cancel Upload", variant="secondary", interactive=True
1178
+ - )
1179
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
1180
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
1181
+
1182
+ with gr.Column(scale=1):
1183
+ - gr.Markdown("## Status Section")
1184
+ - upload_status = gr.Textbox(
1185
+ - label="Upload Status",
1186
+ - lines=10,
1187
+ - interactive=False,
1188
+ - value="Idle",
1189
+ + gr.Markdown("## Status Section", elem_id="status-section")
1190
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
1191
+ + interactive=False, value="Idle"
1192
+ )
1193
+
1194
+ with gr.Tab("Logs"):
1195
+ - log_output = gr.Textbox(
1196
+ - label="Upload Logs",
1197
+ - lines=15,
1198
+ - interactive=False,
1199
+ - placeholder="Logs will appear here...",
1200
+ - value="",
1201
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
1202
+ + interactive=False, placeholder="Logs will appear here...", value=""
1203
+ )
1204
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
1205
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
1206
+
1207
+ # Define the upload button click event
1208
+ - upload_button.click(
1209
+ - fn=upload_files,
1210
+ - inputs=[
1211
+ - files,
1212
+ - repo_id,
1213
+ - token,
1214
+ - private,
1215
+ - threads,
1216
+ - subfolder,
1217
+ - repo_type,
1218
+ - ignore_patterns_selected,
1219
+ - ],
1220
+ - outputs=upload_status,
1221
+ - )
1222
+ + def handle_upload(*args):
1223
+ + threading.Thread(target=upload_files, args=args).start()
1224
+
1225
+ - # Define the cancel button click event
1226
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1227
+ + upload_button.click(fn=handle_upload, inputs=[
1228
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
1229
+ + ], outputs=upload_status)
1230
+
1231
+ - # Define the log refresh button click event
1232
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1233
+ +
1234
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
1235
+
1236
+ return app
1237
+
1238
+ if __name__ == "__main__":
1239
+ app = create_interface()
1240
+ - app.launch(debug=True, share=True)
1241
+ + app.launch(debug=True, share=True, server_port=7860)
1242
+ ```
1243
+
1244
+ ### Key Changes:
1245
+ - **Gradio 5 Components**: Updated components to use `gr.Files` for multiple file selection and `gr.Radio` for repository type selection.
1246
+ - **Layout Optimization**: Improved the layout with better sectioning and labeling.
1247
+ - **Real-time Feedback**: Introduced threading to handle uploads asynchronously, allowing the UI to remain responsive.
1248
+ - **Code Refactoring**: Cleaned up the code for better readability and maintainability.
1249
+
1250
+ This concludes a fully working implementation.
1251
+
1252
+ ================================ Human Message =================================
1253
+
1254
+ Some previously produced diffs were not on the requested format, or the code part was not found in the code. Details:
1255
+ In Hunk:@@ -206,124 +207,134 @@
1256
+ # Gradio Interface
1257
+ def create_interface():
1258
+ with gr.Blocks() as app:
1259
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
1260
+ - gr.Markdown(
1261
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
1262
+ - )
1263
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
1264
+ + gr.Markdown(
1265
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
1266
+ + elem_id="sub-title"
1267
+ + )
1268
+
1269
+ with gr.Row():
1270
+ with gr.Column(scale=1):
1271
+ - gr.Markdown("## Upload Section")
1272
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
1273
+
1274
+ - token = gr.Textbox(
1275
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
1276
+ placeholder="Enter your Hugging Face API token",
1277
+ value=os.getenv("HF_TOKEN", ""),
1278
+ - interactive=True,
1279
+ - lines=1,
1280
+ + interactive=True
1281
+ )
1282
+
1283
+ - repo_type = gr.Dropdown(
1284
+ - label="Repository Type",
1285
+ - choices=["space", "model", "dataset"],
1286
+ - value="space",
1287
+ - interactive=True,
1288
+ + repo_type = gr.Radio(
1289
+ + label="Repository Type", choices=["space", "model", "dataset"],
1290
+ + value="space", interactive=True
1291
+ )
1292
+
1293
+ - repo_id = gr.Textbox(
1294
+ - label="Repository ID",
1295
+ - placeholder="e.g., username/repo-name",
1296
+ - value=os.getenv("DEFAULT_REPO", ""),
1297
+ - interactive=True,
1298
+ - lines=1,
1299
+ + repo_id = gr.Textbox(label="Repository ID",
1300
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
1301
+ + interactive=True
1302
+ )
1303
+
1304
+ - private = gr.Checkbox(
1305
+ - label="Make Repository Private",
1306
+ - value=False,
1307
+ - interactive=True,
1308
+ + private = gr.Checkbox(label="Make Repository Private",
1309
+ + value=False, interactive=True
1310
+ )
1311
+
1312
+ - files = gr.File(
1313
+ - label="Upload Folders",
1314
+ - file_count="multiple",
1315
+ - interactive=True,
1316
+ - type="directory",
1317
+ + files = gr.Files(label="Upload Folders",
1318
+ + file_count="multiple", interactive=True, type="directory"
1319
+ )
1320
+
1321
+ - subfolder = gr.Textbox(
1322
+ - label="Subfolder in Repository (Optional)",
1323
+ - placeholder="e.g., data/uploads",
1324
+ - value="",
1325
+ - interactive=True,
1326
+ - lines=1,
1327
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
1328
+ + placeholder="e.g., data/uploads", value="", interactive=True
1329
+ )
1330
+
1331
+ - threads = gr.Slider(
1332
+ - label="Number of Threads",
1333
+ - minimum=1,
1334
+ - maximum=20,
1335
+ - step=1,
1336
+ - value=5,
1337
+ - interactive=True,
1338
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
1339
+ + step=1, value=5, interactive=True
1340
+ )
1341
+
1342
+ - ignore_patterns_selected = gr.CheckboxGroup(
1343
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
1344
+ - label="Select Patterns to Ignore",
1345
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
1346
+ - interactive=True,
1347
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
1348
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
1349
+ + interactive=True
1350
+ )
1351
+
1352
+ - upload_button = gr.Button(
1353
+ - "Start Upload", variant="primary", interactive=True
1354
+ - )
1355
+ - cancel_button = gr.Button(
1356
+ - "Cancel Upload", variant="secondary", interactive=True
1357
+ - )
1358
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
1359
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
1360
+
1361
+ with gr.Column(scale=1):
1362
+ - gr.Markdown("## Status Section")
1363
+ - upload_status = gr.Textbox(
1364
+ - label="Upload Status",
1365
+ - lines=10,
1366
+ - interactive=False,
1367
+ - value="Idle",
1368
+ + gr.Markdown("## Status Section", elem_id="status-section")
1369
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
1370
+ + interactive=False, value="Idle"
1371
+ )
1372
+
1373
+ with gr.Tab("Logs"):
1374
+ - log_output = gr.Textbox(
1375
+ - label="Upload Logs",
1376
+ - lines=15,
1377
+ - interactive=False,
1378
+ - placeholder="Logs will appear here...",
1379
+ - value="",
1380
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
1381
+ + interactive=False, placeholder="Logs will appear here...", value=""
1382
+ )
1383
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
1384
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
1385
+
1386
+ # Define the upload button click event
1387
+ - upload_button.click(
1388
+ - fn=upload_files,
1389
+ - inputs=[
1390
+ - files,
1391
+ - repo_id,
1392
+ - token,
1393
+ - private,
1394
+ - threads,
1395
+ - subfolder,
1396
+ - repo_type,
1397
+ - ignore_patterns_selected,
1398
+ - ],
1399
+ - outputs=upload_status,
1400
+ - )
1401
+ + def handle_upload(*args):
1402
+ + threading.Thread(target=upload_files, args=args).start()
1403
+
1404
+ - # Define the cancel button click event
1405
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1406
+ + upload_button.click(fn=handle_upload, inputs=[
1407
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
1408
+ + ], outputs=upload_status)
1409
+
1410
+ - # Define the log refresh button click event
1411
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1412
+ +
1413
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
1414
+
1415
+ return app
1416
+
1417
+ if __name__ == "__main__":
1418
+ app = create_interface()
1419
+ - app.launch(debug=True, share=True)
1420
+ + app.launch(debug=True, share=True, server_port=7860)
1421
+ , there was at least one mismatch.
1422
+ Only rewrite the problematic diffs, making sure that the failing ones are now on the correct format and can be found in the code. Make sure to not repeat past mistakes.
1423
+
1424
+
1425
+ ================================== Ai Message ==================================
1426
+
1427
+ Let's address the issues with the previous diff and ensure that the changes are correctly formatted and can be found in the code. We'll focus on the specific section that had issues and correct it.
1428
+
1429
+ ```diff
1430
+ --- app.py
1431
+ +++ app.py
1432
+ @@ -206,124 +207,134 @@
1433
+ # Gradio Interface
1434
+ def create_interface():
1435
+ with gr.Blocks() as app:
1436
+ - gr.Markdown("# πŸš€ InfiniteStorageFace")
1437
+ - gr.Markdown(
1438
+ - "**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**"
1439
+ - )
1440
+ + gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
1441
+ + gr.Markdown(
1442
+ + "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
1443
+ + elem_id="sub-title"
1444
+ + )
1445
+
1446
+ with gr.Row():
1447
+ with gr.Column(scale=1):
1448
+ - gr.Markdown("## Upload Section")
1449
+ + gr.Markdown("## Upload Section", elem_id="upload-section")
1450
+
1451
+ - token = gr.Textbox(
1452
+ - label="Hugging Face Token",
1453
+ - type="password",
1454
+ - placeholder="Enter your Hugging Face API token",
1455
+ - value=os.getenv("HF_TOKEN", ""),
1456
+ - interactive=True,
1457
+ - lines=1,
1458
+ + token = gr.Textbox(label="Hugging Face Token", type="password",
1459
+ + placeholder="Enter your Hugging Face API token",
1460
+ + value=os.getenv("HF_TOKEN", ""),
1461
+ + interactive=True
1462
+ )
1463
+
1464
+ - repo_type = gr.Dropdown(
1465
+ - label="Repository Type",
1466
+ - choices=["space", "model", "dataset"],
1467
+ - value="space",
1468
+ - interactive=True,
1469
+ + repo_type = gr.Radio(
1470
+ + label="Repository Type", choices=["space", "model", "dataset"],
1471
+ + value="space", interactive=True
1472
+ )
1473
+
1474
+ - repo_id = gr.Textbox(
1475
+ - label="Repository ID",
1476
+ - placeholder="e.g., username/repo-name",
1477
+ - value=os.getenv("DEFAULT_REPO", ""),
1478
+ - interactive=True,
1479
+ - lines=1,
1480
+ + repo_id = gr.Textbox(label="Repository ID",
1481
+ + placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
1482
+ + interactive=True
1483
+ )
1484
+
1485
+ - private = gr.Checkbox(
1486
+ - label="Make Repository Private",
1487
+ - value=False,
1488
+ - interactive=True,
1489
+ + private = gr.Checkbox(label="Make Repository Private",
1490
+ + value=False, interactive=True
1491
+ )
1492
+
1493
+ - files = gr.File(
1494
+ - label="Upload Folders",
1495
+ - file_count="multiple",
1496
+ - interactive=True,
1497
+ - type="directory",
1498
+ + files = gr.Files(label="Upload Folders",
1499
+ + file_count="multiple", interactive=True, type="directory"
1500
+ )
1501
+
1502
+ - subfolder = gr.Textbox(
1503
+ - label="Subfolder in Repository (Optional)",
1504
+ - placeholder="e.g., data/uploads",
1505
+ - value="",
1506
+ - interactive=True,
1507
+ - lines=1,
1508
+ + subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
1509
+ + placeholder="e.g., data/uploads", value="", interactive=True
1510
+ )
1511
+
1512
+ - threads = gr.Slider(
1513
+ - label="Number of Threads",
1514
+ - minimum=1,
1515
+ - maximum=20,
1516
+ - step=1,
1517
+ - value=5,
1518
+ - interactive=True,
1519
+ + threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
1520
+ + step=1, value=5, interactive=True
1521
+ )
1522
+
1523
+ - ignore_patterns_selected = gr.CheckboxGroup(
1524
+ - choices=list(IGNORE_PATTERNS_MAP.keys()),
1525
+ - label="Select Patterns to Ignore",
1526
+ - value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
1527
+ - interactive=True,
1528
+ + ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
1529
+ + choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
1530
+ + interactive=True
1531
+ )
1532
+
1533
+ - upload_button = gr.Button(
1534
+ - "Start Upload", variant="primary", interactive=True
1535
+ - )
1536
+ - cancel_button = gr.Button(
1537
+ - "Cancel Upload", variant="secondary", interactive=True
1538
+ - )
1539
+ + upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
1540
+ + cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
1541
+
1542
+ with gr.Column(scale=1):
1543
+ - gr.Markdown("## Status Section")
1544
+ - upload_status = gr.Textbox(
1545
+ - label="Upload Status",
1546
+ - lines=10,
1547
+ - interactive=False,
1548
+ - value="Idle",
1549
+ + gr.Markdown("## Status Section", elem_id="status-section")
1550
+ + upload_status = gr.Textbox(label="Upload Status", lines=10,
1551
+ + interactive=False, value="Idle"
1552
+ )
1553
+
1554
+ with gr.Tab("Logs"):
1555
+ - log_output = gr.Textbox(
1556
+ - label="Upload Logs",
1557
+ - lines=15,
1558
+ - interactive=False,
1559
+ - placeholder="Logs will appear here...",
1560
+ - value="",
1561
+ + log_output = gr.Textbox(label="Upload Logs", lines=15,
1562
+ + interactive=False, placeholder="Logs will appear here...", value=""
1563
+ )
1564
+ - log_refresh = gr.Button("Refresh Logs", interactive=True)
1565
+ + log_refresh = gr.Button("Refresh Logs", interactive=True)
1566
+
1567
+ # Define the upload button click event
1568
+ - upload_button.click(
1569
+ - fn=upload_files,
1570
+ - inputs=[
1571
+ - files,
1572
+ - repo_id,
1573
+ - token,
1574
+ - private,
1575
+ - threads,
1576
+ - subfolder,
1577
+ - repo_type,
1578
+ - ignore_patterns_selected,
1579
+ - ],
1580
+ - outputs=upload_status,
1581
+ - )
1582
+ + def handle_upload(*args):
1583
+ + threading.Thread(target=upload_files, args=args).start()
1584
+
1585
+ - # Define the cancel button click event
1586
+ - cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1587
+ + upload_button.click(fn=handle_upload, inputs=[
1588
+ + files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
1589
+ + ], outputs=upload_status)
1590
+
1591
+ - # Define the log refresh button click event
1592
+ + cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
1593
+ +
1594
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
1595
+
1596
+ return app
1597
+
1598
+ if __name__ == "__main__":
1599
+ app = create_interface()
1600
+ - app.launch(debug=True, share=True)
1601
+ + app.launch(debug=True, share=True, server_port=7860)
1602
+ ```
1603
+
1604
+ ### Key Corrections:
1605
+ - **Element IDs**: Added `elem_id` attributes to `gr.Markdown` components for better styling and identification.
1606
+ - **Component Updates**: Corrected the use of `gr.Files` and `gr.Radio` components.
1607
+ - **Threading**: Introduced threading for the upload process to keep the UI responsive.
1608
+ - **Launch Parameters**: Added `server_port=7860` to the `app.launch()` method for consistency.
1609
+
1610
+ This should now be correctly formatted and aligned with the existing code structure.
__pycache__/app.cpython-311.pyc ADDED
Binary file (12.8 kB). View file
 
app.py CHANGED
@@ -6,12 +6,15 @@ from rich.logging import RichHandler
6
  import logging
7
  import time
8
  import shutil
 
9
  from pathlib import Path
10
 
11
  # Default values
12
  DEFAULT_REPO = os.getenv("DEFAULT_REPO", "luigi12345/megacursos-master-999")
13
- DEFAULT_LOCAL_PATH = os.getenv("DEFAULT_LOCAL_PATH", "/Users/samihalawa/Documents/Megacursos/MEGACURSOS_S3_MASTER")
14
- token = os.getenv("HF_TOKEN")
 
 
15
 
16
  # Initialize Rich console for logging
17
  console = Console()
@@ -19,7 +22,7 @@ logging.basicConfig(
19
  level=logging.INFO,
20
  format="%(message)s",
21
  datefmt="[%Y-%m-%d %H:%M:%S]",
22
- handlers=[RichHandler(console=console, rich_tracebacks=True)]
23
  )
24
  logger = logging.getLogger("InfiniteStorageFace")
25
 
@@ -34,7 +37,7 @@ IGNORE_PATTERNS_MAP = {
34
  "Ignore *.pyc": "*.pyc",
35
  "Ignore *.log": "*.log",
36
  "Ignore *.tmp": "*.tmp",
37
- "Ignore *.DS_Store": "*.DS_Store"
38
  }
39
 
40
  # Shared logs list
@@ -43,6 +46,7 @@ shared_logs = []
43
  # Event to cancel upload
44
  cancel_event = False
45
 
 
46
  # Function to log messages
47
  def log(message):
48
  timestamp = time.strftime("[%Y-%m-%d %H:%M:%S]")
@@ -51,6 +55,7 @@ def log(message):
51
  logger.info(message)
52
  return full_message
53
 
 
54
  # Function to authenticate user with Hugging Face token
55
  def authenticate(token):
56
  if not token:
@@ -61,6 +66,7 @@ def authenticate(token):
61
  except Exception as e:
62
  return False, log(f"❌ Authentication failed: {e}")
63
 
 
64
  # Function to create repository if it doesn't exist
65
  def create_repo_if_not_exists(repo_id, token, repo_type, private):
66
  try:
@@ -75,11 +81,14 @@ def create_repo_if_not_exists(repo_id, token, repo_type, private):
75
  private=private,
76
  repo_type=repo_type,
77
  exist_ok=True,
78
- space_sdk="static" if repo_type == "space" else None
79
  )
80
  return True, log(f"βœ… Created new repository: '{repo_id}'.")
81
  except Exception as create_err:
82
- return False, log(f"❌ Failed to create repository '{repo_id}': {create_err}")
 
 
 
83
 
84
  # Function to clean up ignored folders
85
  def cleanup_before_upload(folder_path, ignore_patterns):
@@ -89,8 +98,11 @@ def cleanup_before_upload(folder_path, ignore_patterns):
89
  shutil.rmtree(path)
90
  log(f"πŸ—‘οΈ Removed ignored folder: {path}")
91
 
 
92
  # Function to upload a folder
93
- def upload_folder_structure(folder_path, repo_id, token, repo_type, target_path, ignore_patterns):
 
 
94
  # Clean up ignored folders
95
  cleanup_before_upload(folder_path, ignore_patterns)
96
 
@@ -103,15 +115,27 @@ def upload_folder_structure(folder_path, repo_id, token, repo_type, target_path,
103
  "multi_commits": True,
104
  "multi_commits_verbose": True,
105
  }
106
- log(f"πŸš€ Uploading folder '{folder_path}' to '{target_path}' in repository '{repo_id}'...")
 
 
107
  try:
108
  upload_folder(**upload_params)
109
  log(f"βœ… Upload completed for '{folder_path}'!")
110
  except Exception as upload_err:
111
  log(f"❌ Upload failed for '{folder_path}': {upload_err}")
112
 
 
113
  # Function to handle uploads, allowing direct folder uploads
114
- def upload_files(files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected):
 
 
 
 
 
 
 
 
 
115
  global cancel_event
116
  cancel_event = False
117
 
@@ -124,7 +148,9 @@ def upload_files(files, repo_id, token, private, threads, subfolder, repo_type,
124
  return "\n".join(logs)
125
 
126
  # Create repo if not exists
127
- repo_success, repo_message = create_repo_if_not_exists(repo_id, token, repo_type, private)
 
 
128
  logs.append(repo_message)
129
  if not repo_success:
130
  return "\n".join(logs)
@@ -133,7 +159,9 @@ def upload_files(files, repo_id, token, private, threads, subfolder, repo_type,
133
  target_path = subfolder.replace("\\", "/") if subfolder else ""
134
 
135
  # Map selected ignore patterns to actual patterns
136
- ignore_patterns = [IGNORE_PATTERNS_MAP[pattern] for pattern in ignore_patterns_selected]
 
 
137
 
138
  # Upload folders directly if provided
139
  if files:
@@ -143,10 +171,16 @@ def upload_files(files, repo_id, token, private, threads, subfolder, repo_type,
143
  return "\n".join(logs)
144
  file_path = file.name
145
  if os.path.isdir(file_path): # Check if the file is a directory
146
- upload_folder_structure(file_path, repo_id, token, repo_type, target_path, ignore_patterns)
 
 
147
  logs.append(log(f"βœ… Uploaded folder '{file_path}'."))
148
  else:
149
- logs.append(log(f"❌ '{file_path}' is not a folder. Only folders can be uploaded."))
 
 
 
 
150
  else:
151
  logs.append(log("❌ No files provided for upload."))
152
 
@@ -157,132 +191,99 @@ def upload_files(files, repo_id, token, private, threads, subfolder, repo_type,
157
  logs.append(log("πŸš€ Upload completed. Check the logs for details."))
158
  return "\n".join(logs)
159
 
 
160
  # Function to cancel upload
161
  def cancel_upload():
162
  global cancel_event
163
  cancel_event = True
164
  return log("Upload has been cancelled.")
165
 
 
166
  # Function to refresh logs
167
  def refresh_logs():
168
  return "\n".join(shared_logs)
169
 
 
170
  # Gradio Interface
171
  def create_interface():
172
  with gr.Blocks() as app:
173
- gr.Markdown("# πŸš€ InfiniteStorageFace")
174
- gr.Markdown("**Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!**")
 
 
 
175
 
176
  with gr.Row():
177
  with gr.Column(scale=1):
178
- gr.Markdown("## Upload Section")
179
 
180
- token = gr.Textbox(
181
- label="Hugging Face Token",
182
- type="password",
183
  placeholder="Enter your Hugging Face API token",
184
  value=os.getenv("HF_TOKEN", ""),
185
- interactive=True,
186
- lines=1,
187
  )
188
 
189
- repo_type = gr.Dropdown(
190
- label="Repository Type",
191
- choices=["space", "model", "dataset"],
192
- value="space",
193
- interactive=True,
194
  )
195
 
196
- repo_id = gr.Textbox(
197
- label="Repository ID",
198
- placeholder="e.g., username/repo-name",
199
- value=os.getenv("DEFAULT_REPO", ""),
200
- interactive=True,
201
- lines=1,
202
  )
203
 
204
- private = gr.Checkbox(
205
- label="Make Repository Private",
206
- value=False,
207
- interactive=True,
208
  )
209
 
210
- files = gr.File(
211
- label="Upload Folders",
212
- file_count="multiple",
213
- interactive=True,
214
- type="directory"
215
  )
216
 
217
- subfolder = gr.Textbox(
218
- label="Subfolder in Repository (Optional)",
219
- placeholder="e.g., data/uploads",
220
- value="",
221
- interactive=True,
222
- lines=1,
223
  )
224
 
225
- threads = gr.Slider(
226
- label="Number of Threads",
227
- minimum=1,
228
- maximum=20,
229
- step=1,
230
- value=5,
231
- interactive=True,
232
  )
233
 
234
- ignore_patterns_selected = gr.CheckboxGroup(
235
- choices=list(IGNORE_PATTERNS_MAP.keys()),
236
- label="Select Patterns to Ignore",
237
- value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
238
- interactive=True,
239
  )
240
 
241
  upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
242
  cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
243
 
244
  with gr.Column(scale=1):
245
- gr.Markdown("## Status Section")
246
- upload_status = gr.Textbox(
247
- label="Upload Status",
248
- lines=10,
249
- interactive=False,
250
- value="Idle",
251
  )
252
 
253
  with gr.Tab("Logs"):
254
- log_output = gr.Textbox(
255
- label="Upload Logs",
256
- lines=15,
257
- interactive=False,
258
- placeholder="Logs will appear here...",
259
- value="",
260
  )
261
  log_refresh = gr.Button("Refresh Logs", interactive=True)
262
 
263
  # Define the upload button click event
264
- upload_button.click(
265
- fn=upload_files,
266
- inputs=[files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected],
267
- outputs=upload_status
268
- )
269
 
270
- # Define the cancel button click event
271
- cancel_button.click(
272
- fn=cancel_upload,
273
- inputs=None,
274
- outputs=upload_status
275
- )
276
 
277
- # Define the log refresh button click event
278
- log_refresh.click(
279
- fn=refresh_logs,
280
- inputs=None,
281
- outputs=log_output
282
- )
283
 
284
  return app
285
 
 
286
  if __name__ == "__main__":
287
  app = create_interface()
288
- app.launch(debug=True, share=True)
 
6
  import logging
7
  import time
8
  import shutil
9
+ import threading
10
  from pathlib import Path
11
 
12
  # Default values
13
  DEFAULT_REPO = os.getenv("DEFAULT_REPO", "luigi12345/megacursos-master-999")
14
+ DEFAULT_LOCAL_PATH = os.getenv(
15
+ "DEFAULT_LOCAL_PATH", "/Users/samihalawa/Documents/Megacursos/MEGACURSOS_S3_MASTER"
16
+ )
17
+ token = os.getenv("HF_TOKEN", "")
18
 
19
  # Initialize Rich console for logging
20
  console = Console()
 
22
  level=logging.INFO,
23
  format="%(message)s",
24
  datefmt="[%Y-%m-%d %H:%M:%S]",
25
+ handlers=[RichHandler(console=console, rich_tracebacks=True)],
26
  )
27
  logger = logging.getLogger("InfiniteStorageFace")
28
 
 
37
  "Ignore *.pyc": "*.pyc",
38
  "Ignore *.log": "*.log",
39
  "Ignore *.tmp": "*.tmp",
40
+ "Ignore *.DS_Store": "*.DS_Store",
41
  }
42
 
43
  # Shared logs list
 
46
  # Event to cancel upload
47
  cancel_event = False
48
 
49
+
50
  # Function to log messages
51
  def log(message):
52
  timestamp = time.strftime("[%Y-%m-%d %H:%M:%S]")
 
55
  logger.info(message)
56
  return full_message
57
 
58
+
59
  # Function to authenticate user with Hugging Face token
60
  def authenticate(token):
61
  if not token:
 
66
  except Exception as e:
67
  return False, log(f"❌ Authentication failed: {e}")
68
 
69
+
70
  # Function to create repository if it doesn't exist
71
  def create_repo_if_not_exists(repo_id, token, repo_type, private):
72
  try:
 
81
  private=private,
82
  repo_type=repo_type,
83
  exist_ok=True,
84
+ space_sdk="static" if repo_type == "space" else None,
85
  )
86
  return True, log(f"βœ… Created new repository: '{repo_id}'.")
87
  except Exception as create_err:
88
+ return False, log(
89
+ f"❌ Failed to create repository '{repo_id}': {create_err}"
90
+ )
91
+
92
 
93
  # Function to clean up ignored folders
94
  def cleanup_before_upload(folder_path, ignore_patterns):
 
98
  shutil.rmtree(path)
99
  log(f"πŸ—‘οΈ Removed ignored folder: {path}")
100
 
101
+
102
  # Function to upload a folder
103
+ def upload_folder_structure(
104
+ folder_path, repo_id, token, repo_type, target_path, ignore_patterns
105
+ ):
106
  # Clean up ignored folders
107
  cleanup_before_upload(folder_path, ignore_patterns)
108
 
 
115
  "multi_commits": True,
116
  "multi_commits_verbose": True,
117
  }
118
+ log(
119
+ f"πŸš€ Uploading folder '{folder_path}' to '{target_path}' in repository '{repo_id}'..."
120
+ )
121
  try:
122
  upload_folder(**upload_params)
123
  log(f"βœ… Upload completed for '{folder_path}'!")
124
  except Exception as upload_err:
125
  log(f"❌ Upload failed for '{folder_path}': {upload_err}")
126
 
127
+
128
  # Function to handle uploads, allowing direct folder uploads
129
+ def upload_files(
130
+ files,
131
+ repo_id,
132
+ token,
133
+ private,
134
+ threads,
135
+ subfolder,
136
+ repo_type,
137
+ ignore_patterns_selected,
138
+ ):
139
  global cancel_event
140
  cancel_event = False
141
 
 
148
  return "\n".join(logs)
149
 
150
  # Create repo if not exists
151
+ repo_success, repo_message = create_repo_if_not_exists(
152
+ repo_id, token, repo_type, private
153
+ )
154
  logs.append(repo_message)
155
  if not repo_success:
156
  return "\n".join(logs)
 
159
  target_path = subfolder.replace("\\", "/") if subfolder else ""
160
 
161
  # Map selected ignore patterns to actual patterns
162
+ ignore_patterns = [
163
+ IGNORE_PATTERNS_MAP[pattern] for pattern in ignore_patterns_selected
164
+ ]
165
 
166
  # Upload folders directly if provided
167
  if files:
 
171
  return "\n".join(logs)
172
  file_path = file.name
173
  if os.path.isdir(file_path): # Check if the file is a directory
174
+ upload_folder_structure(
175
+ file_path, repo_id, token, repo_type, target_path, ignore_patterns
176
+ )
177
  logs.append(log(f"βœ… Uploaded folder '{file_path}'."))
178
  else:
179
+ logs.append(
180
+ log(
181
+ f"❌ '{file_path}' is not a folder. Only folders can be uploaded."
182
+ )
183
+ )
184
  else:
185
  logs.append(log("❌ No files provided for upload."))
186
 
 
191
  logs.append(log("πŸš€ Upload completed. Check the logs for details."))
192
  return "\n".join(logs)
193
 
194
+
195
  # Function to cancel upload
196
  def cancel_upload():
197
  global cancel_event
198
  cancel_event = True
199
  return log("Upload has been cancelled.")
200
 
201
+
202
  # Function to refresh logs
203
  def refresh_logs():
204
  return "\n".join(shared_logs)
205
 
206
+
207
  # Gradio Interface
208
  def create_interface():
209
  with gr.Blocks() as app:
210
+ gr.Markdown("# πŸš€ InfiniteStorageFace", elem_id="main-title")
211
+ gr.Markdown(
212
+ "Effortlessly upload your files or folders to Hugging Face repositories with real-time feedback and progress tracking!",
213
+ elem_id="sub-title"
214
+ )
215
 
216
  with gr.Row():
217
  with gr.Column(scale=1):
218
+ gr.Markdown("## Upload Section", elem_id="upload-section")
219
 
220
+ token = gr.Textbox(label="Hugging Face Token", type="password",
 
 
221
  placeholder="Enter your Hugging Face API token",
222
  value=os.getenv("HF_TOKEN", ""),
223
+ interactive=True
 
224
  )
225
 
226
+ repo_type = gr.Radio(
227
+ label="Repository Type", choices=["space", "model", "dataset"],
228
+ value="space", interactive=True
 
 
229
  )
230
 
231
+ repo_id = gr.Textbox(label="Repository ID",
232
+ placeholder="e.g., username/repo-name", value=os.getenv("DEFAULT_REPO", ""),
233
+ interactive=True
 
 
 
234
  )
235
 
236
+ private = gr.Checkbox(label="Make Repository Private",
237
+ value=False, interactive=True
 
 
238
  )
239
 
240
+ files = gr.Files(label="Upload Folders",
241
+ file_count="multiple", interactive=True, type="directory"
 
 
 
242
  )
243
 
244
+ subfolder = gr.Textbox(label="Subfolder in Repository (Optional)",
245
+ placeholder="e.g., data/uploads", value="", interactive=True
 
 
 
 
246
  )
247
 
248
+ threads = gr.Slider(label="Number of Threads", minimum=1, maximum=20,
249
+ step=1, value=5, interactive=True
 
 
 
 
 
250
  )
251
 
252
+ ignore_patterns_selected = gr.CheckboxGroup(label="Select Patterns to Ignore",
253
+ choices=list(IGNORE_PATTERNS_MAP.keys()), value=["Ignore __pycache__", "Ignore .git", "Ignore *.pyc"],
254
+ interactive=True
 
 
255
  )
256
 
257
  upload_button = gr.Button("Start Upload", variant="primary", interactive=True)
258
  cancel_button = gr.Button("Cancel Upload", variant="secondary", interactive=True)
259
 
260
  with gr.Column(scale=1):
261
+ gr.Markdown("## Status Section", elem_id="status-section")
262
+ upload_status = gr.Textbox(label="Upload Status", lines=10,
263
+ interactive=False, value="Idle"
 
 
 
264
  )
265
 
266
  with gr.Tab("Logs"):
267
+ log_output = gr.Textbox(label="Upload Logs", lines=15,
268
+ interactive=False, placeholder="Logs will appear here...", value=""
 
 
 
 
269
  )
270
  log_refresh = gr.Button("Refresh Logs", interactive=True)
271
 
272
  # Define the upload button click event
273
+ def handle_upload(*args):
274
+ threading.Thread(target=upload_files, args=args).start()
 
 
 
275
 
276
+ upload_button.click(fn=handle_upload, inputs=[
277
+ files, repo_id, token, private, threads, subfolder, repo_type, ignore_patterns_selected
278
+ ], outputs=upload_status)
 
 
 
279
 
280
+ cancel_button.click(fn=cancel_upload, inputs=None, outputs=upload_status)
281
+
282
+ log_refresh.click(fn=refresh_logs, inputs=None, outputs=log_output)
 
 
 
283
 
284
  return app
285
 
286
+
287
  if __name__ == "__main__":
288
  app = create_interface()
289
+ app.launch(debug=True, share=True, server_port=7860)