# gallery.py # -*- coding: utf-8 -*- import os from pathlib import Path import streamlit as st # ===== Config: suporta pasta 'Config' (maiúscula) e 'config' (minúscula) ===== try: from Config.settings import PAGE_SIZE_DEFAULT except Exception: try: from config.settings import PAGE_SIZE_DEFAULT except Exception: PAGE_SIZE_DEFAULT = 12 # fallback seguro # ===== Storage da galeria: tenta 'core.gallery_storage' e, se não houver 'core/', usa raiz ===== try: from core.gallery_storage import ( save_report_image, gallery_list_images_sorted, delete_report_image, ) except Exception: from gallery_storage import ( save_report_image, gallery_list_images_sorted, delete_report_image, ) def render_reports_gallery_uploader(key_prefix: str) -> None: """Uploader de imagens para a galeria (qualquer usuário).""" st.subheader("📤 Publicar foto do relatório") st.caption("Envie uma imagem (JPG/PNG/WEBP). Todos os usuários poderão visualizar na galeria.") uploader_name = "" uploader_email = "" if st.session_state.get("aluno_logged_in"): uploader_name = st.session_state.get("aluno_nome") or "" uploader_email = st.session_state.get("aluno_email") or "" elif st.session_state.get("is_admin"): uploader_name = st.session_state.get("admin_user") or "" col_name, _ = st.columns([2, 3]) name_input = col_name.text_input( "Seu nome (opcional)", value=uploader_name, max_chars=40, placeholder="Ex.: Rodrigo", key=f"{key_prefix}gallery_name_input", ) up = st.file_uploader( "Selecione a imagem do relatório", type=["png", "jpg", "jpeg", "webp"], accept_multiple_files=False, help="Dica: até ~5MB carrega mais rápido", key=f"{key_prefix}gallery_file_uploader", ) if up: try: st.image(up, caption="Pré-visualização", use_container_width=True) except Exception: st.info("Pré-visualização indisponível para este arquivo.") publish_col, _ = st.columns([1, 3]) if publish_col.button( "📌 Publicar", type="primary", use_container_width=True, disabled=(up is None), key=f"{key_prefix}gallery_publish_btn", ): if up is None: st.warning("Selecione uma imagem antes de publicar.") return try: saved = save_report_image( uploaded_file=up, uploader_name=(name_input or None), uploader_email=(uploader_email or None), ) if saved: st.success("Imagem publicada com sucesso!") st.rerun() except Exception as e: st.error(f"Falha ao salvar imagem: {e}") def render_reports_gallery_grid(page_size: int = PAGE_SIZE_DEFAULT, key_prefix: str = "") -> None: """Grade com miniaturas + download; exclusão apenas para Admin (server-side check).""" st.subheader("🖼️ Galeria de Relatórios") imgs = gallery_list_images_sorted() if not imgs: st.info("Ainda não há imagens publicadas.") return import math total = len(imgs) pages = max(1, math.ceil(total / page_size)) key_page = f"{key_prefix}gallery_page" st.session_state.setdefault(key_page, 1) cur_page = st.session_state[key_page] if cur_page > pages: cur_page = pages st.session_state[key_page] = cur_page if cur_page < 1: cur_page = 1 st.session_state[key_page] = cur_page col_left, col_center, col_right = st.columns([1, 3, 1]) with col_left: if st.button("⬅️", disabled=(cur_page <= 1), key=f"{key_prefix}gallery_nav_prev"): st.session_state[key_page] = max(1, cur_page - 1) st.rerun() with col_center: sel = st.selectbox( "Página", options=list(range(1, pages + 1)), index=cur_page - 1, key=f"{key_prefix}gallery_page_select", label_visibility="collapsed", ) if sel != cur_page: st.session_state[key_page] = sel st.rerun() with col_right: if st.button("➡️", disabled=(cur_page >= pages), key=f"{key_prefix}gallery_nav_next"): st.session_state[key_page] = min(pages, cur_page + 1) st.rerun() st.caption( f"Mostrando {page_size} por página — {total} imagens no total · " f"Página {st.session_state.get(key_page, 1)} de {pages}" ) start = (st.session_state[key_page] - 1) * page_size end = min(start + page_size, total) page_items = imgs[start:end] cols = st.columns(3) is_admin = bool(st.session_state.get("is_admin")) for i, (name, mtime, orig_path, thumb_path) in enumerate(page_items): col = cols[i % 3] with col: try: if Path(thumb_path).exists(): col.image(str(thumb_path), use_container_width=True, caption=name) else: col.image(str(orig_path), use_container_width=True, caption=name) except Exception: col.warning(f"Não foi possível carregar {name}.") continue # Download do original try: with open(orig_path, "rb") as f: mime = "image/jpeg" if name.lower().endswith((".jpg", ".jpeg")) else "image/png" st.download_button( label="⬇️ Baixar original", data=f, file_name=name, mime=mime, use_container_width=True, key=f"{key_prefix}dl_{name}", ) except Exception as e: col.warning(f"Download indisponível: {e}") # Exclusão — somente Admin (verificação também no servidor) if is_admin: if st.button("🗑️ Remover", key=f"{key_prefix}rm_{name}", type="secondary", use_container_width=True): try: delete_report_image(filename=name, is_admin=True) st.success("Imagem removida.") st.rerun() except PermissionError as e: st.error(str(e)) except Exception as e: st.error(f"Erro ao remover: {e}") else: st.caption("Somente Admin pode excluir.") def aba_galeria_relatorios(context_key: str) -> None: """Aba completa: upload + grid (keys isoladas por contexto).""" with st.container(border=True): render_reports_gallery_uploader(key_prefix=context_key) st.divider() render_reports_gallery_grid(page_size=PAGE_SIZE_DEFAULT, key_prefix=context_key)