File size: 18,597 Bytes
4117d94
6b42e0d
 
 
 
 
 
a5e365d
7278d33
 
a5e365d
7278d33
 
 
 
 
a5e365d
 
 
 
 
7278d33
a5e365d
7278d33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5e365d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4117d94
6b42e0d
4117d94
6b42e0d
 
 
 
 
 
 
 
 
4117d94
6b42e0d
 
 
4117d94
6b42e0d
 
 
 
 
 
4117d94
6b42e0d
 
 
 
 
 
4117d94
6b42e0d
 
 
 
 
 
4117d94
6b42e0d
 
 
 
 
4117d94
6b42e0d
 
 
 
 
4117d94
6b42e0d
 
 
 
 
4117d94
6b42e0d
 
 
 
 
 
a5e365d
 
 
 
 
 
 
 
 
 
 
 
 
 
7278d33
 
 
 
 
 
 
 
 
 
e95ab15
 
a5e365d
 
 
 
 
 
e95ab15
 
 
 
 
 
 
 
 
 
 
7278d33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e95ab15
7278d33
e95ab15
7278d33
e95ab15
a5e365d
 
 
e95ab15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5e365d
e95ab15
a5e365d
 
 
7278d33
 
 
 
 
 
 
 
a5e365d
7278d33
 
 
 
 
 
 
 
a5e365d
 
 
7278d33
 
 
 
 
 
 
 
 
a5e365d
7278d33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e95ab15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5e365d
e95ab15
 
 
 
7278d33
 
 
 
 
e95ab15
 
 
7278d33
a5e365d
 
 
 
 
e95ab15
a5e365d
 
 
 
 
 
 
 
7278d33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5e365d
e95ab15
 
 
a5e365d
 
e95ab15
a5e365d
 
 
 
 
 
 
 
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
import gradio as gr
from crewai import Task, LLM, Agent, Crew
from xhtml2pdf import pisa
import markdown
import tempfile
import os
import io
import hashlib
from supabase import create_client
import os

# Set up the Supabase client
# Replace these with your actual Supabase URL and key
SUPABASE_URL = "https://wlriuezvfrsqfkvalabq.supabase.co"
SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Indscml1ZXp2ZnJzcWZrdmFsYWJxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDA4ODA1OTAsImV4cCI6MjA1NjQ1NjU5MH0.syhO_hTeiJb3To4_jAn2h9kXl0uDw_noMXTOuQwnwgE"
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)

# Password hashing function
def hash_password(password):
    return hashlib.sha256(password.encode()).hexdigest()

# Login function using Supabase
def login(username, password):
    try:
        # Query the 'usuario' table in Supabase
        response = supabase.table('usuario').select('*').eq('login', username).execute()
        
        # Check if user exists and password matches
        if response.data and len(response.data) > 0:
            stored_hash = response.data[0].get('senha')
            if stored_hash == hash_password(password):
                return True, f"Bem-vindo, {username}!"
            else:
                return False, "Senha incorreta. Tente novamente."
        else:
            return False, "Usuário não encontrado. Tente novamente."
            
    except Exception as e:
        print(f"Error during login: {e}")
        return False, "Erro ao fazer login. Por favor, tente novamente."

# New registration function using Supabase
def register_user(username, password, confirm_password):
    try:
        # Check if passwords match
        if password != confirm_password:
            return False, "As senhas não coincidem. Tente novamente."
        
        # Check if username already exists
        response = supabase.table('usuario').select('*').eq('login', username).execute()
        if response.data and len(response.data) > 0:
            return False, "Nome de usuário já existe. Escolha outro."
        
        # Hash the password
        hashed_password = hash_password(password)
        
        # Insert new user
        response = supabase.table('usuario').insert({
            "login": username, 
            "senha": hashed_password
        }).execute()
        
        # Check if insertion was successful
        if response.data:
            return True, "Cadastro realizado com sucesso! Você pode fazer login agora."
        else:
            return False, "Erro ao cadastrar usuário. Tente novamente."
            
    except Exception as e:
        print(f"Error during registration: {e}")
        return False, "Erro ao realizar cadastro. Por favor, tente novamente."

