mbasaranoglu commited on
Commit
0a5b9f7
·
1 Parent(s): 4fa43d3

Make email optional and show results as HTML in Gradio - solves HuggingFace Spaces SMTP timeout issue

Browse files
Files changed (1) hide show
  1. app.py +58 -19
app.py CHANGED
@@ -838,7 +838,7 @@ def get_fetcher():
838
  logger.debug("[FETCHER] HTTP fetcher kullanılıyor")
839
  return http_fetcher
840
 
841
- def run_full_report():
842
  """Tam rapor çalıştırır (PHP tefas_daily_report.php'nin aynısı)"""
843
  logger.info("="*50)
844
  logger.info("[REPORT] Tam rapor başlatılıyor...")
@@ -862,7 +862,7 @@ def run_full_report():
862
  logger.info(f"[REPORT] HTTP fallback başarılı, {len(fon_data_list)} fon verisi çekildi")
863
  except Exception as e2:
864
  logger.error(f"[REPORT] HTTP fallback de başarısız: {str(e2)}")
865
- return f"❌ Veri çekilemedi!\n\nSelenium hatası: {str(e)}\nHTTP hatası: {str(e2)}\n\nDebug log: /tmp/tefas_debug.log"
866
 
867
  # Dict'e çevir
868
  fon_dict = {}
@@ -875,23 +875,47 @@ def run_full_report():
875
  portfolios = portfolio_calc.calculate_all_portfolios(fon_dict)
876
  logger.info(f"[REPORT] {len(portfolios)} portföy hesaplandı")
877
 
878
- # E-posta gönder
879
- logger.info(f"[REPORT] E-posta gönderiliyor: {config['email']['to_email']}")
880
  email_sender = EmailSender(config)
881
- result = email_sender.send_report(fon_dict, portfolios)
882
 
883
- if result['success']:
884
- basarili = sum(1 for f in fon_data_list if not f.get('error'))
885
- hatali = sum(1 for f in fon_data_list if f.get('error'))
886
- logger.info(f"[REPORT] Rapor başarıyla gönderildi! Başarılı: {basarili}, Hatalı: {hatali}")
887
- return f"✅ Rapor başarıyla gönderildi!\n\nBaşarılı fon: {basarili}, Hatalı fon: {hatali}\n\nAlıcı: {config['email']['to_email']}\n\nDebug log: /tmp/tefas_debug.log"
888
- else:
889
- logger.error(f"[REPORT] E-posta gönderilemedi: {result['message']}")
890
- return f" E-posta gönderilemedi: {result['message']}\n\nDebug log: /tmp/tefas_debug.log"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
891
 
892
  except Exception as e:
893
  logger.error(f"[REPORT] Genel hata: {str(e)}", exc_info=True)
894
- return f"❌ Hata oluştu: {str(e)}\n\nDebug log: /tmp/tefas_debug.log"
895
 
896
  def fetch_fund(fund_code):
897
  """Tek bir fon için veri çeker ve formatlar"""
