Roudrigus commited on
Commit
2f9e3c9
·
verified ·
1 Parent(s): 12e31c8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -15
app.py CHANGED
@@ -1,4 +1,5 @@
1
  # -*- coding: utf-8 -*-
 
2
  import streamlit as st
3
  from dotenv import load_dotenv
4
  from datetime import date, datetime, time
@@ -57,7 +58,7 @@ from login import login
57
  from utils_permissoes import verificar_permissao
58
  from utils_layout import exibir_logo
59
  from modules_map import MODULES
60
- from banco import engine, Base, SessionLocal
61
  from models import QuizPontuacao
62
  from models import IOIRunSugestao
63
  from models import AvisoGlobal
@@ -536,6 +537,46 @@ def _show_birthday_banner_if_needed():
536
  unsafe_allow_html=True
537
  )
538
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  # ===============================
540
  # MAIN
541
  # ===============================
@@ -551,15 +592,18 @@ def main():
551
  st.session_state.user_responses_viewed = False
552
  if "nav_target" not in st.session_state:
553
  st.session_state.nav_target = None
554
-
555
- # ✅ Estado do intervalo de autoatualização (padrão aumentado p/ 60s; 0 = desligado)
556
  st.session_state.setdefault("__auto_refresh_interval_sec__", 60)
 
557
 
558
  # LOGIN
559
  if not st.session_state.logado:
560
  st.session_state.quiz_verificado = False
561
  exibir_logo(top=True, sidebar=False)
562
  login()
 
 
 
 
563
  return
564
 
565
  # 👥 Heartbeat + Badge de usuários logados (APENAS ADMIN)
@@ -580,14 +624,27 @@ def main():
580
  unsafe_allow_html=True
581
  )
582
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583
  # 🔄 Botão de Recarregar (mantém a sessão ativa) + ⏱️ Controle do intervalo
584
  st.sidebar.markdown("---")
585
- # Linha com botão de recarregar e popover para o intervalo
586
  col_reload, col_interval = st.sidebar.columns([1, 1])
587
  if col_reload.button("🔄 Recarregar (sem sair)", key="__btn_reload_now__"):
588
  st.rerun()
589
 
590
- # Popover (se disponível) para configurar intervalo; fallback para expander
591
  if hasattr(st, "popover"):
592
  with col_interval.popover("⏱️ Autoatualização"):