# Function to create PDF from markdown
def markdown_to_pdf(markdown_text):
    """
    Convert markdown text to PDF content
    """
    # Convert markdown to HTML
    html_text = markdown.markdown(markdown_text)
    
    # Add some basic styling
    styled_html = f"""
    <html>
    <head>
        <style>
            body {{ font-family: Arial, sans-serif; margin: 20px; }}
            h1 {{ color: #2c3e50; }}
            h2 {{ color: #3498db; }}
            h3 {{ color: #2980b9; }}
            a {{ color: #3498db; }}
        </style>
    </head>
    <body>
        {html_text}
    </body>
    </html>
    """
    
    # Create PDF from HTML content
    pdf_output = io.BytesIO()
    pisa.CreatePDF(styled_html, dest=pdf_output)
    pdf_output.seek(0)
    
    return pdf_output

groqllm = LLM(model="groq/llama-3.3-70b-versatile")

def executar_equipe_interface(disciplina, assunto, topicos_str):
    # Converter a string de tópicos para uma lista
    topicos = [t.strip() for t in topicos_str.split(',') if t.strip()]
    
    solicitacao = {
        "disciplina": disciplina,
        "assunto": assunto,
        "topicos": topicos
    }

    disciplina = solicitacao['disciplina']
    assunto = solicitacao['assunto']
    topicos = ', '.join(solicitacao['topicos'])

    agentMotivador = Agent(
        role='Motivador',
        goal='Escrever uma mensagem motivacional para o estudante.',
        backstory='Você é um coach motivacional com experiência em ajudar estudantes a manterem o foco.',
        llm=groqllm
    )

    agentPlano = Agent(
        role='Coordenador de Estudos',
        goal=f'Sua tarefa é criar um plano de estudo estruturado com base nas seguintes informações: Disciplina: {disciplina}, Assunto: {assunto}, Tópicos: {topicos}',
        backstory='Você é um especialista em educação com experiência em criar planos de estudos eficientes.',
        llm=groqllm
    )

    agentMaterialVideo = Agent(
        role='Pesquisador de Material',
        goal=f'Sua tarefa é pesquisar no Youtube por vídeos que explique as Disciplina: {disciplina} sobre o Assunto: {assunto} e seus Tópicos: {topicos}',
        backstory='Você é um especialista em educação com experiência em criar planos de estudos eficientes.',
        llm=groqllm
    )

    tarefaMotivar =  Task(
        description='Escrever uma mensagem motivacional para o estudante.',
        agent=agentMotivador,
        expected_output='Dois parágrafos com uma Mensagem motivacional em markdown.',
    )

    tarefaGerarPlano = Task(
        description=f'Criar um plano de estudo estruturado com base nas seguintes informações: Disciplina: {disciplina}, Assunto: {assunto}, Tópicos: {topicos}.',
        agent=agentPlano,
        expected_output='Plano de estudos personalizado em markdown',
    )

    tarefaBuscarVideos = Task(
        description=f'Pesquisar no Youtube por vídeos que explique as Disciplina: {disciplina} sobre o Assunto: {assunto} e seus Tópicos: {topicos}',
        agent=agentMaterialVideo,
        expected_output='Lista de vídeos relacionados ao assunto em markdown.',
    )

    saida1 = agentMotivador.execute_task(tarefaMotivar)
    saida2 = agentPlano.execute_task(tarefaGerarPlano)
    saida3 = agentMaterialVideo.execute_task(tarefaBuscarVideos)

    saida_final = f"{saida1}\n\n{saida2}\n\n{saida3}"
    
    # Generate PDF from the output
    pdf_output = markdown_to_pdf(saida_final)
    
    # Save the PDF to a temporary file
    temp_dir = tempfile.gettempdir()
    pdf_filename = f"material_estudo_{hash_password(saida_final)[:8]}.pdf"
    pdf_path = os.path.join(temp_dir, pdf_filename)
    
    with open(pdf_path, 'wb') as f:
        f.write(pdf_output.getbuffer())
    
    return saida_final, pdf_path

