maxapi-python 2.0.0__py3-none-any.whl → 2.1.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 (61) hide show
  1. {maxapi_python-2.0.0.dist-info → maxapi_python-2.1.0.dist-info}/METADATA +4 -1
  2. {maxapi_python-2.0.0.dist-info → maxapi_python-2.1.0.dist-info}/RECORD +61 -54
  3. pymax/__init__.py +1 -1
  4. pymax/api/auth/enums.py +13 -2
  5. pymax/api/auth/payloads.py +10 -6
  6. pymax/api/auth/service.py +75 -12
  7. pymax/api/bots/__init__.py +1 -0
  8. pymax/api/bots/payloads.py +7 -0
  9. pymax/api/bots/service.py +35 -0
  10. pymax/api/chats/enums.py +1 -0
  11. pymax/api/chats/payloads.py +14 -0
  12. pymax/api/chats/service.py +112 -12
  13. pymax/api/facade.py +2 -0
  14. pymax/api/messages/payloads.py +5 -1
  15. pymax/api/messages/service.py +36 -11
  16. pymax/api/self/service.py +18 -6
  17. pymax/api/session/payloads.py +9 -2
  18. pymax/api/uploads/models.py +1 -4
  19. pymax/api/uploads/payloads.py +9 -3
  20. pymax/api/uploads/service.py +103 -35
  21. pymax/api/users/service.py +15 -5
  22. pymax/app.py +15 -5
  23. pymax/auth/qr.py +11 -6
  24. pymax/auth/sms.py +13 -4
  25. pymax/base.py +1 -0
  26. pymax/client.py +4 -1
  27. pymax/client_web.py +4 -2
  28. pymax/config.py +11 -3
  29. pymax/connection/connection.py +15 -5
  30. pymax/connection/readers/tcp.py +4 -2
  31. pymax/dispatch/dispatcher.py +28 -10
  32. pymax/dispatch/mapping.py +11 -4
  33. pymax/dispatch/router.py +2 -0
  34. pymax/files/base.py +6 -1
  35. pymax/formatting/markdown.py +4 -1
  36. pymax/infra/auth.py +42 -0
  37. pymax/infra/base.py +2 -0
  38. pymax/infra/bots.py +33 -0
  39. pymax/infra/chat.py +102 -1
  40. pymax/protocol/tcp/compression.py +3 -1
  41. pymax/protocol/tcp/framing.py +6 -11
  42. pymax/protocol/tcp/payload.py +3 -2
  43. pymax/protocol/tcp/protocol.py +13 -3
  44. pymax/protocol/ws/protocol.py +9 -3
  45. pymax/session/protocol.py +6 -2
  46. pymax/session/store.py +24 -8
  47. pymax/telemetry/navigation.py +3 -1
  48. pymax/telemetry/service.py +9 -3
  49. pymax/transport/tcp.py +10 -4
  50. pymax/transport/websocket.py +0 -2
  51. pymax/types/domain/__init__.py +3 -0
  52. pymax/types/domain/bots.py +14 -0
  53. pymax/types/domain/error.py +3 -3
  54. pymax/types/domain/folder.py +1 -1
  55. pymax/types/domain/login.py +18 -6
  56. pymax/types/domain/member.py +16 -0
  57. pymax/types/domain/presence.py +15 -0
  58. pymax/types/domain/sync.py +21 -5
  59. pymax/types/domain/user.py +12 -0
  60. {maxapi_python-2.0.0.dist-info → maxapi_python-2.1.0.dist-info}/WHEEL +0 -0
  61. {maxapi_python-2.0.0.dist-info → maxapi_python-2.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maxapi-python
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: Python wrapper для API мессенджера Max
5
5
  Project-URL: Homepage, https://github.com/MaxApiTeam/PyMax
6
6
  Project-URL: Repository, https://github.com/MaxApiTeam/PyMax
@@ -196,6 +196,9 @@ client.include_router(router)
196
196
 
197
197
  ```bash
198
198
  uv sync --all-groups
199
+ uv run pre-commit install
200
+ uv run pre-commit run --all-files
201
+ uv run pytest
199
202
  uv run python -c "import pymax; print(pymax.__all__)"
200
203
  uv run sphinx-build -b html docs docs/_build/html
201
204
  ```
@@ -1,79 +1,83 @@
1
- pymax/__init__.py,sha256=fmEHxWejLJiQmuvPDKBWhYJmo1c-U1Q8R6n-7kVaFPw,1255
2
- pymax/app.py,sha256=yZBRWDy60DfzZFdsNDovhCI3N_hCgBkwkFSVFr13jCI,9489
3
- pymax/base.py,sha256=Qy4E8Rr-4xuJE-rlFP624O35slEwUyu3gtqUcPbGr-c,7212
4
- pymax/client.py,sha256=YCOZI_BIUvDKGNXBxnVErVTZ8cXr8DE8SS9UqGD85VA,3967
5
- pymax/client_web.py,sha256=J0jM3ewuokVntYSvuqg6jtJMgA2yhyN8gb8V9w4qFhk,2990
6
- pymax/config.py,sha256=-rqgFPlZ1E92TDFk6iG0k23GvkSWMwY4NyWHJkYPbUs,8531
1
+ pymax/__init__.py,sha256=-f9yJXBxQn-YB5JLrX3VrTKV7_vFjPJs13AQqraH2ao,1255
2
+ pymax/app.py,sha256=SZMvhC237H1N58b5XcjRNGjwK-FiTgsevHnpzt-sdvg,9643
3
+ pymax/base.py,sha256=Q6FR5K1nOaeVnYlzRgqC6_v7AWUiJJCkI4TuzCYbj-U,7255
4
+ pymax/client.py,sha256=KiDEiUL49IGxRtq4-Sr3IABa8Rh1TRPq41Gv5jH2m_Q,4013
5
+ pymax/client_web.py,sha256=iTwlsY75d_wg-vUGObTq7SVinp0L__2r8cvG49BtmUI,3041
6
+ pymax/config.py,sha256=CkswnDfDjDIlYg1v0Ra3czjZvceePIaobJP51qHMdTg,8615
7
7
  pymax/exceptions.py,sha256=8pxjZsfgrMPrZfE3zedIbabqP75diEr2_6Xg3PGjiSQ,963
8
8
  pymax/logging.py,sha256=K0dsOMN4LPxybIvCeo5q1yWNRL-TSbu2r5IB25lhYb0,3410
9
9
  pymax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  pymax/routers.py,sha256=UvIEWcBF1VPBmUFrubBQ7uo3DZylf4qdbnQGDkUYjyE,225
11
11
  pymax/api/__init__.py,sha256=oWC09vGaP6S7_nnTJ4y5PbTkbA4U29DhafpwIqD2QGI,356
12
- pymax/api/facade.py,sha256=YhwgVfpuWv__9KFXIpnw8ktUsrBzYtRPkZrMN0nfQVY,832
12
+ pymax/api/facade.py,sha256=WapwUPspVxA8JMYRvWGKtaKs9rUvIJLTMaXods6julo,899
13
13
  pymax/api/models.py,sha256=1i9WfX_1zz-uke0EqTu1GbmHPpUxKElEBEFeaQAIYTI,348
14
14
  pymax/api/response.py,sha256=sWbvM-3MhJpwo0-w_5-puDpFQL62UWQxR1gzYWdw4HU,2574
15
15
  pymax/api/auth/__init__.py,sha256=m6yw6RPrq10iNkSI8z59n3OXTnAw8VfxIALnhVztL2g,33
16
- pymax/api/auth/enums.py,sha256=RnKeeBCHcleeyJ1KSRRG1QSp7I_tS6jmJKv7SUHwQnY,518
17
- pymax/api/auth/payloads.py,sha256=SN7CL9fTDsVKJYjSKWwN8xBwa6OnI4BCN0sS8LxNT8E,2910
18
- pymax/api/auth/service.py,sha256=DU_8RpELw1PYflbtDj5JCycfU9aD5uG2Tn63KWlCME4,10073
16
+ pymax/api/auth/enums.py,sha256=QFtOBnD-qmoROzu2pfgWD6swMOdapOgumsEOHEulsog,661
17
+ pymax/api/auth/payloads.py,sha256=XxrVdNcz1uV6hUxDp9Dt_stENECi_eDlxuiqt44DHeo,3006
18
+ pymax/api/auth/service.py,sha256=sjZcMyP6siH0dR19eYwkhhLU09bVJD4FCNeSra2Rjac,11639
19
19
  pymax/api/auth/types.py,sha256=VrYR7rIZOrW45yKnQmC5MSe9kxgXmqPzh9VG_y1tSEs,200
20
+ pymax/api/bots/__init__.py,sha256=4P7rM-XeeDOElEktov1Vbfo8nzjJgmyA4_pQl4WvzRQ,33
21
+ pymax/api/bots/payloads.py,sha256=-vrswY_VlQrLKoqOxrFBl7pE8QG4dLQSaGOtKs4Lq1o,152
22
+ pymax/api/bots/service.py,sha256=ssVty2_4WMQbecQGcIJYEeYZ0RT6VgMu5qzqgAcegWo,877
20
23
  pymax/api/chats/__init__.py,sha256=UMp3uKdB3tZlnWckndgF3jaU-3-49OJE18z2d0OlmIU,155
21
- pymax/api/chats/enums.py,sha256=KstEKTpBAkz0MC4rezkrtpsrlbzqyVA8qbfYP1f_jmo,603
22
- pymax/api/chats/payloads.py,sha256=J5lRsx5Xzc3lzcYVxS7ptrr7dQl01oSXoEZYMhtr10M,2495
23
- pymax/api/chats/service.py,sha256=fLauRNUqoZ5GGUxgrR8T7I_2lcStgWzCNWdmI2Ubzvc,9023
24
+ pymax/api/chats/enums.py,sha256=FdByRiHYX9Xs7RyNabKqxGugNs9tJ3VBXwTb_43XGC8,627
25
+ pymax/api/chats/payloads.py,sha256=Y4S2x60i3txeA75GV_pGJ3ov7pLMp4GjGuhoqlRI2ow,2824
26
+ pymax/api/chats/service.py,sha256=lfbhameeXtF9uk3uvcIuFs7JxJPc1tvawRtKLSGYrpg,11461
24
27
  pymax/api/messages/__init__.py,sha256=fw_uF6tgSbkxvqaSVE65wU0KWsu47u1CtR0Y4BbD-K0,36
25
28
  pymax/api/messages/enums.py,sha256=7hWOcbEjrggDoNqFUrzNPq2c1QrAdoYg_q5Tfz3e_XY,344
26
- pymax/api/messages/payloads.py,sha256=P1acrWLLxIzfVRDiwPOAwFGwG69ip0nVqQdtZFuq3qc,1865
27
- pymax/api/messages/service.py,sha256=tVaZa3bqWeRLoicD1oYNzmMc0s4zIntYOvdhTIpojBs,10169
29
+ pymax/api/messages/payloads.py,sha256=gvlZcfyExSFRyTghcoewpyiaaNVj4f4TTHjxBVL8aWg,1882
30
+ pymax/api/messages/service.py,sha256=N5_KYArZB-VX7kOLMfkrwzrpNgvqNFLRLOym_ghM6IQ,10468
28
31
  pymax/api/self/__init__.py,sha256=TfbqL4xLb5IMhbW8mlAK-AwVFqqPWMADogKZeWtkw0A,79
29
32
  pymax/api/self/enums.py,sha256=iKEqPy44LyQKvAPfyhpkSXgmWWohxry73F0CVgtekwY,180
30
33
  pymax/api/self/payloads.py,sha256=-SFqkNxC5ZLKnLty_Gyz_b_P3X1esu_7Urb4HjrQxM4,774
31
- pymax/api/self/service.py,sha256=HvfDyGYvm8x9RKBOF1CAFaGB1IZjqhM1S8id7Q4gc2Q,4545
34
+ pymax/api/self/service.py,sha256=3TBB-wxGTJ9jRCJJNfitk0hJNtWQDn9gWS_sap1Hou8,4685
32
35
  pymax/api/session/__init__.py,sha256=zo-rCKBVBsFK-810T-Le4VbAYKt109cQ6elf0UkgiNk,36
33
36
  pymax/api/session/enums.py,sha256=InBdwAu_filqW3rMfGrOkHgmFfqgB1ytjnCcxDq29xc,236
34
- pymax/api/session/payloads.py,sha256=KJBoP_XfL2lJbXvR3tzWf2WaLn73L2LiEuqP0cdJ6u0,2258
37
+ pymax/api/session/payloads.py,sha256=mDXgI_oVfqLim7J9F9BMUwKx9Vs8EknJ02kstrF3ClE,2340
35
38
  pymax/api/session/service.py,sha256=8ELcsnKNHLT8hgExw5laZvHF6SIOSQB6RpXoxf1rbbI,1994
36
39
  pymax/api/uploads/__init__.py,sha256=E7INNsBeMStze2VWMADX4mrswsQeJb85C71sSuiOpv0,35
37
- pymax/api/uploads/models.py,sha256=H8KaTi8MD-WEJrJon0cusgcKevELPmhaWpCrI8vLPoU,1008
38
- pymax/api/uploads/payloads.py,sha256=OqsfFJIRe2io7mltHPbDPORT8U5t27H6pvqrdNKPRHY,652
39
- pymax/api/uploads/service.py,sha256=YWzA-VbGtiCBUT3w95iTi3bAkAc_1ysgliqFob1I2Bs,18369
40
+ pymax/api/uploads/models.py,sha256=c2Yunnl9nRkDZuItXGKlY0Oi5DjnB4f5bcruQ49ARZk,934
41
+ pymax/api/uploads/payloads.py,sha256=hf0MwLdtTHnt5KGONbV4hnByjy5X0PJLqer6uq9nuuw,694
42
+ pymax/api/uploads/service.py,sha256=5wa4MI3jL7BFWCWbMLWZBP-NTOqRcblUq4Iz19ekXx4,19481
40
43
  pymax/api/users/__init__.py,sha256=CDakgSKwVAkX-kNoDmIo2JsFPsS7Nx3j2vIMwQnPRck,82
41
44
  pymax/api/users/enums.py,sha256=m3d225sjWkBIRF5NNi3ChnyZ6BgKUEbPYoYwVjpifZ4,205
42
45
  pymax/api/users/payloads.py,sha256=VoXXctQDl7WXt5zqoRKzdONqmris5Cxf7-6Hy_Gcd-A,288
43
- pymax/api/users/service.py,sha256=lW5Lq9u7F91ofn5Cn-QuaOcQKn7Gry7heWQlOz2TwFM,3997
46
+ pymax/api/users/service.py,sha256=1yTRHLPIusqj7PF5g-8xSU6d5eo6Q2IyH2QkYSxZ8ls,4107
44
47
  pymax/auth/__init__.py,sha256=KgghKg0CPcJzX_D14TvxuDzhNmoVoFGjv414NouJVgk,512
45
48
  pymax/auth/base.py,sha256=v492FMUmSKft6oJRmCdIr33sy50Z0kqBwu5t7cVLQe4,1222
46
49
  pymax/auth/email.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
50
  pymax/auth/models.py,sha256=2SbjOJev1-B1bFEFM0NJPNX4wBTc4JbVDDouRHoAYc0,91
48
51
  pymax/auth/providers.py,sha256=B3EaS-iKxrZffcxiBKjoA1TsytwybHUunjZUtbjiiVE,4148
49
- pymax/auth/qr.py,sha256=VdrlaW15illIhqPaTczepA4my3P06Fa433HQ0eaucJE,4171
52
+ pymax/auth/qr.py,sha256=17VTtcwNcpuzbR_1t1bpwmdDFxLniNidakOYSKjOJNc,4309
50
53
  pymax/auth/service.py,sha256=cUZxs5UW9ysSaJ-UXSOz0ug3fDo1eN0xAjO7VP1MdTU,619
51
- pymax/auth/sms.py,sha256=m8M1oB6XErciesIBTgeQvJhqor13h8hlyVkYWzZmISA,4045
54
+ pymax/auth/sms.py,sha256=34L9Od_0RYitK9G4xxFDJAq-3vf_AfzIGfBShwVNSRk,4185
52
55
  pymax/connection/__init__.py,sha256=YTboFk9AfYkRUw2Hf4oxn63LTGV475fxp_oel1j4gas,42
53
- pymax/connection/connection.py,sha256=UJvdAaHdxtH8tYv241rD8E7y99berY-1oeQcWJ56frk,6645
56
+ pymax/connection/connection.py,sha256=mLqQOE7eeIJEOE2Nx7hZibCgDar1evgo5IksGGyfzvM,6859
54
57
  pymax/connection/pending.py,sha256=qezxL019d1E6oiCmSgCSfojLj7sxR1BEGgcKBWSFhok,1328
55
58
  pymax/connection/readers/__init__.py,sha256=9g5ZbcWiHxW1kAi2ckiNqejoGHwoDwFd4WvtYQSyRzU,52
56
59
  pymax/connection/readers/base.py,sha256=FlvyMUFoZ4FORAh0vBU6_I0BnrQ9_1twpUIKz-Vkj58,126
57
- pymax/connection/readers/tcp.py,sha256=9MtFygdKQO8Lm7ZRAxdWFvApiG5wmo9gw82GqA7cRPk,1052
60
+ pymax/connection/readers/tcp.py,sha256=jEs0u6yn34uskRGuy-dqRMQOzTzcgAAfuk-cTEVkDdQ,1087
58
61
  pymax/connection/readers/ws.py,sha256=IjeH5CoXvBWde46tZLx6uKONkjhCU6NeC79x3Swfw8E,368
59
62
  pymax/dispatch/__init__.py,sha256=bvHjlw2ltujMAiegW-Sv2fSGKUnkmtPcYINUZ-Ty8qo,189
60
- pymax/dispatch/dispatcher.py,sha256=rXsBfxYzL0KbK-IZgiQI-SAVFSxDX1V5YZi2Jj6bubs,6948
63
+ pymax/dispatch/dispatcher.py,sha256=BKgFPUF6FIU1ZjzQ1CxZO7JvwF11_Yjw1XgKT5dtGCs,7071
61
64
  pymax/dispatch/enums.py,sha256=b2ZMBON7ls4QDjeoye-o7mPHFxMxc-CTtYBUuKyhfrQ,298
62
- pymax/dispatch/mapping.py,sha256=2djWFBaoAcHthf-7DWMFBCg_ImhWmue8NvXmpwmZSiE,2400
65
+ pymax/dispatch/mapping.py,sha256=Ek8tVawHUZ4nBN0z7hLuG6eV_5BlVp63UrHvtDZLo7Y,2463
63
66
  pymax/dispatch/resolvers.py,sha256=XAZFy2N_zKuVztbwGKF_wzzUrrfM4cs1nGxiSP2jb1w,1511
64
- pymax/dispatch/router.py,sha256=i9HCycAP3It8-Pm88P3_X3vzn7MblWzuHbB5Rx-7TLM,6590
67
+ pymax/dispatch/router.py,sha256=0R_Z-YP9yLAyWlBaBgevgHP0BmZGr4N8JIRtjob8KSA,6592
65
68
  pymax/files/__init__.py,sha256=TR0N6YXX4IHBsXQo8uiK68C-Xg3LSj48d4Zsv71CWZE,126
66
- pymax/files/base.py,sha256=z8r8zxQVK7Z4XzvFdv_Sx9nkmx17ZeThrCP6pXgsJAM,2648
69
+ pymax/files/base.py,sha256=0aksCGxmrvqEKJdhRWcuPZJfEn7RWcl5tn5gn63q1os,2689
67
70
  pymax/files/file.py,sha256=JSkuKx0fdGxzcsyMajWTosFzTlfgZYvQbh-RDp9OZyQ,2337
68
71
  pymax/files/photo.py,sha256=TeGBzVXFpiExhMjKCLHFjCu3DYKFZ6-jub-RZ_SiCco,3523
69
72
  pymax/files/static.py,sha256=U_KfM0rbGMEWcsBnWIhIXzzk46hHYQ7KJnrGnfDLoMs,142
70
73
  pymax/files/video.py,sha256=fGXgSY5zH-voYPVjbDBnkGI1TeP-KOSq3DZEDFNnn68,2153
71
74
  pymax/formatting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
- pymax/formatting/markdown.py,sha256=ukozC8ZYtmB-dKoK9KwIwofHZ3p5NoVbRdtgNDsWmPY,6118
75
+ pymax/formatting/markdown.py,sha256=a9nbeQOcyf0fvKUuKY7NRtQKqF3ApQXgBaHu0-L0NF0,6202
73
76
  pymax/infra/__init__.py,sha256=lKq6cehhB87HltV53TD0kr0p7ekWlZlrKTpaYiq0XFw,28
74
- pymax/infra/auth.py,sha256=_l9-RxbMgBeMUfHE9fszZLYB5Zt45iOumDunbUGOVZg,2215
75
- pymax/infra/base.py,sha256=Ss7upi4YYdvWX9c0U3ehdbW0nVEcsaZncDmpPJ7r8oc,325
76
- pymax/infra/chat.py,sha256=MPvoqV1C43o7oUXsxNt6xgwlhaJO0i0ZkeCsoKwN3xI,9034
77
+ pymax/infra/auth.py,sha256=YuYH_NWNz8UfPyko6bv_cIzXDIvFeivDrxZCIpGoANU,3648
78
+ pymax/infra/base.py,sha256=sOo40Qkp14bE6CxVKppJhy3e0F5VhFPhnL3iBs8y5dA,368
79
+ pymax/infra/bots.py,sha256=IJs4ErFxjbMeiHfQgpDiDhtEu9ws-lIp8fb8I96szy8,1202
80
+ pymax/infra/chat.py,sha256=gZdkciUl_BCnPucxb8JubQ6phPCTcmVfX9C3edKXZRM,12690
77
81
  pymax/infra/message.py,sha256=Hee5z9a47aZRnSAvTMdTaa5BzwMnOnSoB-z3JVX3J3o,8518
78
82
  pymax/infra/protocol.py,sha256=I2WrAeAgATuNSdK2gvHU-MhhxdRBfSMGMovF5HPFsQw,208
79
83
  pymax/infra/self.py,sha256=w2eHIgmKkarhfbtAdGo_iZ4Qbs2DaSzzm-TLzXKNn8E,4963
@@ -83,40 +87,43 @@ pymax/protocol/base.py,sha256=_bisk1BU_GSMSPIqfnizSCgm_qBrdbB5cJw6foAa2tc,294
83
87
  pymax/protocol/enums.py,sha256=9y4kn9y2pKinaT_twdeW5MXVH3O-sJF6h0v5KbC9VkA,4376
84
88
  pymax/protocol/models.py,sha256=kno-09OoPoLKBMixS9nrDkCbxcIwvU37RlZgaq5MfVo,584
85
89
  pymax/protocol/tcp/__init__.py,sha256=ivIZZ-UoT_MiRIUWTLiyeKSBOzf9XztSprHPHgoWNuI,34
86
- pymax/protocol/tcp/compression.py,sha256=sa9xe3cjAYXsJCPPxGc6iRyctFaT15VcqQ0fiC8vk4A,3014
87
- pymax/protocol/tcp/framing.py,sha256=nBnCrlIaxOMAbAVDXTAY6jdMoKlbh0jV-XCVsOO-i7U,1874
88
- pymax/protocol/tcp/payload.py,sha256=vQERjBNJLaltmWOCvnSQHcpDzA7x9VBhK3oECtO0qsU,4272
89
- pymax/protocol/tcp/protocol.py,sha256=2XcOE23JaUoimWohvgpIwLbqHpi_0GSO9AGCCshKMgc,2227
90
+ pymax/protocol/tcp/compression.py,sha256=K0xf8W_pVB-CFD0cJs3SrpTK3WXeZom3ToMo8Iu3Qug,3028
91
+ pymax/protocol/tcp/framing.py,sha256=Zp-glGsPqYODOnkmKdf6Ux8dcjleyuPWudQdHeO5PXQ,1652
92
+ pymax/protocol/tcp/payload.py,sha256=dKAriFuWoonCmfogijv7FTXEKlNPz8vOwI6xO6INJG0,4301
93
+ pymax/protocol/tcp/protocol.py,sha256=T5N2qoCoYxcHqPylBqpLW3ej1Ew3XBvoKWMuXyc0qLc,2322
90
94
  pymax/protocol/ws/__init__.py,sha256=oQK0h28B6gGItf7eHanWy_XsgUA_L9Lclnuz9ZQL9YI,33
91
- pymax/protocol/ws/protocol.py,sha256=z6zzBQTlJfzwOmLsJYoYQ2L1AYpY5wYMJyPir_zfNBQ,913
95
+ pymax/protocol/ws/protocol.py,sha256=Ob90-jLDwGqo8ymwDPvwUnWacWyQtneKEjCThfpqbKE,1003
92
96
  pymax/session/__init__.py,sha256=natjnLjPjTvkfvSYtoiPxzmU44XJi0MpjWiOPD-On4g,100
93
97
  pymax/session/models.py,sha256=jvnTHfjCX1p5TcANfWZ0vUJlciuqumatwdrgYiKm4kY,250
94
- pymax/session/protocol.py,sha256=8ibp-HiaJaGmx23v7GeL0GFsvLPZZqWOuIOJnanqoCM,612
95
- pymax/session/store.py,sha256=FkhrG0J2ueU2Z4PxJQxFPOcunKnpVavnAaJgPb2bx-E,7770
98
+ pymax/session/protocol.py,sha256=MvGGVO5NhI0q83tkHLPbTjz0HAi1H--zjEhJmdneebE,640
99
+ pymax/session/store.py,sha256=rIQ3JkxvrY1Yy6RwIO9_4Qyixg-2KSEi6CHrbUioLE4,7946
96
100
  pymax/telemetry/__init__.py,sha256=6mP5y-iTbVIlqpSWIKWCTz2fFNBwkAEYwS4PFbyv9xM,71
97
- pymax/telemetry/navigation.py,sha256=vlP7d863s9aIBpt9SPpjEbTXLoq3uqpuhD-VWj0w9hI,5441
101
+ pymax/telemetry/navigation.py,sha256=A7Vky5KRwGdntq2J5hY5BBtBLBCoRaLo6m2gbbrvW88,5463
98
102
  pymax/telemetry/payloads.py,sha256=MCKYGpQ4Tvx_8LH86Et0yevea2Th2z3b7a9pfmrQRys,3959
99
- pymax/telemetry/service.py,sha256=9L0K7Rl7hE79Mly2mo1QLiDqP0uiaKCzNzRBdDvFGks,7030
103
+ pymax/telemetry/service.py,sha256=xuAUsLt0QOwypxn8NjSUtSTfcZxgIY9YVWnvZ-KawZY,7120
100
104
  pymax/transport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
105
  pymax/transport/base.py,sha256=0D3srQ36F0s23pIjqd6YzRGKK9wCmXKr3wfe2XYYlos,448
102
- pymax/transport/tcp.py,sha256=HGhe5LW3KhwQRPYBKdzDWNpv9dfnOQHMUHsa14vis6M,2915
103
- pymax/transport/websocket.py,sha256=7R2WgeYINNUq0BZVnzyVD1cZPCDZuVVi6b65lMndEcc,1520
106
+ pymax/transport/tcp.py,sha256=9HCmPK-qBC5AvFINW4jHyzXQPTWvIYFiwxDmVHA8-og,2998
107
+ pymax/transport/websocket.py,sha256=0ezkSoENWKV00EATIizGx16-ihCnaTC76zzGnwbS_3c,1504
104
108
  pymax/types/__init__.py,sha256=y77mfDRgxmfcamobi0rj2d3PsxhH0zxyvKPhL2iUdS8,44
105
- pymax/types/domain/__init__.py,sha256=glpM6uh_2BlaFMTM1F18EjnyvsJugIrC0M_ud6YUwVo,385
109
+ pymax/types/domain/__init__.py,sha256=R4iJv0b5gnNVG3MrerVlGVzPvNR-n36QZFukEX64fn4,470
106
110
  pymax/types/domain/auth.py,sha256=8p4qX9RAJ6dIsAmoKFrfxlq6dct689qXgrngcep48a4,5214
107
111
  pymax/types/domain/base.py,sha256=Q32PcKR3gtrISySowR3zPyl9KeQCoUL6lfyTR3ulMzo,623
112
+ pymax/types/domain/bots.py,sha256=dErZZbvspznU6yUupzCs4R55pEWgoeps7NEhZFrb-Uo,333
108
113
  pymax/types/domain/chat.py,sha256=xpLutj9uCIQupAO1zu2eXzEEXL8DcQ4N6tkZQeQUsCM,18329
109
114
  pymax/types/domain/element.py,sha256=slMVlp5Fn1H1hFUinruuP7s2wawkSrS5c1eCeY31p-g,620
110
115
  pymax/types/domain/enums.py,sha256=eGMWnlv0mYJ8K-0FsC_wp4Co2M6YWyKI1Lx90MJ6s4g,412
111
- pymax/types/domain/error.py,sha256=0UlH_eikpnToj2yrlpBxmr85IAANR1whrBdo6Nesj88,556
112
- pymax/types/domain/folder.py,sha256=dS2EhMiTIEJAiynSV2CqSrPtmf2V3cjNc_aTdSKmmuY,2456
113
- pymax/types/domain/login.py,sha256=1ugRakYM0MymAqgHKdvuhnwH2w4adoEHc_hbH5-56Fw,1287
116
+ pymax/types/domain/error.py,sha256=WZoDAXf5vt8O4VYy7iEHLGBfH6hZQZ1fVkTz9rVCTN0,584
117
+ pymax/types/domain/folder.py,sha256=Xe1CmWfh3BhjpPNV-aWqT2JA4sX6ya2HaC3BSDMEqL8,2445
118
+ pymax/types/domain/login.py,sha256=mpGWNcFi5pwRsZbPA_GCtC1b-dreZA1hxayz5P7eL90,1451
119
+ pymax/types/domain/member.py,sha256=8gUNn4fBS_S2ap45A40lRlrDXYFMoq0Kx-dh57hMWQc,490
114
120
  pymax/types/domain/message.py,sha256=vb1Rmxnz145EP5_C1fpjvGLrenATN6HBivrst9M8OOc,14387
115
121
  pymax/types/domain/name.py,sha256=qMIshIqgWkVuROxmiCRhwfJf8XtmhSBoEU6nXs_gEh0,523
122
+ pymax/types/domain/presence.py,sha256=NdI2wHLxc3UOSUyTallGb6Cw4xRlh6DniW2ee-aZdWI,466
116
123
  pymax/types/domain/profile.py,sha256=taN5PjlKp4EDypVhDx89vmBDpSKh-kT-ISpu1tR2cY8,471
117
124
  pymax/types/domain/session.py,sha256=T0b0qjI65kNQOCgx3nIkaIqynD4eGKyqnscbIlPFVnQ,2002
118
- pymax/types/domain/sync.py,sha256=lBDWo4ACLq2ov5XBccfnI8s_dsGEA7O4mIJVBSUpyrc,3248
119
- pymax/types/domain/user.py,sha256=diy8UmMN1-KkLJjuybnVlj7qC_0jlEzM49N0jMYk2dk,4520
125
+ pymax/types/domain/sync.py,sha256=3hNN2Dwle-rD7YxJW00n5GPR6vmLdhW5GhiJsaC9ekc,3498
126
+ pymax/types/domain/user.py,sha256=NjJfQtkRBrsmB-JGg2nsXWLvgqu3q5YKx2BALkoDrOI,5120
120
127
  pymax/types/domain/attachments/__init__.py,sha256=7QS5881emGVJ4YBMxHkzxYWWwRjPH9-VKWu9xzGnr8s,432
121
128
  pymax/types/domain/attachments/audio.py,sha256=X_GR68yDCDqRlLcO4qtZPQigfmQfkRFb9OF-TZgoDkw,1075
122
129
  pymax/types/domain/attachments/call.py,sha256=RV-BFutymZFinzUiRdaIryqx6ubku2v6y6brc-qsHOQ,818
@@ -134,7 +141,7 @@ pymax/types/events/__init__.py,sha256=fNLP_8zYRsew2k-1s8wXCJeSPm8QQ4gmiZ86B51SuC
134
141
  pymax/types/events/file.py,sha256=XhpXn0Vt9OODkx1OkGb9jfQwc1uNgz1NTn_j9FZnQ8s,102
135
142
  pymax/types/events/message.py,sha256=d4dlnpu3VCtZ4vFdRXaACvydAE9sbGGkk52E48K0U_U,1248
136
143
  pymax/types/events/video.py,sha256=swBHYadmDS0SjLXGqVqRYsuMoVZ6MjD2aYR2fbM-AJc,104
137
- maxapi_python-2.0.0.dist-info/METADATA,sha256=KNq51Db-VLPk0Vgpd2fhG6sjdcXwgQING1uTkGLLio4,7563
138
- maxapi_python-2.0.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
139
- maxapi_python-2.0.0.dist-info/licenses/LICENSE,sha256=hOR249ItqMdcly1A0amqEWRNRTq4Gv5NJtmQ3A5qK4E,1070
140
- maxapi_python-2.0.0.dist-info/RECORD,,
144
+ maxapi_python-2.1.0.dist-info/METADATA,sha256=kmE4GpooJO7S8X4GH8qELBv0cQZqDJvXZlBH_t2vktE,7637
145
+ maxapi_python-2.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
146
+ maxapi_python-2.1.0.dist-info/licenses/LICENSE,sha256=hOR249ItqMdcly1A0amqEWRNRTq4Gv5NJtmQ3A5qK4E,1070
147
+ maxapi_python-2.1.0.dist-info/RECORD,,
pymax/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "2.0.0"
1
+ __version__ = "2.1.0"
2
2
 
3
3
 
4
4
  from .auth import (
pymax/api/auth/enums.py CHANGED
@@ -8,10 +8,21 @@ class AuthType(str, Enum):
8
8
  RESEND = "RESEND"
9
9
 
10
10
 
11
- class Capability(int, Enum):
12
- DEFAULT = 0 # В душе не чаю что это такое но при первой установке 2фа там 0 3 4 так что пусть будет дефолт
11
+ class ProfileOptions(int, Enum):
12
+ """Битовые/числовые признаки профиля, связанные с 2FA."""
13
+
13
14
  ESIA_VERIFIED_FLAG = 1
14
15
  SECOND_FACTOR_PASSWORD_ENABLED = 2
15
16
  SECOND_FACTOR_HAS_EMAIL = 3
16
17
  SECOND_FACTOR_HAS_HINT = 4
18
+
19
+
20
+ class TwoFactorAction(int, Enum):
21
+ """Действия 2FA, передаваемые в expectedCapabilities."""
22
+
23
+ SET_PASSWORD = 0
24
+ UPDATE_PASSWORD = 1
25
+ RESTORE_PASSWORD = 2
26
+ HINT = 3
27
+ EMAIL = 4
17
28
  REMOVE_2FA = 5
@@ -1,10 +1,10 @@
1
- from pydantic import Field, field_serializer
1
+ from pydantic import Field
2
2
 
3
3
  from pymax.api.models import CamelModel
4
4
  from pymax.api.session.payloads import MobileUserAgentPayload
5
5
  from pymax.types.domain.sync import DEFAULT_CONFIG_HASH, ConfigHash, SyncState
6
6
 
7
- from .enums import AuthType, Capability
7
+ from .enums import AuthType, TwoFactorAction
8
8
 
9
9
 
10
10
  class RequestCodePayload(CamelModel):
@@ -115,7 +115,7 @@ class SetHintPayload(CamelModel):
115
115
 
116
116
 
117
117
  class SetTwoFactorPayload(CamelModel):
118
- expected_capabilities: list[Capability]
118
+ expected_capabilities: list[TwoFactorAction]
119
119
  track_id: str
120
120
  password: str
121
121
  hint: str | None = None
@@ -123,7 +123,11 @@ class SetTwoFactorPayload(CamelModel):
123
123
 
124
124
  class RemoveTwoFactorPayload(CamelModel):
125
125
  track_id: str
126
- remove2fa: bool = True
127
- expected_capabilities: list[Capability] = Field(
128
- default_factory=lambda: [Capability.REMOVE_2FA]
126
+ remove2fa: bool = Field(default=True, alias="remove2fa")
127
+ expected_capabilities: list[TwoFactorAction] = Field(
128
+ default_factory=lambda: [TwoFactorAction.REMOVE_2FA]
129
129
  )
130
+
131
+
132
+ class ApproveQrLoginPayload(CamelModel):
133
+ qr_link: str
pymax/api/auth/service.py CHANGED
@@ -2,7 +2,11 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
- from pymax.api.response import payload_item, payload_keys, require_payload_model
5
+ from pymax.api.response import (
6
+ payload_item,
7
+ payload_keys,
8
+ require_payload_model,
9
+ )
6
10
  from pymax.api.session.enums import DeviceType
7
11
  from pymax.auth import EmailCodeProvider
8
12
  from pymax.auth.providers import ConsoleEmailCodeProvider
@@ -17,8 +21,9 @@ from pymax.types.domain.auth import (
17
21
  )
18
22
  from pymax.types.domain.login import LoginResponse
19
23
 
20
- from .enums import Capability
24
+ from .enums import ProfileOptions, TwoFactorAction
21
25
  from .payloads import (
26
+ ApproveQrLoginPayload,
22
27
  CheckPasswordChallengePayload,
23
28
  CheckQrPayload,
24
29
  ConfirmQrPayload,
@@ -51,14 +56,18 @@ class AuthService:
51
56
  async def request_code(self, phone: str) -> StartAuthResponse:
52
57
  logger.info("requesting sms code phone_set=%s", bool(phone))
53
58
  frame = RequestCodePayload(phone=phone)
54
- response = await self.app.invoke(Opcode.AUTH_REQUEST, frame.to_payload())
59
+ response = await self.app.invoke(
60
+ Opcode.AUTH_REQUEST, frame.to_payload()
61
+ )
55
62
  logger.debug(
56
63
  "sms code request accepted payload_keys=%s",
57
64
  payload_keys(response),
58
65
  )
59
66
  return require_payload_model(response, StartAuthResponse)
60
67
 
61
- async def send_code(self, token: str, verify_code: str) -> CheckCodeResponse:
68
+ async def send_code(
69
+ self, token: str, verify_code: str
70
+ ) -> CheckCodeResponse:
62
71
  logger.info(
63
72
  "sending sms code token_set=%s code_set=%s",
64
73
  bool(token),
@@ -152,14 +161,18 @@ class AuthService:
152
161
  async def check_qr(self, track_id: str) -> CheckQrResponse:
153
162
  frame = CheckQrPayload(track_id=track_id)
154
163
 
155
- response = await self.app.invoke(Opcode.GET_QR_STATUS, frame.to_payload())
164
+ response = await self.app.invoke(
165
+ Opcode.GET_QR_STATUS, frame.to_payload()
166
+ )
156
167
 
157
168
  return require_payload_model(response, CheckQrResponse)
158
169
 
159
170
  async def confirm_qr(self, track_id: str) -> CheckCodeResponse:
160
171
  frame = ConfirmQrPayload(track_id=track_id)
161
172
 
162
- response = await self.app.invoke(Opcode.LOGIN_BY_QR, frame.to_payload())
173
+ response = await self.app.invoke(
174
+ Opcode.LOGIN_BY_QR, frame.to_payload()
175
+ )
163
176
 
164
177
  return require_payload_model(response, CheckCodeResponse)
165
178
 
@@ -182,11 +195,15 @@ class AuthService:
182
195
  logger.debug("creating auth track")
183
196
  frame = CreateAuthTrackPayload()
184
197
 
185
- response = await self.app.invoke(Opcode.AUTH_CREATE_TRACK, frame.to_payload())
198
+ response = await self.app.invoke(
199
+ Opcode.AUTH_CREATE_TRACK, frame.to_payload()
200
+ )
186
201
 
187
202
  return payload_item(response, "trackId", str)
188
203
 
189
- async def _set_email(self, track_id: str, email: str, provider: EmailCodeProvider) -> bool:
204
+ async def _set_email(
205
+ self, track_id: str, email: str, provider: EmailCodeProvider
206
+ ) -> bool:
190
207
  logger.info("setting 2fa email email_set=%s", bool(email))
191
208
 
192
209
  frame = RequestEmailCodePayload(
@@ -225,7 +242,9 @@ class AuthService:
225
242
  track_id=track_id,
226
243
  password=password,
227
244
  )
228
- await self.app.invoke(Opcode.AUTH_VALIDATE_PASSWORD, frame.to_payload())
245
+ await self.app.invoke(
246
+ Opcode.AUTH_VALIDATE_PASSWORD, frame.to_payload()
247
+ )
229
248
 
230
249
  return True
231
250
 
@@ -263,13 +282,13 @@ class AuthService:
263
282
  await self._set_hint(track_id, str(hint))
264
283
  has_hint = True
265
284
 
266
- expected_capabilities = [Capability.DEFAULT]
285
+ expected_capabilities = [TwoFactorAction.SET_PASSWORD]
267
286
 
268
287
  if has_hint:
269
- expected_capabilities.append(Capability.SECOND_FACTOR_HAS_HINT)
288
+ expected_capabilities.append(TwoFactorAction.HINT)
270
289
 
271
290
  if has_email:
272
- expected_capabilities.append(Capability.SECOND_FACTOR_HAS_EMAIL)
291
+ expected_capabilities.append(TwoFactorAction.EMAIL)
273
292
 
274
293
  frame = SetTwoFactorPayload(
275
294
  track_id=track_id,
@@ -311,3 +330,47 @@ class AuthService:
311
330
  await self.app.invoke(Opcode.AUTH_SET_2FA, frame.to_payload())
312
331
 
313
332
  return True
333
+
334
+ async def authorize_qr_login(self, qr_link: str) -> bool:
335
+ logger.info("approving qr login qr_link_set=%s", bool(qr_link))
336
+
337
+ frame = ApproveQrLoginPayload(qr_link=qr_link)
338
+
339
+ await self.app.invoke(Opcode.AUTH_QR_APPROVE, frame.to_payload())
340
+
341
+ return True
342
+
343
+ async def check_2fa(self) -> bool:
344
+ if not self.app.me or not self.app.me.profile_options:
345
+ return False
346
+
347
+ return (
348
+ ProfileOptions.SECOND_FACTOR_PASSWORD_ENABLED
349
+ in self.app.me.profile_options
350
+ )
351
+
352
+ async def change_password(
353
+ self, password_old: str, password_new: str
354
+ ) -> bool:
355
+ track_id = await self._get_track_id()
356
+
357
+ if not track_id:
358
+ logger.error("missing track_id in auth create track response")
359
+ raise RuntimeError("Failed to create auth track")
360
+
361
+ await self._check_2fa_password(track_id, password_old)
362
+
363
+ await self._set_password(track_id, password_new)
364
+
365
+ expected_capabilities = [TwoFactorAction.UPDATE_PASSWORD]
366
+
367
+ frame = SetTwoFactorPayload(
368
+ track_id=track_id,
369
+ password=password_new,
370
+ hint=None,
371
+ expected_capabilities=expected_capabilities,
372
+ )
373
+
374
+ await self.app.invoke(Opcode.AUTH_SET_2FA, frame.to_payload())
375
+ logger.info("2fa password set successfully")
376
+ return True
@@ -0,0 +1 @@
1
+ from .service import BotsService
@@ -0,0 +1,7 @@
1
+ from pymax.api.models import CamelModel
2
+
3
+
4
+ class RequestInitDataPayload(CamelModel):
5
+ bot_id: int
6
+ chat_id: int
7
+ start_param: str | None = None
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pymax.api.response import require_payload_model
6
+ from pymax.logging import get_logger
7
+ from pymax.protocol import Opcode
8
+ from pymax.types.domain import InitData
9
+
10
+ from .payloads import RequestInitDataPayload
11
+
12
+ if TYPE_CHECKING:
13
+ from pymax.app import App
14
+
15
+
16
+ logger = get_logger(__name__)
17
+
18
+
19
+ class BotsService:
20
+ def __init__(self, app: App) -> None:
21
+ self.app = app
22
+
23
+ async def get_init_data(
24
+ self,
25
+ bot_id: int,
26
+ chat_id: int,
27
+ start_param: str | None = None,
28
+ ) -> InitData:
29
+ frame = RequestInitDataPayload(
30
+ bot_id=bot_id, chat_id=chat_id, start_param=start_param
31
+ )
32
+ response = await self.app.invoke(
33
+ Opcode.WEB_APP_INIT_DATA, frame.to_payload()
34
+ )
35
+ return require_payload_model(response, InitData)
pymax/api/chats/enums.py CHANGED
@@ -21,6 +21,7 @@ class ChatOption(str, Enum):
21
21
  class ChatPayloadKey(str, Enum):
22
22
  CHAT = "chat"
23
23
  CHATS = "chats"
24
+ MEMBERS = "members"
24
25
 
25
26
 
26
27
  class ChatLinkPrefix(str, Enum):
@@ -101,3 +101,17 @@ class LeaveChatPayload(CamelModel):
101
101
 
102
102
  class FetchChatsPayload(CamelModel):
103
103
  marker: int
104
+
105
+
106
+ class FetchJoinRequests(CamelModel):
107
+ chat_id: int
108
+ type: str = "JOIN_REQUEST" # ENUM!!!!!
109
+ count: int = 100
110
+
111
+
112
+ class JoinRequestActionPayload(CamelModel):
113
+ chat_id: int
114
+ user_ids: list[int]
115
+ type: str = "JOIN_REQUEST" # TODO: ENUMM!!!
116
+ show_history: bool | None = True
117
+ operation: ChatMemberOperation