Spaces:
Running
Running
Commit
·
7f104b6
1
Parent(s):
56aeab4
Correções no novo método de conversão dos textos para .md
Browse files- app.py +34 -9
- requirements.txt +0 -0
app.py
CHANGED
@@ -10,6 +10,7 @@ import concurrent.futures
|
|
10 |
from html import escape, unescape
|
11 |
import re
|
12 |
from markdown_it import MarkdownIt
|
|
|
13 |
|
14 |
# Importações do LangChain
|
15 |
from langchain.prompts import PromptTemplate
|
@@ -35,16 +36,40 @@ app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024
|
|
35 |
# Instancia o conversor de Markdown
|
36 |
md = MarkdownIt()
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
def is_html_empty(html: str) -> bool:
|
39 |
"""
|
40 |
Verifica de forma robusta se uma string HTML não contém texto visível,
|
41 |
-
lidando com entidades HTML.
|
42 |
"""
|
43 |
if not html:
|
44 |
return True
|
|
|
45 |
text_only = re.sub('<[^<]+?>', '', html)
|
|
|
46 |
decoded_text = unescape(text_only)
|
47 |
-
|
|
|
|
|
|
|
48 |
|
49 |
@app.route('/')
|
50 |
def index():
|
@@ -137,21 +162,21 @@ def process():
|
|
137 |
|
138 |
grok_text = results.get('grok', '')
|
139 |
print(f"--- Resposta Bruta do GROK (Atômico) ---\n{grok_text}\n--------------------------------------")
|
140 |
-
grok_html =
|
141 |
if is_html_empty(grok_html):
|
142 |
grok_html = f"<pre>{escape(grok_text)}</pre>"
|
143 |
yield f"data: {json.dumps({'partial_result': {'id': 'grok-output', 'content': grok_html}})}\n\n"
|
144 |
|
145 |
sonnet_text = results.get('sonnet', '')
|
146 |
print(f"--- Resposta Bruta do Sonnet (Atômico) ---\n{sonnet_text}\n----------------------------------------")
|
147 |
-
sonnet_html =
|
148 |
if is_html_empty(sonnet_html):
|
149 |
sonnet_html = f"<pre>{escape(sonnet_text)}</pre>"
|
150 |
yield f"data: {json.dumps({'partial_result': {'id': 'sonnet-output', 'content': sonnet_html}})}\n\n"
|
151 |
|
152 |
gemini_text = results.get('gemini', '')
|
153 |
print(f"--- Resposta Bruta do Gemini (Atômico) ---\n{gemini_text}\n----------------------------------------")
|
154 |
-
gemini_html =
|
155 |
if is_html_empty(gemini_html):
|
156 |
gemini_html = f"<pre>{escape(gemini_text)}</pre>"
|
157 |
yield f"data: {json.dumps({'partial_result': {'id': 'gemini-output', 'content': gemini_html}})}\n\n"
|
@@ -170,7 +195,7 @@ def process():
|
|
170 |
return
|
171 |
|
172 |
print(f"--- Resposta Bruta do GROK (Hierárquico) ---\n{resposta_grok}\n------------------------------------------")
|
173 |
-
grok_html =
|
174 |
if is_html_empty(grok_html):
|
175 |
grok_html = f"<pre>{escape(resposta_grok)}</pre>"
|
176 |
yield f"data: {json.dumps({'progress': 33, 'message': 'Claude Sonnet está processando...', 'partial_result': {'id': 'grok-output', 'content': grok_html}})}\n\n"
|
@@ -185,7 +210,7 @@ def process():
|
|
185 |
return
|
186 |
|
187 |
print(f"--- Resposta Bruta do Sonnet (Hierárquico) ---\n{resposta_sonnet}\n--------------------------------------------")
|
188 |
-
sonnet_html =
|
189 |
if is_html_empty(sonnet_html):
|
190 |
sonnet_html = f"<pre>{escape(resposta_sonnet)}</pre>"
|
191 |
yield f"data: {json.dumps({'progress': 66, 'message': 'Gemini está processando...', 'partial_result': {'id': 'sonnet-output', 'content': sonnet_html}})}\n\n"
|
@@ -199,7 +224,7 @@ def process():
|
|
199 |
return
|
200 |
|
201 |
print(f"--- Resposta Bruta do Gemini (Hierárquico) ---\n{resposta_gemini}\n--------------------------------------------")
|
202 |
-
gemini_html =
|
203 |
if is_html_empty(gemini_html):
|
204 |
gemini_html = f"<pre>{escape(gemini_html)}</pre>"
|
205 |
yield f"data: {json.dumps({'progress': 100, 'message': 'Processamento concluído!', 'partial_result': {'id': 'gemini-output', 'content': gemini_html}, 'done': True, 'mode': 'hierarchical'})}\n\n"
|
@@ -242,7 +267,7 @@ def merge():
|
|
242 |
print(f"--- Resposta Bruta do Merge (GROK) ---\n{resposta_merge}\n------------------------------------")
|
243 |
word_count = len(resposta_merge.split())
|
244 |
|
245 |
-
merge_html =
|
246 |
if is_html_empty(merge_html):
|
247 |
merge_html = f"<pre>{escape(resposta_merge)}</pre>"
|
248 |
|
|
|
10 |
from html import escape, unescape
|
11 |
import re
|
12 |
from markdown_it import MarkdownIt
|
13 |
+
from markdown2 import markdown as markdown2_render
|
14 |
|
15 |
# Importações do LangChain
|
16 |
from langchain.prompts import PromptTemplate
|
|
|
36 |
# Instancia o conversor de Markdown
|
37 |
md = MarkdownIt()
|
38 |
|
39 |
+
# [ADICIONADO] Função para renderização com fallback: tenta MarkdownIt, depois markdown2
|
40 |
+
|
41 |
+
def render_markdown_cascata(texto: str) -> str:
|
42 |
+
try:
|
43 |
+
html_1 = md.render(texto)
|
44 |
+
if not is_html_empty(html_1):
|
45 |
+
return html_1
|
46 |
+
except Exception as e:
|
47 |
+
print(f"MarkdownIt falhou: {e}")
|
48 |
+
|
49 |
+
try:
|
50 |
+
html_2 = markdown2_render(texto)
|
51 |
+
if not is_html_empty(html_2):
|
52 |
+
return html_2
|
53 |
+
except Exception as e:
|
54 |
+
print(f"markdown2 falhou: {e}")
|
55 |
+
|
56 |
+
return f"<pre>{escape(texto)}</pre>"
|
57 |
+
|
58 |
def is_html_empty(html: str) -> bool:
|
59 |
"""
|
60 |
Verifica de forma robusta se uma string HTML não contém texto visível,
|
61 |
+
lidando com entidades HTML e múltiplos tipos de espaços em branco.
|
62 |
"""
|
63 |
if not html:
|
64 |
return True
|
65 |
+
# 1. Remove todas as tags HTML
|
66 |
text_only = re.sub('<[^<]+?>', '', html)
|
67 |
+
# 2. Decodifica entidades HTML (ex: para ' ')
|
68 |
decoded_text = unescape(text_only)
|
69 |
+
# 3. Substitui qualquer sequência de caracteres de espaço em branco por um único espaço
|
70 |
+
normalized_space = re.sub(r'\s+', ' ', decoded_text)
|
71 |
+
# 4. Verifica se o texto restante (após remover espaços nas pontas) está de fato vazio
|
72 |
+
return not normalized_space.strip()
|
73 |
|
74 |
@app.route('/')
|
75 |
def index():
|
|
|
162 |
|
163 |
grok_text = results.get('grok', '')
|
164 |
print(f"--- Resposta Bruta do GROK (Atômico) ---\n{grok_text}\n--------------------------------------")
|
165 |
+
grok_html = render_markdown_cascata(grok_text)
|
166 |
if is_html_empty(grok_html):
|
167 |
grok_html = f"<pre>{escape(grok_text)}</pre>"
|
168 |
yield f"data: {json.dumps({'partial_result': {'id': 'grok-output', 'content': grok_html}})}\n\n"
|
169 |
|
170 |
sonnet_text = results.get('sonnet', '')
|
171 |
print(f"--- Resposta Bruta do Sonnet (Atômico) ---\n{sonnet_text}\n----------------------------------------")
|
172 |
+
sonnet_html = render_markdown_cascata(sonnet_text)
|
173 |
if is_html_empty(sonnet_html):
|
174 |
sonnet_html = f"<pre>{escape(sonnet_text)}</pre>"
|
175 |
yield f"data: {json.dumps({'partial_result': {'id': 'sonnet-output', 'content': sonnet_html}})}\n\n"
|
176 |
|
177 |
gemini_text = results.get('gemini', '')
|
178 |
print(f"--- Resposta Bruta do Gemini (Atômico) ---\n{gemini_text}\n----------------------------------------")
|
179 |
+
gemini_html = render_markdown_cascata(gemini_text)
|
180 |
if is_html_empty(gemini_html):
|
181 |
gemini_html = f"<pre>{escape(gemini_text)}</pre>"
|
182 |
yield f"data: {json.dumps({'partial_result': {'id': 'gemini-output', 'content': gemini_html}})}\n\n"
|
|
|
195 |
return
|
196 |
|
197 |
print(f"--- Resposta Bruta do GROK (Hierárquico) ---\n{resposta_grok}\n------------------------------------------")
|
198 |
+
grok_html = render_markdown_cascata(resposta_grok)
|
199 |
if is_html_empty(grok_html):
|
200 |
grok_html = f"<pre>{escape(resposta_grok)}</pre>"
|
201 |
yield f"data: {json.dumps({'progress': 33, 'message': 'Claude Sonnet está processando...', 'partial_result': {'id': 'grok-output', 'content': grok_html}})}\n\n"
|
|
|
210 |
return
|
211 |
|
212 |
print(f"--- Resposta Bruta do Sonnet (Hierárquico) ---\n{resposta_sonnet}\n--------------------------------------------")
|
213 |
+
sonnet_html = render_markdown_cascata(resposta_sonnet)
|
214 |
if is_html_empty(sonnet_html):
|
215 |
sonnet_html = f"<pre>{escape(resposta_sonnet)}</pre>"
|
216 |
yield f"data: {json.dumps({'progress': 66, 'message': 'Gemini está processando...', 'partial_result': {'id': 'sonnet-output', 'content': sonnet_html}})}\n\n"
|
|
|
224 |
return
|
225 |
|
226 |
print(f"--- Resposta Bruta do Gemini (Hierárquico) ---\n{resposta_gemini}\n--------------------------------------------")
|
227 |
+
gemini_html = render_markdown_cascata(resposta_gemini)
|
228 |
if is_html_empty(gemini_html):
|
229 |
gemini_html = f"<pre>{escape(gemini_html)}</pre>"
|
230 |
yield f"data: {json.dumps({'progress': 100, 'message': 'Processamento concluído!', 'partial_result': {'id': 'gemini-output', 'content': gemini_html}, 'done': True, 'mode': 'hierarchical'})}\n\n"
|
|
|
267 |
print(f"--- Resposta Bruta do Merge (GROK) ---\n{resposta_merge}\n------------------------------------")
|
268 |
word_count = len(resposta_merge.split())
|
269 |
|
270 |
+
merge_html = render_markdown_cascata(resposta_merge)
|
271 |
if is_html_empty(merge_html):
|
272 |
merge_html = f"<pre>{escape(resposta_merge)}</pre>"
|
273 |
|
requirements.txt
CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
|
|