def main_app():
    # Load CSS from external file
    css_path = os.path.join(os.path.dirname(__file__), "static", "styles.css")
    
    try:
        with open(css_path, "r") as css_file:
            custom_css = css_file.read()
    except FileNotFoundError:
        # Fallback in case the file is not found
        print(f"Warning: CSS file not found at {css_path}")
        custom_css = ""
    
    with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as app:
        # Authentication state
        is_logged_in = gr.State(False)
        current_user = gr.State("")

        # Login Interface
        with gr.Group(visible=True) as login_block:
            with gr.Column(elem_classes=["main-container"]):
                with gr.Row(elem_classes=["header"]):
                    gr.Markdown("# Sistema de Material de Estudo")
                    gr.Markdown("### Assistente Inteligente para Geração de Material Educacional")
                
                with gr.Column(elem_classes=["login-container"]):
                    gr.Markdown("### Login")
                    with gr.Group():
                        username_input = gr.Textbox(label="Usuário", placeholder="Digite seu nome de usuário")
                        password_input = gr.Textbox(label="Senha", type="password", placeholder="Digite sua senha")
                        login_message = gr.Textbox(label="", interactive=False, visible=False)
                        with gr.Row():
                            login_button = gr.Button("Entrar", variant="primary")
                    
                    with gr.Row(elem_classes=["register-link"]):
                        gr.Markdown("Não tem uma conta?")
                        register_nav_button = gr.Button("Cadastre-se", size="sm")
                        
                    with gr.Accordion("Informação", open=False):
                        gr.Markdown("""
                        Por favor insira suas credenciais para acessar o sistema.
                        """)
        
        # Registration Interface
        with gr.Group(visible=False) as register_block:
            with gr.Column(elem_classes=["main-container"]):
                with gr.Row(elem_classes=["header"]):
                    gr.Markdown("# Sistema de Material de Estudo")
                    gr.Markdown("### Cadastro de Novo Usuário")
                
                with gr.Column(elem_classes=["login-container"]):
                    with gr.Group():
                        new_username = gr.Textbox(label="Nome de Usuário", placeholder="Escolha um nome de usuário")
                        new_password = gr.Textbox(label="Senha", type="password", placeholder="Digite uma senha segura")
                        confirm_password = gr.Textbox(label="Confirmar Senha", type="password", placeholder="Digite a senha novamente")
                        register_message = gr.Textbox(label="", interactive=False, visible=False)
                        
                        with gr.Row():
                            back_button = gr.Button("Voltar", variant="secondary")
                            register_button = gr.Button("Cadastrar", variant="primary")
                    
                    with gr.Accordion("Informação", open=False):
                        gr.Markdown("""
                        Crie uma conta para acessar o sistema de geração de materiais de estudo.
                        """)

        # Main Application Interface
        with gr.Group(visible=False) as main_block:
            with gr.Column(elem_classes=["main-container"]):
                with gr.Row(elem_classes=["user-info"]):
                    user_display = gr.Markdown("Bem-vindo!")
                    logout_button = gr.Button("Sair", size="sm")
                
                gr.Markdown("# Gerador Inteligente de Material de Estudos")
                gr.Markdown("### Personalize seu material educacional completo em minutos")
                
                with gr.Column(elem_classes=["form-card"]):
                    gr.Markdown("### Dados do Material")
                    with gr.Row():
                        with gr.Column(scale=1):
                            disciplina_input = gr.Textbox(
                                label="Disciplina", 
                                placeholder="Ex: Matemática, Física, História...",
                                value="Matemática"
                            )
                        with gr.Column(scale=1):
                            assunto_input = gr.Textbox(
                                label="Assunto", 
                                placeholder="Ex: Funções, Leis de Newton, Segunda Guerra Mundial...",
                                value="Funções"
                            )
                    
                    topicos_input = gr.Textbox(
                        label="Tópicos (separados por vírgula)", 
                        placeholder="Ex: Função quadrática, Função exponencial, Função logarítmica...",
                        value="Função quadrática, Função exponencial, Função logarítmica",
                        lines=2
                    )
                
                with gr.Row():
                    generate_button = gr.Button("Gerar Material de Estudo", variant="primary", size="lg")
                
                # Progress indicator during generation
                with gr.Group(visible=False) as progress_group:
                    progress_bar = gr.Progress()
                    progress_text = gr.Markdown("Gerando material, por favor aguarde...")
                
                # Output tabs
                with gr.Tabs() as tabs:
                    with gr.TabItem("Visualizar Material"):
                        markdown_output = gr.Markdown(label="Material Completo")
                    
                    with gr.TabItem("Download"):
                        with gr.Column():
                            gr.Markdown("### Download do Material")
                            pdf_output = gr.File(label="Download PDF")
                            gr.Markdown("Clique no botão acima para baixar seu material em formato PDF.")

        # Login function with improved feedback
        def login_fn(username, password):
            success, message = login(username, password)
            if success:
                return [
                    gr.update(visible=False),  # login_block
                    gr.update(visible=True),   # main_block
                    gr.update(value=message, visible=False),  # login_message
                    f"**Usuário:** {username}",  # user_display
                    True,  # is_logged_in
                    username  # current_user
                ]
            else:
                return [
                    gr.update(visible=True),  # login_block
                    gr.update(visible=False),  # main_block
                    gr.update(value=message, visible=True),  # login_message
                    "",  # user_display
                    False,  # is_logged_in
                    ""  # current_user
                ]

        # Logout function
        def logout_fn():
            return [
                gr.update(visible=True),  # login_block
                gr.update(visible=False),  # main_block
                "",  # username_input
                "",  # password_input
                gr.update(value="", visible=False),  # login_message
                False,  # is_logged_in
                ""  # current_user
            ]
        
        # Registration function
        def register_fn(username, password, confirm_password):
            success, message = register_user(username, password, confirm_password)
            if success:
                # Return to login screen with success message
                return [
                    gr.update(visible=False),  # register_block
                    gr.update(visible=True),   # login_block
                    gr.update(value=message, visible=True),  # login_message
                    "",  # new_username
                    "",  # new_password
                    "",  # confirm_password
                    gr.update(value="", visible=False)  # register_message
                ]
            else:
                return [
                    gr.update(visible=True),  # register_block
                    gr.update(visible=False),  # login_block
                    gr.update(value="", visible=False),  # login_message
                    username,  # new_username (preserve input)
                    "",  # new_password
                    "",  # confirm_password
                    gr.update(value=message, visible=True)  # register_message
                ]
        
        # Navigation functions
        def show_register():
            return [
                gr.update(visible=False),  # login_block
                gr.update(visible=True),   # register_block
                gr.update(value="", visible=False)  # login_message
            ]
        
        def show_login():
            return [
                gr.update(visible=False),  # register_block
                gr.update(visible=True),   # login_block
                gr.update(value="", visible=False)  # register_message
            ]

        # Generate material function with progress tracking
        def generate_material(disciplina, assunto, topicos, progress=gr.Progress()):
            # Show progress during generation
            progress(0, desc="Iniciando geração do material...")
            
            # First phase - motivational content
            progress(0.25, desc="Gerando conteúdo motivacional...")
            
            # Second phase - study plan
            progress(0.5, desc="Elaborando plano de estudos...")
            
            # Third phase - gathering video resources
            progress(0.75, desc="Pesquisando recursos de vídeo...")
            
            # Execute the actual material generation
            markdown, pdf = executar_equipe_interface(disciplina, assunto, topicos)
            
            # Complete
            progress(1.0, desc="Material gerado com sucesso!")
            
            return [
                markdown,  # markdown_output
                pdf,  # pdf_output
                gr.update(visible=False)  # progress_group
            ]

        # Show progress during generation
        def show_progress():
            return gr.update(visible=True)  # progress_group

        # Connect buttons to functions
        login_button.click(
            login_fn,
            inputs=[username_input, password_input],
            outputs=[login_block, main_block, login_message, user_display, is_logged_in, current_user]
        )
        
        logout_button.click(
            logout_fn,
            outputs=[login_block, main_block, username_input, password_input, 
                     login_message, is_logged_in, current_user]
        )
        
        # Registration navigation buttons
        register_nav_button.click(
            show_register,
            outputs=[login_block, register_block, login_message]
        )
        
        back_button.click(
            show_login,
            outputs=[register_block, login_block, register_message]
        )
        
        # Registration form submission
        register_button.click(
            register_fn,
            inputs=[new_username, new_password, confirm_password],
            outputs=[register_block, login_block, login_message, new_username, 
                    new_password, confirm_password, register_message]
        )
        
        generate_button.click(
            show_progress,
            outputs=[progress_group]
        ).then(
            generate_material,
            inputs=[disciplina_input, assunto_input, topicos_input],
            outputs=[markdown_output, pdf_output, progress_group]
        )

    return app

# Launch the application
if __name__ == "__main__":
    app = main_app()
    app.launch()