Update app.py
Browse files
app.py
CHANGED
|
@@ -38,16 +38,19 @@ CONFIG = {
|
|
| 38 |
rate_limiter = RateLimiter(max_calls=60, period=60)
|
| 39 |
|
| 40 |
DICAS_OAB = {
|
| 41 |
-
"Endereçamento": "Em relações de consumo, prefira o foro do domicílio do autor (
|
| 42 |
"Qualificação": "Mencione nome, estado civil (se informado), endereço (use 'Rua XXX' se não fornecido).",
|
| 43 |
"Fatos": "Descreva os fatos cronologicamente, sem inventar informações.",
|
| 44 |
"Pedidos": "Seja específico nos pedidos (ex.: 'condenação ao pagamento de R$ X').",
|
| 45 |
-
"Custas": "Inclua 'Requer a juntada da guia de custas devidamente recolhida'."
|
|
|
|
|
|
|
| 46 |
}
|
| 47 |
|
| 48 |
HISTORICO = []
|
| 49 |
CORRECAO_CACHE = {}
|
| 50 |
|
|
|
|
| 51 |
def preprocess_image_for_ocr(img):
|
| 52 |
try:
|
| 53 |
gray = img.convert('L')
|
|
@@ -166,20 +169,21 @@ def process_file(file_obj):
|
|
| 166 |
except Exception as e:
|
| 167 |
return f"❌ Erro ao processar o arquivo: {str(e)}"
|
| 168 |
|
|
|
|
| 169 |
def calcular_pontuacao(enderecamento, fundamentos, pedidos, fechamento):
|
| 170 |
tabela = [
|
| 171 |
("**Endereçamento**", ""),
|
| 172 |
("1. Correto endereçamento ao juízo competente", f"{enderecamento[0]:.2f} / 0,10"),
|
| 173 |
-
("2. Qualificação das partes
|
| 174 |
("**Fundamentos**", ""),
|
| 175 |
-
("3. Exposição clara dos fatos", f"{fundamentos[0]:.2f} / 0,20"),
|
| 176 |
("4. Fundamentação jurídica adequada", f"{fundamentos[1]:.2f} / 0,25"),
|
| 177 |
-
("5. Demonstração de ilícito e dano", f"{fundamentos[2]:.2f} / 0,25"),
|
| 178 |
("**Pedidos**", ""),
|
| 179 |
-
("6. Pedidos claros e específicos", f"{pedidos[0]:.2f} / 0,30"),
|
| 180 |
-
("7. Valor da causa indicado", f"{pedidos[1]:.2f} / 0,10"),
|
| 181 |
-
("8. Provas pretendidas
|
| 182 |
-
("9. Opção sobre audiência
|
| 183 |
("10. Pedido de citação do réu", f"{pedidos[4]:.2f} / 0,10"),
|
| 184 |
("11. Juntada da guia de custas", f"{pedidos[5]:.2f} / 0,10"),
|
| 185 |
("**Fechamento**", ""),
|
|
@@ -192,17 +196,18 @@ def calcular_pontuacao(enderecamento, fundamentos, pedidos, fechamento):
|
|
| 192 |
def validar_peticao_basica(peticao):
|
| 193 |
problemas = []
|
| 194 |
if "EXCELENTÍSSIMO" not in peticao.upper():
|
| 195 |
-
problemas.append("⚠️ Endereçamento ausente ou incompleto.")
|
| 196 |
if "Art. 319" not in peticao and "CPC" not in peticao:
|
| 197 |
-
problemas.append("⚠️ Fundamentação jurídica não menciona o CPC.")
|
| 198 |
if "Dá-se à causa o valor" not in peticao:
|
| 199 |
problemas.append("⚠️ Valor da causa não especificado (Art. 319, V, CPC).")
|
| 200 |
if "juntada da guia de custas" not in peticao.lower():
|
| 201 |
-
problemas.append("⚠️ Pedido de juntada da guia de custas ausente.")
|
| 202 |
if "Nestes termos" not in peticao:
|
| 203 |
problemas.append("⚠️ Fechamento formal ausente.")
|
| 204 |
return problemas
|
| 205 |
|
|
|
|
| 206 |
def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
| 207 |
base_prompt = f"""
|
| 208 |
## Correção Rigorosa de Petição Inicial Cível (Critérios Realistas da OAB)
|
|
@@ -214,12 +219,12 @@ def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
|
| 214 |
### Análise da Petição
|
| 215 |
1. Análise Geral (Breve visão geral sobre a petição - máximo 3 linhas)
|
| 216 |
2. Nota Final (0 a 10 com uma casa decimal)
|
| 217 |
-
3. Pontos Positivos (Liste pelo menos 3 aspectos bem executados)
|
| 218 |
-
4. Pontos a Melhorar (Liste os problemas encontrados em ordem de gravidade)
|
| 219 |
5. Análise Específica dos Requisitos:
|
| 220 |
-
- Endereçamento e qualificação do juízo
|
| 221 |
- Qualificação das partes (Art. 319, II, CPC)
|
| 222 |
-
- Fatos e fundamentos jurídicos (Art. 319, III, CPC)
|
| 223 |
- Pedidos com especificações (Art. 319, IV, CPC)
|
| 224 |
- Valor da causa (Art. 319, V, CPC)
|
| 225 |
- Provas com que o autor pretende demonstrar a verdade dos fatos (Art. 319, VI, CPC)
|
|
@@ -236,7 +241,7 @@ def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
|
| 236 |
6. A frase "Nestes termos, pede deferimento" com vírgula é incorreta; corrija para "Nestes termos pede deferimento" e destaque o erro na análise
|
| 237 |
7. A petição deve finalizar com "Local e data.\nADVOGADO.\nOAB." sem identificação do aluno (nome, número ou estado na OAB); se houver identificação específica (ex.: número ou estado), zere a nota (0,0)
|
| 238 |
**Instruções Especiais para Endereçamento:**
|
| 239 |
-
- CPC (
|
| 240 |
- Avalie o contexto: priorize o foro do autor em casos consumeristas.
|
| 241 |
**Pontuação Detalhada:**
|
| 242 |
Inclua uma tabela com:
|
|
@@ -263,11 +268,11 @@ def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
|
| 263 |
---
|
| 264 |
|
| 265 |
### Petição Corrigida
|
| 266 |
-
Forneça a petição do aluno reescrita com todas as correções aplicadas, incluindo partes omitidas (como pedidos ou custas) e ajustando erros identificados nos "Pontos a Melhorar" e "Análise Específica". Use apenas informações do caso e fundamente com leis brasileiras relevantes (ex.: CPC, CDC). Estruture a petição corrigida com:
|
| 267 |
1. Endereçamento correto
|
| 268 |
2. Qualificação completa (Art. 319, II, CPC)
|
| 269 |
3. Fatos claros (Art. 319, III, CPC)
|
| 270 |
-
4. Fundamentação jurídica (ex.: CPC, CDC)
|
| 271 |
5. Pedidos específicos (Art. 319, IV, CPC)
|
| 272 |
6. Valor da causa (Art. 319, V, CPC)
|
| 273 |
7. Provas (Art. 319, VI, CPC)
|
|
@@ -284,10 +289,13 @@ def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
|
| 284 |
b) Uma sugestão de redação corrigida baseada no caso.
|
| 285 |
c) Um exemplo prático de redação correta em outro contexto (ex.: "Em uma ação de dano moral, poderia ser: 'Requer a condenação ao pagamento de R$ 10.000,00 por danos morais, conforme Súmula 387 do STJ.'").
|
| 286 |
d) Uma dica prática do banco ({json.dumps(DICAS_OAB)}) ou personalizada.
|
|
|
|
|
|
|
| 287 |
- Não resuma; detalhe cada erro de forma pedagógica e clara.
|
| 288 |
"""
|
| 289 |
return base_prompt
|
| 290 |
|
|
|
|
| 291 |
def estruturar_prompt_geracao_caso():
|
| 292 |
return """
|
| 293 |
Crie um caso fictício detalhado para uma petição inicial cível, similar ao exemplo:
|
|
@@ -403,6 +411,8 @@ def corrigir_peticao(caso, peticao_texto=None, peticao_arquivo=None, modo_treina
|
|
| 403 |
"peticao": peticao_conteudo,
|
| 404 |
"correcao_completa": correção_completa
|
| 405 |
})
|
|
|
|
|
|
|
| 406 |
CORRECAO_CACHE[cache_key] = correção_formatada
|
| 407 |
return aviso_validacao + correção_formatada
|
| 408 |
except requests.Timeout:
|
|
@@ -418,6 +428,7 @@ def corrigir_peticao(caso, peticao_texto=None, peticao_arquivo=None, modo_treina
|
|
| 418 |
except Exception as e:
|
| 419 |
return aviso_validacao + f"❌ Erro inesperado: {str(e)}"
|
| 420 |
|
|
|
|
| 421 |
def formatar_correção(texto):
|
| 422 |
linhas = texto.split('\n')
|
| 423 |
texto_formatado = ""
|
|
@@ -431,7 +442,7 @@ def formatar_correção(texto):
|
|
| 431 |
elif "Pontos a Melhorar" in linha:
|
| 432 |
texto_formatado += f"### ⚠️ {linha.strip()}\n\n"
|
| 433 |
elif "- Invenção de fatos" in linha:
|
| 434 |
-
texto_formatado += f"**🔴 {linha.strip()}**\n"
|
| 435 |
elif linha.strip().startswith('-') and len(linha) > 2 and any(termo in linha for termo in ["Endereçamento", "Qualificação", "Fatos", "Pedidos", "Valor", "Provas"]):
|
| 436 |
texto_formatado += f"**{linha.strip()}**\n"
|
| 437 |
elif "Explicação" in linha or "Sugestão" in linha or "Dica" in linha or "Exemplo" in linha:
|
|
@@ -479,6 +490,7 @@ def calcular_progresso():
|
|
| 479 |
tendencia = "⬆️ Melhorando" if len(notas) > 1 and notas[-1] > notas[-2] else "⬇️ Estável ou piorando"
|
| 480 |
return f"📊 Progresso: Média {media:.1f}/10 | Tentativas: {len(notas)} | Tendência: {tendencia}"
|
| 481 |
|
|
|
|
| 482 |
def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
| 483 |
if not caso:
|
| 484 |
return "⚠️ Forneça um caso antes de comparar.", "", "", "", ""
|
|
@@ -511,12 +523,12 @@ def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
|
| 511 |
elif linha.startswith('- '):
|
| 512 |
texto = linha[2:]
|
| 513 |
if any(kw in texto.lower() for kw in ["invenção", "custas", "art. 319"]):
|
| 514 |
-
criticas.append(f"🔴 REMOVIDO: {texto}")
|
| 515 |
resultado_diff.append(f"<div class='linha-removida'><del>{escape(texto)}</del></div>")
|
| 516 |
elif linha.startswith('+ '):
|
| 517 |
texto = linha[2:]
|
| 518 |
if any(kw in texto.lower() for kw in ["custas", "art. 319"]):
|
| 519 |
-
criticas.append(f"🟢 ADICIONADO: {texto}")
|
| 520 |
resultado_diff.append(f"<div class='linha-adicionada'><ins>{escape(texto)}</ins></div>")
|
| 521 |
elif linha.startswith('? '):
|
| 522 |
continue
|
|
@@ -542,6 +554,7 @@ Diferença Líquida: {total_adicionadas - total_removidas} linhas
|
|
| 542 |
"""
|
| 543 |
return peticao, peticao_corrigida, resumo_estatistico, criticas_texto, visualizacao_detalhada
|
| 544 |
|
|
|
|
| 545 |
def exportar_diferencas_html(caso, peticao_texto, correcao):
|
| 546 |
_, _, resumo_estatistico, criticas_texto, visualizacao_detalhada = comparar_peticao_melhorada(caso, peticao_texto, correcao)
|
| 547 |
html_content = f"""
|
|
@@ -567,14 +580,16 @@ def exportar_diferencas_html(caso, peticao_texto, correcao):
|
|
| 567 |
</body>
|
| 568 |
</html>
|
| 569 |
"""
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
|
|
|
|
|
|
| 578 |
|
| 579 |
def interface_gradio():
|
| 580 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
@@ -584,13 +599,13 @@ def interface_gradio():
|
|
| 584 |
with gr.Column(scale=1):
|
| 585 |
gr.Markdown("""
|
| 586 |
### 🔍 Critérios de Avaliação
|
| 587 |
-
- ✅ Endereçamento correto
|
| 588 |
-
- ✅ Qualificação das partes
|
| 589 |
-
- ✅ Fatos e fundamentos
|
| 590 |
-
- ✅ Pedidos claros e específicos
|
| 591 |
-
- ✅ Valor da causa
|
| 592 |
-
- ✅ Provas pretendidas
|
| 593 |
-
- ✅ Opção sobre conciliação
|
| 594 |
- ✅ Pedido de citação adequado
|
| 595 |
- ✅ Juntada da guia de custas
|
| 596 |
- ✅ Fechamento formal
|
|
@@ -598,7 +613,7 @@ def interface_gradio():
|
|
| 598 |
- ❌ Identificação do candidato: nota máxima 3,0
|
| 599 |
- ❌ Invenção de fatos: -5,0 pontos
|
| 600 |
- ❌ Sem pedido de custas: -1,0 ponto
|
| 601 |
-
- ❌ Identificação específica na OAB
|
| 602 |
""")
|
| 603 |
modo_treinamento = gr.Checkbox(label="Modo de Treinamento Interativo", value=False)
|
| 604 |
with gr.Accordion("⚙️ Configurações", open=False):
|
|
@@ -695,7 +710,7 @@ def interface_gradio():
|
|
| 695 |
inputs=[caso_input, peticao_texto, resultado_output],
|
| 696 |
outputs=[download_file]
|
| 697 |
).then(
|
| 698 |
-
fn=lambda x: [gr.update(visible=True, value=x), gr.update(visible=True)],
|
| 699 |
outputs=[download_file, download_btn]
|
| 700 |
)
|
| 701 |
|
|
@@ -718,7 +733,7 @@ def interface_gradio():
|
|
| 718 |
""")
|
| 719 |
gr.Markdown("""
|
| 720 |
### ℹ️ Modo de Treinamento Interativo
|
| 721 |
-
Ative para explicações detalhadas.
|
| 722 |
### 📋 Como usar
|
| 723 |
1. Gere ou cole o caso
|
| 724 |
2. Insira a petição
|
|
|
|
| 38 |
rate_limiter = RateLimiter(max_calls=60, period=60)
|
| 39 |
|
| 40 |
DICAS_OAB = {
|
| 41 |
+
"Endereçamento": "Em relações de consumo, prefira o foro do domicílio do autor (Art. 101, I, CDC).",
|
| 42 |
"Qualificação": "Mencione nome, estado civil (se informado), endereço (use 'Rua XXX' se não fornecido).",
|
| 43 |
"Fatos": "Descreva os fatos cronologicamente, sem inventar informações.",
|
| 44 |
"Pedidos": "Seja específico nos pedidos (ex.: 'condenação ao pagamento de R$ X').",
|
| 45 |
+
"Custas": "Inclua 'Requer a juntada da guia de custas devidamente recolhida'.",
|
| 46 |
+
"Fundamentação": "Baseie-se em artigos do CPC ou CDC e, se possível, em súmulas do STJ (ex.: Súmula 387 para danos morais).",
|
| 47 |
+
"Fechamento": "Finalize com 'Nestes termos pede deferimento', sem vírgula."
|
| 48 |
}
|
| 49 |
|
| 50 |
HISTORICO = []
|
| 51 |
CORRECAO_CACHE = {}
|
| 52 |
|
| 53 |
+
# Funções de pré-processamento e extração de texto permanecem inalteradas
|
| 54 |
def preprocess_image_for_ocr(img):
|
| 55 |
try:
|
| 56 |
gray = img.convert('L')
|
|
|
|
| 169 |
except Exception as e:
|
| 170 |
return f"❌ Erro ao processar o arquivo: {str(e)}"
|
| 171 |
|
| 172 |
+
# Função de cálculo de pontuação aprimorada com explicações
|
| 173 |
def calcular_pontuacao(enderecamento, fundamentos, pedidos, fechamento):
|
| 174 |
tabela = [
|
| 175 |
("**Endereçamento**", ""),
|
| 176 |
("1. Correto endereçamento ao juízo competente", f"{enderecamento[0]:.2f} / 0,10"),
|
| 177 |
+
("2. Qualificação das partes (Art. 319, II, CPC)", f"{enderecamento[1]:.2f} / 0,20"),
|
| 178 |
("**Fundamentos**", ""),
|
| 179 |
+
("3. Exposição clara dos fatos (Art. 319, III, CPC)", f"{fundamentos[0]:.2f} / 0,20"),
|
| 180 |
("4. Fundamentação jurídica adequada", f"{fundamentos[1]:.2f} / 0,25"),
|
| 181 |
+
("5. Demonstração de ilícito e dano (Art. 186, CC)", f"{fundamentos[2]:.2f} / 0,25"),
|
| 182 |
("**Pedidos**", ""),
|
| 183 |
+
("6. Pedidos claros e específicos (Art. 319, IV, CPC)", f"{pedidos[0]:.2f} / 0,30"),
|
| 184 |
+
("7. Valor da causa indicado (Art. 319, V, CPC)", f"{pedidos[1]:.2f} / 0,10"),
|
| 185 |
+
("8. Provas pretendidas (Art. 319, VI, CPC)", f"{pedidos[2]:.2f} / 0,10"),
|
| 186 |
+
("9. Opção sobre audiência (Art. 319, VII, CPC)", f"{pedidos[3]:.2f} / 0,10"),
|
| 187 |
("10. Pedido de citação do réu", f"{pedidos[4]:.2f} / 0,10"),
|
| 188 |
("11. Juntada da guia de custas", f"{pedidos[5]:.2f} / 0,10"),
|
| 189 |
("**Fechamento**", ""),
|
|
|
|
| 196 |
def validar_peticao_basica(peticao):
|
| 197 |
problemas = []
|
| 198 |
if "EXCELENTÍSSIMO" not in peticao.upper():
|
| 199 |
+
problemas.append("⚠️ Endereçamento ausente ou incompleto (Art. 319, I, CPC).")
|
| 200 |
if "Art. 319" not in peticao and "CPC" not in peticao:
|
| 201 |
+
problemas.append("⚠️ Fundamentação jurídica não menciona o CPC (Art. 319).")
|
| 202 |
if "Dá-se à causa o valor" not in peticao:
|
| 203 |
problemas.append("⚠️ Valor da causa não especificado (Art. 319, V, CPC).")
|
| 204 |
if "juntada da guia de custas" not in peticao.lower():
|
| 205 |
+
problemas.append("⚠️ Pedido de juntada da guia de custas ausente (-1,0 ponto).")
|
| 206 |
if "Nestes termos" not in peticao:
|
| 207 |
problemas.append("⚠️ Fechamento formal ausente.")
|
| 208 |
return problemas
|
| 209 |
|
| 210 |
+
# Prompt estruturado aprimorado com feedback pedagógico
|
| 211 |
def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
| 212 |
base_prompt = f"""
|
| 213 |
## Correção Rigorosa de Petição Inicial Cível (Critérios Realistas da OAB)
|
|
|
|
| 219 |
### Análise da Petição
|
| 220 |
1. Análise Geral (Breve visão geral sobre a petição - máximo 3 linhas)
|
| 221 |
2. Nota Final (0 a 10 com uma casa decimal)
|
| 222 |
+
3. Pontos Positivos (Liste pelo menos 3 aspectos bem executados com justificativa legal)
|
| 223 |
+
4. Pontos a Melhorar (Liste os problemas encontrados em ordem de gravidade com explica��ão e base legal)
|
| 224 |
5. Análise Específica dos Requisitos:
|
| 225 |
+
- Endereçamento e qualificação do juízo (Art. 319, I, CPC; Art. 101, I, CDC se aplicável)
|
| 226 |
- Qualificação das partes (Art. 319, II, CPC)
|
| 227 |
+
- Fatos e fundamentos jurídicos (Art. 319, III, CPC; Art. 186, CC)
|
| 228 |
- Pedidos com especificações (Art. 319, IV, CPC)
|
| 229 |
- Valor da causa (Art. 319, V, CPC)
|
| 230 |
- Provas com que o autor pretende demonstrar a verdade dos fatos (Art. 319, VI, CPC)
|
|
|
|
| 241 |
6. A frase "Nestes termos, pede deferimento" com vírgula é incorreta; corrija para "Nestes termos pede deferimento" e destaque o erro na análise
|
| 242 |
7. A petição deve finalizar com "Local e data.\nADVOGADO.\nOAB." sem identificação do aluno (nome, número ou estado na OAB); se houver identificação específica (ex.: número ou estado), zere a nota (0,0)
|
| 243 |
**Instruções Especiais para Endereçamento:**
|
| 244 |
+
- CPC (Art. 46): foro competente é o domicílio do réu; CDC (Art. 101, I): em relação de consumo, foro do autor é correto.
|
| 245 |
- Avalie o contexto: priorize o foro do autor em casos consumeristas.
|
| 246 |
**Pontuação Detalhada:**
|
| 247 |
Inclua uma tabela com:
|
|
|
|
| 268 |
---
|
| 269 |
|
| 270 |
### Petição Corrigida
|
| 271 |
+
Forneça a petição do aluno reescrita com todas as correções aplicadas, incluindo partes omitidas (como pedidos ou custas) e ajustando erros identificados nos "Pontos a Melhorar" e "Análise Específica". Use apenas informações do caso e fundamente com leis brasileiras relevantes (ex.: CPC, CDC, Súmula 387 do STJ para danos morais). Estruture a petição corrigida com:
|
| 272 |
1. Endereçamento correto
|
| 273 |
2. Qualificação completa (Art. 319, II, CPC)
|
| 274 |
3. Fatos claros (Art. 319, III, CPC)
|
| 275 |
+
4. Fundamentação jurídica (ex.: CPC, CDC, Art. 186, CC)
|
| 276 |
5. Pedidos específicos (Art. 319, IV, CPC)
|
| 277 |
6. Valor da causa (Art. 319, V, CPC)
|
| 278 |
7. Provas (Art. 319, VI, CPC)
|
|
|
|
| 289 |
b) Uma sugestão de redação corrigida baseada no caso.
|
| 290 |
c) Um exemplo prático de redação correta em outro contexto (ex.: "Em uma ação de dano moral, poderia ser: 'Requer a condenação ao pagamento de R$ 10.000,00 por danos morais, conforme Súmula 387 do STJ.'").
|
| 291 |
d) Uma dica prática do banco ({json.dumps(DICAS_OAB)}) ou personalizada.
|
| 292 |
+
- Verifique a coerência entre os fatos do caso e a petição, destacando inconsistências.
|
| 293 |
+
- Sugira estratégias jurídicas adicionais baseadas no caso (ex.: citar Art. 186, CC ou Súmula 387, STJ para danos morais).
|
| 294 |
- Não resuma; detalhe cada erro de forma pedagógica e clara.
|
| 295 |
"""
|
| 296 |
return base_prompt
|
| 297 |
|
| 298 |
+
# Funções de geração de caso e correção permanecem similares
|
| 299 |
def estruturar_prompt_geracao_caso():
|
| 300 |
return """
|
| 301 |
Crie um caso fictício detalhado para uma petição inicial cível, similar ao exemplo:
|
|
|
|
| 411 |
"peticao": peticao_conteudo,
|
| 412 |
"correcao_completa": correção_completa
|
| 413 |
})
|
| 414 |
+
if len(HISTORICO) > 10: # Limite de histórico
|
| 415 |
+
HISTORICO.pop(0)
|
| 416 |
CORRECAO_CACHE[cache_key] = correção_formatada
|
| 417 |
return aviso_validacao + correção_formatada
|
| 418 |
except requests.Timeout:
|
|
|
|
| 428 |
except Exception as e:
|
| 429 |
return aviso_validacao + f"❌ Erro inesperado: {str(e)}"
|
| 430 |
|
| 431 |
+
# Função de formatação com mais detalhes pedagógicos
|
| 432 |
def formatar_correção(texto):
|
| 433 |
linhas = texto.split('\n')
|
| 434 |
texto_formatado = ""
|
|
|
|
| 442 |
elif "Pontos a Melhorar" in linha:
|
| 443 |
texto_formatado += f"### ⚠️ {linha.strip()}\n\n"
|
| 444 |
elif "- Invenção de fatos" in linha:
|
| 445 |
+
texto_formatado += f"**🔴 {linha.strip()} (-5,0 pontos)**\n"
|
| 446 |
elif linha.strip().startswith('-') and len(linha) > 2 and any(termo in linha for termo in ["Endereçamento", "Qualificação", "Fatos", "Pedidos", "Valor", "Provas"]):
|
| 447 |
texto_formatado += f"**{linha.strip()}**\n"
|
| 448 |
elif "Explicação" in linha or "Sugestão" in linha or "Dica" in linha or "Exemplo" in linha:
|
|
|
|
| 490 |
tendencia = "⬆️ Melhorando" if len(notas) > 1 and notas[-1] > notas[-2] else "⬇️ Estável ou piorando"
|
| 491 |
return f"📊 Progresso: Média {media:.1f}/10 | Tentativas: {len(notas)} | Tendência: {tendencia}"
|
| 492 |
|
| 493 |
+
# Função de comparação aprimorada com feedback visual
|
| 494 |
def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
| 495 |
if not caso:
|
| 496 |
return "⚠️ Forneça um caso antes de comparar.", "", "", "", ""
|
|
|
|
| 523 |
elif linha.startswith('- '):
|
| 524 |
texto = linha[2:]
|
| 525 |
if any(kw in texto.lower() for kw in ["invenção", "custas", "art. 319"]):
|
| 526 |
+
criticas.append(f"🔴 REMOVIDO: {texto} (inconsistente ou incorreto)")
|
| 527 |
resultado_diff.append(f"<div class='linha-removida'><del>{escape(texto)}</del></div>")
|
| 528 |
elif linha.startswith('+ '):
|
| 529 |
texto = linha[2:]
|
| 530 |
if any(kw in texto.lower() for kw in ["custas", "art. 319"]):
|
| 531 |
+
criticas.append(f"🟢 ADICIONADO: {texto} (essencial para conformidade)")
|
| 532 |
resultado_diff.append(f"<div class='linha-adicionada'><ins>{escape(texto)}</ins></div>")
|
| 533 |
elif linha.startswith('? '):
|
| 534 |
continue
|
|
|
|
| 554 |
"""
|
| 555 |
return peticao, peticao_corrigida, resumo_estatistico, criticas_texto, visualizacao_detalhada
|
| 556 |
|
| 557 |
+
# Função de exportação corrigida para o problema do download
|
| 558 |
def exportar_diferencas_html(caso, peticao_texto, correcao):
|
| 559 |
_, _, resumo_estatistico, criticas_texto, visualizacao_detalhada = comparar_peticao_melhorada(caso, peticao_texto, correcao)
|
| 560 |
html_content = f"""
|
|
|
|
| 580 |
</body>
|
| 581 |
</html>
|
| 582 |
"""
|
| 583 |
+
try:
|
| 584 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp:
|
| 585 |
+
temp_path = tmp.name
|
| 586 |
+
HTML(string=html_content).write_pdf(temp_path)
|
| 587 |
+
return temp_path
|
| 588 |
+
except Exception as e:
|
| 589 |
+
return None
|
| 590 |
+
finally:
|
| 591 |
+
if 'temp_path' in locals() and os.path.exists(temp_path):
|
| 592 |
+
os.unlink(temp_path)
|
| 593 |
|
| 594 |
def interface_gradio():
|
| 595 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
|
|
| 599 |
with gr.Column(scale=1):
|
| 600 |
gr.Markdown("""
|
| 601 |
### 🔍 Critérios de Avaliação
|
| 602 |
+
- ✅ Endereçamento correto (Art. 319, I, CPC)
|
| 603 |
+
- ✅ Qualificação das partes (Art. 319, II, CPC)
|
| 604 |
+
- ✅ Fatos e fundamentos (Art. 319, III, CPC)
|
| 605 |
+
- ✅ Pedidos claros e específicos (Art. 319, IV, CPC)
|
| 606 |
+
- ✅ Valor da causa (Art. 319, V, CPC)
|
| 607 |
+
- ✅ Provas pretendidas (Art. 319, VI, CPC)
|
| 608 |
+
- ✅ Opção sobre conciliação (Art. 319, VII, CPC)
|
| 609 |
- ✅ Pedido de citação adequado
|
| 610 |
- ✅ Juntada da guia de custas
|
| 611 |
- ✅ Fechamento formal
|
|
|
|
| 613 |
- ❌ Identificação do candidato: nota máxima 3,0
|
| 614 |
- ❌ Invenção de fatos: -5,0 pontos
|
| 615 |
- ❌ Sem pedido de custas: -1,0 ponto
|
| 616 |
+
- ❌ Identificação específica na OAB: nota 0,0
|
| 617 |
""")
|
| 618 |
modo_treinamento = gr.Checkbox(label="Modo de Treinamento Interativo", value=False)
|
| 619 |
with gr.Accordion("⚙️ Configurações", open=False):
|
|
|
|
| 710 |
inputs=[caso_input, peticao_texto, resultado_output],
|
| 711 |
outputs=[download_file]
|
| 712 |
).then(
|
| 713 |
+
fn=lambda x: [gr.update(visible=True, value=x) if x else gr.update(visible=True, value=None, label="Erro ao gerar PDF"), gr.update(visible=True)],
|
| 714 |
outputs=[download_file, download_btn]
|
| 715 |
)
|
| 716 |
|
|
|
|
| 733 |
""")
|
| 734 |
gr.Markdown("""
|
| 735 |
### ℹ️ Modo de Treinamento Interativo
|
| 736 |
+
Ative para explicações detalhadas com exemplos práticos e sugestões.
|
| 737 |
### 📋 Como usar
|
| 738 |
1. Gere ou cole o caso
|
| 739 |
2. Insira a petição
|