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/types.py DELETED
@@ -1,1220 +0,0 @@
1
- from typing import Any
2
-
3
- from typing_extensions import Self, override
4
-
5
- from .static.enum import (
6
- AccessType,
7
- AttachType,
8
- ChatType,
9
- FormattingType,
10
- MessageStatus,
11
- MessageType,
12
- )
13
-
14
- # TODO: все это нужно переделать на pydantic модели.
15
- # Я просто придерживаюсь текущего стиля.
16
- # - 6RUN0
17
- # Хз, а в чем аргументация, так контроля больше и пайдентик модели явного преимущества не дают.
18
- # - ink-developer
19
-
20
-
21
- class Presence:
22
- def __init__(self, seen: int | None) -> None:
23
- """
24
- Присутствие пользователя.
25
-
26
- {
27
- "seen": {{ unix timestamp }}
28
- },
29
- """
30
- # TODO надо сделать пребразование в datetime с учетом таймзоны
31
- self.seen = seen
32
-
33
- @classmethod
34
- def from_dict(cls, data: dict[str, Any]) -> Self:
35
- return cls(seen=data.get("seen"))
36
-
37
- @override
38
- def __repr__(self) -> str:
39
- return f"Presence(seen={self.seen!r})"
40
-
41
- @override
42
- def __str__(self) -> str:
43
- return f"{self.seen}"
44
-
45
-
46
- class Name:
47
- def __init__(
48
- self,
49
- name: str | None,
50
- first_name: None | str,
51
- last_name: str | None,
52
- type: str | None,
53
- ) -> None:
54
- """
55
- Структура имени пользователя.
56
-
57
- Структура может поменяться, ничего не гарантируется.
58
- На данный момент она такая:
59
- {
60
- "name": "Василий",
61
- "firstName": "Пупкин",
62
- "lastName": "Чеевич",
63
- "type": "ONEME"
64
- }
65
- """
66
- self.name = name
67
- self.first_name = first_name
68
- self.last_name = last_name
69
- self.type = type
70
-
71
- @classmethod
72
- def from_dict(cls, data: dict[str, Any]) -> Self:
73
- return cls(
74
- name=data.get("name"),
75
- first_name=data.get("firstName"),
76
- last_name=data.get("lastName"),
77
- type=data.get("type"),
78
- )
79
-
80
- @override
81
- def __repr__(self) -> str:
82
- return f"Name(name={self.name!r}, first_name={self.first_name!r}, last_name={self.last_name!r}, type={self.type!r})"
83
-
84
- @override
85
- def __str__(self) -> str:
86
- return self.name or ""
87
-
88
-
89
- class Names(Name):
90
- def __init__(
91
- self,
92
- name: str | None,
93
- first_name: None | str,
94
- last_name: str | None,
95
- type: str | None,
96
- ) -> None:
97
- """
98
- Синоним для класса Name.
99
- """
100
- super().__init__(name=name, first_name=first_name, last_name=last_name, type=type)
101
-
102
-
103
- class Contact:
104
- def __init__(
105
- self,
106
- id: int | None,
107
- account_status: int | None,
108
- base_raw_url: str | None,
109
- base_url: str | None,
110
- names: list[Name] | None,
111
- options: list[str] | None,
112
- photo_id: int | None,
113
- update_time: int | None,
114
- ) -> None:
115
- """
116
- Контакт.
117
-
118
- Сруктура:
119
- {
120
- "accountStatus": 0,
121
- "baseUrl": "https://i.oneme.ru/i?r=...",
122
- "names": [
123
- Name{},
124
- ],
125
- "options": [
126
- "TT",
127
- "ONEME"
128
- ],
129
- "photoId": {{ file id }},
130
- "updateTime": 0,
131
- "id": {{ user id }},
132
- "baseRawUrl": "https://i.oneme.ru/i?r=..."
133
- }
134
- """
135
- self.id = id
136
- self.account_status = account_status
137
- self.base_raw_url = base_raw_url
138
- self.base_url = base_url
139
- self.names = names
140
- self.options = options or []
141
- self.photo_id = photo_id
142
- # TODO надо сделать пребразование в datetime с учетом таймзоны
143
- self.update_time = update_time
144
-
145
- @classmethod
146
- def from_dict(cls, data: dict[str, Any]) -> Self:
147
- return cls(
148
- account_status=data.get("accountStatus"),
149
- update_time=data.get("updateTime"),
150
- id=data.get("id"),
151
- names=[Name.from_dict(n) for n in data.get("names", [])],
152
- options=data.get("options"),
153
- base_url=data.get("baseUrl"),
154
- base_raw_url=data.get("baseRawUrl"),
155
- photo_id=data.get("photoId"),
156
- )
157
-
158
- @override
159
- def __repr__(self) -> str:
160
- return f"Contact(id={self.id!r}, names={self.names!r}, status={self.account_status!r})"
161
-
162
- @override
163
- def __str__(self) -> str:
164
- return f"Contact {self.id}: {', '.join(str(n) for n in self.names or [])}"
165
-
166
-
167
- class Member:
168
- def __init__(
169
- self,
170
- contact: Contact,
171
- presence: Presence,
172
- read_mark: int | None,
173
- ) -> None:
174
- """
175
- Участник чата.
176
-
177
- Структура:
178
- {
179
- "presence": Presence{}
180
- "readMark": {{ timestamp with milliseconds }},
181
- "contact": Contact{}
182
- },
183
- """
184
- self.presence = presence
185
- # TODO надо сделать пребразование в datetime с учетом таймзоны
186
- self.read_mark = read_mark
187
- self.contact = contact
188
-
189
- @classmethod
190
- def from_dict(cls, data: dict[str, Any]) -> Self:
191
- presence_value = data.get("presence")
192
- if isinstance(presence_value, dict):
193
- presence = Presence.from_dict(presence_value)
194
- else:
195
- presence = Presence.from_dict({})
196
- contact_value = data.get("contact")
197
- if isinstance(contact_value, dict):
198
- contact = Contact.from_dict(contact_value)
199
- else:
200
- contact = Contact.from_dict({})
201
- return cls(
202
- contact=contact,
203
- presence=presence,
204
- read_mark=data.get("readMark"),
205
- )
206
-
207
- @override
208
- def __repr__(self) -> str:
209
- return f"Member(presence={self.presence!r}, read_mark={self.read_mark!r}, contact={self.contact!r})"
210
-
211
- @override
212
- def __str__(self) -> str:
213
- return f"Member {self.contact.id}: {', '.join(str(n) for n in self.contact.names or [])}"
214
-
215
-
216
- class StickerAttach:
217
- def __init__(
218
- self,
219
- author_type: str,
220
- lottie_url: str | None,
221
- url: str,
222
- sticker_id: int,
223
- tags: list[str] | None,
224
- width: int,
225
- set_id: int,
226
- time: int,
227
- sticker_type: str,
228
- audio: bool,
229
- height: int,
230
- type: AttachType,
231
- ):
232
- self.author_type = author_type
233
- self.lottie_url = lottie_url
234
- self.url = url
235
- self.sticker_id = sticker_id
236
- self.tags = tags
237
- self.width = width
238
- self.set_id = set_id
239
- self.time = time
240
- self.sticker_type = sticker_type
241
- self.audio = audio
242
- self.height = height
243
- self.type = type
244
-
245
- @classmethod
246
- def from_dict(cls, data: dict[str, Any]) -> Self:
247
- return cls(
248
- author_type=data["authorType"],
249
- lottie_url=data.get("lottieUrl"),
250
- url=data["url"],
251
- sticker_id=data["stickerId"],
252
- tags=data.get("tags"),
253
- width=data["width"],
254
- set_id=data["setId"],
255
- time=data["time"],
256
- sticker_type=data["stickerType"],
257
- audio=data["audio"],
258
- height=data["height"],
259
- type=AttachType(data["_type"]),
260
- )
261
-
262
- @override
263
- def __repr__(self) -> str:
264
- return (
265
- f"StickerAttach(author_type={self.author_type!r}, lottie_url={self.lottie_url!r}, "
266
- f"url={self.url!r}, sticker_id={self.sticker_id!r}, tags={self.tags!r}, "
267
- f"width={self.width!r}, set_id={self.set_id!r}, time={self.time!r}, "
268
- f"sticker_type={self.sticker_type!r}, audio={self.audio!r}, height={self.height!r}, "
269
- f"type={self.type!r})"
270
- )
271
-
272
- @override
273
- def __str__(self) -> str:
274
- return f"StickerAttach: {self.sticker_id}"
275
-
276
-
277
- class ControlAttach:
278
- def __init__(self, type: AttachType, event: str, **kwargs: dict[str, Any]) -> None:
279
- self.type = type
280
- self.event = event
281
- self.extra = kwargs
282
-
283
- @classmethod
284
- def from_dict(cls, data: dict[str, Any]) -> Self:
285
- data = dict(data)
286
- attach_type = AttachType(data.pop("_type"))
287
- event = data.pop("event")
288
- return cls(
289
- type=attach_type,
290
- event=event,
291
- **data,
292
- )
293
-
294
- @override
295
- def __repr__(self) -> str:
296
- return f"ControlAttach(type={self.type!r}, event={self.event!r}, extra={self.extra!r})"
297
-
298
- @override
299
- def __str__(self) -> str:
300
- return f"ControlAttach: {self.event}"
301
-
302
-
303
- class AudioAttach:
304
- def __init__(
305
- self,
306
- duration: int,
307
- audio_id: int,
308
- url: str,
309
- wave: str,
310
- transcription_status: str, # TODO: сделать энам
311
- token: str,
312
- type: AttachType,
313
- ) -> None:
314
- self.duration = duration
315
- self.audio_id = audio_id
316
- self.url = url
317
- self.wave = wave
318
- self.transcription_status = transcription_status
319
- self.token = token
320
- self.type = type
321
-
322
- @classmethod
323
- def from_dict(cls, data: dict[str, Any]) -> Self:
324
- return cls(
325
- duration=data["duration"],
326
- audio_id=data["audioId"],
327
- url=data["url"],
328
- wave=data["wave"],
329
- transcription_status=data["transcriptionStatus"],
330
- token=data["token"],
331
- type=AttachType(data["_type"]),
332
- )
333
-
334
- @override
335
- def __repr__(self) -> str:
336
- return (
337
- f"AudioAttach(duration={self.duration!r}, audio_id={self.audio_id!r}, "
338
- f"url={self.url!r}, wave={self.wave!r}, transcription_status={self.transcription_status!r}, "
339
- f"token={self.token!r}, type={self.type!r})"
340
- )
341
-
342
- @override
343
- def __str__(self) -> str:
344
- return f"AudioAttach: {self.audio_id}"
345
-
346
-
347
- class PhotoAttach:
348
- def __init__(
349
- self,
350
- base_url: str,
351
- height: int,
352
- width: int,
353
- photo_id: int,
354
- photo_token: str,
355
- preview_data: str | None,
356
- type: AttachType,
357
- ) -> None:
358
- self.base_url = base_url
359
- self.height = height
360
- self.width = width
361
- self.photo_id = photo_id
362
- self.photo_token = photo_token
363
- self.preview_data = preview_data
364
- self.type = type
365
-
366
- @classmethod
367
- def from_dict(cls, data: dict[str, Any]) -> Self:
368
- return cls(
369
- base_url=data["baseUrl"],
370
- height=data["height"],
371
- width=data["width"],
372
- photo_id=data["photoId"],
373
- photo_token=data["photoToken"],
374
- preview_data=data.get("previewData"),
375
- type=AttachType(data["_type"]),
376
- )
377
-
378
- @override
379
- def __repr__(self) -> str:
380
- return (
381
- f"PhotoAttach(photo_id={self.photo_id!r}, base_url={self.base_url!r}, "
382
- f"height={self.height!r}, width={self.width!r}, photo_token={self.photo_token!r}, "
383
- f"preview_data={self.preview_data!r}, type={self.type!r})"
384
- )
385
-
386
- @override
387
- def __str__(self) -> str:
388
- return f"PhotoAttach: {self.photo_id}"
389
-
390
-
391
- class VideoAttach:
392
- def __init__(
393
- self,
394
- height: int,
395
- width: int,
396
- video_id: int,
397
- duration: int,
398
- preview_data: str,
399
- type: AttachType,
400
- thumbnail: str,
401
- token: str,
402
- video_type: int,
403
- ) -> None:
404
- self.height = height
405
- self.width = width
406
- self.video_id = video_id
407
- self.duration = duration
408
- self.preview_data = preview_data
409
- self.type = type
410
- self.thumbnail = thumbnail
411
- self.token = token
412
- self.video_type = video_type
413
-
414
- @classmethod
415
- def from_dict(cls, data: dict[str, Any]) -> Self:
416
- return cls(
417
- height=data["height"],
418
- width=data["width"],
419
- video_id=data["videoId"],
420
- duration=data["duration"],
421
- preview_data=data["previewData"],
422
- type=AttachType(data["_type"]),
423
- thumbnail=data["thumbnail"],
424
- token=data["token"],
425
- video_type=data["videoType"],
426
- )
427
-
428
- @override
429
- def __repr__(self) -> str:
430
- return (
431
- f"VideoAttach(video_id={self.video_id!r}, height={self.height!r}, "
432
- f"width={self.width!r}, duration={self.duration!r}, "
433
- f"preview_data={self.preview_data!r}, type={self.type!r}, "
434
- f"thumbnail={self.thumbnail!r}, token={self.token!r}, "
435
- f"video_type={self.video_type!r})"
436
- )
437
-
438
- @override
439
- def __str__(self) -> str:
440
- return f"VideoAttach: {self.video_id}"
441
-
442
-
443
- class FileAttach:
444
- def __init__(self, file_id: int, name: str, size: int, token: str, type: AttachType) -> None:
445
- self.file_id = file_id
446
- self.name = name
447
- self.size = size
448
- self.token = token
449
- self.type = type
450
-
451
- @classmethod
452
- def from_dict(cls, data: dict[str, Any]) -> Self:
453
- return cls(
454
- file_id=data["fileId"],
455
- name=data["name"],
456
- size=data["size"],
457
- token=data["token"],
458
- type=AttachType(data["_type"]),
459
- )
460
-
461
- @override
462
- def __repr__(self) -> str:
463
- return (
464
- f"FileAttach(file_id={self.file_id!r}, name={self.name!r}, "
465
- f"size={self.size!r}, token={self.token!r}, type={self.type!r})"
466
- )
467
-
468
- @override
469
- def __str__(self) -> str:
470
- return f"FileAttach: {self.file_id}"
471
-
472
-
473
- class FileRequest:
474
- def __init__(
475
- self,
476
- unsafe: bool,
477
- url: str,
478
- ) -> None:
479
- self.unsafe = unsafe
480
- self.url = url
481
-
482
- @classmethod
483
- def from_dict(cls, data: dict[str, Any]) -> Self:
484
- return cls(
485
- unsafe=data["unsafe"],
486
- url=data["url"],
487
- )
488
-
489
-
490
- class VideoRequest:
491
- def __init__(
492
- self,
493
- external: str,
494
- cache: bool,
495
- url: str,
496
- ) -> None:
497
- self.external = external
498
- self.cache = cache
499
- self.url = url
500
-
501
- @classmethod
502
- def from_dict(cls, data: dict[str, Any]) -> Self:
503
- # listdata = list(data.values()) # Костыль ✅
504
- url = [v for k, v in data.items() if k not in ("EXTERNAL", "cache")][
505
- 0
506
- ] # Еще больший костыль ✅
507
- return cls(
508
- external=data["EXTERNAL"],
509
- cache=data["cache"],
510
- url=url,
511
- )
512
-
513
-
514
- class Me:
515
- def __init__(
516
- self,
517
- id: int,
518
- account_status: int,
519
- phone: str,
520
- names: list[Names],
521
- update_time: int,
522
- options: list[str] | None = None,
523
- ) -> None:
524
- self.id = id
525
- self.account_status = account_status
526
- self.phone = phone
527
- self.update_time = update_time
528
- self.options = options
529
- self.names = names
530
-
531
- @classmethod
532
- def from_dict(cls, data: dict[str, Any]) -> Self:
533
- return cls(
534
- id=data["id"],
535
- account_status=data["accountStatus"],
536
- phone=data["phone"],
537
- names=[Names.from_dict(n) for n in data["names"]],
538
- update_time=data["updateTime"],
539
- options=data.get("options"),
540
- )
541
-
542
- @override
543
- def __repr__(self) -> str:
544
- return f"Me(id={self.id!r}, account_status={self.account_status!r}, phone={self.phone!r}, names={self.names!r}, update_time={self.update_time!r}, options={self.options!r})"
545
-
546
- @override
547
- def __str__(self) -> str:
548
- return f"Me {self.id}: {', '.join(str(n) for n in self.names)}"
549
-
550
-
551
- class Element:
552
- def __init__(self, type: FormattingType | str, length: int, from_: int | None = None) -> None:
553
- self.type = type
554
- self.length = length
555
- self.from_ = from_
556
-
557
- @classmethod
558
- def from_dict(cls, data: dict[Any, Any]) -> Self:
559
- return cls(type=data["type"], length=data["length"], from_=data.get("from"))
560
-
561
- @override
562
- def __repr__(self) -> str:
563
- return f"Element(type={self.type!r}, length={self.length!r}, from_={self.from_!r})"
564
-
565
- @override
566
- def __str__(self) -> str:
567
- return f"{self.type}({self.length})"
568
-
569
-
570
- class MessageLink:
571
- def __init__(self, chat_id: int, message: "Message", type: str) -> None:
572
- self.chat_id = chat_id
573
- self.message = message
574
- self.type = type
575
-
576
- @classmethod
577
- def from_dict(cls, data: dict[str, Any]) -> Self:
578
- return cls(
579
- chat_id=data["chatId"],
580
- message=Message.from_dict(data["message"]),
581
- type=data["type"],
582
- )
583
-
584
- @override
585
- def __repr__(self) -> str:
586
- return (
587
- f"MessageLink(chat_id={self.chat_id!r}, message={self.message!r}, type={self.type!r})"
588
- )
589
-
590
- @override
591
- def __str__(self) -> str:
592
- return f"MessageLink: {self.chat_id}/{self.message.id}"
593
-
594
-
595
- class ReactionCounter:
596
- def __init__(self, count: int, reaction: str) -> None:
597
- self.count = count
598
- self.reaction = reaction
599
-
600
- @classmethod
601
- def from_dict(cls, data: dict[str, Any]) -> Self:
602
- return cls(count=data["count"], reaction=data["reaction"])
603
-
604
- @override
605
- def __repr__(self) -> str:
606
- return f"ReactionCounter(count={self.count!r}, reaction={self.reaction!r})"
607
-
608
- @override
609
- def __str__(self) -> str:
610
- return f"{self.reaction}: {self.count}"
611
-
612
-
613
- class ReactionInfo:
614
- def __init__(
615
- self,
616
- total_count: int,
617
- counters: list[ReactionCounter],
618
- your_reaction: str | None = None,
619
- ) -> None:
620
- self.total_count = total_count
621
- self.counters = counters
622
- self.your_reaction = your_reaction
623
-
624
- @classmethod
625
- def from_dict(cls, data: dict[str, Any]) -> Self:
626
- return cls(
627
- total_count=data.get("totalCount", 0),
628
- counters=[ReactionCounter.from_dict(c) for c in data.get("counters", [])],
629
- your_reaction=data.get("yourReaction"),
630
- )
631
-
632
-
633
- class ContactAttach:
634
- def __init__(
635
- self, contact_id: int, first_name: str, last_name: str, name: str, photo_url: str
636
- ) -> None:
637
- self.contact_id = contact_id
638
- self.first_name = first_name
639
- self.last_name = last_name
640
- self.name = name
641
- self.photo_url = photo_url
642
- self.type = AttachType.CONTACT
643
-
644
- @classmethod
645
- def from_dict(cls, data: dict[str, Any]) -> Self:
646
- return cls(
647
- contact_id=data["contactId"],
648
- first_name=data["firstName"],
649
- last_name=data["lastName"],
650
- name=data["name"],
651
- photo_url=data["photoUrl"],
652
- )
653
-
654
- @override
655
- def __repr__(self) -> str:
656
- return f"ContactAttach(contact_id={self.contact_id!r}, first_name={self.first_name!r}, last_name={self.last_name!r}, name={self.name!r}, photo_url={self.photo_url!r})"
657
-
658
- @override
659
- def __str__(self) -> str:
660
- return f"ContactAttach: {self.name}"
661
-
662
-
663
- class Message:
664
- def __init__(
665
- self,
666
- chat_id: int | None,
667
- sender: int | None,
668
- elements: list[Element] | None,
669
- reaction_info: ReactionInfo | None,
670
- options: int | None,
671
- id: int,
672
- time: int,
673
- link: MessageLink | None,
674
- text: str,
675
- status: MessageStatus | None,
676
- type: MessageType | str,
677
- attaches: (
678
- list[
679
- PhotoAttach
680
- | VideoAttach
681
- | FileAttach
682
- | ControlAttach
683
- | StickerAttach
684
- | AudioAttach
685
- | ContactAttach
686
- ]
687
- | None
688
- ),
689
- ) -> None:
690
- self.chat_id = chat_id
691
- self.sender = sender
692
- self.elements = elements
693
- self.options = options
694
- self.id = id
695
- self.time = time
696
- self.text = text
697
- self.type = type
698
- self.attaches = attaches
699
- self.status = status
700
- self.link = link
701
- self.reactionInfo = reaction_info
702
-
703
- @classmethod
704
- def from_dict(cls, data: dict[Any, Any]) -> Self:
705
- message = data["message"] if data.get("message") else data
706
- attaches: list[
707
- PhotoAttach
708
- | VideoAttach
709
- | FileAttach
710
- | ControlAttach
711
- | StickerAttach
712
- | AudioAttach
713
- | ContactAttach
714
- ] = []
715
- for a in message.get("attaches", []):
716
- if a["_type"] == AttachType.PHOTO:
717
- attaches.append(PhotoAttach.from_dict(a))
718
- elif a["_type"] == AttachType.VIDEO:
719
- attaches.append(VideoAttach.from_dict(a))
720
- elif a["_type"] == AttachType.FILE:
721
- attaches.append(FileAttach.from_dict(a))
722
- elif a["_type"] == AttachType.CONTROL:
723
- attaches.append(ControlAttach.from_dict(a))
724
- elif a["_type"] == AttachType.STICKER:
725
- attaches.append(StickerAttach.from_dict(a))
726
- elif a["_type"] == AttachType.AUDIO:
727
- attaches.append(AudioAttach.from_dict(a))
728
- elif a["_type"] == AttachType.CONTACT:
729
- attaches.append(ContactAttach.from_dict(a))
730
- link_value = message.get("link")
731
- if isinstance(link_value, dict):
732
- link = MessageLink.from_dict(link_value)
733
- else:
734
- link = None
735
- reaction_info_value = message.get("reactionInfo")
736
- if isinstance(reaction_info_value, dict):
737
- reaction_info = ReactionInfo.from_dict(reaction_info_value)
738
- else:
739
- reaction_info = None
740
- return cls(
741
- chat_id=data.get("chatId"),
742
- sender=message.get("sender"),
743
- elements=[Element.from_dict(e) for e in message.get("elements", [])],
744
- options=message.get("options"),
745
- id=message["id"],
746
- time=message["time"],
747
- text=message["text"],
748
- type=message["type"],
749
- attaches=attaches,
750
- status=message.get("status"),
751
- link=link,
752
- reaction_info=reaction_info,
753
- )
754
-
755
- @override
756
- def __repr__(self) -> str:
757
- return (
758
- f"Message(id={self.id!r}, sender={self.sender!r}, text={self.text!r}, "
759
- f"type={self.type!r}, status={self.status!r}, elements={self.elements!r})"
760
- f"attaches={self.attaches!r}, chat_id={self.chat_id!r}, time={self.time!r}, options={self.options!r}, reactionInfo={self.reactionInfo!r})"
761
- )
762
-
763
- @override
764
- def __str__(self) -> str:
765
- return f"Message {self.id} from {self.sender}: {self.text}"
766
-
767
-
768
- class Dialog:
769
- def __init__(
770
- self,
771
- cid: int | None,
772
- owner: int,
773
- has_bots: bool | None,
774
- join_time: int,
775
- created: int,
776
- last_message: Message | None,
777
- type: ChatType | str,
778
- last_fire_delayed_error_time: int,
779
- last_delayed_update_time: int,
780
- prev_message_id: str | None,
781
- options: dict[str, bool],
782
- modified: int,
783
- last_event_time: int,
784
- id: int,
785
- status: str,
786
- participants: dict[str, int],
787
- ) -> None:
788
- self.cid = cid
789
- self.owner = owner
790
- self.has_bots = has_bots
791
- self.join_time = join_time
792
- self.created = created
793
- self.last_message = last_message
794
- self.type = type
795
- self.last_fire_delayed_error_time = last_fire_delayed_error_time
796
- self.last_delayed_update_time = last_delayed_update_time
797
- self.prev_message_id = prev_message_id
798
- self.options = options
799
- self.modified = modified
800
- self.last_event_time = last_event_time
801
- self.id = id
802
- self.status = status
803
- self.participants = participants
804
-
805
- @classmethod
806
- def from_dict(cls, data: dict[Any, Any]) -> Self:
807
- return cls(
808
- cid=data.get("cid"),
809
- owner=data["owner"],
810
- has_bots=data.get("hasBots"),
811
- join_time=data["joinTime"],
812
- created=data["created"],
813
- last_message=(
814
- Message.from_dict(data["lastMessage"]) if data.get("lastMessage") else None
815
- ),
816
- type=ChatType(data["type"]),
817
- last_fire_delayed_error_time=data["lastFireDelayedErrorTime"],
818
- last_delayed_update_time=data["lastDelayedUpdateTime"],
819
- prev_message_id=data.get("prevMessageId"),
820
- options=data.get("options", {}),
821
- modified=data["modified"],
822
- last_event_time=data["lastEventTime"],
823
- id=data["id"],
824
- status=data["status"],
825
- participants=data["participants"],
826
- )
827
-
828
- @override
829
- def __repr__(self) -> str:
830
- return f"Dialog(id={self.id!r}, owner={self.owner!r}, type={self.type!r}, last_message={self.last_message!r})"
831
-
832
- @override
833
- def __str__(self) -> str:
834
- return f"Dialog {self.id} ({self.type})"
835
-
836
-
837
- class Chat:
838
- def __init__(
839
- self,
840
- participants_count: int,
841
- access: AccessType | str,
842
- invited_by: int | None,
843
- link: str | None,
844
- chat_type: ChatType | str,
845
- title: str | None,
846
- last_fire_delayed_error_time: int,
847
- last_delayed_update_time: int,
848
- options: dict[str, bool],
849
- base_raw_icon_url: str | None,
850
- base_icon_url: str | None,
851
- description: str | None,
852
- modified: int,
853
- id_: int,
854
- admin_participants: dict[int, dict[Any, Any]],
855
- participants: dict[int, int],
856
- owner: int,
857
- join_time: int,
858
- created: int,
859
- last_message: Message | None,
860
- prev_message_id: str | None,
861
- last_event_time: int,
862
- messages_count: int,
863
- admins: list[int],
864
- restrictions: int | None,
865
- status: str,
866
- cid: int,
867
- ) -> None:
868
- self.participants_count = participants_count
869
- self.access = access
870
- self.invited_by = invited_by
871
- self.link = link
872
- self.type = chat_type
873
- self.title = title
874
- self.last_fire_delayed_error_time = last_fire_delayed_error_time
875
- self.last_delayed_update_time = last_delayed_update_time
876
- self.options = options
877
- self.base_raw_icon_url = base_raw_icon_url
878
- self.base_icon_url = base_icon_url
879
- self.description = description
880
- self.modified = modified
881
- self.id = id_
882
- self.admin_participants = admin_participants
883
- self.participants = participants
884
- self.owner = owner
885
- self.join_time = join_time
886
- self.created = created
887
- self.last_message = last_message
888
- self.prev_message_id = prev_message_id
889
- self.last_event_time = last_event_time
890
- self.messages_count = messages_count
891
- self.admins = admins
892
- self.restrictions = restrictions
893
- self.status = status
894
- self.cid = cid
895
-
896
- @classmethod
897
- def from_dict(cls, data: dict[Any, Any]) -> Self:
898
- raw_admins = data.get("adminParticipants", {}) or {}
899
- admin_participants: dict[int, dict[Any, Any]] = {int(k): v for k, v in raw_admins.items()}
900
- raw_participants = data.get("participants", {}) or {}
901
- participants: dict[int, int] = {int(k): v for k, v in raw_participants.items()}
902
- last_msg = Message.from_dict(data["lastMessage"]) if data.get("lastMessage") else None
903
- return cls(
904
- participants_count=data.get("participantsCount", 0),
905
- access=AccessType(data.get("access", AccessType.PUBLIC.value)),
906
- invited_by=data.get("invitedBy"),
907
- link=data.get("link"),
908
- base_raw_icon_url=data.get("baseRawIconUrl"),
909
- base_icon_url=data.get("baseIconUrl"),
910
- description=data.get("description"),
911
- chat_type=ChatType(data.get("type", ChatType.CHAT.value)),
912
- title=data.get("title"),
913
- last_fire_delayed_error_time=data.get("lastFireDelayedErrorTime", 0),
914
- last_delayed_update_time=data.get("lastDelayedUpdateTime", 0),
915
- options=data.get("options", {}),
916
- modified=data.get("modified", 0),
917
- id_=data.get("id", 0),
918
- admin_participants=admin_participants,
919
- participants=participants,
920
- owner=data.get("owner", 0),
921
- join_time=data.get("joinTime", 0),
922
- created=data.get("created", 0),
923
- last_message=last_msg,
924
- prev_message_id=data.get("prevMessageId"),
925
- last_event_time=data.get("lastEventTime", 0),
926
- messages_count=data.get("messagesCount", 0),
927
- admins=data.get("admins", []),
928
- restrictions=data.get("restrictions"),
929
- status=data.get("status", ""),
930
- cid=data.get("cid", 0),
931
- )
932
-
933
- @override
934
- def __repr__(self) -> str:
935
- return f"Chat(id={self.id!r}, title={self.title!r}, type={self.type!r})"
936
-
937
- @override
938
- def __str__(self) -> str:
939
- return f"{self.title} ({self.type})"
940
-
941
-
942
- class Channel(Chat):
943
- @override
944
- def __repr__(self) -> str:
945
- return f"Channel(id={self.id!r}, title={self.title!r})"
946
-
947
- @override
948
- def __str__(self) -> str:
949
- return f"Channel: {self.title}"
950
-
951
-
952
- class User:
953
- def __init__(
954
- self,
955
- account_status: int,
956
- update_time: int,
957
- id: int,
958
- names: list[Names],
959
- options: list[str] | None = None,
960
- base_url: str | None = None,
961
- base_raw_url: str | None = None,
962
- photo_id: int | None = None,
963
- description: str | None = None,
964
- gender: int | None = None,
965
- link: str | None = None,
966
- web_app: str | None = None,
967
- menu_button: dict[str, Any] | None = None,
968
- ) -> None:
969
- self.account_status = account_status
970
- self.update_time = update_time
971
- self.id = id
972
- self.names = names
973
- self.options = options or []
974
- self.base_url = base_url
975
- self.base_raw_url = base_raw_url
976
- self.photo_id = photo_id
977
- self.description = description
978
- self.gender = gender
979
- self.link = link
980
- self.web_app = web_app
981
- self.menu_button = menu_button
982
-
983
- @classmethod
984
- def from_dict(cls, data: dict[str, Any]) -> Self:
985
- return cls(
986
- account_status=data["accountStatus"],
987
- update_time=data["updateTime"],
988
- id=data["id"],
989
- names=[Names.from_dict(n) for n in data.get("names", [])],
990
- options=data.get("options"),
991
- base_url=data.get("baseUrl"),
992
- base_raw_url=data.get("baseRawUrl"),
993
- photo_id=data.get("photoId"),
994
- description=data.get("description"),
995
- gender=data.get("gender"),
996
- link=data.get("link"),
997
- web_app=data.get("webApp"),
998
- menu_button=data.get("menuButton"),
999
- )
1000
-
1001
- @override
1002
- def __repr__(self) -> str:
1003
- return f"User(id={self.id!r}, names={self.names!r}, status={self.account_status!r})"
1004
-
1005
- @override
1006
- def __str__(self) -> str:
1007
- return f"User {self.id}: {', '.join(str(n) for n in self.names)}"
1008
-
1009
-
1010
- class Attach: # УБРАТЬ ГАДА!!! или нет...
1011
- def __init__(
1012
- self,
1013
- _type: AttachType,
1014
- video_id: int | None = None,
1015
- photo_token: str | None = None,
1016
- file_id: int | None = None,
1017
- token: str | None = None,
1018
- ) -> None:
1019
- self.type = _type
1020
- self.video_id = video_id
1021
- self.photo_token = photo_token
1022
- self.file_id = file_id
1023
- self.token = token
1024
-
1025
- @classmethod
1026
- def from_dict(cls, data: dict[str, Any]) -> Self:
1027
- return cls(
1028
- _type=AttachType(data["type"]),
1029
- video_id=data.get("videoId"),
1030
- photo_token=data.get("photoToken"),
1031
- file_id=data.get("fileId"),
1032
- token=data.get("token"),
1033
- )
1034
-
1035
- @override
1036
- def __repr__(self) -> str:
1037
- return (
1038
- f"Attach(type={self.type!r}, video_id={self.video_id!r}, "
1039
- f"photo_token={self.photo_token!r}, file_id={self.file_id!r}, token={self.token!r})"
1040
- )
1041
-
1042
- @override
1043
- def __str__(self) -> str:
1044
- return f"Attach: {self.type}"
1045
-
1046
-
1047
- class Session:
1048
- def __init__(
1049
- self,
1050
- client: str,
1051
- info: str,
1052
- location: str,
1053
- time: int,
1054
- current: bool | None = None,
1055
- ) -> None:
1056
- self.client = client
1057
- self.info = info
1058
- self.location = location
1059
- self.time = time
1060
- self.current = current if current is not None else False
1061
-
1062
- @classmethod
1063
- def from_dict(cls, data: dict[str, Any]) -> Self:
1064
- return cls(
1065
- client=data["client"],
1066
- info=data["info"],
1067
- location=data["location"],
1068
- time=data["time"],
1069
- current=data.get("current"),
1070
- )
1071
-
1072
- @override
1073
- def __repr__(self) -> str:
1074
- return (
1075
- f"Session(client={self.client!r}, info={self.info!r}, "
1076
- f"location={self.location!r}, time={self.time!r}, current={self.current!r})"
1077
- )
1078
-
1079
- @override
1080
- def __str__(self) -> str:
1081
- return (
1082
- f"Session: {self.client} from {self.location} at {self.time} (current={self.current})"
1083
- )
1084
-
1085
-
1086
- class Folder:
1087
- def __init__(
1088
- self,
1089
- source_id: int,
1090
- include: list[int],
1091
- options: list[Any],
1092
- update_time: int,
1093
- id: str,
1094
- filters: list[Any],
1095
- title: str,
1096
- ) -> None:
1097
- self.source_id = source_id
1098
- self.include = include
1099
- self.options = options
1100
- self.update_time = update_time
1101
- self.id = id
1102
- self.filters = filters
1103
- self.title = title
1104
-
1105
- @classmethod
1106
- def from_dict(cls, data: dict[str, Any]) -> Self:
1107
- return cls(
1108
- source_id=data.get("sourceId", 0),
1109
- include=data.get("include", []),
1110
- options=data.get("options", []),
1111
- update_time=data.get("updateTime", 0),
1112
- id=data.get("id", ""),
1113
- filters=data.get("filters", []),
1114
- title=data.get("title", ""),
1115
- )
1116
-
1117
- @override
1118
- def __repr__(self) -> str:
1119
- return (
1120
- f"Folder(id={self.id!r}, title={self.title!r}, source_id={self.source_id!r}, "
1121
- f"include={self.include!r}, options={self.options!r}, "
1122
- f"update_time={self.update_time!r}, filters={self.filters!r})"
1123
- )
1124
-
1125
- @override
1126
- def __str__(self) -> str:
1127
- return f"Folder: {self.title} ({self.id})"
1128
-
1129
-
1130
- class FolderUpdate:
1131
- def __init__(
1132
- self, folder_order: list[str] | None, folder: Folder | None, folder_sync: int
1133
- ) -> None:
1134
- self.folder_order = folder_order
1135
- self.folder = folder
1136
- self.folder_sync = folder_sync
1137
-
1138
- @classmethod
1139
- def from_dict(cls, data: dict[str, Any]) -> Self:
1140
- folder_order = data.get("foldersOrder", [])
1141
- folder_sync = data.get("folderSync", 0)
1142
- folder_data = data.get("folder", {})
1143
- folder = Folder.from_dict(folder_data)
1144
- return cls(
1145
- folder_order=folder_order,
1146
- folder=folder,
1147
- folder_sync=folder_sync,
1148
- )
1149
-
1150
- @override
1151
- def __repr__(self) -> str:
1152
- return (
1153
- f"FolderUpdate(folder_order={self.folder_order!r}, "
1154
- f"folder={self.folder!r}, folder_sync={self.folder_sync!r})"
1155
- )
1156
-
1157
- @override
1158
- def __str__(self) -> str:
1159
- return f"FolderUpdate: {self.folder.title} ({self.folder.id})"
1160
-
1161
-
1162
- class FolderList:
1163
- def __init__(
1164
- self,
1165
- folders_order: list[str],
1166
- folders: list[Folder],
1167
- folder_sync: int,
1168
- all_filter_exclude_folders: list[Any] | None = None,
1169
- ) -> None:
1170
- self.folders_order = folders_order
1171
- self.folders = folders
1172
- self.all_filter_exclude_folders = all_filter_exclude_folders or []
1173
- self.folder_sync = folder_sync
1174
-
1175
- @classmethod
1176
- def from_dict(cls, data: dict[str, Any]) -> Self:
1177
- return cls(
1178
- folders_order=data.get("foldersOrder", []),
1179
- folders=[Folder.from_dict(f) for f in data.get("folders", [])],
1180
- all_filter_exclude_folders=data.get("allFilterExcludeFolders", []),
1181
- folder_sync=data.get("folderSync", 0),
1182
- )
1183
-
1184
- @override
1185
- def __repr__(self) -> str:
1186
- return (
1187
- f"FolderList(folders_order={self.folders_order!r}, "
1188
- f"folders={self.folders!r}, "
1189
- f"all_filter_exclude_folders={self.all_filter_exclude_folders!r}, "
1190
- f"folder_sync={self.folder_sync!r})"
1191
- )
1192
-
1193
- @override
1194
- def __str__(self) -> str:
1195
- return f"FolderList: {len(self.folders)} folders"
1196
-
1197
-
1198
- class ReadState:
1199
- def __init__(
1200
- self,
1201
- unread: int,
1202
- mark: int,
1203
- ) -> None:
1204
- self.unread = unread
1205
- self.mark = mark
1206
-
1207
- @classmethod
1208
- def from_dict(cls, data: dict[str, Any]) -> Self:
1209
- return cls(
1210
- unread=data["unread"],
1211
- mark=data["mark"],
1212
- )
1213
-
1214
- @override
1215
- def __repr__(self) -> str:
1216
- return f"ReadState(unread={self.unread!r}, mark={self.mark!r})"
1217
-
1218
- @override
1219
- def __str__(self) -> str:
1220
- return f"ReadState: unread={self.unread}, mark={self.mark}"