| import gradio as gr |
| import sqlite3 |
| import os |
|
|
| DB = "verbnetbr.db" |
|
|
| head_content = """ |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> |
| <script> |
| // Força o modo claro no Gradio para evitar conflito de cores no celular |
| function forceLightMode() { |
| document.body.classList.remove('dark'); |
| document.documentElement.classList.remove('dark'); |
| } |
| // Executa ao carregar e monitora mudanças |
| window.onload = forceLightMode; |
| setInterval(forceLightMode, 1000); |
| </script> |
| """ |
|
|
| |
| css = """ |
| .top-header { background-color: #f8f9fa; border-bottom: 1px solid #dee2e6; } |
| .site-title { font-weight: bold; color: #114278 !important; margin: 0; } |
| .content-area { padding: 30px 10px; min-height: 400px; color: #212529 !important; } |
| /* Garante que o fundo do Gradio não fique preto no celular */ |
| .gradio-container { background-color: white !important; } |
| """ |
|
|
| |
|
|
| def buscar_por_texto(termo): |
| if not termo or len(termo.strip()) < 2: |
| return [["Aviso", "Digite pelo menos 2 caracteres para buscar."]] |
| |
| con = sqlite3.connect(DB) |
| cur = con.cursor() |
| |
| query = """ |
| SELECT verbo, classe FROM candidatos |
| WHERE (verbo LIKE ? OR classe LIKE ?) AND exp1=1 |
| ORDER BY verbo |
| """ |
| cur.execute(query, (f'%{termo}%', f'%{termo}%')) |
| rows = cur.fetchall() |
| con.close() |
| return [list(r) for r in rows] if rows else [["-", "Nenhum resultado encontrado"]] |
|
|
| def buscar_por_letra(letra): |
| con = sqlite3.connect(DB) |
| cur = con.cursor() |
| cur.execute("SELECT verbo, classe FROM candidatos WHERE verbo LIKE ? AND exp1=1 ORDER BY verbo", (letra+'%',)) |
| rows = cur.fetchall() |
| con.close() |
| return [list(r) for r in rows] |
|
|
| def buscar_todas_classes(): |
| con = sqlite3.connect(DB) |
| cur = con.cursor() |
| cur.execute("SELECT DISTINCT classe FROM candidatos WHERE exp1=1 ORDER BY classe") |
| rows = cur.fetchall() |
| con.close() |
| return [["-", r[0]] for r in rows] |
|
|
| def buscar_detalhes(evt: gr.SelectData): |
| |
| if evt.index[1] == 0: |
| return gr.update() |
| |
| classe = evt.value |
| if classe in ["-", "Nenhum resultado encontrado", "Aviso", ""]: |
| return "" |
| |
| con = sqlite3.connect(DB) |
| cur = con.cursor() |
| cur.execute("SELECT verbo FROM candidatos WHERE classe = ? AND exp1=1", (classe,)) |
| verbos = [r[0] for r in cur.fetchall()] |
| cur.execute("SELECT papel FROM papeis WHERE classe = ?", (classe,)) |
| papeis = [r[0] for r in cur.fetchall()] |
| cur.execute("SELECT alternancia, pingles, singles FROM classes WHERE classe = ?", (classe,)) |
| frames_rows = cur.fetchall() |
| con.close() |
|
|
| html = f""" |
| <div style='margin-top: 30px; border-top: 2px solid #114278; padding-top: 20px; color: #212529;'> |
| <center><h2 style="color: #114278;">{classe}</h2></center> |
| <b>Classe na VerbNet:</b> <a href="http://verbs.colorado.edu/verb-index/vn/{classe}.php" target="_blank" style="color: blue; text-decoration: underline;">{classe}</a><br><br> |
| <b>Papéis Temáticos:</b> {" ".join(papeis)}<br><br> |
| <b>Membros:</b> {", ".join(verbos)}<br><br> |
| <table style='width:100%; border-collapse: collapse;'> |
| <tr style='color: white; background-color: #114278;'> |
| <th style='padding: 10px; text-align: left;'>VerbNet.Br</th> |
| <th style='width: 5%; background-color: white;'></th> |
| <th style='padding: 10px; text-align: left;'>VerbNet</th> |
| </tr> |
| """ |
| for alt, ping, sing in frames_rows: |
| html += f"<tr><td style='padding:10px; border-bottom:1px solid #ddd;'>{alt}</td><td style='background-color: white;'></td><td style='padding:10px; border-bottom:1px solid #ddd;'>{ping} - {sing}</td></tr>" |
| html += "</table></div>" |
| return html |
|
|
| def carregar_html(nome_arquivo): |
| if os.path.exists(nome_arquivo): |
| with open(nome_arquivo, "r", encoding="utf-8") as f: |
| return f.read() |
| return f"<p>Arquivo {nome_arquivo} não encontrado.</p>" |
|
|
| |
|
|
| with gr.Blocks(css=css, head=head_content) as demo: |
| |
| gr.HTML('<header class="top-header py-4"><div class="container"><h1 class="site-title">VerbNet.Br 1.0</h1></div></header>') |
|
|
| with gr.Tabs(): |
| with gr.TabItem("Home"): |
| gr.HTML(carregar_html("index.html")) |
|
|
| with gr.TabItem("Busca"): |
| with gr.Column(elem_classes="container content-area"): |
| |
| |
| with gr.Column(elem_classes="search-container"): |
| gr.HTML('<h3 style="margin-bottom:15px; font-size: 1.2rem; color: #2d5a27;">Digite parte de um verbo ou de uma classe da VerbNet.Br:</h3>') |
| with gr.Row(): |
| input_texto = gr.Textbox(show_label=False, placeholder="Ex: correr, consider...", scale=4) |
| btn_buscar = gr.Button("Buscar", variant="primary", scale=1) |
| |
| |
| gr.HTML('<p style="margin-bottom:5px;">Ou selecione pela letra inicial do verbo:</p>') |
| with gr.Row(): |
| letras = "ABCDEFGHILMNOPQRSTUVXZ" |
| btns_alfabeto = [gr.Button(l, elem_classes="alphabet-btn", min_width=35) for l in letras] |
| |
| btn_todas = gr.Button("Ver Todas as Classes da VerbNet.Br", variant="secondary") |
|
|
| saida_letra = gr.Dataframe(headers=["Verbo", "Classe"], interactive=False) |
| saida_classe = gr.HTML() |
|
|
| with gr.TabItem("Publicações"): |
| gr.HTML(carregar_html("publicacoes.html")) |
|
|
| with gr.TabItem("Contato"): |
| gr.HTML(carregar_html("contato.html")) |
|
|
| |
| |
| btn_buscar.click(fn=buscar_por_texto, inputs=input_texto, outputs=saida_letra) |
| input_texto.submit(fn=buscar_por_texto, inputs=input_texto, outputs=saida_letra) |
|
|
| |
| for btn, letra in zip(btns_alfabeto, letras): |
| btn.click(fn=lambda l=letra: buscar_por_letra(l), outputs=saida_letra) |
| |
| btn_todas.click(fn=buscar_todas_classes, outputs=saida_letra) |
| saida_letra.select(fn=buscar_detalhes, outputs=saida_classe) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|