acecalisto3 commited on
Commit
15fb404
·
verified ·
1 Parent(s): 68c65a0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +318 -318
app.py CHANGED
@@ -237,326 +237,326 @@ class FileProcessor:
237
  return []
238
 
239
 
240
- def generate_qr(json_data):
241
- """Generate QR code from JSON data and return the file path."""
242
- try:
243
- # Try first with automatic version selection
244
- qr = qrcode.QRCode(
245
- error_correction=qrcode.constants.ERROR_CORRECT_L,
246
- box_size=10,
247
- border=4,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  )
249
- qr.add_data(json_data)
250
- qr.make(fit=True)
251
-
252
- img = qr.make_image(fill_color="black", back_color="white")
253
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
254
- img.save(temp_file.name)
255
- return temp_file.name
256
- except Exception as e:
257
- # If the data is too large for a QR code
258
- logger.error(f"QR generation error: {e}")
259
- # Create a simple QR with error message
260
- qr = qrcode.QRCode(
261
- version=1,
262
- error_correction=qrcode.constants.ERROR_CORRECT_L,
263
- box_size=10,
264
- border=4,
265
  )
266
- qr.add_data("Error: Data too large for QR code")
267
- qr.make(fit=True)
268
-
269
- img = qr.make_image(fill_color="black", back_color="white")
270
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
271
- img.save(temp_file.name)
272
- return temp_file.name
273
-
274
-
275
- def create_interface():
276
- """Create a comprehensive Gradio interface with advanced features and styling"""
277
- css = """
278
- body {
279
- font-family: 'Inter', sans-serif;
280
- background: linear-gradient(to bottom, #08041C, #030712); /* Dark cosmic background */
281
- color: #ffffff;
282
- }
283
- .container {
284
- max-width: 1200px;
285
- margin: auto;
286
- background-color: rgba(255, 255, 255, 0.06);
287
- backdrop-filter: blur(12px);
288
- border: 1px solid rgba(255, 255, 255, 0.1);
289
- border-radius: 1rem;
290
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
291
- padding: 2rem;
292
- }
293
- h1 {
294
- color: #00FF00;
295
- text-align: center;
296
- text-shadow: 0 0 10px rgba(0, 255, 0, 0.8);
297
- }
298
- h2, h3, h4 {
299
- color: #FF9900;
300
- text-shadow: 0 0 10px rgba(255, 153, 0, 0.8);
301
- }
302
- .tab {
303
- background-color: rgba(255, 255, 255, 0.06);
304
- backdrop-filter: blur(12px);
305
- border: 1px solid rgba(255, 255, 255, 0.1);
306
- border-radius: 0.75rem;
307
- margin-bottom: 1rem;
308
- padding: 1.5rem;
309
- }
310
- .tab:hover {
311
- background-color: rgba(255, 255, 255, 0.1);
312
- }
313
- .warning {
314
- background-color: #fff3cd;
315
- color: #856404;
316
- border-radius: 0.5rem;
317
- padding: 1rem;
318
- margin-bottom: 1rem;
319
- }
320
- .error {
321
- background-color: #f8d7da;
322
- color: #721c24;
323
- border-radius: 0.5rem;
324
- padding: 1rem;
325
- margin-bottom: 1rem;
326
- }
327
- input[type="text"], input[type="file"] {
328
- width: 100%;
329
- padding: 0.75rem;
330
- border-radius: 0.5rem;
331
- background-color: rgba(0, 0, 0, 0.2);
332
- color: #ffffff;
333
- border: 1px solid #4a5568;
334
- font-size: 1rem;
335
- transition: border-color 0.3s ease;
336
- }
337
- input[type="text"]:focus, input[type="file"]:focus {
338
- outline: none;
339
- border-color: #00FF00;
340
- box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
341
- }
342
- .btn-primary {
343
- padding: 0.75rem 1.5rem;
344
- border-radius: 1.5rem;
345
- font-weight: 600;
346
- cursor: pointer;
347
- transition: transform 0.2s ease, box-shadow 0.2s ease, background-image 0.3s;
348
- background-image: linear-gradient(to right, #00FF00, #00A300);
349
- color: #000000;
350
- border: none;
351
- box-shadow: 0 0 8px rgba(0, 255, 0, 0.5);
352
- }
353
- .btn-primary:hover {
354
- transform: scale(1.05);
355
- box-shadow: 0 0 12px rgba(0, 255, 0, 0.7);
356
- background-image: linear-gradient(to right, #00A300, #007D00);
357
- }
358
- .btn-secondary {
359
- padding: 0.75rem 1.5rem;
360
- border-radius: 1.5rem;
361
- font-weight: 600;
362
- cursor: pointer;
363
- transition: transform 0.2s ease, box-shadow 0.2s ease, background-image 0.3s;
364
- background-image: linear-gradient(to right, #FF9900, #FF6600);
365
- color: #000000;
366
- border: none;
367
- box-shadow: 0 0 8px rgba(255, 153, 0, 0.5);
368
- }
369
- .btn-secondary:hover {
370
- transform: scale(1.05);
371
- box-shadow: 0 0 12px rgba(255, 153, 0, 0.7);
372
- background-image: linear-gradient(to right, #FF6600, #CC4700);
373
- }
374
- textarea {
375
- width: 100%;
376
- padding: 0.75rem;
377
- border-radius: 0.5rem;
378
- background-color: rgba(0, 0, 0, 0.2);
379
- color: #ffffff;
380
- border: 1px solid #4a5568;
381
- font-size: 1rem;
382
- transition: border-color 0.3s ease;
383
- min-height: 8rem;
384
- }
385
- textarea:focus {
386
- outline: none;
387
- border-color: #00FF00;
388
- box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
389
- }
390
- .output-box {
391
- background-color: rgba(0, 0, 0, 0.2);
392
- border: 1px solid #4a5568;
393
- border-radius: 0.5rem;
394
- padding: 1rem;
395
- overflow-x: auto;
396
- color: #ffffff;
397
- font-size: 1rem;
398
- white-space: pre-wrap;
399
- }
400
- #json-editor {
401
- background-color: rgba(0, 0, 0, 0.2);
402
- color: #ffffff;
403
- border: 1px solid #4a5568;
404
- border-radius: 0.5rem;
405
- padding: 1rem;
406
- font-size: 1rem;
407
- min-height: 20rem;
408
- }
409
- #json-editor:focus {
410
- outline: none;
411
- border-color: #00FF00;
412
- box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
413
- }
414
- #url-input {
415
- background-color: rgba(0, 0, 0, 0.2);
416
- color: #ffffff;
417
- border: 1px solid #4a5568;
418
- border-radius: 0.5rem;
419
- padding: 1rem;
420
- font-size: 1rem;
421
- min-height: 8rem;
422
- }
423
- #url-input:focus {
424
- outline: none;
425
- border-color: #00FF00;
426
- box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
427
- }
428
- #output-text{
429
- background-color: rgba(0, 0, 0, 0.2);
430
- color: #ffffff;
431
- border: 1px solid #4a5568;
432
- border-radius: 0.5rem;
433
- padding: 1rem;
434
- font-size: 1rem;
435
- }
436
- """
437
- with gr.Blocks(css=css, title="Advanced Text & URL Processor") as interface:
438
- gr.Markdown("# 🌐 Advanced URL & Text Processing Toolkit")
439
-
440
- with gr.Tab("URL Processing") as url_tab:
441
- url_input = gr.Textbox(
442
- label="Enter URLs (comma or newline separated)",
443
- lines=5,
444
- placeholder="https://example1.com\nhttps://example2.com",
445
- interactive=True,
446
- elem_id="url-input"
447
- )
448
-
449
- with gr.Tab("File Input") as file_tab:
450
- file_input = gr.File(
451
- label="Upload text file or ZIP archive",
452
- file_types=[".txt", ".zip", ".md", ".csv", ".json", ".xml"]
453
- )
454
-
455
- with gr.Tab("Text Input") as text_tab:
456
- text_input = gr.Textbox(
457
- label="Raw Text Input",
458
- lines=5,
459
- placeholder="Paste your text here...",
460
- interactive=True
461
- )
462
-
463
- with gr.Tab("JSON Editor") as json_tab:
464
- json_editor = gr.Textbox(
465
- label="JSON Editor",
466
- lines=20,
467
- placeholder="View and edit your JSON data here...",
468
- interactive=True,
469
- elem_id="json-editor"
470
- )
471
-
472
- with gr.Tab("Scratchpad") as scratchpad_tab:
473
- scratchpad = gr.Textbox(
474
- label="Scratchpad",
475
- lines=10,
476
- placeholder="Quick notes or text collections...",
477
- interactive=True
478
- )
479
-
480
- process_btn = gr.Button("Process Input", variant="primary")
481
- qr_btn = gr.Button("Generate QR Code", variant="secondary")
482
-
483
- output_text = gr.Textbox(label="Processing Results", interactive=False, elem_id="output-text")
484
- output_file = gr.File(label="Processed Output")
485
- qr_output = gr.Image(label="QR Code", type="filepath") # To display the generated QR code
486
-
487
- def process_all_inputs(urls, file, text, notes):
488
- """Process all input types with progress tracking"""
489
- try:
490
- processor = URLProcessor()
491
- file_processor = FileProcessor()
492
- results = []
493
- # Process URLs
494
- if urls:
495
- url_list = re.split(r'[,\n]', urls)
496
- url_list = [url.strip() for url in url_list if url.strip()]
497
- for url in url_list:
498
- validation = processor.validate_url(url)
499
- if validation.get('is_valid'):
500
- content = processor.fetch_content(url)
501
- if content:
502
- results.append({
503
- 'source': 'url',
504
- 'url': url,
505
- 'content': content,
506
- 'timestamp': datetime.now().isoformat()
507
- })
508
- # Process files
509
- if file:
510
- results.extend(file_processor.process_file(file))
511
- # Process text input
512
- if text:
513
- cleaned_text = processor.advanced_text_cleaning(text)
514
- results.append({
515
- 'source': 'direct_input',
516
- 'content': cleaned_text,
517
- 'timestamp': datetime.now().isoformat()
518
- })
519
- # Generate output
520
- if results:
521
- output_dir = Path('output') / datetime.now().strftime('%Y-%m-%d')
522
- output_dir.mkdir(parents=True, exist_ok=True)
523
- output_path = output_dir / f'processed_{int(time.time())}.json'
524
- with open(output_path, 'w', encoding='utf-8') as f:
525
- json.dump(results, f, ensure_ascii=False, indent=2)
526
- summary = f"Processed {len(results)} items successfully!"
527
- json_data = json.dumps(results, indent=2) # Prepare JSON for QR code
528
- return str(output_path), summary, json_data # Return JSON for editor
529
- else:
530
- return None, "No valid content to process.", ""
531
- except Exception as e:
532
- logger.error(f"Processing error: {e}")
533
- return None, f"Error: {str(e)}", ""
534
-
535
- def generate_qr_code(json_data):
536
- """Generate QR code from JSON data."""
537
- if not json_data:
538
- return "No data to encode."
539
- qr_file = generate_qr(json_data)
540
- return qr_file
541
-
542
- process_btn.click(
543
- process_all_inputs,
544
- inputs=[url_input, file_input, text_input, scratchpad],
545
- outputs=[output_file, output_text, json_editor]
546
  )
