File size: 8,455 Bytes
7280012
 
0472e0d
 
0f5a06e
0472e0d
 
 
 
299d496
0472e0d
7280012
 
 
 
 
 
 
 
 
 
 
 
0472e0d
299d496
 
 
 
7280012
0472e0d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c0d8c9
 
7280012
 
 
 
 
 
 
 
 
 
 
8c0d8c9
0472e0d
299d496
0472e0d
 
7280012
0472e0d
 
7280012
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299d496
0472e0d
 
 
 
 
299d496
0472e0d
 
7280012
 
 
 
 
 
 
0472e0d
 
299d496
cb5e151
299d496
0472e0d
299d496
cb5e151
0472e0d
cb5e151
0472e0d
299d496
0472e0d
 
299d496
0472e0d
cb5e151
 
7280012
 
 
 
 
 
 
 
cb5e151
 
 
 
 
 
 
 
 
299d496
cb5e151
299d496
cb5e151
7280012
299d496
cb5e151
 
 
 
 
 
 
 
 
 
 
 
 
 
0472e0d
 
 
cb5e151
0472e0d
 
7280012
 
 
 
0472e0d
 
 
 
 
 
 
 
 
7280012
0472e0d
 
 
 
8c0d8c9
 
0472e0d
 
 
02e4f0b
9aebc33
 
0472e0d
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# app.py

import os
import sys
import time
import gradio as gr
import requests
from langchain.prompts import ChatPromptTemplate
from langchain_community.llms import Ollama
from datetime import datetime

from func_ai import classify_comment, retrieve_from_vdb, analyze_sentiment, log_message as ai_log
from func_facebook import (
    get_page_id,
    has_page_replied,
    get_unanswered_comments,
    reply_comment,
    hide_negative_comments,
    log_message as fb_log
)

# Инициализация переменных окружения
VECTOR_API_URL = os.getenv('API_URL')

def log_message(message):
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print(f"[{timestamp}] {message}")

# Шаблон для генерации ответов
template = """
You are an assistant answering users' questions using the provided context. Your tasks:

1. **Brevity**: Respond concisely, using only relevant information from the context.
2. **Politeness**: Start your response with a greeting and maintain a respectful tone.
3. **Clarity**: Avoid unnecessary explanations and use simple language.
4. **Language of the response**: Detect the language of the user's comment and reply in the same language.
5. **Safety**: Do not use phrases like "according to the context" and remove any warnings.
6. **Accuracy**: Provide the user with only important and verified purchase links.


<context>
{context}
</context>

Question: {input}
"""

def delete_faiss_index():
    log_message("Удаляем FAISS индекс.")
    try:
        response = requests.delete(f"{VECTOR_API_URL}/delete_index/")
        if response.status_code == 200:
            log_message("FAISS индекс успешно удален.")
            return "FAISS успешно удален."
        else:
            log_message(f"Ошибка при удалении FAISS индекса: {response.json().get('detail')}")
            return {"status": "error", "message": response.json().get("detail", "Ошибка при удалении FAISS индекса.")}
    except Exception as e:
        log_message(f"Ошибка при удалении FAISS индекса: {e}")
        return {"status": "error", "message": str(e)}

def upload_file_vdb(file):
    log_message("Загружаем файл")
    API_URL = f"{VECTOR_API_URL}/upload/"

    file_path = file.name  # Получаем имя файла
    file_name = os.path.basename(file_path)

    # Сохраняем загруженный файл во временное место
    temp_path = f"/tmp/{file_name}"
    try:
        with open(temp_path, 'wb') as f:
            f.write(file.read())
        log_message(f"Файл сохранен во временное место: {temp_path}")

        # Отправляем файл в векторную базу данных
        with open(temp_path, 'rb') as f:
            files = {'file': (file_name, f)}
            response = requests.post(API_URL, files=files)

        # Удаляем временный файл
        os.remove(temp_path)
        log_message(f"Временный файл {temp_path} удален.")

        # Обработка ответа от сервера
        if response.status_code == 200:
            log_message("Файл успешно загружен.")
            return "Файл успешно загружен."
        else:
            log_message(f"Ошибка при загрузке файла: {response.json().get('detail')}")
            return f"Ошибка: {response.json().get('detail')}"
    except Exception as e:
        log_message(f"Ошибка при загрузке файла: {e}")
        return f"Ошибка: {str(e)}"