@@ -954,12 +978,27 @@ with gr.Blocks(title="TEFAS Fon Takip", theme=gr.themes.Soft()) as app:
954
  """)
955
 
956
  with gr.Tabs():
957
- with gr.Tab("🚀 Tam Rapor (E-posta Gönder)"):
958
- gr.Markdown("### Tüm fonları çekip, portföy analizi yapıp e-posta gönderir")
959
- btn_full_report = gr.Button("📧 Tam Rapor Gönder", variant="primary", size="lg")
960
- output_full_report = gr.Textbox(label="Sonuç", lines=10)
 
 
 
 
 
961
 
962
- btn_full_report.click(fn=run_full_report, inputs=None, outputs=output_full_report)
 
 
 
 
 
 
 
 
 
 
963
 
964
  with gr.Tab("🔍 Tek Fon Sorgula"):
965
  fund_input_single = gr.Textbox(
 
838
  logger.debug("[FETCHER] HTTP fetcher kullanılıyor")
839
  return http_fetcher
840
 
841
+ def run_full_report(send_email=True):
842
  """Tam rapor çalıştırır (PHP tefas_daily_report.php'nin aynısı)"""
843
  logger.info("="*50)
844
  logger.info("[REPORT] Tam rapor başlatılıyor...")
 
862
  logger.info(f"[REPORT] HTTP fallback başarılı, {len(fon_data_list)} fon verisi çekildi")
863
  except Exception as e2:
864
  logger.error(f"[REPORT] HTTP fallback de başarısız: {str(e2)}")
865
+ return f"<div style='color: #e74c3c; padding: 20px; background: #ffe6e6; border-radius: 8px;'><strong>Veri çekilemedi!</strong><br><br>Selenium hatası: {escape(str(e))}<br>HTTP hatası: {escape(str(e2))}</div>"
866
 
867
  # Dict'e çevir
868
  fon_dict = {}
 
875
  portfolios = portfolio_calc.calculate_all_portfolios(fon_dict)
876
  logger.info(f"[REPORT] {len(portfolios)} portföy hesaplandı")
877
 
878
+ # Sonuçları HTML olarak oluştur
 
879
  email_sender = EmailSender(config)
880
+ html_content = email_sender.generate_html_email(fon_dict, portfolios)
881
 
882
+ # E-posta göndermeyi dene (opsiyonel)
883
+ email_result = None
884
+ if send_email:
885
+ logger.info(f"[REPORT] E-posta gönderiliyor: {config['email']['to_email']}")
886
+ try:
887
+ email_result = email_sender.send_report(fon_dict, portfolios)
888
+ if email_result['success']:
889
+ logger.info("[REPORT] E-posta başarıyla gönderildi")
890
+ else:
891
+ logger.warning(f"[REPORT] E-posta gönderilemedi: {email_result['message']}")
892
+ except Exception as e:
893
+ logger.warning(f"[REPORT] E-posta gönderme hatası (devam ediliyor): {str(e)}")
894
+ email_result = {'success': False, 'message': str(e)}
895
+
896
+ # Sonuç HTML'ine e-posta durumunu ekle
897
+ basarili = sum(1 for f in fon_data_list if not f.get('error'))
898
+ hatali = sum(1 for f in fon_data_list if f.get('error'))
899
+
900
+ status_html = f"""
901
+ <div style="background: #ecf0f1; padding: 15px; margin: 20px 0; border-radius: 8px; border-left: 4px solid #3498db;">
902
+ <h3 style="margin-top: 0; color: #2c3e50;">📊 Rapor Özeti</h3>
903
+ <p><strong>Başarılı fon:</strong> {basarili} | <strong>Hatalı fon:</strong> {hatali}</p>
904
+ <p><strong>Portföy sayısı:</strong> {len(portfolios)}</p>
905
+ {f"<p style='color: #27ae60;'><strong>✅ E-posta gönderildi:</strong> {config['email']['to_email']}</p>" if send_email and email_result and email_result.get('success') else ""}
906
+ {f"<p style='color: #e74c3c;'><strong>⚠️ E-posta gönderilemedi:</strong> {escape(email_result.get('message', 'Bilinmeyen hata') if email_result else 'E-posta gönderilmedi')}<br><small>HuggingFace Spaces dış SMTP bağlantılarını engelliyor olabilir. Sonuçlar aşağıda görüntülenebilir.</small></p>" if send_email and (not email_result or not email_result.get('success')) else ""}
907
+ {f"<p style='color: #7f8c8d;'><small>E-posta gönderilmedi (opsiyonel kapatıldı)</small></p>" if not send_email else ""}
908
+ </div>
909
+ """
910
+
911
+ # HTML içeriğini status ile birleştir
912
+ final_html = status_html + html_content
913
+
914
+ return final_html
915
 
916
  except Exception as e:
917
  logger.error(f"[REPORT] Genel hata: {str(e)}", exc_info=True)
918
+ return f"<div style='color: #e74c3c; padding: 20px; background: #ffe6e6; border-radius: 8px;'><strong>Hata oluştu:</strong><br><br>{escape(str(e))}</div>"
919
 
920
  def fetch_fund(fund_code):
921
  """Tek bir fon için veri çeker ve formatlar"""
 
978
  """)
979
 
980
  with gr.Tabs():
981
+ with gr.Tab("🚀 Tam Rapor"):
982
+ gr.Markdown("### Tüm fonları çekip, portföy analizi yapıp rapor oluşturur")
983
+
984
+ with gr.Row():
985
+ send_email_checkbox = gr.Checkbox(
986
+ label="E-posta Gönder (Opsiyonel - HuggingFace Spaces'te çalışmayabilir)",
987
+ value=False,
988
+ info="E-posta göndermeyi denemek için işaretleyin. HuggingFace Spaces dış SMTP bağlantılarını engelliyor olabilir."
989
+ )
990
 
991
+ btn_full_report = gr.Button("📊 Tam Rapor Oluştur", variant="primary", size="lg")
992
+ output_full_report = gr.HTML(label="Rapor")
993
+
994
+ def run_report_with_email(send_email):
995
+ return run_full_report(send_email=send_email)
996
+
997
+ btn_full_report.click(
998
+ fn=run_report_with_email,
999
+ inputs=send_email_checkbox,
1000
+ outputs=output_full_report
1001
+ )
1002
 
1003
  with gr.Tab("🔍 Tek Fon Sorgula"):
1004
  fund_input_single = gr.Textbox(