Marek4321 commited on
Commit
c8adced
·
verified ·
1 Parent(s): d406562

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +159 -43
app.py CHANGED
@@ -24,7 +24,7 @@ from config import NVIDIA_THEME, DEFAULT_SETTINGS
24
 
25
  # Konfiguracja strony
26
  st.set_page_config(
27
- page_title="QualiInsightLab - FGI/IDI Research Analyzer",
28
  page_icon="🎙️",
29
  layout="wide",
30
  initial_sidebar_state="expanded"
@@ -101,19 +101,36 @@ class FGIIDIAnalyzer:
101
  if 'overall_progress' not in st.session_state:
102
  st.session_state.overall_progress = 0
103
 
104
- def log_message(self, message, level="INFO"):
105
- """Dodaj wiadomość do logów"""
106
  timestamp = datetime.now().strftime("%H:%M:%S")
107
  log_entry = f"[{timestamp}] {level}: {message}"
108
- st.session_state.logs.append(log_entry)
109
 
110
- # Ograniczenie liczby logów do 100
111
- if len(st.session_state.logs) > 100:
112
- st.session_state.logs = st.session_state.logs[-100:]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
  def render_sidebar(self):
115
  """Renderuj sidebar z konfiguracją"""
116
- st.sidebar.title("🎙️ FGI/IDI Analyzer")
117
  st.sidebar.markdown("---")
118
 
119
  # API Keys
@@ -183,7 +200,43 @@ class FGIIDIAnalyzer:
183
  'language': language
184
  }
185
 
