File size: 6,605 Bytes
8cc92c2
 
 
 
 
 
64c5bab
 
 
 
 
 
 
 
 
 
 
 
 
 
8cc92c2
 
 
64c5bab
 
 
 
8cc92c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64c5bab
 
 
 
8cc92c2
64c5bab
 
8cc92c2
 
 
 
 
 
 
 
 
 
 
 
64c5bab
8cc92c2
64c5bab
8cc92c2
 
 
 
 
 
 
 
 
 
64c5bab
8cc92c2
 
 
 
 
 
 
 
 
 
 
64c5bab
8cc92c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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>
"""

# --- Estilos CSS Customizados ---
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; }
"""

# --- Funções de Base de Dados ---

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()
    # Busca por parte do verbo OU parte da classe
    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):
    # evt.index[1] é o índice da coluna. 0 = Verbo, 1 = Classe.
    if evt.index[1] == 0:
        return gr.update() # Não faz nada se clicar na coluna do Verbo
    
    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>&nbsp; <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>&nbsp; {" ".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>"

# --- Interface Gradio ---

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"):
                
                # --- NOVO: Campo de busca por texto (idêntico à imagem) ---
                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)
                
                # Botões de Letras
                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"))

    # --- Eventos ---
    # Busca por texto (Enter ou Botão)
    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)

    # Letras e Ver Todas
    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()