547
- qr_btn.click(generate_qr_code, inputs=[json_editor], outputs=[qr_output])
548
-
549
- gr.Markdown("""
550
- ### Usage Guidelines
551
- - **URL Processing**: Enter valid HTTP/HTTPS URLs, separated by commas or newlines.
552
- - **File Input**: Upload text files orZIP archives containing text files.
553
- - **Text Input**: Paste text directly for processing.
554
- - **JSON Editor**: View the processed data in JSON format. This is automatically updated after processing.
555
- - **Scratchpad**: Use this area for temporary notes or text snippets.
556
- - Click "Process Input" to analyze the data. The results will be available for download and in the JSON Editor.
557
- - Click "Generate QR Code" to create a QR code from the JSON data.
558
- """)
559
- return interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
 
561
 
562
  def main():
@@ -576,4 +576,4 @@ def main():
576
 
577
 
578
  if __name__ == "__main__":
579
- main()
 
237
  return []
238
 
239
 
240
+ def generate_qr(json_data):
241
+ """Generate QR code from JSON data and return the file path."""
242
+ try:
243
+ # Try first with automatic version selection
244
+ qr = qrcode.QRCode(
245
+ error_correction=qrcode.constants.ERROR_CORRECT_L,
246
+ box_size=10,
247
+ border=4,
248
+ )
249
+ qr.add_data(json_data)
250
+ qr.make(fit=True)
251
+
252
+ img = qr.make_image(fill_color="black", back_color="white")
253
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
254
+ img.save(temp_file.name)
255
+ return temp_file.name
256
+ except Exception as e:
257
+ # If the data is too large for a QR code
258
+ logger.error(f"QR generation error: {e}")
259
+ # Create a simple QR with error message
260
+ qr = qrcode.QRCode(
261
+ version=1,
262
+ error_correction=qrcode.constants.ERROR_CORRECT_L,
263
+ box_size=10,
264
+ border=4,
265
+ )
266
+ qr.add_data("Error: Data too large for QR code")
267
+ qr.make(fit=True)
268
+
269
+ img = qr.make_image(fill_color="black", back_color="white")
270
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
271
+ img.save(temp_file.name)
272
+ return temp_file.name
273
+
274
+
275
+ def create_interface():
276
+ """Create a comprehensive Gradio interface with advanced features and styling"""
277
+ css = """
278
+ body {
279
+ font-family: 'Inter', sans-serif;
280
+ background: linear-gradient(to bottom, #08041C, #030712); /* Dark cosmic background */
281
+ color: #ffffff;
282
+ }
283
+ .container {
284
+ max-width: 1200px;
285
+ margin: auto;
286
+ background-color: rgba(255, 255, 255, 0.06);
287
+ backdrop-filter: blur(12px);
288
+ border: 1px solid rgba(255, 255, 255, 0.1);
289
+ border-radius: 1rem;
290
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
291
+ padding: 2rem;
292
+ }
293
+ h1 {
294
+ color: #00FF00;
295
+ text-align: center;
296
+ text-shadow: 0 0 10px rgba(0, 255, 0, 0.8);
297
+ }
298
+ h2, h3, h4 {
299
+ color: #FF9900;
300
+ text-shadow: 0 0 10px rgba(255, 153, 0, 0.8);
301
+ }
302
+ .tab {
303
+ background-color: rgba(255, 255, 255, 0.06);
304
+ backdrop-filter: blur(12px);
305
+ border: 1px solid rgba(255, 255, 255, 0.1);
306
+ border-radius: 0.75rem;
307
+ margin-bottom: 1rem;
308
+ padding: 1.5rem;
309
+ }
310
+ .tab:hover {
311
+ background-color: rgba(255, 255, 255, 0.1);
312
+ }
313
+ .warning {
314
+ background-color: #fff3cd;
315
+ color: #856404;
316
+ border-radius: 0.5rem;
317
+ padding: 1rem;
318
+ margin-bottom: 1rem;
319
+ }
320
+ .error {
321
+ background-color: #f8d7da;
322
+ color: #721c24;
323
+ border-radius: 0.5rem;
324
+ padding: 1rem;
325
+ margin-bottom: 1rem;
326
+ }
327
+ input[type="text"], input[type="file"] {
328
+ width: 100%;
329
+ padding: 0.75rem;
330
+ border-radius: 0.5rem;
331
+ background-color: rgba(0, 0, 0, 0.2);
332
+ color: #ffffff;
333
+ border: 1px solid #4a5568;
334
+ font-size: 1rem;
335
+ transition: border-color 0.3s ease;
336
+ }
337
+ input[type="text"]:focus, input[type="file"]:focus {
338
+ outline: none;
339
+ border-color: #00FF00;
340
+ box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
341
+ }
342
+ .btn-primary {
343
+ padding: 0.75rem 1.5rem;
344
+ border-radius: 1.5rem;
345
+ font-weight: 600;
346
+ cursor: pointer;
347
+ transition: transform 0.2s ease, box-shadow 0.2s ease, background-image 0.3s;
348
+ background-image: linear-gradient(to right, #00FF00, #00A300);
349
+ color: #000000;
350
+ border: none;
351
+ box-shadow: 0 0 8px rgba(0, 255, 0, 0.5);
352
+ }
353
+ .btn-primary:hover {
354
+ transform: scale(1.05);
355
+ box-shadow: 0 0 12px rgba(0, 255, 0, 0.7);
356
+ background-image: linear-gradient(to right, #00A300, #007D00);
357
+ }
358
+ .btn-secondary {
359
+ padding: 0.75rem 1.5rem;
360
+ border-radius: 1.5rem;
361
+ font-weight: 600;
362
+ cursor: pointer;
363
+ transition: transform 0.2s ease, box-shadow 0.2s ease, background-image 0.3s;
364
+ background-image: linear-gradient(to right, #FF9900, #FF6600);
365
+ color: #000000;
366
+ border: none;
367
+ box-shadow: 0 0 8px rgba(255, 153, 0, 0.5);
368
+ }
369
+ .btn-secondary:hover {
370
+ transform: scale(1.05);
371
+ box-shadow: 0 0 12px rgba(255, 153, 0, 0.7);
372
+ background-image: linear-gradient(to right, #FF6600, #CC4700);
373
+ }
374
+ textarea {
375
+ width: 100%;
376
+ padding: 0.75rem;
377
+ border-radius: 0.5rem;
378
+ background-color: rgba(0, 0, 0, 0.2);
379
+ color: #ffffff;
380
+ border: 1px solid #4a5568;
381
+ font-size: 1rem;
382
+ transition: border-color 0.3s ease;
383
+ min-height: 8rem;
384
+ }
385
+ textarea:focus {
386
+ outline: none;
387
+ border-color: #00FF00;
388
+ box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
389
+ }
390
+ .output-box {
391
+ background-color: rgba(0, 0, 0, 0.2);
392
+ border: 1px solid #4a5568;
393
+ border-radius: 0.5rem;
394
+ padding: 1rem;
395
+ overflow-x: auto;
396
+ color: #ffffff;
397
+ font-size: 1rem;
398
+ white-space: pre-wrap;
399
+ }
400
+ #json-editor {
401
+ background-color: rgba(0, 0, 0, 0.2);
402
+ color: #ffffff;
403
+ border: 1px solid #4a5568;
404
+ border-radius: 0.5rem;
405
+ padding: 1rem;
406
+ font-size: 1rem;
407
+ min-height: 20rem;
408
+ }
409
+ #json-editor:focus {
410
+ outline: none;
411
+ border-color: #00FF00;
412
+ box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
413
+ }
414
+ #url-input {
415
+ background-color: rgba(0, 0, 0, 0.2);
416
+ color: #ffffff;
417
+ border: 1px solid #4a5568;
418
+ border-radius: 0.5rem;
419
+ padding: 1rem;
420
+ font-size: 1rem;
421
+ min-height: 8rem;
422
+ }
423
+ #url-input:focus {
424
+ outline: none;
425
+ border-color: #00FF00;
426
+ box-shadow: 0 0 5px rgba(0, 255, 0, 0.7);
427
+ }
428
+ #output-text{
429
+ background-color: rgba(0, 0, 0, 0.2);
430
+ color: #ffffff;
431
+ border: 1px solid #4a5568;
432
+ border-radius: 0.5rem;
433
+ padding: 1rem;
434
+ font-size: 1rem;
435
+ }
436
+ """
437
+ with gr.Blocks(css=css, title="Advanced Text & URL Processor") as interface:
438
+ gr.Markdown("# 🌐 Advanced URL & Text Processing Toolkit")
439
+
440
+ with gr.Tab("URL Processing") as url_tab:
441
+ url_input = gr.Textbox(
442
+ label="Enter URLs (comma or newline separated)",
443
+ lines=5,
444
+ placeholder="https://example1.com\nhttps://example2.com",
445
+ interactive=True,
446
+ elem_id="url-input"
447
  )
