File size: 6,038 Bytes
65dd513
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
from cryptography.fernet import Fernet
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import os
import time
import datetime

# Хранилище сообщений в памяти
messages = []
GLOBAL_PASSWORD = "default_password"  # Установите общий пароль для всего чата
SALT = os.urandom(16)  # Генерируем общую соль для всех сообщений
MAX_MESSAGES = 100  # Максимальное количество сохраняемых сообщений

def generate_key(password, salt):
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=100000,
    )
    key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
    return key

def encrypt_message(text):
    key = generate_key(GLOBAL_PASSWORD, SALT)
    f = Fernet(key)
    return f.encrypt(text.encode())

def decrypt_message(encrypted_data):
    key = generate_key(GLOBAL_PASSWORD, SALT)
    f = Fernet(key)
    return f.decrypt(encrypted_data).decode()

def send_message(username, message_text, password):
    global GLOBAL_PASSWORD
    
    if not message_text or not username:
        return "Введите имя и сообщение", get_chat_history(password)
    
    # Если это первое сообщение, устанавливаем пароль
    if not messages and password:
        GLOBAL_PASSWORD = password
    
    # Проверяем пароль для существующего чата
    if messages and password != GLOBAL_PASSWORD:
        return "❌ Неверный пароль чата", get_chat_history(password)
    
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    
    try:
        # Подготовка сообщения для шифрования
        full_message = f"{username} ({timestamp}): {message_text}"
        
        # Шифруем и сохраняем сообщение
        encrypted_data = encrypt_message(full_message)
        messages.append(encrypted_data)
        
        # Ограничиваем количество сообщений
        if len(messages) > MAX_MESSAGES:
            messages.pop(0)
        
        return "", get_chat_history(password)
    except Exception as e:
        return f"Ошибка: {str(e)}", get_chat_history(password)

def get_chat_history(password):
    global GLOBAL_PASSWORD
    
    if not messages:
        return "Чат пуст. Отправьте первое сообщение!"
    
    if password != GLOBAL_PASSWORD:
        return "🔒 Введите правильный пароль чата для просмотра сообщений"
    
    try:
        # Расшифровываем и отображаем все сообщения
        decrypted_messages = []
        for msg in messages:
            decrypted = decrypt_message(msg)
            decrypted_messages.append(decrypted)
        
        return "\n".join(decrypted_messages)
    except Exception as e:
        return f"Ошибка при расшифровке: {str(e)}"

def check_for_updates(chat_history, password):
    time.sleep(1)  # Задержка для предотвращения слишком частого обновления
    return get_chat_history(password)

# Создаем интерфейс Gradio
with gr.Blocks(title="Зашифрованный чат (72 часа)") as demo:
    gr.Markdown("## 🔒 Временный зашифрованный чат")
    gr.Markdown("Чат доступен в течение 72 часов или до закрытия Google Colab")
    
    with gr.Row():
        username = gr.Textbox(label="Ваше имя", placeholder="Введите ваше имя...")
        chat_password = gr.Textbox(label="Пароль чата", type="password", 
                                   placeholder="Пароль для шифрования чата...")
    
    chat_display = gr.Textbox(label="Сообщения чата", lines=15, interactive=False)
    
    with gr.Row():
        message_input = gr.Textbox(label="Сообщение", placeholder="Введите сообщение...", lines=2)
        send_btn = gr.Button("Отправить")
    
    error_box = gr.Textbox(label="Статус", interactive=False, visible=True)
    
    refresh_btn = gr.Button("Обновить чат")
    
    # Обработчики событий
    send_btn.click(
        fn=send_message, 
        inputs=[username, message_input, chat_password], 
        outputs=[error_box, chat_display]
    ).then(lambda: "", outputs=message_input)
    
    refresh_btn.click(
        fn=check_for_updates,
        inputs=[chat_display, chat_password],
        outputs=[chat_display]
    )
    
    # Автоматическое обновление
    chat_display.change(
        fn=lambda: time.sleep(0.5),  # Небольшая пауза
        inputs=None,
        outputs=None
    )
    
    gr.Markdown("""
    ### 📝 Инструкция по использованию
    1. **Первый пользователь** устанавливает пароль чата
    2. **Поделитесь ссылкой** и паролем с участниками чата
    3. **Все участники** должны использовать один и тот же пароль
    4. Нажимайте "Обновить чат" чтобы увидеть новые сообщения
    5. История сообщений хранится только в памяти и будет потеряна при закрытии Colab
    
    ### ⚠️ Важно: 
    - Ссылка будет работать не более 72 часов
    - При закрытии вкладки Google Colab чат будет потерян
    - Чат не сохраняется между сессиями
    """)

demo.launch(share=True)