MySafeCode commited on
Commit
04bd3ae
·
verified ·
1 Parent(s): dbe81f4

Create add.py

Browse files
Files changed (1) hide show
  1. add.py +471 -0
add.py ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import zipfile
4
+ import tempfile
5
+ import shutil
6
+ from pathlib import Path
7
+ import mimetypes
8
+ import time
9
+
10
+ # Create uploads directory
11
+ UPLOADS_FOLDER = "uploads"
12
+ os.makedirs(UPLOADS_FOLDER, exist_ok=True)
13
+
14
+ def process_file(file_obj, file_name, action):
15
+ """
16
+ Process uploaded file: return original or create zip
17
+ """
18
+ if not file_obj:
19
+ return None, "❌ No file uploaded"
20
+
21
+ try:
22
+ # In Gradio 6+, file_obj is a dictionary
23
+ if isinstance(file_obj, dict):
24
+ file_path = file_obj["path"]
25
+ original_name = file_obj["name"]
26
+ else:
27
+ # Fallback for older versions
28
+ file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
29
+ original_name = os.path.basename(file_path)
30
+
31
+ # Save uploaded file temporarily
32
+ temp_dir = tempfile.mkdtemp()
33
+ custom_name = file_name.strip() if file_name and file_name.strip() else original_name
34
+ original_path = os.path.join(temp_dir, custom_name)
35
+
36
+ # Copy file to temp location
37
+ shutil.copy2(file_path, original_path)
38
+
39
+ if action == "original":
40
+ # Return original file - for Gradio 6+, return a dictionary
41
+ return {
42
+ "path": original_path,
43
+ "name": custom_name
44
+ }, f"✅ Ready to download: {custom_name}"
45
+
46
+ elif action == "zip":
47
+ # Create zip file
48
+ base_name = os.path.splitext(custom_name)[0]
49
+ zip_name = f"{base_name}.zip"
50
+ zip_path = os.path.join(temp_dir, zip_name)
51
+
52
+ with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
53
+ zipf.write(original_path, custom_name)
54
+
55
+ return {
56
+ "path": zip_path,
57
+ "name": zip_name
58
+ }, f"✅ Zipped as: {zip_name}"
59
+
60
+ elif action == "zip_with_password":
61
+ # Create password-protected zip
62
+ try:
63
+ import pyminizip
64
+ base_name = os.path.splitext(custom_name)[0]
65
+ zip_name = f"{base_name}_protected.zip"
66
+ zip_path = os.path.join(temp_dir, zip_name)
67
+
68
+ # Compress with password
69
+ pyminizip.compress(
70
+ original_path,
71
+ None,
72
+ zip_path,
73
+ "password123", # Default password
74
+ 5 # Compression level
75
+ )
76
+ return {
77
+ "path": zip_path,
78
+ "name": zip_name
79
+ }, f"✅ Password-protected zip created (password: password123)"
80
+
81
+ except ImportError:
82
+ return None, "❌ pyminizip not installed. Install with: pip install pyminizip"
83
+
84
+ else:
85
+ return None, "❌ Invalid action selected"
86
+
87
+ except Exception as e:
88
+ return None, f"❌ Error: {str(e)}"
89
+
90
+ def process_multiple_files(files, action):
91
+ """
92
+ Process multiple uploaded files
93
+ """
94
+ if not files:
95
+ return None, "❌ No files uploaded"
96
+
97
+ try:
98
+ temp_dir = tempfile.mkdtemp()
99
+
100
+ if action == "individual":
101
+ # Create zip containing all files
102
+ zip_name = "files.zip"
103
+ zip_path = os.path.join(temp_dir, zip_name)
104
+
105
+ with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
106
+ for file_obj in files:
107
+ # Handle Gradio 6+ file object format
108
+ if isinstance(file_obj, dict):
109
+ file_path = file_obj["path"]
110
+ file_name = file_obj["name"]
111
+ else:
112
+ file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
113
+ file_name = os.path.basename(file_path)
114
+
115
+ zipf.write(file_path, file_name)
116
+
117
+ return {
118
+ "path": zip_path,
119
+ "name": zip_name
120
+ }, f"✅ Created zip with {len(files)} files"
121
+
122
+ elif action == "separate":
123
+ # Create separate zips for each file
124
+ zip_name = "separate_files.zip"
125
+ zip_path = os.path.join(temp_dir, zip_name)
126
+
127
+ with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
128
+ for file_obj in files:
129
+ # Handle Gradio 6+ file object format
130
+ if isinstance(file_obj, dict):
131
+ file_path = file_obj["path"]
132
+ file_name = file_obj["name"]
133
+ else:
134
+ file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
135
+ file_name = os.path.basename(file_path)
136
+
137
+ # Create individual zip first
138
+ base_name = os.path.splitext(file_name)[0]
139
+ individual_zip_name = f"{base_name}.zip"
140
+ individual_zip_path = os.path.join(temp_dir, individual_zip_name)
141
+
142
+ with zipfile.ZipFile(individual_zip_path, 'w', zipfile.ZIP_DEFLATED) as ind_zip:
143
+ ind_zip.write(file_path, file_name)
144
+
145
+ # Add individual zip to main zip
146
+ zipf.write(individual_zip_path, individual_zip_name)
147
+
148
+ return {
149
+ "path": zip_path,
150
+ "name": zip_name
151
+ }, f"✅ Created zip with {len(files)} individual zips"
152
+
153
+ else:
154
+ return None, "❌ Invalid action selected"
155
+
156
+ except Exception as e:
157
+ return None, f"❌ Error: {str(e)}"
158
+
159
+ def get_file_info(file_obj):
160
+ """Get information about uploaded file"""
161
+ if not file_obj:
162
+ return "No file selected"
163
+
164
+ try:
165
+ # Handle Gradio 6+ file object format
166
+ if isinstance(file_obj, dict):
167
+ file_path = file_obj["path"]
168
+ file_name = file_obj["name"]
169
+ else:
170
+ file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
171
+ file_name = os.path.basename(file_path)
172
+
173
+ file_size = os.path.getsize(file_path)
174
+ file_ext = os.path.splitext(file_name)[1].lower()
175
+
176
+ # Get file type
177
+ mime_type, _ = mimetypes.guess_type(file_path)
178
+ file_type = mime_type.split('/')[0] if mime_type else "Unknown"
179
+
180
+ # Get creation and modification times
181
+ ctime = time.ctime(os.path.getctime(file_path))
182
+ mtime = time.ctime(os.path.getmtime(file_path))
183
+
184
+ info = f"""
185
+ 📄 **File Information:**
186
+
187
+ **Name:** {file_name}
188
+ **Size:** {file_size:,} bytes ({file_size/1024:.2f} KB)
189
+ **Extension:** {file_ext}
190
+ **Type:** {file_type}
191
+ **Created:** {ctime}
192
+ **Modified:** {mtime}
193
+ **Path:** {file_path}
194
+ """
195
+
196
+ return info
197
+
198
+ except Exception as e:
199
+ return f"❌ Error getting file info: {str(e)}"
200
+
201
+ # Create Gradio interface
202
+ with gr.Blocks(title="File Upload & Download Manager") as iface:
203
+
204
+ gr.Markdown("# 📁 File Upload & Download Manager")
205
+ gr.Markdown("Upload files and download them as original or zipped")
206
+
207
+ with gr.Tabs():
208
+ # Single File Tab
209
+ with gr.Tab("Single File"):
210
+ with gr.Row():
211
+ with gr.Column(scale=2):
212
+ single_file = gr.File(
213
+ label="Upload a File",
214
+ file_count="single"
215
+ )
216
+
217
+ file_name_input = gr.Textbox(
218
+ label="Custom Filename (optional)",
219
+ placeholder="Leave empty to keep original name...",
220
+ info="Enter a custom name for the downloaded file"
221
+ )
222
+
223
+ single_action = gr.Radio(
224
+ choices=[
225
+ ("Download Original", "original"),
226
+ ("Download as ZIP", "zip"),
227
+ ("Password-protected ZIP", "zip_with_password")
228
+ ],
229
+ label="Select Action",
230
+ value="original"
231
+ )
232
+
233
+ single_btn = gr.Button("Process File", variant="primary")
234
+
235
+ with gr.Column(scale=1):
236
+ file_info = gr.Markdown(label="File Information")
237
+ single_status = gr.Textbox(label="Status", interactive=False)
238
+ single_download = gr.File(label="Download Processed File", interactive=False)
239
+
240
+ # Update file info when file is uploaded
241
+ single_file.change(
242
+ fn=get_file_info,
243
+ inputs=[single_file],
244
+ outputs=file_info
245
+ )
246
+
247
+ # Multiple Files Tab
248
+ with gr.Tab("Multiple Files"):
249
+ with gr.Row():
250
+ with gr.Column(scale=2):
251
+ multi_files = gr.File(
252
+ label="Upload Multiple Files",
253
+ file_count="multiple",
254
+ # Updated file_types format for Gradio 6+
255
+ file_types=[
256
+ "image", "video", "audio",
257
+ "text", ".pdf", ".zip", ".txt",
258
+ ".doc", ".docx", ".xls", ".xlsx"
259
+ ]
260
+ )
261
+
262
+ multi_action = gr.Radio(
263
+ choices=[
264
+ ("Combine all files into one ZIP", "individual"),
265
+ ("Create separate ZIPs for each file", "separate")
266
+ ],
267
+ label="Select Action",
268
+ value="individual"
269
+ )
270
+
271
+ multi_btn = gr.Button("Process Files", variant="primary")
272
+
273
+ with gr.Column(scale=1):
274
+ multi_status = gr.Textbox(label="Status", interactive=False)
275
+ multi_download = gr.File(label="Download Processed Files", interactive=False)
276
+
277
+ # Batch Processing Tab
278
+ with gr.Tab("Batch Processing"):
279
+ with gr.Row():
280
+ with gr.Column():
281
+ gr.Markdown("### Upload Multiple Files for Batch Processing")
282
+
283
+ batch_files = gr.File(
284
+ label="Upload Files",
285
+ file_count="multiple",
286
+ file_types=None # All file types
287
+ )
288
+
289
+ batch_options = gr.CheckboxGroup(
290
+ choices=[
291
+ "Create individual ZIPs",
292
+ "Create combined ZIP",
293
+ "Rename with timestamp",
294
+ "Add to existing ZIP"
295
+ ],
296
+ label="Processing Options",
297
+ value=["Create combined ZIP"]
298
+ )
299
+
300
+ with gr.Row():
301
+ batch_format = gr.Dropdown(
302
+ choices=[".zip", ".7z", ".tar.gz"],
303
+ value=".zip",
304
+ label="Archive Format"
305
+ )
306
+
307
+ compression_level = gr.Slider(
308
+ minimum=1,
309
+ maximum=9,
310
+ value=6,
311
+ step=1,
312
+ label="Compression Level"
313
+ )
314
+
315
+ batch_btn = gr.Button("Process Batch", variant="primary", size="lg")
316
+
317
+ with gr.Column():
318
+ batch_status = gr.Textbox(label="Status", interactive=False, lines=3)
319
+ batch_download = gr.File(label="Download Results", interactive=False)
320
+
321
+ # Instructions
322
+ with gr.Accordion("📖 Instructions & Features", open=False):
323
+ gr.Markdown("""
324
+ ## How to Use:
325
+
326
+ ### Single File Tab:
327
+ 1. **Upload** a single file
328
+ 2. (Optional) Enter a custom filename
329
+ 3. **Choose action**: Download original, as ZIP, or password-protected ZIP
330
+ 4. Click **Process File**
331
+
332
+ ### Multiple Files Tab:
333
+ 1. **Upload** multiple files (Ctrl+Click to select multiple)
334
+ 2. **Choose action**: Combine into one ZIP or create separate ZIPs
335
+ 3. Click **Process Files**
336
+
337
+ ### Batch Processing Tab:
338
+ 1. **Upload** multiple files
339
+ 2. **Select processing options**
340
+ 3. Choose archive format and compression level
341
+ 4. Click **Process Batch**
342
+
343
+ ## Features:
344
+ - ✅ Single file upload and download
345
+ - ✅ Multiple file upload and batch processing
346
+ - ✅ ZIP file creation with compression
347
+ - ✅ Password-protected ZIPs (requires pyminizip)
348
+ - ✅ File information display
349
+ - ✅ Custom filename support
350
+ - ✅ Multiple archive formats
351
+
352
+ ## Notes:
353
+ - Files are processed in temporary storage
354
+ - Original files are not modified
355
+ - Large files may take time to process
356
+ - Password for protected ZIPs: `password123`
357
+ - For Gradio 6+ compatibility, file objects are handled differently
358
+ """)
359
+
360
+ # Connect events
361
+ single_btn.click(
362
+ fn=process_file,
363
+ inputs=[single_file, file_name_input, single_action],
364
+ outputs=[single_download, single_status]
365
+ )
366
+
367
+ multi_btn.click(
368
+ fn=process_multiple_files,
369
+ inputs=[multi_files, multi_action],
370
+ outputs=[multi_download, multi_status]
371
+ )
372
+
373
+ # Batch processing function
374
+ def process_batch(files, options, format_type, compression):
375
+ if not files:
376
+ return None, "❌ No files uploaded"
377
+
378
+ try:
379
+ temp_dir = tempfile.mkdtemp()
380
+ results = []
381
+
382
+ # Process based on options
383
+ if "Create combined ZIP" in options:
384
+ zip_name = f"combined{format_type}"
385
+ zip_path = os.path.join(temp_dir, zip_name)
386
+
387
+ if format_type == ".zip":
388
+ with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED, compresslevel=compression) as zipf:
389
+ for file_obj in files:
390
+ # Handle Gradio 6+ file object format
391
+ if isinstance(file_obj, dict):
392
+ file_path = file_obj["path"]
393
+ arcname = file_obj["name"]
394
+ else:
395
+ file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
396
+ arcname = os.path.basename(file_path)
397
+
398
+ if "Rename with timestamp" in options:
399
+ name, ext = os.path.splitext(arcname)
400
+ arcname = f"{name}_{int(time.time())}{ext}"
401
+ zipf.write(file_path, arcname)
402
+
403
+ results.append({
404
+ "path": zip_path,
405
+ "name": zip_name
406
+ })
407
+
408
+ if "Create individual ZIPs" in options:
409
+ for file_obj in files:
410
+ # Handle Gradio 6+ file object format
411
+ if isinstance(file_obj, dict):
412
+ file_path = file_obj["path"]
413
+ file_name = file_obj["name"]
414
+ else:
415
+ file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
416
+ file_name = os.path.basename(file_path)
417
+
418
+ base_name = os.path.splitext(file_name)[0]
419
+ if "Rename with timestamp" in options:
420
+ base_name = f"{base_name}_{int(time.time())}"
421
+
422
+ individual_zip_name = f"{base_name}{format_type}"
423
+ individual_zip_path = os.path.join(temp_dir, individual_zip_name)
424
+
425
+ if format_type == ".zip":
426
+ with zipfile.ZipFile(individual_zip_path, 'w', zipfile.ZIP_DEFLATED, compresslevel=compression) as zipf:
427
+ zipf.write(file_path, file_name)
428
+
429
+ results.append({
430
+ "path": individual_zip_path,
431
+ "name": individual_zip_name
432
+ })
433
+
434
+ # If multiple results, create a final zip
435
+ if len(results) > 1:
436
+ final_zip_name = f"batch_results{format_type}"
437
+ final_zip_path = os.path.join(temp_dir, final_zip_name)
438
+
439
+ with zipfile.ZipFile(final_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
440
+ for result in results:
441
+ zipf.write(result["path"], result["name"])
442
+
443
+ output_file = {
444
+ "path": final_zip_path,
445
+ "name": final_zip_name
446
+ }
447
+ elif results:
448
+ output_file = results[0]
449
+ else:
450
+ return None, "⚠️ No processing options selected"
451
+
452
+ return output_file, f"✅ Processed {len(files)} file(s) with {len(options)} option(s)"
453
+
454
+ except Exception as e:
455
+ return None, f"❌ Error: {str(e)}"
456
+
457
+ batch_btn.click(
458
+ fn=process_batch,
459
+ inputs=[batch_files, batch_options, batch_format, compression_level],
460
+ outputs=[batch_download, batch_status]
461
+ )
462
+
463
+ # Launch the app
464
+ if __name__ == "__main__":
465
+ iface.launch(
466
+ server_name="127.0.0.1",
467
+ server_port=7861, # Different port to avoid conflict
468
+ show_error=True,
469
+ share=False,
470
+ theme=gr.themes.Soft() # Moved theme here for Gradio 6+ compatibility
471
+ )