448
+
449
+ with gr.Tab("File Input") as file_tab:
450
+ file_input = gr.File(
451
+ label="Upload text file or ZIP archive",
452
+ file_types=[".txt", ".zip", ".md", ".csv", ".json", ".xml"]
 
 
 
 
 
 
 
 
 
 
 
453
  )
454
+
455
+ with gr.Tab("Text Input") as text_tab:
456
+ text_input = gr.Textbox(
457
+ label="Raw Text Input",
458
+ lines=5,
459
+ placeholder="Paste your text here...",
460
+ interactive=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  )
462
+
463
+ with gr.Tab("JSON Editor") as json_tab:
464
+ json_editor = gr.Textbox(
465
+ label="JSON Editor",
466
+ lines=20,
467
+ placeholder="View and edit your JSON data here...",
468
+ interactive=True,
469
+ elem_id="json-editor"
470
+ )
471
+
472
+ with gr.Tab("Scratchpad") as scratchpad_tab:
473
+ scratchpad = gr.Textbox(
474
+ label="Scratchpad",
475
+ lines=10,
476
+ placeholder="Quick notes or text collections...",
477
+ interactive=True
478
+ )
479
+
480
+ process_btn = gr.Button("Process Input", variant="primary")
481
+ qr_btn = gr.Button("Generate QR Code", variant="secondary")
482
+
483
+ output_text = gr.Textbox(label="Processing Results", interactive=False, elem_id="output-text")
484
+ output_file = gr.File(label="Processed Output")
485
+ qr_output = gr.Image(label="QR Code", type="filepath") # To display the generated QR code
486
+
487
+ def process_all_inputs(urls, file, text, notes):
488
+ """Process all input types with progress tracking"""
489
+ try:
490
+ processor = URLProcessor()
491
+ file_processor = FileProcessor()
492
+ results = []
493
+ # Process URLs
494
+ if urls:
495
+ url_list = re.split(r'[,\n]', urls)
496
+ url_list = [url.strip() for url in url_list if url.strip()]
497
+ for url in url_list:
498
+ validation = processor.validate_url(url)
499
+ if validation.get('is_valid'):
500
+ content = processor.fetch_content(url)
501
+ if content:
502
+ results.append({
503
+ 'source': 'url',
504
+ 'url': url,
505
+ 'content': content,
506
+ 'timestamp': datetime.now().isoformat()
507
+ })
508
+ # Process files
509
+ if file:
510
+ results.extend(file_processor.process_file(file))
511
+ # Process text input
512
+ if text:
513
+ cleaned_text = processor.advanced_text_cleaning(text)
514
+ results.append({
515
+ 'source': 'direct_input',
516
+ 'content': cleaned_text,
517
+ 'timestamp': datetime.now().isoformat()
518
+ })
519
+ # Generate output
520
+ if results:
521
+ output_dir = Path('output') / datetime.now().strftime('%Y-%m-%d')
522
+ output_dir.mkdir(parents=True, exist_ok=True)
523
+ output_path = output_dir / f'processed_{int(time.time())}.json'
524
+ with open(output_path, 'w', encoding='utf-8') as f:
525
+ json.dump(results, f, ensure_ascii=False, indent=2)
526
+ summary = f"Processed {len(results)} items successfully!"
527
+ json_data = json.dumps(results, indent=2) # Prepare JSON for QR code
528
+ return str(output_path), summary, json_data # Return JSON for editor
529
+ else:
530
+ return None, "No valid content to process.", ""
531
+ except Exception as e:
532
+ logger.error(f"Processing error: {e}")
533
+ return None, f"Error: {str(e)}", ""
534
+
535
+ def generate_qr_code(json_data):
536
+ """Generate QR code from JSON data."""
537
+ if not json_data:
538
+ return "No data to encode."
539
+ qr_file = generate_qr(json_data)
540
+ return qr_file
541
+
542
+ process_btn.click(
543
+ process_all_inputs,
544
+ inputs=[url_input, file_input, text_input, scratchpad],
545
+ outputs=[output_file, output_text, json_editor]
546
+ )
547
+ qr_btn.click(generate_qr_code, inputs=[json_editor], outputs=[qr_output])
548
+
549
+ gr.Markdown("""
550
+ ### Usage Guidelines
551
+ - **URL Processing**: Enter valid HTTP/HTTPS URLs, separated by commas or newlines.
552
+ - **File Input**: Upload text files or ZIP archives containing text files.
553
+ - **Text Input**: Paste text directly for processing.
554
+ - **JSON Editor**: View the processed data in JSON format. This is automatically updated after processing.
555
+ - **Scratchpad**: Use this area for temporary notes or text snippets.
556
+ - Click "Process Input" to analyze the data. The results will be available for download and in the JSON Editor.
557
+ - Click "Generate QR Code" to create a QR code from the JSON data.
558
+ """)
559
+ return interface
560
 
561
 
562
  def main():
 
576
 
577
 
578
  if __name__ == "__main__":
579
+ main()