File size: 7,259 Bytes
f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e aa048d9 f011d3e 3168916 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | # app.py
# -*- coding: utf-8 -*-
import os
import sys
import streamlit as st
# ==========================
# Bootstrap de caminho (prioriza módulos locais do projeto)
# ==========================
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
if PROJECT_ROOT not in sys.path:
sys.path.insert(0, PROJECT_ROOT)
# ==========================
# Configurações básicas (compatível com 'Config' e 'config')
# ==========================
APP_TITLE = "Academia ARM — Cursos"
APP_ICON = "🎓"
APP_LAYOUT = "wide"
try:
# Primeiro tenta com 'Config' (maiúsculo)
from Config.settings import APP_TITLE as _TITLE, APP_ICON as _ICON, APP_LAYOUT as _LAYOUT
APP_TITLE, APP_ICON, APP_LAYOUT = _TITLE, _ICON, _LAYOUT
except ModuleNotFoundError:
try:
# Fallback para 'config' (minúsculo)
from config.settings import APP_TITLE as _TITLE, APP_ICON as _ICON, APP_LAYOUT as _LAYOUT
APP_TITLE, APP_ICON, APP_LAYOUT = _TITLE, _ICON, _LAYOUT
except ModuleNotFoundError:
# Mantém os defaults definidos acima
pass
# ==========================
# Configuração da página (deve vir antes de qualquer outro comando Streamlit)
# ==========================
st.set_page_config(page_title=APP_TITLE, page_icon=APP_ICON, layout=APP_LAYOUT)
# ==========================
# Utils.ensure_dirs (opcional)
# ==========================
def _try_import_utils():
try:
from utils import ensure_dirs # type: ignore
return ensure_dirs
except Exception as e:
st.warning(
"⚠️ Não foi possível importar `utils.ensure_dirs`. "
"Se você não precisa criar diretórios locais, pode ignorar. "
f"Detalhes: {e}"
)
return lambda: None # no-op
ensure_dirs = _try_import_utils()
# ==========================
# db.init_db (opcional) — caso você tenha um init local ou remoto
# ==========================
def _try_import_db():
try:
from db import init_db # type: ignore
return init_db
except Exception as e:
st.warning(
"⚠️ Não foi possível importar `db.init_db`. "
"Se você usa persistência via Hugging Face Dataset, "
"verifique o módulo `db.py` ou `database/hfdb.py`. "
f"Detalhes: {e}"
)
return lambda: None # no-op
init_db = _try_import_db()
# ==========================
# Integração com Hugging Face Dataset (opcional, recomendado)
# ==========================
def _try_import_hfdb():
try:
from database.hfdb import ensure_db_file, load_data, save_data # type: ignore
return ensure_db_file, load_data, save_data, None
except Exception as e:
return None, None, None, e
ensure_db_file, load_data, save_data, hfdb_err = _try_import_hfdb()
# ==========================
# Páginas
# ==========================
def _try_import_pages():
page_aluno = None
page_admin = None
aluno_err = admin_err = None
try:
import aluno as _aluno # type: ignore
page_aluno = _aluno
except Exception as e:
aluno_err = e
try:
import admin as _admin # type: ignore
page_admin = _admin
except Exception as e:
admin_err = e
return page_aluno, aluno_err, page_admin, admin_err
page_aluno, aluno_import_err, page_admin, admin_import_err = _try_import_pages()
# ==========================
# Boot do App
# ==========================
# Cria diretórios locais (se aplicável)
try:
ensure_dirs()
except Exception as e:
st.warning(f"⚠️ Falha ao preparar diretórios locais: {e}")
# Inicialização genérica (se existente)
try:
init_db()
except Exception as e:
st.error("❌ Falha ao inicializar o banco de dados/persistência (init_db).")
st.exception(e)
# Se hfdb estiver disponível, garante arquivo e carrega estado inicial
DB_STATE = None
if ensure_db_file and load_data:
try:
ensure_db_file()
DB_STATE = load_data()
except Exception as e:
st.error("❌ Não foi possível preparar/carregar o arquivo de banco no Dataset (HF).")
st.exception(e)
elif hfdb_err:
st.info(
"ℹ️ Persistência via Hugging Face Dataset não habilitada. "
"Crie `database/hfdb.py` e configure os Secrets/Variables para persistência."
)
# Estados padrão
st.session_state.setdefault("is_admin", False)
st.session_state.setdefault("admin_user", None)
st.session_state.setdefault("aluno_logged_in", False)
st.session_state.setdefault("aluno_nome", "")
st.session_state.setdefault("aluno_email", "")
st.session_state.setdefault("cal_ver", 0)
# ==========================
# (Opcional) Debug de ambiente — remova depois que tudo estiver OK
# ==========================
def _debug_env():
with st.expander("🔎 Debug rápido (ambiente)", expanded=False):
st.write("HF_DATASET_PATH:", os.getenv("HF_DATASET_PATH"))
st.write("HF_DB_FILE:", os.getenv("HF_DB_FILE"))
st.write("HF_TOKEN presente?:", bool(os.getenv("HF_TOKEN")))
st.write("hfdb import error:", str(hfdb_err) if hfdb_err else None)
st.write("DB_STATE inicial carregado?:", DB_STATE is not None)
# ==========================
# Router
# ==========================
def main() -> None:
st.title(APP_TITLE)
_debug_env() # pode remover depois
# Indica se houve problemas de import nas páginas
if aluno_import_err:
st.warning(f"⚠️ Módulo `aluno` não pôde ser carregado: {aluno_import_err}")
if admin_import_err:
st.warning(f"⚠️ Módulo `admin` não pôde ser carregado: {admin_import_err}")
# Exibe um snapshot mínimo dos dados (se hfdb estiver ativo)
if DB_STATE is not None:
with st.expander("🗄️ Snapshot do banco (somente leitura)", expanded=False):
try:
st.json(DB_STATE)
except Exception:
st.write(DB_STATE)
tab_aluno, tab_admin = st.tabs(["👩🎓 Aluno", "🛠️ Admin"])
with tab_aluno:
if page_aluno and hasattr(page_aluno, "render"):
try:
# Se a página do aluno quiser usar o estado/handlers de persistência:
# ela pode aceitar parâmetros (se você preferir esse padrão):
# page_aluno.render(DB_STATE, load_data, save_data)
page_aluno.render()
except Exception as e:
st.error("Ocorreu um erro ao carregar a aba **Aluno**. Os demais menus continuam disponíveis.")
st.exception(e)
else:
st.info("A aba **Aluno** ainda não está disponível. Verifique o arquivo `aluno.py` e a função `render()`.")
with tab_admin:
if page_admin and hasattr(page_admin, "render"):
try:
# Idem comentário acima — você pode padronizar assinatura: render(db, load_fn, save_fn)
page_admin.render()
except Exception as e:
st.error("Ocorreu um erro ao carregar a aba **Admin**.")
st.exception(e)
else:
st.info("A aba **Admin** ainda não está disponível. Verifique o arquivo `admin.py` e a função `render()`.")
if __name__ == "__main__":
main() |