maxapi-python 1.2.4__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. maxapi_python-2.0.0.dist-info/METADATA +217 -0
  2. maxapi_python-2.0.0.dist-info/RECORD +140 -0
  3. {maxapi_python-1.2.4.dist-info → maxapi_python-2.0.0.dist-info}/WHEEL +1 -1
  4. pymax/__init__.py +50 -105
  5. pymax/api/__init__.py +17 -0
  6. pymax/api/auth/__init__.py +1 -0
  7. pymax/api/auth/enums.py +17 -0
  8. pymax/api/auth/payloads.py +129 -0
  9. pymax/api/auth/service.py +313 -0
  10. pymax/api/auth/types.py +13 -0
  11. pymax/api/chats/__init__.py +8 -0
  12. pymax/api/chats/enums.py +27 -0
  13. pymax/api/chats/payloads.py +103 -0
  14. pymax/api/chats/service.py +277 -0
  15. pymax/api/facade.py +32 -0
  16. pymax/api/messages/__init__.py +1 -0
  17. pymax/api/messages/enums.py +17 -0
  18. pymax/api/messages/payloads.py +92 -0
  19. pymax/api/messages/service.py +337 -0
  20. pymax/api/models.py +13 -0
  21. pymax/api/response.py +123 -0
  22. pymax/api/self/__init__.py +2 -0
  23. pymax/api/self/enums.py +11 -0
  24. pymax/api/self/payloads.py +41 -0
  25. pymax/api/self/service.py +142 -0
  26. pymax/api/session/__init__.py +1 -0
  27. pymax/api/session/enums.py +10 -0
  28. pymax/api/session/payloads.py +76 -0
  29. pymax/api/session/service.py +72 -0
  30. pymax/api/uploads/__init__.py +1 -0
  31. pymax/api/uploads/models.py +49 -0
  32. pymax/api/uploads/payloads.py +25 -0
  33. pymax/api/uploads/service.py +458 -0
  34. pymax/api/users/__init__.py +2 -0
  35. pymax/api/users/enums.py +12 -0
  36. pymax/api/users/payloads.py +16 -0
  37. pymax/api/users/service.py +124 -0
  38. pymax/app.py +273 -0
  39. pymax/auth/__init__.py +25 -0
  40. pymax/auth/base.py +37 -0
  41. pymax/auth/email.py +0 -0
  42. pymax/auth/models.py +5 -0
  43. pymax/auth/providers.py +127 -0
  44. pymax/auth/qr.py +135 -0
  45. pymax/auth/service.py +25 -0
  46. pymax/auth/sms.py +122 -0
  47. pymax/base.py +204 -0
  48. pymax/client.py +106 -0
  49. pymax/client_web.py +83 -0
  50. pymax/config.py +215 -0
  51. pymax/connection/__init__.py +1 -0
  52. pymax/connection/connection.py +205 -0
  53. pymax/connection/pending.py +46 -0
  54. pymax/connection/readers/__init__.py +2 -0
  55. pymax/connection/readers/base.py +6 -0
  56. pymax/connection/readers/tcp.py +29 -0
  57. pymax/connection/readers/ws.py +14 -0
  58. pymax/dispatch/__init__.py +10 -0
  59. pymax/dispatch/dispatcher.py +222 -0
  60. pymax/dispatch/enums.py +12 -0
  61. pymax/dispatch/mapping.py +73 -0
  62. pymax/dispatch/resolvers.py +52 -0
  63. pymax/dispatch/router.py +216 -0
  64. pymax/exceptions.py +22 -89
  65. pymax/files/__init__.py +9 -0
  66. pymax/files/base.py +82 -0
  67. pymax/files/file.py +76 -0
  68. pymax/files/photo.py +108 -0
  69. pymax/files/static.py +10 -0
  70. pymax/files/video.py +74 -0
  71. pymax/formatting/__init__.py +0 -0
  72. pymax/formatting/markdown.py +217 -0
  73. pymax/infra/__init__.py +1 -0
  74. pymax/infra/auth.py +55 -0
  75. pymax/infra/base.py +15 -0
  76. pymax/infra/chat.py +240 -0
  77. pymax/infra/message.py +252 -0
  78. pymax/infra/protocol.py +9 -0
  79. pymax/infra/self.py +139 -0
  80. pymax/infra/user.py +107 -0
  81. pymax/logging.py +129 -0
  82. pymax/protocol/__init__.py +11 -0
  83. pymax/protocol/base.py +13 -0
  84. pymax/{static/enum.py → protocol/enums.py} +36 -79
  85. pymax/protocol/models.py +33 -0
  86. pymax/protocol/tcp/__init__.py +1 -0
  87. pymax/protocol/tcp/compression.py +97 -0
  88. pymax/protocol/tcp/framing.py +68 -0
  89. pymax/protocol/tcp/payload.py +127 -0
  90. pymax/protocol/tcp/protocol.py +68 -0
  91. pymax/protocol/ws/__init__.py +1 -0
  92. pymax/protocol/ws/protocol.py +27 -0
  93. pymax/py.typed +0 -0
  94. pymax/routers.py +8 -0
  95. pymax/session/__init__.py +3 -0
  96. pymax/session/models.py +11 -0
  97. pymax/session/protocol.py +14 -0
  98. pymax/session/store.py +232 -0
  99. pymax/telemetry/__init__.py +3 -0
  100. pymax/telemetry/navigation.py +181 -0
  101. pymax/telemetry/payloads.py +142 -0
  102. pymax/telemetry/service.py +225 -0
  103. pymax/transport/__init__.py +0 -0
  104. pymax/transport/base.py +14 -0
  105. pymax/transport/tcp.py +93 -0
  106. pymax/transport/websocket.py +50 -0
  107. pymax/types/__init__.py +2 -0
  108. pymax/types/domain/__init__.py +11 -0
  109. pymax/types/domain/attachments/__init__.py +11 -0
  110. pymax/types/domain/attachments/audio.py +35 -0
  111. pymax/types/domain/attachments/call.py +26 -0
  112. pymax/types/domain/attachments/contact.py +32 -0
  113. pymax/types/domain/attachments/control.py +20 -0
  114. pymax/types/domain/attachments/enums.py +27 -0
  115. pymax/types/domain/attachments/file.py +56 -0
  116. pymax/types/domain/attachments/keyboards/__init__.py +1 -0
  117. pymax/types/domain/attachments/keyboards/inline.py +19 -0
  118. pymax/types/domain/attachments/photo.py +45 -0
  119. pymax/types/domain/attachments/share.py +29 -0
  120. pymax/types/domain/attachments/sticker.py +50 -0
  121. pymax/types/domain/attachments/video.py +90 -0
  122. pymax/types/domain/auth.py +161 -0
  123. pymax/types/domain/base.py +17 -0
  124. pymax/types/domain/chat.py +426 -0
  125. pymax/types/domain/element.py +24 -0
  126. pymax/types/domain/enums.py +24 -0
  127. pymax/types/domain/error.py +20 -0
  128. pymax/types/domain/folder.py +74 -0
  129. pymax/types/domain/login.py +35 -0
  130. pymax/types/domain/message.py +378 -0
  131. pymax/types/domain/name.py +20 -0
  132. pymax/types/domain/profile.py +15 -0
  133. pymax/types/domain/session.py +52 -0
  134. pymax/types/domain/sync.py +80 -0
  135. pymax/types/domain/user.py +117 -0
  136. pymax/types/events/__init__.py +3 -0
  137. pymax/types/events/file.py +5 -0
  138. pymax/types/events/message.py +37 -0
  139. pymax/types/events/video.py +5 -0
  140. maxapi_python-1.2.4.dist-info/METADATA +0 -205
  141. maxapi_python-1.2.4.dist-info/RECORD +0 -33
  142. pymax/core.py +0 -390
  143. pymax/crud.py +0 -96
  144. pymax/files.py +0 -138
  145. pymax/filters.py +0 -164
  146. pymax/formatter.py +0 -31
  147. pymax/formatting.py +0 -74
  148. pymax/interfaces.py +0 -552
  149. pymax/mixins/__init__.py +0 -40
  150. pymax/mixins/auth.py +0 -368
  151. pymax/mixins/channel.py +0 -130
  152. pymax/mixins/group.py +0 -458
  153. pymax/mixins/handler.py +0 -285
  154. pymax/mixins/message.py +0 -879
  155. pymax/mixins/scheduler.py +0 -28
  156. pymax/mixins/self.py +0 -259
  157. pymax/mixins/socket.py +0 -297
  158. pymax/mixins/telemetry.py +0 -112
  159. pymax/mixins/user.py +0 -219
  160. pymax/mixins/websocket.py +0 -142
  161. pymax/models.py +0 -8
  162. pymax/navigation.py +0 -187
  163. pymax/payloads.py +0 -367
  164. pymax/protocols.py +0 -123
  165. pymax/static/constant.py +0 -89
  166. pymax/types.py +0 -1220
  167. pymax/utils.py +0 -90
  168. {maxapi_python-1.2.4.dist-info → maxapi_python-2.0.0.dist-info}/licenses/LICENSE +0 -0
