Начальная реализация транспорта ws для max web и прочие улучшения

This commit is contained in:
Alexey Polyakov
2026-04-07 12:36:30 +03:00
parent 52949602af
commit 0ffc649dd9
19 changed files with 873 additions and 228 deletions
+3 -3
View File
@@ -34,7 +34,7 @@ class AuthProcessors(BaseProcessor):
phone = payload.get("phone").replace("+", "").replace(" ", "").replace("-", "")
# Генерируем токен
token = secrets.token_urlsafe(128)
token = secrets.token_urlsafe(102)
token_hash = hashlib.sha256(token.encode()).hexdigest()
# Время истечения токена
@@ -282,7 +282,7 @@ class AuthProcessors(BaseProcessor):
"""
INSERT INTO user_data
(phone, contacts, folders, user_config, chat_config)
VALUES (%s %s, %s, %s, %s)
VALUES (%s, %s, %s, %s, %s)
""",
(
phone,
@@ -409,7 +409,7 @@ class AuthProcessors(BaseProcessor):
)
chats = await self.tools.generate_chats(
chats, self.db_pool, user.get("id")
chats, self.db_pool, user.get("id"), protocol_type=self.type
)
# Формируем данные пакета
+2 -1
View File
@@ -58,8 +58,9 @@ class HistoryProcessors(BaseProcessor):
result = await cursor.fetchall()
for row in result:
# TODO: Сборку тела сообщения нужно вынести в отдельную функцию
messages.append({
"id": row.get("id"),
"id": row.get("id") if self.type == 'mobile' else str(row.get('id')),
"time": int(row.get("time")),
"type": row.get("type"),
"sender": row.get("sender"),
+1
View File
@@ -32,6 +32,7 @@ class MainProcessors(BaseProcessor):
"app-update-type": 0, # 1 = принудительное обновление
"reg-country-code": self.static.REG_COUNTRY_CODES,
"phone-auto-complete-enabled": False,
"qr-auth-enabled": False,
"lang": True
}
+1 -1
View File
@@ -83,7 +83,7 @@ class MessagesProcessors(BaseProcessor):
# Вычисляем ID чата по ID пользователя и ID отправителя,
# в случае отсутствия ID чата
if not chatId:
if chatId is None:
chatId = userId ^ senderId
# Если клиент хочет отправить сообщение в избранное,
+52 -31
View File
@@ -76,48 +76,69 @@ class SearchProcessors(BaseProcessor):
# Валидируем данные пакета
try:
SearchByPhonePayloadModel.model_validate(payload)
except pydantic.ValidationError as error:
self.logger.error(f"Возникли ошибки при валидации пакета: {error}")
except Exception as e:
await self._send_error(seq, self.opcodes.CONTACT_INFO_BY_PHONE, self.error_types.INVALID_PAYLOAD, writer)
return
# Ищем пользователя в бд
phone = payload.get("phone").replace("+", "").replace(" ", "").replace("-", "")
async with self.db_pool.acquire() as conn:
async with conn.cursor() as cursor:
await cursor.execute("SELECT * FROM users WHERE phone = %s", (phone,))
await cursor.execute("SELECT * FROM users WHERE phone = %s", (int(payload.get("phone")),))
user = await cursor.fetchone()
# Если пользователь найден
if user:
# Аватарка с биографией
photoId = None if not user.get("avatar_id") else int(user.get("avatar_id"))
avatar_url = None if not photoId else self.config.avatar_base_url + photoId
description = None if not user.get("description") else user.get("description")
# Если пользователь не найден, отправляем ошибку
if not user:
await self._send_error(seq, self.opcodes.CONTACT_INFO_BY_PHONE, self.error_types.USER_NOT_FOUND, writer)
return
# ID чата
chatId = senderId ^ user.get("id")
# Генерируем профиль
profile = self.tools.generate_profile(
id=user.get("id"),
phone=int(user.get("phone")),
avatarUrl=avatar_url,
photoId=photoId,
updateTime=int(user.get("updatetime")),
firstName=user.get("firstname"),
lastName=user.get("lastname"),
options=json.loads(user.get("options")),
description=description,
accountStatus=int(user.get("accountstatus")),
profileOptions=json.loads(user.get("profileoptions")),
includeProfileOptions=False,
username=user.get("username")
# Ищем диалог в бд
await cursor.execute("SELECT * FROM chats WHERE id = %s", (chatId,))
chat = await cursor.fetchone()
# Если диалога нет - создаем
if not chat:
await cursor.execute(
"INSERT INTO chats (id, owner, type) VALUES (%s, %s, %s)",
(chatId, senderId, "DIALOG")
)
else:
profile = None
# Добавляем участников в таблицу chat_participants
participants = [int(senderId), int(user.get("id"))]
for user_id in participants:
await cursor.execute(
"INSERT INTO chat_participants (chat_id, user_id) VALUES (%s, %s)",
(chatId, user_id)
)
# Аватарка с биографией
photoId = None if not user.get("avatar_id") else int(user.get("avatar_id"))
avatar_url = None if not photoId else self.config.avatar_base_url + photoId
description = None if not user.get("description") else user.get("description")
# Генерируем профиль
profile = self.tools.generate_profile(
id=user.get("id"),
phone=int(user.get("phone")),
avatarUrl=avatar_url,
photoId=photoId,
updateTime=int(user.get("updatetime")),
firstName=user.get("firstname"),
lastName=user.get("lastname"),
options=json.loads(user.get("options")),
description=description,
accountStatus=int(user.get("accountstatus")),
profileOptions=json.loads(user.get("profileoptions")),
includeProfileOptions=False,
username=user.get("username")
)
# Создаем данные пакета
payload = {
"profile": profile
"contact": profile
}
# Создаем пакет
@@ -162,7 +183,7 @@ class SearchProcessors(BaseProcessor):
# Получаем последнее сообщение из чата
message, messageTime = await self.tools.get_last_message(
chatId, self.db_pool
chatId, self.db_pool, protocol_type=self.type
)
# Добавляем чат в список
@@ -176,7 +197,7 @@ class SearchProcessors(BaseProcessor):
else:
# Получаем последнее сообщение из чата
message, messageTime = await self.tools.get_last_message(
senderId, self.db_pool
senderId, self.db_pool, protocol_type=self.type
)
# ID избранного