|
import language_tool_python |
|
import openai |
|
import streamlit as st |
|
import subprocess |
|
from pathlib import Path |
|
import html |
|
|
|
is_java_installed = False |
|
|
|
|
|
def install_java(): |
|
global is_java_installed |
|
if is_java_installed: return |
|
try: |
|
|
|
subprocess.run(["apt-get", "update"], check=True) |
|
subprocess.run(["apt-get", "install", "-y", "openjdk-17-jdk"], check=True) |
|
|
|
is_java_installed = True |
|
except Exception as e: |
|
st.error(f"Ошибка установки Java: {e}") |
|
|
|
|
|
@st.cache_resource |
|
def load_assets(): |
|
openai.api_key = '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' |
|
install_java() |
|
tool = language_tool_python.LanguageTool('ru-RU', |
|
language_tool_download_version="6.1") |
|
return tool |
|
|
|
|
|
def generate_gpt_comment(message, context): |
|
response = openai.ChatCompletion.create( |
|
model="gpt-4o", |
|
messages=[ |
|
{"role": "user", "content": f"Прокомментируй ошибку: {message} в данном тексте '{context}'. Не больше одного предложения, на русском."} |
|
] |
|
) |
|
return response.choices[0].message['content'] |
|
|
|
|
|
def check_text(text, tool): |
|
matches = tool.check(text) |
|
errors = [] |
|
for match in matches: |
|
error_info = { |
|
'start': match.offset, |
|
'end': match.offset + match.errorLength, |
|
'message': generate_gpt_comment(match.message, match.context), |
|
} |
|
errors.append(error_info) |
|
return errors |
|
|
|
|
|
def main(): |
|
st.markdown(""" |
|
<style> |
|
/* Сохраняем белый текст для темной темы */ |
|
.stApp, .stTextInput, .stTextArea, .stMarkdown { |
|
color: white; |
|
} |
|
|
|
/* Специальный стиль для текста внутри выделенных ошибок */ |
|
.error-highlight { |
|
background-color: #ffe066; |
|
border-bottom: 2px dotted #ff9900; |
|
position: relative; |
|
color: black !important; /* Принудительно черный текст в выделениях */ |
|
} |
|
|
|
/* Стиль для контейнера с результатом */ |
|
.result-container { |
|
background: rgba(255, 255, 255, 0.1); |
|
padding: 20px; |
|
border-radius: 8px; |
|
border: 1px solid #444; |
|
white-space: pre-wrap; |
|
font-family: monospace; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.title('Проверка орфографии') |
|
text = st.text_area("Введите текст для проверки:", height=200).replace("\n", " ") |
|
tool = load_assets() |
|
|
|
if st.button('Проверить текст'): |
|
if not text.strip(): |
|
st.warning("Введите текст для проверки") |
|
else: |
|
errors = check_text(text, tool) |
|
|
|
if not errors: |
|
st.success("Ошибок не найдено! 👍") |
|
else: |
|
sorted_errors = sorted(errors, key=lambda x: x['start']) |
|
|
|
highlighted = [] |
|
last_pos = 0 |
|
|
|
for error in sorted_errors: |
|
highlighted.append(html.escape(text[last_pos:error['start']])) |
|
|
|
highlighted.append( |
|
f'<span style="background-color: #ffe066; border-bottom: 2px dotted #ff9900; ' |
|
f'position: relative;" title="{html.escape(error["message"])}">' |
|
f'{html.escape(text[error["start"]:error["end"]])}' |
|
f'</span>' |
|
) |
|
|
|
last_pos = error['end'] |
|
|
|
highlighted.append(html.escape(text[last_pos:])) |
|
|
|
html_content = f""" |
|
<div style=" |
|
background: white; |
|
padding: 20px; |
|
border-radius: 8px; |
|
border: 1px solid #ddd; |
|
white-space: pre-wrap; |
|
font-family: monospace; |
|
color: #000000; |
|
"> |
|
{''.join(highlighted)} |
|
</div> |
|
""" |
|
|
|
st.markdown("### Результат проверки:") |
|
st.markdown(html_content, unsafe_allow_html=True) |
|
|
|
st.markdown("### Найденные ошибки:") |
|
for i, error in enumerate(errors, 1): |
|
st.markdown(f"{i}. **Позиция {error['start']}-{error['end']}**: {error['message']}") |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |
|
|