File size: 6,006 Bytes
a52faf6
77619f4
e3c1e1d
a52faf6
77619f4
a52faf6
7bf3b1f
 
e3c1e1d
41c1169
7bf3b1f
e3c1e1d
 
 
7bf3b1f
e3c1e1d
 
 
a52faf6
 
d7fc09f
668c42c
7af81f3
a52faf6
 
6306328
 
 
 
 
 
 
 
 
a52faf6
 
 
 
 
 
 
6306328
a52faf6
 
 
 
 
285e310
2eb0a24
 
 
 
77619f4
7af81f3
2eb0a24
77619f4
 
 
2eb0a24
 
 
a52faf6
7af81f3
77619f4
 
 
 
7af81f3
aa68abd
a52faf6
 
77619f4
a52faf6
 
 
aa68abd
77619f4
 
 
7af81f3
77619f4
7af81f3
77619f4
 
7af81f3
77619f4
7af81f3
 
 
77619f4
7af81f3
 
77619f4
 
7af81f3
47cd49c
7af81f3
 
 
 
 
77619f4
 
 
 
 
 
 
 
 
 
 
 
 
 
7af81f3
77619f4
7af81f3
77619f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47cd49c
77619f4
 
 
 
 
 
 
 
 
 
 
 
47cd49c
77619f4
 
a52faf6
 
77619f4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
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('Проверка орфографии')
    
    # Сохраняем текст в session_state
    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:
        # Генерация HTML с кликабельными ошибками
        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)

        # JavaScript для обработки кликов
        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)
        
        # Обработка кликов через custom component
        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()