186
- def cleanup_session(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  """Wyczyść sesję i pliki tymczasowe"""
188
  # Zatrzymaj przetwarzanie jeśli trwa
189
  if st.session_state.processing_status == 'running':
@@ -346,6 +399,9 @@ class FGIIDIAnalyzer:
346
  """Renderuj postęp przetwarzania"""
347
  progress_container = st.container()
348
 
 
 
 
349
  with progress_container:
350
  # Overall progress bar
351
  st.progress(st.session_state.overall_progress)
@@ -365,25 +421,30 @@ class FGIIDIAnalyzer:
365
  st.rerun()
366
 
367
  def process_files_async(self, settings):
368
- """Asynchroniczne przetwarzanie plików"""
369
  try:
370
- self.log_message("🚀 Rozpoczynam przetwarzanie plików")
371
 
372
  total_files = len(st.session_state.uploaded_files)
373
 
374
  # ETAP 1: Transkrypcja plików
375
  for i, file_info in enumerate(st.session_state.uploaded_files):
376
- if st.session_state.processing_status != 'running':
377
- self.log_message("⏹️ Przetwarzanie zatrzymane przez użytkownika")
378
- break
 
 
 
 
 
 
379
 
380
  try:
381
  # Update progress
382
  progress = i / (total_files + 1) # +1 for report generation
383
- st.session_state.overall_progress = progress
384
- st.session_state.current_file_progress = f"🎙️ Transkrybuję: {file_info['name']}"
385
 
386
- self.log_message(f"📝 Rozpoczynam transkrypcję: {file_info['name']}")
387
 
388
  # Przetwórz plik (kompresja/podział jeśli potrzeba)
389
  processed_files = self.file_handler.process_file(
@@ -400,7 +461,7 @@ class FGIIDIAnalyzer:
400
  for pf in processed_files:
401
  file_size_mb = os.path.getsize(pf) / (1024 * 1024)
402
  if file_size_mb > 25:
403
- self.log_message(f"⚠️ Część {pf} za duża: {file_size_mb:.1f}MB", "WARNING")
404
  else:
405
  valid_parts.append(pf)
406
 
@@ -414,47 +475,102 @@ class FGIIDIAnalyzer:
414
  )
415
 
416
  if transcription:
417
- st.session_state.transcriptions[file_info['name']] = transcription
418
- self.log_message(f"✅ Transkrypcja zakończona: {file_info['name']}")
419
  else:
420
- self.log_message(f"❌ Transkrypcja nieudana: {file_info['name']}", "ERROR")
421
 
422
  except Exception as e:
423
- self.log_message(f"❌ Błąd przetwarzania {file_info['name']}: {str(e)}", "ERROR")
424
  continue
425
 
426
  # ETAP 2: Generowanie raportu
427
- if st.session_state.transcriptions and st.session_state.processing_status == 'running':
428
- st.session_state.current_file_progress = "📄 Generuję raport badawczy..."
429
- st.session_state.overall_progress = 0.9
430
-
431
- self.log_message("📄 Rozpoczynam generowanie raportu")
432
 
 
433
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  final_report = self.report_generator.generate_comprehensive_report(
435
- st.session_state.transcriptions,
436
- st.session_state.research_brief
437
  )
438
 
439
- st.session_state.final_report = final_report
440
- st.session_state.processing_status = 'completed'
441
- st.session_state.overall_progress = 1.0
442
- st.session_state.current_file_progress = "✅ Zakończono!"
 
 
 
 
443
 
444
- self.log_message("🎉 Raport wygenerowany pomyślnie!")
 
445
 
446
- except Exception as e:
447
- self.log_message(f"❌ Błąd generowania raportu: {str(e)}", "ERROR")
 
 
 
 
 
 
 
 
448
  st.session_state.processing_status = 'error'
 
 
449
 
450
- else:
451
- if not st.session_state.transcriptions:
452
- self.log_message("❌ Brak transkrypcji do wygenerowania raportu", "ERROR")
453
- st.session_state.processing_status = 'error'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
 
455
  except Exception as e:
456
- self.log_message(f"💥 Błąd krytyczny: {str(e)}", "ERROR")
457
- st.session_state.processing_status = 'error'
458
 
459
  def render_results(self):
460
  """Renderuj wyniki"""
@@ -531,7 +647,7 @@ class FGIIDIAnalyzer:
531
  settings = self.render_sidebar()
532
 
533
  # Main content
534
- st.title("🎙️ FGI/IDI Research Analyzer")
535
  st.markdown("*Automatyczna transkrypcja i analiza wywiadów fokusowych oraz indywidualnych*")
536
  st.markdown("---")
537
 
 
24
 
25
  # Konfiguracja strony
26
  st.set_page_config(
27
+ page_title="QualiInsightLab",
28
  page_icon="🎙️",
29
  layout="wide",
30
  initial_sidebar_state="expanded"
 
101
  if 'overall_progress' not in st.session_state:
102
  st.session_state.overall_progress = 0
103
 
104
+ def log_message(self, message, level="INFO", force_local=False):
105
+ """Dodaj wiadomość do logów - thread-safe"""
106
  timestamp = datetime.now().strftime("%H:%M:%S")
107
  log_entry = f"[{timestamp}] {level}: {message}"
 
108
 
109
+ try:
110
+ # Sprawdź czy jesteśmy w głównym wątku Streamlit
111
+ if not force_local and 'logs' in st.session_state:
112
+ st.session_state.logs.append(log_entry)
113
+
114
+ # Ograniczenie liczby logów do 100
115
+ if len(st.session_state.logs) > 100:
116
+ st.session_state.logs = st.session_state.logs[-100:]
117
+ else:
118
+ # Fallback dla wątków - zapisz do lokalnej listy
119
+ if not hasattr(self, 'local_logs'):
120
+ self.local_logs = []
121
+ self.local_logs.append(log_entry)
122
+
123
+ # Wyświetl w konsoli jeśli jesteśmy w wątku
124
+ print(log_entry)
125
+
126
+ except Exception as e:
127
+ # Ostateczny fallback
128
+ print(f"LOG ERROR: {log_entry}")
129
+ print(f"LOG ERROR DETAILS: {e}")
130
 
131
  def render_sidebar(self):
132
  """Renderuj sidebar z konfiguracją"""
133
+ st.sidebar.title("🎙️ QualiInsightLab")
134
  st.sidebar.markdown("---")
135
 
136
  # API Keys
 
200
  'language': language
201
  }
202
 
203
+ def update_progress_safe(self, progress_value, status_message):
204
+ """Thread-safe aktualizacja postępu"""
205
+ try:
206
+ st.session_state.overall_progress = progress_value
207
+ st.session_state.current_file_progress = status_message
208
+ except:
209
+ # Fallback - wyświetl w konsoli
210
+ print(f"PROGRESS: {progress_value:.1%} - {status_message}")
211
+
212
+ def update_transcriptions_safe(self, filename, transcription):
213
+ """Thread-safe aktualizacja transkrypcji"""
214
+ try:
215
+ st.session_state.transcriptions[filename] = transcription
216
+ except:
217
+ # Fallback - zapisz do lokalnej zmiennej
218
+ if not hasattr(self, 'local_transcriptions'):
219
+ self.local_transcriptions = {}
220
+ self.local_transcriptions[filename] = transcription
221
+ print(f"TRANSCRIPTION: {filename} completed locally")
222
+
223
+ def sync_local_data(self):
224
+ """Synchronizuj dane lokalne z session_state"""
225
+ try:
226
+ # Przenies logi lokalne do session_state
227
+ if hasattr(self, 'local_logs'):
228
+ for log in self.local_logs:
229
+ st.session_state.logs.append(log)
230
+ self.local_logs = []
231
+
232
+ # Przenies transkrypcje lokalne do session_state
233
+ if hasattr(self, 'local_transcriptions'):
234
+ for filename, transcription in self.local_transcriptions.items():
235
+ st.session_state.transcriptions[filename] = transcription
236
+ self.local_transcriptions = {}
237
+
238
+ except Exception as e:
239
+ print(f"SYNC ERROR: {e}")
240
  """Wyczyść sesję i pliki tymczasowe"""
241
  # Zatrzymaj przetwarzanie jeśli trwa
242
  if st.session_state.processing_status == 'running':
 
399
  """Renderuj postęp przetwarzania"""
400
  progress_container = st.container()
401
 
402
+ # Synchronizuj dane z wątku
403
+ self.sync_local_data()
404
+
405
  with progress_container:
406
  # Overall progress bar
407
  st.progress(st.session_state.overall_progress)
 
421
  st.rerun()
422
 
423
  def process_files_async(self, settings):
424
+ """Asynchroniczne przetwarzanie plików - thread-safe"""
425
  try:
426
+ self.log_message("🚀 Rozpoczynam przetwarzanie plików", force_local=True)
427
 
428
  total_files = len(st.session_state.uploaded_files)
429
 
430
  # ETAP 1: Transkrypcja plików
431
  for i, file_info in enumerate(st.session_state.uploaded_files):
432
+ # Sprawdź status w bezpieczny sposób
433
+ try:
434
+ if st.session_state.processing_status != 'running':
435
+ self.log_message("⏹️ Przetwarzanie zatrzymane przez użytkownika", force_local=True)
436
+ return
437
+ except:
438
+ # Jeśli nie można sprawdzić statusu, zakończ
439
+ print("Cannot access session_state status - stopping")
440
+ return
441
 
442
  try:
443
  # Update progress
444
  progress = i / (total_files + 1) # +1 for report generation
445
+ self.update_progress_safe(progress, f"🎙️ Transkrybuję: {file_info['name']}")
 
446
 
447
+ self.log_message(f"📝 Rozpoczynam transkrypcję: {file_info['name']}", force_local=True)
448
 
449
  # Przetwórz plik (kompresja/podział jeśli potrzeba)
450
  processed_files = self.file_handler.process_file(
 
461
  for pf in processed_files:
462
  file_size_mb = os.path.getsize(pf) / (1024 * 1024)
463
  if file_size_mb > 25:
464
+ self.log_message(f"⚠️ Część {pf} za duża: {file_size_mb:.1f}MB", "WARNING", force_local=True)
465
  else:
466
  valid_parts.append(pf)
467
 
 
475
  )
476
 
477
  if transcription:
478
+ self.update_transcriptions_safe(file_info['name'], transcription)
479
+ self.log_message(f"✅ Transkrypcja zakończona: {file_info['name']}", force_local=True)
480
  else:
481
+ self.log_message(f"❌ Transkrypcja nieudana: {file_info['name']}", "ERROR", force_local=True)
482
 
483
  except Exception as e:
484
+ self.log_message(f"❌ Błąd przetwarzania {file_info['name']}: {str(e)}", "ERROR", force_local=True)
485
  continue
486
 
487
  # ETAP 2: Generowanie raportu
488
+ try:
489
+ # Sprawdź czy mamy transkrypcje (lokalnie lub w session_state)
490
+ transcriptions_to_use = {}
 
 
491
 
492
+ # Zbierz transkrypcje z session_state
493
  try:
494
+ transcriptions_to_use.update(st.session_state.transcriptions)
495
+ except:
496
+ pass
497
+
498
+ # Dodaj lokalne transkrypcje jeśli są
499
+ if hasattr(self, 'local_transcriptions'):
500
+ transcriptions_to_use.update(self.local_transcriptions)
501
+
502
+ if transcriptions_to_use:
503
+ self.update_progress_safe(0.9, "📄 Generuję raport badawczy...")
504
+ self.log_message("📄 Rozpoczynam generowanie raportu", force_local=True)
505
+
506
+ # Pobierz brief z session_state
507
+ try:
508
+ brief = st.session_state.research_brief
509
+ except:
510
+ brief = ""
511
+
512
  final_report = self.report_generator.generate_comprehensive_report(
513
+ transcriptions_to_use,
514
+ brief
515
  )
516
 
517
+ # Zapisz raport
518
+ try:
519
+ st.session_state.final_report = final_report
520
+ st.session_state.processing_status = 'completed'
521
+ except:
522
+ # Fallback - zapisz lokalnie
523
+ self.local_final_report = final_report
524
+ print("REPORT: Generated and saved locally")
525
 
526
+ self.update_progress_safe(1.0, " Zakończono!")
527
+ self.log_message("🎉 Raport wygenerowany pomyślnie!", force_local=True)
528
 
529
+ else:
530
+ self.log_message("❌ Brak transkrypcji do wygenerowania raportu", "ERROR", force_local=True)
531
+ try:
532
+ st.session_state.processing_status = 'error'
533
+ except:
534
+ print("ERROR: No transcriptions available")
535
+
536
+ except Exception as e:
537
+ self.log_message(f"❌ Błąd generowania raportu: {str(e)}", "ERROR", force_local=True)
538
+ try:
539
  st.session_state.processing_status = 'error'
540
+ except:
541
+ print(f"REPORT ERROR: {e}")
542
 
543
+ except Exception as e:
544
+ self.log_message(f"💥 Błąd krytyczny: {str(e)}", "ERROR", force_local=True)
545
+ try:
546
+ st.session_state.processing_status = 'error'
547
+ except:
548
+ print(f"CRITICAL ERROR: {e}")
549
+
550
+ def sync_local_data(self):
551
+ """Synchronizuj dane lokalne z session_state"""
552
+ try:
553
+ # Przenies logi lokalne do session_state
554
+ if hasattr(self, 'local_logs'):
555
+ for log in self.local_logs:
556
+ if 'logs' in st.session_state:
557
+ st.session_state.logs.append(log)
558
+ self.local_logs = []
559
+
560
+ # Przenies transkrypcje lokalne do session_state
561
+ if hasattr(self, 'local_transcriptions'):
562
+ for filename, transcription in self.local_transcriptions.items():
563
+ st.session_state.transcriptions[filename] = transcription
564
+ self.local_transcriptions = {}
565
+
566
+ # Przenies raport lokalny do session_state
567
+ if hasattr(self, 'local_final_report'):
568
+ st.session_state.final_report = self.local_final_report
569
+ st.session_state.processing_status = 'completed'
570
+ delattr(self, 'local_final_report')
571
 
572
  except Exception as e:
573
+ print(f"SYNC ERROR: {e}")
 
574
 
575
  def render_results(self):
576
  """Renderuj wyniki"""
 
647
  settings = self.render_sidebar()
648
 
649
  # Main content
650
+ st.title("🎙️ QualiInsightLab")
651
  st.markdown("*Automatyczna transkrypcja i analiza wywiadów fokusowych oraz indywidualnych*")
652
  st.markdown("---")
653