From bd95755db40ec20cbd95231ea7ed1016350b9005 Mon Sep 17 00:00:00 2001 From: Alexey Polyakov Date: Mon, 27 Apr 2026 17:40:28 +0300 Subject: [PATCH] =?UTF-8?q?MAX:=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D0=B0=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/oneme/models.py | 6 +++ src/oneme/processors/folders.py | 91 +++++++++++++++++++++++++++++++-- src/oneme/socket.py | 9 ++++ src/oneme/websocket.py | 9 ++++ tables.sql | 1 + 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/oneme/models.py b/src/oneme/models.py index edd999d..74d6927 100644 --- a/src/oneme/models.py +++ b/src/oneme/models.py @@ -75,6 +75,12 @@ class SendMessagePayloadModel(pydantic.BaseModel): class SyncFoldersPayloadModel(pydantic.BaseModel): folderSync: int +class CreateFolderPayloadModel(pydantic.BaseModel): + id: str + title: str + filters: list = [] + include: list = [] + class SearchChatsPayloadModel(pydantic.BaseModel): chatIds: list diff --git a/src/oneme/processors/folders.py b/src/oneme/processors/folders.py index f94f953..e9222a1 100644 --- a/src/oneme/processors/folders.py +++ b/src/oneme/processors/folders.py @@ -2,7 +2,7 @@ import pydantic import json import time from classes.baseprocessor import BaseProcessor -from oneme.models import SyncFoldersPayloadModel +from oneme.models import SyncFoldersPayloadModel, CreateFolderPayloadModel class FoldersProcessors(BaseProcessor): async def folders_get(self, payload, seq, writer, senderPhone): @@ -19,7 +19,7 @@ class FoldersProcessors(BaseProcessor): async with self.db_pool.acquire() as conn: async with conn.cursor() as cursor: await cursor.execute( - "SELECT id, title, filters, options, update_time, source_id " + "SELECT id, title, filters, `include`, options, update_time, source_id " "FROM user_folders WHERE phone = %s ORDER BY sort_order", (int(senderPhone),) ) @@ -30,9 +30,10 @@ class FoldersProcessors(BaseProcessor): "id": folder["id"], "title": folder["title"], "filters": json.loads(folder["filters"]), + "include": json.loads(folder["include"]), "updateTime": folder["update_time"], "options": json.loads(folder["options"]), - "sourceId": folder["source_id"], + "sourceId": folder["source_id"] } for folder in result_folders ] @@ -45,10 +46,92 @@ class FoldersProcessors(BaseProcessor): "allFilterExcludeFolders": [] } + print( + json.dumps(payload, indent=4) + ) + # Собираем пакет packet = self.proto.pack_packet( cmd=self.proto.CMD_OK, seq=seq, opcode=self.opcodes.FOLDERS_GET, payload=payload ) # Отправляем - await self._send(writer, packet) \ No newline at end of file + await self._send(writer, packet) + + async def folders_update(self, payload, seq, writer, senderPhone): + """Создание папки""" + # Валидируем данные пакета + try: + CreateFolderPayloadModel.model_validate(payload) + except pydantic.ValidationError as error: + self.logger.error(f"Возникли ошибки при валидации пакета: {error}") + await self._send_error(seq, self.opcodes.FOLDERS_UPDATE, self.error_types.INVALID_PAYLOAD, writer) + return + + update_time = int(time.time() * 1000) + + async with self.db_pool.acquire() as conn: + async with conn.cursor() as cursor: + await cursor.execute( + "SELECT COALESCE(MAX(sort_order), -1) as max_order FROM user_folders WHERE phone = %s", + (int(senderPhone),) + ) + row = await cursor.fetchone() + next_order = row["max_order"] + 1 + + # Создаем новую папку + await cursor.execute( + "INSERT INTO user_folders (id, phone, title, filters, `include`, options, source_id, update_time, sort_order) " + "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)", + ( + payload.get("id"), + int(senderPhone), + payload.get("title"), + json.dumps(payload.get("filters")), + json.dumps(payload.get("include", [])), + json.dumps([]), + 1, + update_time, + next_order, + ) + ) + await conn.commit() + + # Получаем обновленный порядок папок + await cursor.execute( + "SELECT id FROM user_folders WHERE phone = %s ORDER BY sort_order", + (int(senderPhone),) + ) + all_folders = await cursor.fetchall() + + folders_order = [f["id"] for f in all_folders] + + # Формируем данные пакета + response_payload = { + "folder": { + "id": payload.get("id"), + "title": payload.get("title"), + "include": payload.get("include"), + "filters": payload.get("filters"), + "updateTime": update_time, + "options": [], + "sourceId": 1, + }, + "folderSync": update_time, + "foldersOrder": folders_order, + } + + # Формируем пакет + packet = self.proto.pack_packet( + cmd=self.proto.CMD_OK, seq=seq, opcode=self.opcodes.FOLDERS_UPDATE, payload=response_payload + ) + + await self._send(writer, packet) + + # Разработчики протокола, объяснитесь, что за хеш !!! а еще подарите нам способ его формирования + notify_about_hash = self.proto.pack_packet( + cmd=0, seq=1, opcode=self.opcodes.NOTIF_CONFIG, + payload={"config": {"hash": "0"}} + ) + + await self._send(writer, notify_about_hash) \ No newline at end of file diff --git a/src/oneme/socket.py b/src/oneme/socket.py index b6fba36..8834133 100644 --- a/src/oneme/socket.py +++ b/src/oneme/socket.py @@ -194,6 +194,15 @@ class OnemeMobile: writer, userPhone, ) + case self.opcodes.FOLDERS_UPDATE: + await self.auth_required( + userPhone, + self.processors.folders_update, + payload, + seq, + writer, + userPhone, + ) case self.opcodes.SESSIONS_INFO: await self.auth_required( userPhone, diff --git a/src/oneme/websocket.py b/src/oneme/websocket.py index 35a6320..9ce1dac 100644 --- a/src/oneme/websocket.py +++ b/src/oneme/websocket.py @@ -168,6 +168,15 @@ class OnemeWS: websocket, userPhone, ) + case self.opcodes.FOLDERS_UPDATE: + await self.auth_required( + userPhone, + self.processors.folders_update, + payload, + seq, + websocket, + userPhone, + ) case self.opcodes.SESSIONS_INFO: await self.auth_required( userPhone, diff --git a/tables.sql b/tables.sql index a2ad81b..f183022 100644 --- a/tables.sql +++ b/tables.sql @@ -102,6 +102,7 @@ CREATE TABLE `user_folders` ( `phone` VARCHAR(20) NOT NULL, `title` VARCHAR(128) NOT NULL, `filters` JSON NOT NULL DEFAULT ('[]'), + `include` JSON NOT NULL DEFAULT ('[]'), `options` JSON NOT NULL DEFAULT ('[]'), `source_id` INT NOT NULL DEFAULT 1, `update_time` BIGINT NOT NULL DEFAULT 0,