def generate_response(user_query, llm):
    log_message(f"Генерация ответа на запрос: {user_query}")
    prompt = ChatPromptTemplate.from_template(template)

    documents = retrieve_from_vdb(user_query)
    context = "\n".join(documents)

    log_message(f"Контекст из базы данных: {context[:100]}...")
    full_prompt = prompt.format(context=context, input=user_query)

    try:
        response = llm.invoke(full_prompt)
        log_message(f"Сгенерированный ответ: {response}")
        return response
    except Exception as e:
        log_message(f"Ошибка при генерации ответа: {e}")
        return "Извините, возникла ошибка при обработке вашего запроса."

def process_comments(ACCESS_TOKEN):
    log_message("Начинаем процесс скрытия отрицательных комментариев.")
    hidden_comments_data = hide_negative_comments(ACCESS_TOKEN)
    log_message(f"Количество постов с скрытыми комментариями: {len(hidden_comments_data)}")

    log_message("Получение неотвеченных комментариев.")
    posts_with_unanswered_comments = get_unanswered_comments(ACCESS_TOKEN)

    page_id = get_page_id(ACCESS_TOKEN)
    if not page_id:
        log_message("Не удалось получить ID страницы.")
        return {"status": "failed", "reason": "Не удалось получить ID страницы."}

    log_message(f"ID страницы: {page_id}")

    processed_posts = []

    # Инициализируем модель Ollama
    try:
        llm = Ollama(model="llama3.1")
        log_message("Модель Ollama 'llama3.1' инициализирована.")
    except Exception as e:
        log_message(f"Ошибка инициализации модели Ollama: {e}")
        return {"status": "failed", "reason": "Ошибка инициализации модели AI."}

    for post_data in posts_with_unanswered_comments:
        post_id = post_data['post_id']
        post_message = post_data['post_message']
        unanswered_comments = post_data['unanswered_comments']

        post_replies = []

        for comment in unanswered_comments:
            message = comment['message']
            log_message(f"Обработка комментария: {message}")
            classification = classify_comment(message)
            log_message(f"Классификация комментария: {classification}")
            if classification == "interrogative":
                response_message = generate_response(message, llm)
                log_message(f"Ответ на комментарий: {response_message}")
                success = reply_comment(comment_id=comment['id'], message=response_message, token=ACCESS_TOKEN)
                if success:
                    post_replies.append({
                        'comment_id': comment['id'],
                        'comment_message': comment['message'],
                        'reply_message': response_message
                    })

        processed_posts.append({
            'post_id': post_id,
            'post_message': post_message,
            'hidden_comments': next((item['hidden_comments'] for item in hidden_comments_data if item['post_id'] == post_id), []),
            'replies': post_replies
        })

    return {
        "status": "completed",
        "posts": processed_posts
    }

def generate_response_interface(user_query, llm):
    return generate_response(user_query, llm)

# Создание интерфейса Gradio
with gr.Blocks() as demo:
    with gr.Tab("Главная страница"):
        gr.Markdown("# Facebook Comment Filter")
        token_input = gr.Textbox(label="Access Token")
        output_main = gr.JSON()
        process_btn = gr.Button("Процессировать комментарии")
        process_btn.click(process_comments, inputs=token_input, outputs=output_main)

    with gr.Tab("Загрузить данные"):
        gr.Markdown("# Отправь Excel файл")
        file_input = gr.File(label="Загрузите Excel файл (.xlsx)")
        output_second = gr.Text()
        second_page_btn = gr.Button("Отправить файл")
        second_page_btn.click(upload_file_vdb, inputs=file_input, outputs=output_second)
        delete_btn = gr.Button("Удалить FAISS индекс")
        delete_btn.click(delete_faiss_index, outputs=output_second)

if __name__ == "__main__":
    demo.launch(
        debug=True,
        server_port=7860,
        server_name="0.0.0.0",
    )