pymax/mixins/group.py DELETED
@@ -1,458 +0,0 @@
1
- import time
2
-
3
- from pymax.exceptions import Error
4
- from pymax.payloads import (
5
- ChangeGroupProfilePayload,
6
- ChangeGroupSettingsOptions,
7
- ChangeGroupSettingsPayload,
8
- CreateGroupAttach,
9
- CreateGroupMessage,
10
- CreateGroupPayload,
11
- FetchChatsPayload,
12
- GetChatInfoPayload,
13
- InviteUsersPayload,
14
- JoinChatPayload,
15
- LeaveChatPayload,
16
- RemoveUsersPayload,
17
- ReworkInviteLinkPayload,
18
- )
19
- from pymax.protocols import ClientProtocol
20
- from pymax.static.enum import Opcode
21
- from pymax.types import Chat, Message
22
- from pymax.utils import MixinsUtils
23
-
24
-
25
- class GroupMixin(ClientProtocol):
26
- async def create_group(
27
- self,
28
- name: str,
29
- participant_ids: list[int] | None = None,
30
- notify: bool = True,
31
- ) -> tuple[Chat, Message] | None:
32
- """
33
- Создает группу
34
-
35
- Args:
36
- name (str): Название группы.
37
- participant_ids (list[int] | None, optional): Список идентификаторов участников. Defaults to None.
38
- notify (bool, optional): Флаг оповещения. Defaults to True.
39
-
40
- Returns:
41
- tuple[Chat, Message] | None: Объект Chat и Message или None при ошибке.
42
- """
43
- payload = CreateGroupPayload(
44
- message=CreateGroupMessage(
45
- cid=int(time.time() * 1000),
46
- attaches=[
47
- CreateGroupAttach(
48
- _type="CONTROL",
49
- title=name,
50
- user_ids=(participant_ids if participant_ids else []),
51
- )
52
- ],
53
- ),
54
- notify=notify,
55
- ).model_dump(by_alias=True)
56
-
57
- data = await self._send_and_wait(opcode=Opcode.MSG_SEND, payload=payload)
58
- if data.get("payload", {}).get("error"):
59
- MixinsUtils.handle_error(data)
60
-
61
- chat = Chat.from_dict(data["payload"]["chat"])
62
- message = Message.from_dict(data["payload"])
63
-
64
- if chat:
65
- cached_chat = await self._get_chat(chat.id)
66
- if cached_chat is None:
67
- self.chats.append(chat)
68
- else:
69
- idx = self.chats.index(cached_chat)
70
- self.chats[idx] = chat
71
-
72
- return chat, message
73
-
74
- async def invite_users_to_group(
75
- self,
76
- chat_id: int,
77
- user_ids: list[int],
78
- show_history: bool = True,
79
- ) -> Chat | None:
80
- """
81
- Приглашает пользователей в группу
82
-
83
- Args:
84
- chat_id (int): ID группы.
85
- user_ids (list[int]): Список идентификаторов пользователей.
86
- show_history (bool, optional): Флаг оповещения. Defaults to True.
87
-
88
- Returns:
89
- Chat | None: Объект Chat или None при ошибке.
90
- """
91
- payload = InviteUsersPayload(
92
- chat_id=chat_id,
93
- user_ids=user_ids,
94
- show_history=show_history,
95
- operation="add",
96
- ).model_dump(by_alias=True)
97
-
98
- data = await self._send_and_wait(opcode=Opcode.CHAT_MEMBERS_UPDATE, payload=payload)
99
-
100
- if data.get("payload", {}).get("error"):
101
- MixinsUtils.handle_error(data)
102
-
103
- chat = Chat.from_dict(data["payload"]["chat"])
104
- if chat:
105
- cached_chat = await self._get_chat(chat.id)
106
- if cached_chat is None:
107
- self.chats.append(chat)
108
- else:
109
- idx = self.chats.index(cached_chat)
110
- self.chats[idx] = chat
111
-
112
- return chat
113
-
114
- async def invite_users_to_channel(
115
- self,
116
- chat_id: int,
117
- user_ids: list[int],
118
- show_history: bool = True,
119
- ) -> Chat | None:
120
- """
121
- Приглашает пользователей в канал
122
-
123
- Args:
124
- chat_id (int): ID канала.
125
- user_ids (list[int]): Список идентификаторов пользователей.
126
- show_history (bool, optional): Флаг оповещения. Defaults to True.
127
-
128
- Returns:
129
- Chat | None: Объект Chat или None при ошибке.
130
- """
131
- return await self.invite_users_to_group(chat_id, user_ids, show_history)
132
-
133
- async def remove_users_from_group(
134
- self,
135
- chat_id: int,
136
- user_ids: list[int],
137
- clean_msg_period: int,
138
- ) -> bool:
139
- """
140
- Удаляет пользователей из группы
141
-
142
- Args:
143
- chat_id (int): ID группы.
144
- user_ids (list[int]): Список идентификаторов пользователей.
145
- clean_msg_period (int): Период очистки сообщений.
146
-
147
- Returns:
148
- bool: True, если удаление прошло успешно, иначе False.
149
- """
150
- payload = RemoveUsersPayload(
151
- chat_id=chat_id,
152
- user_ids=user_ids,
153
- clean_msg_period=clean_msg_period,
154
- ).model_dump(by_alias=True)
155
-
156
- data = await self._send_and_wait(opcode=Opcode.CHAT_MEMBERS_UPDATE, payload=payload)
157
-
158
- if data.get("payload", {}).get("error"):
159
- MixinsUtils.handle_error(data)
160
-
161
- chat = Chat.from_dict(data["payload"]["chat"])
162
- if chat:
163
- cached_chat = await self._get_chat(chat.id)
164
- if cached_chat is None:
165
- self.chats.append(chat)
166
- else:
167
- idx = self.chats.index(cached_chat)
168
- self.chats[idx] = chat
169
-
170
- return True
171
-
172
- async def change_group_settings(
173
- self,
174
- chat_id: int,
175
- all_can_pin_message: bool | None = None,
176
- only_owner_can_change_icon_title: bool | None = None,
177
- only_admin_can_add_member: bool | None = None,
178
- only_admin_can_call: bool | None = None,
179
- members_can_see_private_link: bool | None = None,
180
- ) -> None:
181
- """
182
- Изменяет настройки группы
183
-
184
- Args:
185
- chat_id (int): ID группы.
186
- all_can_pin_message (bool | None, optional): Все могут закреплять сообщения. Defaults to None.
187
- only_owner_can_change_icon_title (bool | None, optional): Только владелец может менять иконку и название. Defaults to None.
188
- only_admin_can_add_member (bool | None, optional): Только администраторы могут добавлять участников. Defaults to None.
189
- only_admin_can_call (bool | None, optional): Только администраторы могут звонить. Defaults to None.
190
- members_can_see_private_link (bool | None, optional): Участники могут видеть приватную ссылку. Defaults to None.
191
- Returns:
192
- None
193
- """
194
- payload = ChangeGroupSettingsPayload(
195
- chat_id=chat_id,
196
- options=ChangeGroupSettingsOptions(
197
- ALL_CAN_PIN_MESSAGE=all_can_pin_message,
198
- ONLY_OWNER_CAN_CHANGE_ICON_TITLE=only_owner_can_change_icon_title,
199
- ONLY_ADMIN_CAN_ADD_MEMBER=only_admin_can_add_member,
200
- ONLY_ADMIN_CAN_CALL=only_admin_can_call,
201
- MEMBERS_CAN_SEE_PRIVATE_LINK=members_can_see_private_link,
202
- ),
203
- ).model_dump(by_alias=True, exclude_none=True)
204
-
205
- data = await self._send_and_wait(opcode=Opcode.CHAT_UPDATE, payload=payload)
206
-
207
- if data.get("payload", {}).get("error"):
208
- MixinsUtils.handle_error(data)
209
-
210
- chat = Chat.from_dict(data["payload"]["chat"])
211
- if chat:
212
- cached_chat = await self._get_chat(chat.id)
213
- if cached_chat is None:
214
- self.chats.append(chat)
215
- else:
216
- idx = self.chats.index(cached_chat)
217
- self.chats[idx] = chat
218
-
219
- async def change_group_profile(
220
- self,
221
- chat_id: int,
222
- name: str | None,
223
- description: str | None = None,
224
- ) -> None:
225
- """
226
- Изменяет профиль группы
227
-
228
- Args:
229
- chat_id (int): ID группы.
230
- name (str | None): Название группы.
231
- description (str | None, optional): Описание группы. Defaults to None.
232
-
233
- Returns:
234
- None
235
- """
236
- payload = ChangeGroupProfilePayload(
237
- chat_id=chat_id,
238
- theme=name,
239
- description=description,
240
- ).model_dump(by_alias=True, exclude_none=True)
241
-
242
- data = await self._send_and_wait(opcode=Opcode.CHAT_UPDATE, payload=payload)
243
-
244
- if data.get("payload", {}).get("error"):
245
- MixinsUtils.handle_error(data)
246
-
247
- chat = Chat.from_dict(data["payload"]["chat"])
248
- if chat:
249
- cached_chat = await self._get_chat(chat.id)
250
- if cached_chat is None:
251
- self.chats.append(chat)
252
- else:
253
- idx = self.chats.index(cached_chat)
254
- self.chats[idx] = chat
255
-
256
- def _process_chat_join_link(self, link: str) -> str | None:
257
- idx = link.find("join/")
258
- return link[idx:] if idx != -1 else None
259
-
260
- async def join_group(self, link: str) -> Chat:
261
- """
262
- Вступает в группу по ссылке
263
-
264
- Args:
265
- link (str): Ссылка на группу.
266
-
267
- Returns:
268
- Chat: Объект чата группы
269
- """
270
- proceed_link = self._process_chat_join_link(link)
271
- if proceed_link is None:
272
- raise ValueError("Invalid group link")
273
-
274
- payload = JoinChatPayload(link=proceed_link).model_dump(by_alias=True)
275
-
276
- data = await self._send_and_wait(opcode=Opcode.CHAT_JOIN, payload=payload)
277
-
278
- if data.get("payload", {}).get("error"):
279
- MixinsUtils.handle_error(data)
280
-
281
- chat = Chat.from_dict(data["payload"]["chat"])
282
- if chat:
283
- cached_chat = await self._get_chat(chat.id)
284
- if cached_chat is None:
285
- self.chats.append(chat)
286
- else:
287
- idx = self.chats.index(cached_chat)
288
- self.chats[idx] = chat
289
-
290
- return chat
291
-
292
- async def resolve_group_by_link(self, link: str) -> Chat | None:
293
- """
294
- Разрешает группу по ссылке
295
-
296
- Args:
297
- link (str): Ссылка на группу.
298
-
299
- Returns:
300
- Chat | None: Объект чата группы или None, если не найдено.
301
- """
302
- proceed_link = self._process_chat_join_link(link)
303
- if proceed_link is None:
304
- raise ValueError("Invalid group link")
305
-
306
- data = await self._send_and_wait(
307
- opcode=Opcode.LINK_INFO,
308
- payload={
309
- "link": proceed_link,
310
- },
311
- )
312
-
313
- if data.get("payload", {}).get("error"):
314
- MixinsUtils.handle_error(data)
315
-
316
- chat = Chat.from_dict(data["payload"].get("chat", {}))
317
- return chat
318
-
319
- async def rework_invite_link(self, chat_id: int) -> Chat:
320
- """
321
- Пересоздает ссылку для приглашения в группу
322
-
323
- Args:
324
- chat_id (int): ID группы.
325
-
326
- Returns:
327
- Chat: Обновленный объект чата с новой ссылкой.
328
- """
329
- payload = ReworkInviteLinkPayload(chat_id=chat_id).model_dump(by_alias=True)
330
-
331
- data = await self._send_and_wait(opcode=Opcode.CHAT_UPDATE, payload=payload)
332
-
333
- if data.get("payload", {}).get("error"):
334
- MixinsUtils.handle_error(data)
335
-
336
- chat = Chat.from_dict(data["payload"].get("chat"))
337
- if not chat:
338
- raise Error("no_chat", "Chat data missing in response", "Chat Error")
339
-
340
- return chat
341
-
342
- async def get_chats(self, chat_ids: list[int]) -> list[Chat]:
343
- """
344
- Получает информацию о группах по их ID
345
-
346
- :param chat_ids: Список идентификаторов групп.
347
- :type chat_ids: list[int]
348
- :return: Список объектов Chat.
349
- :rtype: list[Chat]
350
- """
351
- missed_chat_ids = [
352
- chat_id for chat_id in chat_ids if await self._get_chat(chat_id) is None
353
- ]
354
- if missed_chat_ids:
355
- payload = GetChatInfoPayload(chat_ids=missed_chat_ids).model_dump(by_alias=True)
356
- else:
357
- chats: list[Chat] = [
358
- chat for chat_id in chat_ids if (chat := await self._get_chat(chat_id)) is not None
359
- ]
360
- return chats
361
-
362
- data = await self._send_and_wait(opcode=Opcode.CHAT_INFO, payload=payload)
363
-
364
- if data.get("payload", {}).get("error"):
365
- MixinsUtils.handle_error(data)
366
-
367
- chats_data = data["payload"].get("chats", [])
368
- chats: list[Chat] = []
369
- for chat_dict in chats_data:
370
- chat = Chat.from_dict(chat_dict)
371
- chats.append(chat)
372
- cached_chat = await self._get_chat(chat.id)
373
- if cached_chat is None:
374
- self.chats.append(chat)
375
- else:
376
- idx = self.chats.index(cached_chat)
377
- self.chats[idx] = chat
378
-
379
- return chats
380
-
381
- async def get_chat(self, chat_id: int) -> Chat:
382
- """
383
- Получает информацию о группе по ее ID
384
-
385
- Args:
386
- chat_id (int): Идентификатор группы.
387
-
388
- Returns:
389
- Chat: Объект Chat.
390
- """
391
- chats = await self.get_chats([chat_id])
392
- if not chats:
393
- raise Error("no_chat", "Chat not found in response", "Chat Error")
394
- return chats[0]
395
-
396
- async def leave_group(self, chat_id: int) -> None:
397
- """
398
- Покидает группу
399
-
400
- :param chat_id: Идентификатор группы.
401
- :type chat_id: int
402
- :return: None
403
- :rtype: None
404
- """
405
- payload = LeaveChatPayload(chat_id=chat_id).model_dump(by_alias=True)
406
-
407
- data = await self._send_and_wait(opcode=Opcode.CHAT_LEAVE, payload=payload)
408
-
409
- if data.get("payload", {}).get("error"):
410
- MixinsUtils.handle_error(data)
411
-
412
- cached_chat = await self._get_chat(chat_id)
413
- if cached_chat is not None:
414
- self.chats.remove(cached_chat)
415
-
416
- async def leave_channel(self, chat_id: int) -> None:
417
- """
418
- Покидает канал
419
-
420
- :param chat_id: Идентификатор канала.
421
- :type chat_id: int
422
- :return: None
423
- :rtype: None
424
- """
425
- await self.leave_group(chat_id)
426
-
427
- async def fetch_chats(self, marker: int | None = None) -> list[Chat]:
428
- """
429
- Загружает список чатов
430
-
431
- :param marker: Маркер для пагинации, по умолчанию None
432
- :type marker: int | None
433
- :return: Список объектов Chat
434
- :rtype: list[Chat]
435
- """
436
- if marker is None:
437
- marker = int(time.time() * 1000)
438
-
439
- payload = FetchChatsPayload(marker=marker).model_dump(by_alias=True)
440
-
441
- data = await self._send_and_wait(opcode=Opcode.CHATS_LIST, payload=payload)
442
-
443
- if data.get("payload", {}).get("error"):
444
- MixinsUtils.handle_error(data)
445
-
446
- chats_data = data["payload"].get("chats", [])
447
- chats: list[Chat] = []
448
- for chat_dict in chats_data:
449
- chat = Chat.from_dict(chat_dict)
450
- chats.append(chat)
451
- cached_chat = await self._get_chat(chat.id)
452
- if cached_chat is None:
453
- self.chats.append(chat)
454
- else:
455
- idx = self.chats.index(cached_chat)
456
- self.chats[idx] = chat
457
-
458
- return chats