|
import streamlit as st |
|
import language_tool_python |
|
import subprocess |
|
import html |
|
import openai |
|
|
|
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> |
|
.error-highlight { |
|
background-color: #ffe066; |
|
border-bottom: 2px dotted #ff9900; |
|
cursor: pointer; |
|
color: black !important; |
|
} |
|
.error-highlight:hover { |
|
background-color: #ffd700; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
st.title('Проверка орфографии') |
|
|
|
|
|
text_input = st.text_area("Введите текст для проверки:", |
|
value=st.session_state.get('text_to_check', ''), |
|
height=200) |
|
text = text_input.replace("\n", " ") |
|
tool = load_assets() |
|
|
|
if st.button('Проверить текст'): |
|
st.session_state.text_to_check = text_input |
|
if not text.strip(): |
|
st.warning("Введите текст для проверки") |
|
else: |
|
errors = check_text(text, tool) |
|
st.session_state.errors = errors |
|
st.session_state.sorted_errors = sorted(errors, key=lambda x: x['start']) |
|
st.session_state.selected_error = None |
|
|
|
|
|
errors = st.session_state.get('errors', []) |
|
sorted_errors = st.session_state.get('sorted_errors', []) |
|
|
|
if errors: |
|
|
|
highlighted = [] |
|
last_pos = 0 |
|
|
|
for index, error in enumerate(sorted_errors): |
|
highlighted.append(html.escape(text[last_pos:error['start']])) |
|
highlighted.append( |
|
f'<span class="error-highlight" onclick="window.parent.postMessage({{index: {index}}}, \'*\')" ' |
|
f'title="Кликните для подробностей">' |
|
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(""" |
|
<script> |
|
window.addEventListener('message', function(event) { |
|
if (event.data.index !== undefined) { |
|
const index = event.data.index; |
|
// Отправляем индекс в Streamlit |
|
const streamlitDoc = window.parent.document; |
|
const iframe = streamlitDoc.querySelector('iframe[data-testid="stIFrame"]'); |
|
if (iframe) { |
|
iframe.contentWindow.postMessage({type: 'streamlit:setComponentValue', value: index}, '*'); |
|
} |
|
} |
|
}); |
|
</script> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
clicked_error = st.session_state.get('clicked_error', None) |
|
|
|
|
|
if clicked_error is not None: |
|
st.session_state.selected_error = clicked_error |
|
|
|
|
|
if 'selected_error' in st.session_state and st.session_state.selected_error is not None: |
|
error = sorted_errors[st.session_state.selected_error] |
|
st.markdown("### Описание ошибки:") |
|
st.markdown(f"**Ошибка {st.session_state.selected_error + 1}**: {error['message']}") |
|
else: |
|
st.markdown("### Найденные ошибки:") |
|
st.markdown("🔍 **Кликните на выделенный текст, чтобы увидеть описание ошибки**") |
|
|
|
if __name__ == "__main__": |
|
main() |
|
|