Spaces:
Paused
Paused
...
Browse files- app/prompt_builder/prompt.py +1 -1
- app/test_gradio_test.py +67 -79
- requirements.txt +1 -0
app/prompt_builder/prompt.py
CHANGED
|
@@ -220,7 +220,7 @@ I. ШАПКА. Lesson Plan Header — provide the core lesson metadata in a comp
|
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
-
II **План урока**
|
| 224 |
|
| 225 |
III **Teaching Reference Sheet** (style guide: this is a reference block and must fit a single vertical A4 compactly yet reader-friendly).
|
| 226 |
Structure:
|
|
|
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
+
II **План урока** (обычная таблица без классов)
|
| 224 |
|
| 225 |
III **Teaching Reference Sheet** (style guide: this is a reference block and must fit a single vertical A4 compactly yet reader-friendly).
|
| 226 |
Structure:
|
app/test_gradio_test.py
CHANGED
|
@@ -59,104 +59,92 @@ def upload_to_catbox(file_bytes: bytes, filename: str = "image.png", expire: str
|
|
| 59 |
import re
|
| 60 |
|
| 61 |
|
|
|
|
|
|
|
| 62 |
from docx import Document
|
| 63 |
from bs4 import BeautifulSoup
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
from docx.shared import Pt
|
|
|
|
| 65 |
import tempfile
|
| 66 |
import os
|
| 67 |
from datetime import datetime
|
| 68 |
|
| 69 |
|
| 70 |
def generate_docx(html_content: str) -> str:
|
| 71 |
-
"""
|
| 72 |
doc = Document()
|
| 73 |
soup = BeautifulSoup(html_content, 'html.parser')
|
| 74 |
|
| 75 |
-
# Обработка шапки
|
| 76 |
header_table = soup.find('table', class_='header-table')
|
| 77 |
if header_table:
|
| 78 |
-
table = doc.add_table(rows=0, cols=
|
| 79 |
table.style = 'Table Grid'
|
| 80 |
|
| 81 |
for row in header_table.find_all('tr'):
|
| 82 |
cells = row.find_all('td')
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
for section in soup.find_all('section', class_='output-block'):
|
| 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 |
-
elif element.name in ['ul', 'ol']:
|
| 132 |
-
list_type = 'ListBullet' if element.name == 'ul' else 'ListNumber'
|
| 133 |
-
for item in element.find_all('li'):
|
| 134 |
-
p = doc.add_paragraph(style=list_type)
|
| 135 |
-
p.add_run(item.get_text().strip())
|
| 136 |
-
|
| 137 |
-
# Обработка обычного текста
|
| 138 |
-
elif element.name == 'p':
|
| 139 |
-
text = element.get_text().strip()
|
| 140 |
-
if text:
|
| 141 |
-
doc.add_paragraph(text)
|
| 142 |
-
|
| 143 |
-
# Обработка "сырого" текста без тегов
|
| 144 |
-
elif not element.name and element.strip():
|
| 145 |
-
doc.add_paragraph(element.strip())
|
| 146 |
-
|
| 147 |
-
# Сохранение документа
|
| 148 |
-
tmp_dir = tempfile.gettempdir()
|
| 149 |
-
filename = f"lesson_plan_{datetime.now().strftime('%Y%m%d%H%M%S')}.docx"
|
| 150 |
-
path = os.path.join(tmp_dir, filename)
|
| 151 |
-
|
| 152 |
-
try:
|
| 153 |
-
doc.save(path)
|
| 154 |
-
if not os.path.exists(path):
|
| 155 |
-
raise Exception("Ошибка создания файла")
|
| 156 |
-
return path
|
| 157 |
-
except Exception as e:
|
| 158 |
-
print(f"Ошибка: {str(e)}")
|
| 159 |
-
raise
|
| 160 |
|
| 161 |
# названия textbooks для автозаполнения поля Учебник
|
| 162 |
import json
|
|
|
|
| 59 |
import re
|
| 60 |
|
| 61 |
|
| 62 |
+
|
| 63 |
+
|
| 64 |
from docx import Document
|
| 65 |
from bs4 import BeautifulSoup
|
| 66 |
+
import tempfile
|
| 67 |
+
import os
|
| 68 |
+
from datetime import datetime
|
| 69 |
+
|
| 70 |
+
from docx import Document
|
| 71 |
from docx.shared import Pt
|
| 72 |
+
from bs4 import BeautifulSoup
|
| 73 |
import tempfile
|
| 74 |
import os
|
| 75 |
from datetime import datetime
|
| 76 |
|
| 77 |
|
| 78 |
def generate_docx(html_content: str) -> str:
|
| 79 |
+
"""Конвертирует HTML от LLM в DOCX с сохранением ключевой структуры"""
|
| 80 |
doc = Document()
|
| 81 |
soup = BeautifulSoup(html_content, 'html.parser')
|
| 82 |
|
| 83 |
+
# Обработка шапки с метками
|
| 84 |
header_table = soup.find('table', class_='header-table')
|
| 85 |
if header_table:
|
| 86 |
+
table = doc.add_table(rows=0, cols=3)
|
| 87 |
table.style = 'Table Grid'
|
| 88 |
|
| 89 |
for row in header_table.find_all('tr'):
|
| 90 |
cells = row.find_all('td')
|
| 91 |
+
doc_row = table.add_row()
|
| 92 |
+
|
| 93 |
+
for i, cell in enumerate(cells[:3]): # Макс 3 колонки
|
| 94 |
+
content = " ".join([t.get_text() for t in cell.find_all(text=True)])
|
| 95 |
+
doc_row.cells[i].text = content.replace(" : ", ": ").strip()
|
| 96 |
+
|
| 97 |
+
# Обработка основной таблицы плана
|
| 98 |
+
lesson_table = soup.find('section', class_='output-block').find('table')
|
| 99 |
+
if lesson_table:
|
| 100 |
+
cols = max(len(row.find_all(['td', 'th'])) for row in lesson_table.find_all('tr'))
|
| 101 |
+
doc_table = doc.add_table(rows=0, cols=cols)
|
| 102 |
+
doc_table.style = 'Table Grid'
|
| 103 |
+
|
| 104 |
+
for row in lesson_table.find_all('tr'):
|
| 105 |
+
cells = row.find_all(['td', 'th'])[:cols]
|
| 106 |
+
if not cells:
|
| 107 |
+
continue
|
| 108 |
+
|
| 109 |
+
doc_row = doc_table.add_row()
|
| 110 |
+
for i, cell in enumerate(cells):
|
| 111 |
+
text = " ".join(cell.stripped_strings)
|
| 112 |
+
doc_cell = doc_row.cells[i]
|
| 113 |
+
doc_cell.text = text
|
| 114 |
+
if cell.find('strong'):
|
| 115 |
+
doc_cell.paragraphs[0].runs[0].bold = True
|
| 116 |
+
|
| 117 |
+
# Обработка Teaching Reference Sheet
|
| 118 |
for section in soup.find_all('section', class_='output-block'):
|
| 119 |
+
if 'Teaching Reference Sheet' in section.get_text():
|
| 120 |
+
doc.add_heading('Teaching Reference Sheet', level=2)
|
| 121 |
+
|
| 122 |
+
# Двухколоночный макет через таблицу
|
| 123 |
+
cols_table = doc.add_table(rows=1, cols=2)
|
| 124 |
+
cols_table.autofit = True
|
| 125 |
+
|
| 126 |
+
# Левая колонка
|
| 127 |
+
left = cols_table.cell(0, 0)
|
| 128 |
+
for item in section.find_all(['h3', 'strong', 'em']):
|
| 129 |
+
if item.name == 'h3':
|
| 130 |
+
left.add_paragraph(item.get_text(), style='Heading3')
|
| 131 |
+
else:
|
| 132 |
+
p = left.add_paragraph()
|
| 133 |
+
p.add_run(item.get_text()).bold = True
|
| 134 |
+
|
| 135 |
+
# Правая колонка
|
| 136 |
+
right = cols_table.cell(0, 1)
|
| 137 |
+
for item in section.find_all('h3'):
|
| 138 |
+
if 'Методические советы' in item.text:
|
| 139 |
+
for sib in item.next_siblings:
|
| 140 |
+
if sib.name == 'h3':
|
| 141 |
+
break
|
| 142 |
+
right.add_paragraph(sib.get_text())
|
| 143 |
+
|
| 144 |
+
# Сохранение
|
| 145 |
+
path = os.path.join(tempfile.gettempdir(), f"lesson_plan_{datetime.now().strftime('%Y%m%d%H%M%S')}.docx")
|
| 146 |
+
doc.save(path)
|
| 147 |
+
return path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
# названия textbooks для автозаполнения поля Учебник
|
| 150 |
import json
|
requirements.txt
CHANGED
|
@@ -7,3 +7,4 @@ pillow
|
|
| 7 |
bs4
|
| 8 |
|
| 9 |
|
|
|
|
|
|
| 7 |
bs4
|
| 8 |
|
| 9 |
|
| 10 |
+
|