593
  new_val = st.number_input(
@@ -690,13 +747,11 @@ def main():
690
 
691
  # --- Usuário: respostas novas (após último 'visto') ---
692
  if perfil != "admin":
693
- # Última vez que o usuário realmente abriu e visualizou as respostas
694
  last_seen_dt = st.session_state.get("__user_last_answer_seen__")
695
 
696
  try:
697
  db = _get_db_session()
698
 
699
- # Qual é a resposta mais recente existente
700
  last_answer_dt_row = (
701
  db.query(IOIRunSugestao.data_resposta)
702
  .filter(
@@ -709,11 +764,9 @@ def main():
709
  )
710
  last_answer_dt = last_answer_dt_row[0] if last_answer_dt_row else None
711
 
712
- # Se há algo mais novo do que o 'visto', marcamos como não visto
713
  if last_answer_dt and (not last_seen_dt or last_answer_dt > last_seen_dt):
714
  st.session_state.user_responses_viewed = False
715
 
716
- # ✅ Conta SOMENTE respostas novas (depois do 'last_seen_dt')
717
  novas_respostas = (
718
  db.query(IOIRunSugestao)
719
  .filter(
@@ -731,7 +784,6 @@ def main():
731
  except Exception:
732
  pass
733
 
734
- # ✅ Exibir card de nova mensagem até o usuário clicar em "Ver respostas"
735
  if novas_respostas > 0 and not st.session_state.get("user_responses_viewed", False):
736
  st.sidebar.markdown(
737
  """
@@ -744,7 +796,6 @@ def main():
744
  unsafe_allow_html=True
745
  )
746
 
747
- # (Opcional) Toast discreto — aparece uma única vez por sessão enquanto houver novidade
748
  if not st.session_state.get("__user_toast_shown__"):
749
  try:
750
  st.toast("Você tem novas respostas do IOI‑RUN. Clique em '📥 Ver respostas'.", icon="💬")
@@ -753,12 +804,10 @@ def main():
753
  st.session_state["__user_toast_shown__"] = True
754
 
755
  if st.sidebar.button("📥 Ver respostas"):
756
- # Não atualizamos last_seen aqui; isso é feito dentro do módulo do usuário
757
  st.session_state.nav_target = "sugestoes_ioirun"
758
  st.session_state.user_responses_viewed = True
759
  st.rerun()
760
  else:
761
- # Se não há novidades, libera o toast para a próxima vez que houver
762
  st.session_state["__user_toast_shown__"] = False
763
 
764
  # ------------------------- Menu lateral -------------------------
@@ -888,7 +937,6 @@ def main():
888
  is_recebimento = (pagina_id == "recebimento")
889
  interval_sec = int(st.session_state.get("__auto_refresh_interval_sec__", 60))
890
  if (interval_sec > 0) and not (is_inbox_admin or is_outlook_rel or is_formulario or is_recebimento):
891
- # key dinâmica por intervalo evita conflitos ao trocar o valor
892
  st_autorefresh(interval=interval_sec * 1000, key=f"sidebar_autorefresh_{interval_sec}s")
893
  except Exception:
894
  pass
@@ -993,6 +1041,7 @@ Selecione o módulo abaixo ou navegue pelo menu — o conteúdo ajusta automatic
993
  st.session_state["nav_target"] = None
994
  st.session_state["__nav_lock__"] = False
995
 
 
996
  if __name__ == "__main__":
997
  main()
998
  # -------------------------
@@ -1018,4 +1067,4 @@ if __name__ == "__main__":
1018
  </p>
1019
  """,
1020
  unsafe_allow_html=True
1021
- )
 
1
  # -*- coding: utf-8 -*-
2
+ import os
3
  import streamlit as st
4
  from dotenv import load_dotenv
5
  from datetime import date, datetime, time
 
58
  from utils_permissoes import verificar_permissao
59
  from utils_layout import exibir_logo
60
  from modules_map import MODULES
61
+ from banco import engine, Base, SessionLocal, db_info
62
  from models import QuizPontuacao
63
  from models import IOIRunSugestao
64
  from models import AvisoGlobal
 
537
  unsafe_allow_html=True
538
  )
539
 
540
+
541
+ # ===============================
542
+ # 🔎 Painel de Diagnóstico de Autenticação (Admin)
543
+ # ===============================
544
+ def _render_auth_diag_panel():
545
+ """Renderiza informações de diagnóstico de autenticação (apenas Admin)."""
546
+ try:
547
+ info = db_info()
548
+ except Exception:
549
+ info = {"url": "(indisponível)", "using_router": _HAS_ROUTER}
550
+
551
+ st.sidebar.markdown("### 🔎 Diagnóstico de Autenticação")
552
+ st.sidebar.caption(f"DISABLE_AUTH = {os.getenv('DISABLE_AUTH')}")
553
+ st.sidebar.caption(f"ALLOW_EMERGENCY_LOGIN = {os.getenv('ALLOW_EMERGENCY_LOGIN')}")
554
+ st.sidebar.caption(f"EMERG_USER set? = {bool(os.getenv('EMERG_USER'))}")
555
+ st.sidebar.caption(f"EMERG_PASS_BCRYPT set? = {bool(os.getenv('EMERG_PASS_BCRYPT'))}")
556
+ st.sidebar.caption(f"DEMO_USER = {os.getenv('DEMO_USER') or '∅'}")
557
+ st.sidebar.caption(f"DEMO_PERFIL = {os.getenv('DEMO_PERFIL') or '∅'}")
558
+ st.sidebar.caption(f"DEMO_EMAIL = {os.getenv('DEMO_EMAIL') or '∅'}")
559
+
560
+ st.sidebar.caption(f"Router habilitado = {_HAS_ROUTER}")
561
+ try:
562
+ _b_label = bank_label(current_db_choice()) if _HAS_ROUTER else (
563
+ "🟢 Produção" if current_db_choice() == "prod" else "🔴 Teste"
564
+ )
565
+ st.sidebar.caption(f"Banco ativo (label) = {_b_label}")
566
+ except Exception as e:
567
+ st.sidebar.caption(f"Banco ativo (erro) = {e}")
568
+
569
+ st.sidebar.caption(f"DB URL = {info.get('url')}")
570
+ st.sidebar.caption(f"SessionState.logado = {st.session_state.get('logado')}")
571
+ st.sidebar.caption(f"SessionState.usuario = {st.session_state.get('usuario')}")
572
+ st.sidebar.caption(f"SessionState.perfil = {st.session_state.get('perfil')}")
573
+ try:
574
+ from login import login as _login_test # noqa: F401
575
+ st.sidebar.success("login.py importado ✅")
576
+ except Exception as e:
577
+ st.sidebar.error(f"Falha ao importar login.py: {e}")
578
+
579
+
580
  # ===============================
581
  # MAIN
582
  # ===============================
 
592
  st.session_state.user_responses_viewed = False
593
  if "nav_target" not in st.session_state:
594
  st.session_state.nav_target = None
 
 
595
  st.session_state.setdefault("__auto_refresh_interval_sec__", 60)
596
+ st.session_state.setdefault("__auth_diag__", False) # 🔧 estado do painel de diagnóstico (Admin)
597
 
598
  # LOGIN
599
  if not st.session_state.logado:
600
  st.session_state.quiz_verificado = False
601
  exibir_logo(top=True, sidebar=False)
602
  login()
603
+
604
+ # ⚠️ Opcional: dica breve quando nenhum caminho de auth está definido
605
+ if not os.getenv("DISABLE_AUTH") and not os.getenv("ALLOW_EMERGENCY_LOGIN"):
606
+ st.info("🔒 Autenticação ativa. Para testes rápidos no Spaces, defina **DISABLE_AUTH=1** ou habilite o **login emergencial** (ALLOW_EMERGENCY_LOGIN=1 + EMERG_*). Depois, **Restart this Space**.")
607
  return
608
 
609
  # 👥 Heartbeat + Badge de usuários logados (APENAS ADMIN)
 
624
  unsafe_allow_html=True
625
  )
626
 
627
+ # 🔘 Botão Admin: habilitar/desabilitar painel de diagnóstico
628
+ st.sidebar.markdown("---")
629
+ if st.session_state.get("__auth_diag__"):
630
+ if st.sidebar.button("🧪 Desativar diagnóstico de login (Admin)"):
631
+ st.session_state["__auth_diag__"] = False
632
+ st.rerun()
633
+ else:
634
+ if st.sidebar.button("🧪 Ativar diagnóstico de login (Admin)"):
635
+ st.session_state["__auth_diag__"] = True
636
+ st.rerun()
637
+
638
+ # Render do painel (se ativo)
639
+ if st.session_state.get("__auth_diag__"):
640
+ _render_auth_diag_panel()
641
+
642
  # 🔄 Botão de Recarregar (mantém a sessão ativa) + ⏱️ Controle do intervalo
643
  st.sidebar.markdown("---")
 
644
  col_reload, col_interval = st.sidebar.columns([1, 1])
645
  if col_reload.button("🔄 Recarregar (sem sair)", key="__btn_reload_now__"):
646
  st.rerun()
647
 
 
648
  if hasattr(st, "popover"):
649
  with col_interval.popover("⏱️ Autoatualização"):
650
  new_val = st.number_input(
 
747
 
748
  # --- Usuário: respostas novas (após último 'visto') ---
749
  if perfil != "admin":
 
750
  last_seen_dt = st.session_state.get("__user_last_answer_seen__")
751
 
752
  try:
753
  db = _get_db_session()
754
 
 
755
  last_answer_dt_row = (
756
  db.query(IOIRunSugestao.data_resposta)
757
  .filter(
 
764
  )
765
  last_answer_dt = last_answer_dt_row[0] if last_answer_dt_row else None
766
 
 
767
  if last_answer_dt and (not last_seen_dt or last_answer_dt > last_seen_dt):
768
  st.session_state.user_responses_viewed = False
769
 
 
770
  novas_respostas = (
771
  db.query(IOIRunSugestao)
772
  .filter(
 
784
  except Exception:
785
  pass
786
 
 
787
  if novas_respostas > 0 and not st.session_state.get("user_responses_viewed", False):
788
  st.sidebar.markdown(
789
  """
 
796
  unsafe_allow_html=True
797
  )
798
 
 
799
  if not st.session_state.get("__user_toast_shown__"):
800
  try:
801
  st.toast("Você tem novas respostas do IOI‑RUN. Clique em '📥 Ver respostas'.", icon="💬")
 
804
  st.session_state["__user_toast_shown__"] = True
805
 
806
  if st.sidebar.button("📥 Ver respostas"):
 
807
  st.session_state.nav_target = "sugestoes_ioirun"
808
  st.session_state.user_responses_viewed = True
809
  st.rerun()
810
  else:
 
811
  st.session_state["__user_toast_shown__"] = False
812
 
813
  # ------------------------- Menu lateral -------------------------
 
937
  is_recebimento = (pagina_id == "recebimento")
938
  interval_sec = int(st.session_state.get("__auto_refresh_interval_sec__", 60))
939
  if (interval_sec > 0) and not (is_inbox_admin or is_outlook_rel or is_formulario or is_recebimento):
 
940
  st_autorefresh(interval=interval_sec * 1000, key=f"sidebar_autorefresh_{interval_sec}s")
941
  except Exception:
942
  pass
 
1041
  st.session_state["nav_target"] = None
1042
  st.session_state["__nav_lock__"] = False
1043
 
1044
+
1045
  if __name__ == "__main__":
1046
  main()
1047
  # -------------------------
 
1067
  </p>
1068
  """,
1069
  unsafe_allow_html=True
1070
+ )