py-tgcalls 2.1.2b2__py3-none-any.whl → 2.2.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.
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/METADATA +2 -2
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/RECORD +32 -31
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/WHEEL +1 -1
- pytgcalls/__version__.py +1 -1
- pytgcalls/ffmpeg.py +2 -2
- pytgcalls/filters.py +6 -2
- pytgcalls/list_to_cmd.py +11 -0
- pytgcalls/methods/calls/leave_call.py +4 -0
- pytgcalls/methods/internal/connect_call.py +10 -1
- pytgcalls/methods/internal/handle_mtproto_updates.py +8 -15
- pytgcalls/methods/stream/play.py +2 -1
- pytgcalls/mtproto/bridged_client.py +64 -2
- pytgcalls/mtproto/client_cache.py +65 -72
- pytgcalls/mtproto/hydrogram_client.py +132 -35
- pytgcalls/mtproto/mtproto_client.py +11 -0
- pytgcalls/mtproto/pyrogram_client.py +135 -43
- pytgcalls/mtproto/telethon_client.py +95 -35
- pytgcalls/mutex.py +3 -1
- pytgcalls/types/cache.py +10 -5
- pytgcalls/types/chats/group_call_participant.py +1 -8
- pytgcalls/types/chats/updated_group_call_participant.py +2 -0
- pytgcalls/types/dict.py +1 -1
- pytgcalls/types/flag.py +4 -3
- pytgcalls/types/list.py +1 -1
- pytgcalls/types/participant_list.py +3 -3
- pytgcalls/types/py_object.py +4 -2
- pytgcalls/types/stream/media_stream.py +5 -4
- pytgcalls/types/stream/record_stream.py +3 -1
- pytgcalls/types/stream/video_quality.py +3 -1
- pytgcalls/ytdlp.py +3 -2
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: py-tgcalls
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Async client API for the Telegram Calls.
|
|
5
5
|
Author-email: Laky-64 <iraci.matteo@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://pytgcalls.github.io/
|
|
@@ -20,7 +20,7 @@ Requires-Python: >=3.9
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
Requires-Dist: aiohttp>=3.9.3
|
|
23
|
-
Requires-Dist: ntgcalls<
|
|
23
|
+
Requires-Dist: ntgcalls<3.0.0,>=2.0.0
|
|
24
24
|
Requires-Dist: deprecation
|
|
25
25
|
Provides-Extra: pyrogram
|
|
26
26
|
Requires-Dist: pyrogram>=1.2.20; extra == "pyrogram"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
py_tgcalls-2.
|
|
1
|
+
py_tgcalls-2.2.0.dist-info/licenses/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
2
2
|
pytgcalls/__init__.py,sha256=qbfwN7rYwIdCegMOzdcbvwazeNjDzgmowgcqLFNqKIM,308
|
|
3
|
-
pytgcalls/__version__.py,sha256=
|
|
3
|
+
pytgcalls/__version__.py,sha256=Vyf6P6UCZKFeQtRzYujPmFfdlqSfnc01VEMWE3O0ZrA,22
|
|
4
4
|
pytgcalls/environment.py,sha256=ctCHACvG6l8SdpPewSBhOvc70kbwpv18maC0TwLvZ08,1924
|
|
5
5
|
pytgcalls/exceptions.py,sha256=Rijc-8T93WEWJxNW9jncU8_M6mYZZZcs8F2bqitEIeI,3787
|
|
6
|
-
pytgcalls/ffmpeg.py,sha256=
|
|
7
|
-
pytgcalls/filters.py,sha256=
|
|
6
|
+
pytgcalls/ffmpeg.py,sha256=CZvSyuztc-TGKbKI9_2G7CLITe1ITf315YPyprWu_Pg,8645
|
|
7
|
+
pytgcalls/filters.py,sha256=8Fq_gvHHdqhIk_XwMJ9wneeZOwrvBkSOKaMJ60r3bZU,6157
|
|
8
|
+
pytgcalls/list_to_cmd.py,sha256=rGJLsejbAQdDb8pctMbLnwea5NkitlfVKc3IpoGi4V4,240
|
|
8
9
|
pytgcalls/mtproto_required.py,sha256=6B-31p5qH_6oekUgypV4nK3hqPS6Nr-pA8S81wjnbaY,630
|
|
9
|
-
pytgcalls/mutex.py,sha256=
|
|
10
|
+
pytgcalls/mutex.py,sha256=vWqji9IAHtAc61FUTVXncx5rZ3rVf5qG_7PI4LmuYmU,733
|
|
10
11
|
pytgcalls/pytgcalls.py,sha256=DxCE0--mb53vyDXLLBAwy1cPrJgLsyC9rba_h2OzR2o,1608
|
|
11
12
|
pytgcalls/pytgcalls_session.py,sha256=_BGJWvf7t3mki2DhlEPjh9cypvYuSFkMSxzTsfepwUk,2719
|
|
12
13
|
pytgcalls/scaffold.py,sha256=Gahln5l70FJZwo1KGqv1A7K9Vn_ozAATpADGFJuPhKA,3162
|
|
@@ -14,7 +15,7 @@ pytgcalls/statictypes.py,sha256=CdlqgQNhTZ_uTE8-B8m01fJ7TlD2B42EI2QBPxDdAtA,3842
|
|
|
14
15
|
pytgcalls/sync.py,sha256=IsOH3TD7cxUg_-zdGt12HoS8sBlXvcGayPZAoxxKM48,3396
|
|
15
16
|
pytgcalls/version_manager.py,sha256=egeGgvb66zWlLTMuw2U-b0x8MfnRzMm1xAEVN87HF5c,296
|
|
16
17
|
pytgcalls/wait_counter_lock.py,sha256=J-KCWUBCt7ktKQKyIseNG0RfXDVRh-h0wKhaZlf4aFs,437
|
|
17
|
-
pytgcalls/ytdlp.py,sha256=
|
|
18
|
+
pytgcalls/ytdlp.py,sha256=MEPkVlFdbexbgqVRMt7C1YadPIER2R-4oN03osl5vq8,2473
|
|
18
19
|
pytgcalls/custom_api/__init__.py,sha256=ZT8d0lc2YrDuw_YSFAXXHHMewoXGFZ-ANOBIAr0vGFQ,60
|
|
19
20
|
pytgcalls/custom_api/custom_api.py,sha256=Ko3aS6psrwPmOhRPxvG0fepXt4STrA0StvINSxz4Cj8,1890
|
|
20
21
|
pytgcalls/handlers/__init__.py,sha256=pubbxI4pLqQpAKf8-toD6ija4cpSvbCJOQFjTiDjX1E,75
|
|
@@ -29,16 +30,16 @@ pytgcalls/methods/__init__.py,sha256=KKnG3uI_3oKKBByQ96kHJiabjxk2J6YLs4HDfOKvQ0A
|
|
|
29
30
|
pytgcalls/methods/calls/__init__.py,sha256=xg4DZZClEnxwaj-DAq3e8gSR-g-MiYBdUEBth64lSXA,214
|
|
30
31
|
pytgcalls/methods/calls/change_volume_call.py,sha256=xMUszg44Gs1RgTXGCwcWEESnwu3XVkW8Kx9HGLDGSEo,842
|
|
31
32
|
pytgcalls/methods/calls/get_participants.py,sha256=HDEMwZwNZM7KSb76P5XVH46qNONvBEVg4x_e-rgJscI,716
|
|
32
|
-
pytgcalls/methods/calls/leave_call.py,sha256=
|
|
33
|
+
pytgcalls/methods/calls/leave_call.py,sha256=YxeCB6mq5OhIy5MoFuC2PgKQ2H0E8VGr4I79upC5URY,1603
|
|
33
34
|
pytgcalls/methods/decorators/__init__.py,sha256=TCGaEVZnHjtOwv-3PNfaCVm0kyFhJApUPUNntt6MwyM,78
|
|
34
35
|
pytgcalls/methods/decorators/on_update.py,sha256=ZTL4YcQk0N4Ru56a5WItUvkSN5SAqr6_RDZvXmZMIHs,316
|
|
35
36
|
pytgcalls/methods/internal/__init__.py,sha256=fcgIxUJKT6QJD30ltnOfzKsLhzTTTklD2qxKlwCvyv0,1057
|
|
36
37
|
pytgcalls/methods/internal/clear_cache.py,sha256=qgG-oubmdtnefnXSiHSPHyBTyXypiLDC7G8l3FzjNw8,236
|
|
37
38
|
pytgcalls/methods/internal/clear_call.py,sha256=yElvn3i6_j14Q7n9kcLSl-muYAGcaIZaEFHdp6MrN0g,549
|
|
38
|
-
pytgcalls/methods/internal/connect_call.py,sha256=
|
|
39
|
+
pytgcalls/methods/internal/connect_call.py,sha256=Py-sB_ImH839tK9GxNUCJDJUNizsZtlm5m6kuiUX3lE,5739
|
|
39
40
|
pytgcalls/methods/internal/emit_sig_data.py,sha256=ucIsknhJHB-0x7lcymXvwQ647AJQ852zH2W6MdlC3ws,216
|
|
40
41
|
pytgcalls/methods/internal/handle_connection_changed.py,sha256=_1u3J6_Pjl1Gs1u_WkhG2FAUl_hxlHUiflaMkKkJDsc,866
|
|
41
|
-
pytgcalls/methods/internal/handle_mtproto_updates.py,sha256=
|
|
42
|
+
pytgcalls/methods/internal/handle_mtproto_updates.py,sha256=ZPGvenIjWiNnTTTKdhQdapHsxwYn4pSKOgKm8bPcPOk,7415
|
|
42
43
|
pytgcalls/methods/internal/handle_stream_ended.py,sha256=DllD1ZfGQbwVh-S0neocwnN-8lQtwwyrzWl9teSrZbY,561
|
|
43
44
|
pytgcalls/methods/internal/handle_stream_frame.py,sha256=_FA782qlOT3tUqnySm7RBpjbgfEEzt1oEBDm-iADsbQ,1145
|
|
44
45
|
pytgcalls/methods/internal/join_presentation.py,sha256=dLB2kolIIm2KQH8yBQbEPJi_y1_cVLWpE52_Rwjn_KE,2178
|
|
@@ -51,7 +52,7 @@ pytgcalls/methods/internal/update_status.py,sha256=6zH7oMM_qPE-88mdC5CBhT07gPvay
|
|
|
51
52
|
pytgcalls/methods/stream/__init__.py,sha256=mAcOih0-NT6T_Gspej6mySpJNPuEe46sUwgKV3vSvYM,336
|
|
52
53
|
pytgcalls/methods/stream/mute.py,sha256=ZrZS_EeNUeUxb6UgbdhwXUdRX826u-qSjH5a6sg7LsE,557
|
|
53
54
|
pytgcalls/methods/stream/pause.py,sha256=-kNvWQuv5VlssNcL-M6rkT5TKFmXlbOzJrDny95qsUc,560
|
|
54
|
-
pytgcalls/methods/stream/play.py,sha256=
|
|
55
|
+
pytgcalls/methods/stream/play.py,sha256=XJB7o4Y5ImY1Qh_tHCkT70cUKOr9JlinWtVKwE8W5Rw,2951
|
|
55
56
|
pytgcalls/methods/stream/record.py,sha256=geYSVtSbp0yRIR1Nmj-L1s-6nqQAh0x0IcA1OuFvuyA,1306
|
|
56
57
|
pytgcalls/methods/stream/resume.py,sha256=AUHU3AtpXO2rtp2V1EKSC_KAWTk2KHMiHaqHluYy31M,563
|
|
57
58
|
pytgcalls/methods/stream/send_frame.py,sha256=Kj9R8OqUM-g7pt-FiWP-US7sCFkH5ciPr9S8v-WPtLg,1062
|
|
@@ -69,20 +70,20 @@ pytgcalls/methods/utilities/run.py,sha256=cnYQd2xB5Cr_WS0Q2cXJZPGiN6JOCULzj1r4xX
|
|
|
69
70
|
pytgcalls/methods/utilities/start.py,sha256=mn0kQZhTUuc-9CCJDbFIVsEtJ8kfnfZOGbVC505qVRM,3232
|
|
70
71
|
pytgcalls/methods/utilities/stream_params.py,sha256=fOSloo1A7WTxaZEtOiPXjdexMeoJjq8CZtfHuIFX7Ns,3325
|
|
71
72
|
pytgcalls/mtproto/__init__.py,sha256=X4zvzFG7km7qHyE0fdvA550WcOVO_xl_p__gvIfDGmw,130
|
|
72
|
-
pytgcalls/mtproto/bridged_client.py,sha256=
|
|
73
|
-
pytgcalls/mtproto/client_cache.py,sha256=
|
|
74
|
-
pytgcalls/mtproto/hydrogram_client.py,sha256=
|
|
75
|
-
pytgcalls/mtproto/mtproto_client.py,sha256=
|
|
76
|
-
pytgcalls/mtproto/pyrogram_client.py,sha256=
|
|
77
|
-
pytgcalls/mtproto/telethon_client.py,sha256=
|
|
73
|
+
pytgcalls/mtproto/bridged_client.py,sha256=Qb9-9FrUdh3g_sx-JOcvkzv3kJtS_pz2Qaos85DgVPI,8280
|
|
74
|
+
pytgcalls/mtproto/client_cache.py,sha256=5unu8sjLRaIKoEgJGaIRjhA4P3U2lFpfakTKFxKLzAM,5591
|
|
75
|
+
pytgcalls/mtproto/hydrogram_client.py,sha256=P2YpeIBYXzBHWLXyk9pGiO_TsIBuzDQ7LvorGZFFM-o,28974
|
|
76
|
+
pytgcalls/mtproto/mtproto_client.py,sha256=9SIG3DNeICIXvggyVE8DQWtToPtxV0t9ZKr6dEMnEMg,8783
|
|
77
|
+
pytgcalls/mtproto/pyrogram_client.py,sha256=CI9uPMdwwE3UGSNfenqIKUl-UD_caVZpCzYR1PB4drY,28970
|
|
78
|
+
pytgcalls/mtproto/telethon_client.py,sha256=w9PuqE_gsDKFYVpF5o_ULMSsYf5sAK8VgImVxbNz2Bc,27106
|
|
78
79
|
pytgcalls/types/__init__.py,sha256=GlgBBXAwbNopXSeTTmiXktrEJhhN_rMBtuAllTBbN3k,1189
|
|
79
80
|
pytgcalls/types/browsers.py,sha256=47Kr5q96n4Q4WvVhA6IUlS2egEcA9GRLlDeFcQYyc9M,9545
|
|
80
|
-
pytgcalls/types/cache.py,sha256=
|
|
81
|
-
pytgcalls/types/dict.py,sha256
|
|
82
|
-
pytgcalls/types/flag.py,sha256=
|
|
83
|
-
pytgcalls/types/list.py,sha256=
|
|
84
|
-
pytgcalls/types/participant_list.py,sha256=
|
|
85
|
-
pytgcalls/types/py_object.py,sha256=
|
|
81
|
+
pytgcalls/types/cache.py,sha256=nJh6B7xnvAiLh0mDJYS9sYhnRvj0BqxrQBLXs4WEUMs,1235
|
|
82
|
+
pytgcalls/types/dict.py,sha256=-R1v5-v5WzhquPN25Bfw9Ow6q2lRRgpsq_FlsOawCUw,78
|
|
83
|
+
pytgcalls/types/flag.py,sha256=MeWDKkUAZa97fUPg5Ni5Rf4pDgiZ_OSRZPseEY7d3rw,104
|
|
84
|
+
pytgcalls/types/list.py,sha256=rGzD9LWAI2hUX71OL_pqZn08YHEbZ-AZ6RTjXPc9wJA,78
|
|
85
|
+
pytgcalls/types/participant_list.py,sha256=wG7a8dvcmcUkagmSo-g4thGMBrqMdEU0fA_zD4tCk2w,931
|
|
86
|
+
pytgcalls/types/py_object.py,sha256=jisGKqJINuzAjkIkLIps61uYM0eFSmC9TtgxGRDAMZI,934
|
|
86
87
|
pytgcalls/types/update.py,sha256=wPCzWLhrsScZ3ksRTyt8IuDaaG5YI-ItG_Yw-OqzK2Y,157
|
|
87
88
|
pytgcalls/types/user_agent.py,sha256=sSfeGqUe0v0wqBgdVszNFK0iOC_0Tdyto9CglBXlY4U,1086
|
|
88
89
|
pytgcalls/types/calls/__init__.py,sha256=lgFG89_NGhWHOQqhfw3adPaQZMzsMKI1f-MyZW3TBBU,478
|
|
@@ -96,8 +97,8 @@ pytgcalls/types/calls/pending_connection.py,sha256=qRRmutInj70rtzbThM7CNznFhEPqT
|
|
|
96
97
|
pytgcalls/types/calls/raw_call_update.py,sha256=hpNw6HrTW8Z36Lh2HinS-wzprryRtsIxyIFbIfjGgeI,795
|
|
97
98
|
pytgcalls/types/chats/__init__.py,sha256=v8pUp_vbr2kQpyHtAQc80N-YqzmXHe9SbllUsa6njkU,261
|
|
98
99
|
pytgcalls/types/chats/chat_update.py,sha256=lzrqNDPv4a_yXpKIfUnhocXqZyIy8XgZladOQTYrrYA,730
|
|
99
|
-
pytgcalls/types/chats/group_call_participant.py,sha256=
|
|
100
|
-
pytgcalls/types/chats/updated_group_call_participant.py,sha256
|
|
100
|
+
pytgcalls/types/chats/group_call_participant.py,sha256=aK7nvI0Jy93g9A_FVeFzk1BZFXzhFry06h8xR4VpqXY,1507
|
|
101
|
+
pytgcalls/types/chats/updated_group_call_participant.py,sha256=bZQsZAsMv_i4k8DJW3phyuHqpa9Dp6IbheHCvj3M630,365
|
|
101
102
|
pytgcalls/types/raw/__init__.py,sha256=ROHsKFeUMUtlFbx2rhfrdB-TuVm0zBuvNo29Ccn5614,308
|
|
102
103
|
pytgcalls/types/raw/audio_parameters.py,sha256=1DsBPwdn_Ukd2Tbkb3whP_ILo9xJY_3XNNmbO4_NO9Q,449
|
|
103
104
|
pytgcalls/types/raw/audio_stream.py,sha256=oN7Sx9oLbNFuNXiGYpoNabMwqWKGquLiHEywef28o7c,488
|
|
@@ -110,12 +111,12 @@ pytgcalls/types/stream/device.py,sha256=EdoDg6lPE7fgoZI04Nr0E9zbIk-iRIBgYYAzVqoC
|
|
|
110
111
|
pytgcalls/types/stream/direction.py,sha256=VepLMe-dXg4M5eVdVyIb2uxYvnpB9OJL5fEgPYUFtTI,592
|
|
111
112
|
pytgcalls/types/stream/external_media.py,sha256=RiuSX5tZGdNsQZ8LIRk5Lp4Ksv9oTvaccmInJRZYo4M,114
|
|
112
113
|
pytgcalls/types/stream/frame.py,sha256=TXo5HZVHbbaVNBqulMhTqGODXH3bpBVlN_of1rosNUQ,586
|
|
113
|
-
pytgcalls/types/stream/media_stream.py,sha256=
|
|
114
|
-
pytgcalls/types/stream/record_stream.py,sha256=
|
|
114
|
+
pytgcalls/types/stream/media_stream.py,sha256=zcRVpNXfL8mhg-SEfAi-f0lDUZMyNYLetophvcAN_gQ,11968
|
|
115
|
+
pytgcalls/types/stream/record_stream.py,sha256=f4VQ6MY8HtOxt7vz0hWBFmbbAIvTRHpAIU2nmj0TF6Y,3197
|
|
115
116
|
pytgcalls/types/stream/stream_ended.py,sha256=xR_kZwFf03hA6rw_nvI7Be7GwoCKzQf_1MKaGpPDXqY,716
|
|
116
117
|
pytgcalls/types/stream/stream_frames.py,sha256=028ZhNV-mN3BGqMlmxusAV1xDQpXRYCeM0WXBZhRUhA,446
|
|
117
|
-
pytgcalls/types/stream/video_quality.py,sha256=
|
|
118
|
-
py_tgcalls-2.
|
|
119
|
-
py_tgcalls-2.
|
|
120
|
-
py_tgcalls-2.
|
|
121
|
-
py_tgcalls-2.
|
|
118
|
+
pytgcalls/types/stream/video_quality.py,sha256=eMCBFPwh5meX3UVEaozcGlwmgaujfpiTa3vBVSBBP_8,275
|
|
119
|
+
py_tgcalls-2.2.0.dist-info/METADATA,sha256=OLWKAf_6F7CxLaWYFyNr0A88kPEhdIRKi2uhTkUii38,5280
|
|
120
|
+
py_tgcalls-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
121
|
+
py_tgcalls-2.2.0.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
|
|
122
|
+
py_tgcalls-2.2.0.dist-info/RECORD,,
|
pytgcalls/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.
|
|
1
|
+
__version__ = '2.2.0'
|
pytgcalls/ffmpeg.py
CHANGED
|
@@ -207,12 +207,12 @@ def build_command(
|
|
|
207
207
|
if headers is not None:
|
|
208
208
|
for i in headers:
|
|
209
209
|
ffmpeg_command.append('-headers')
|
|
210
|
-
ffmpeg_command.append(f'
|
|
210
|
+
ffmpeg_command.append(f'{i}: {headers[i]}')
|
|
211
211
|
|
|
212
212
|
ffmpeg_command += [
|
|
213
213
|
'-nostdin',
|
|
214
214
|
'-i',
|
|
215
|
-
f'
|
|
215
|
+
f'{path}' if name == 'ffmpeg' else path,
|
|
216
216
|
]
|
|
217
217
|
ffmpeg_command += command['mid']
|
|
218
218
|
|
pytgcalls/filters.py
CHANGED
|
@@ -158,6 +158,7 @@ class stream_end(Filter):
|
|
|
158
158
|
self.device & update.device
|
|
159
159
|
)
|
|
160
160
|
)
|
|
161
|
+
return False
|
|
161
162
|
|
|
162
163
|
|
|
163
164
|
# noinspection PyPep8Naming
|
|
@@ -190,14 +191,17 @@ class chat_update(Filter):
|
|
|
190
191
|
|
|
191
192
|
# noinspection PyPep8Naming
|
|
192
193
|
class call_participant(Filter):
|
|
193
|
-
def __init__(
|
|
194
|
+
def __init__(
|
|
195
|
+
self,
|
|
196
|
+
flags: Optional[GroupCallParticipant.Action] = None,
|
|
197
|
+
):
|
|
194
198
|
self.flags = flags
|
|
195
199
|
|
|
196
200
|
async def __call__(self, client: PyTgCalls, update: Update):
|
|
197
201
|
if isinstance(update, UpdatedGroupCallParticipant):
|
|
198
202
|
if self.flags is None:
|
|
199
203
|
return True
|
|
200
|
-
return self.flags & update.
|
|
204
|
+
return self.flags & update.action
|
|
201
205
|
return False
|
|
202
206
|
|
|
203
207
|
|
pytgcalls/list_to_cmd.py
ADDED
|
@@ -17,6 +17,7 @@ class LeaveCall(Scaffold):
|
|
|
17
17
|
async def leave_call(
|
|
18
18
|
self,
|
|
19
19
|
chat_id: Union[int, str],
|
|
20
|
+
close: bool = False,
|
|
20
21
|
):
|
|
21
22
|
chat_id = await self.resolve_chat_id(chat_id)
|
|
22
23
|
is_p2p_waiting = (
|
|
@@ -48,3 +49,6 @@ class LeaveCall(Scaffold):
|
|
|
48
49
|
self._need_unmute.discard(chat_id)
|
|
49
50
|
self._presentations.discard(chat_id)
|
|
50
51
|
self._call_sources.pop(chat_id, None)
|
|
52
|
+
|
|
53
|
+
if chat_id < 0 and close: # type: ignore
|
|
54
|
+
self._app.close_voice_chat(chat_id)
|
|
@@ -5,6 +5,7 @@ from typing import Union
|
|
|
5
5
|
from ntgcalls import ConnectionMode
|
|
6
6
|
from ntgcalls import ConnectionNotFound
|
|
7
7
|
from ntgcalls import MediaDescription
|
|
8
|
+
from ntgcalls import StreamMode
|
|
8
9
|
from ntgcalls import TelegramServerError
|
|
9
10
|
|
|
10
11
|
from ...exceptions import TimedOutAnswer
|
|
@@ -31,8 +32,12 @@ class ConnectCall(Scaffold):
|
|
|
31
32
|
if not payload:
|
|
32
33
|
payload = await self._binding.create_call(
|
|
33
34
|
chat_id,
|
|
34
|
-
media_description,
|
|
35
35
|
)
|
|
36
|
+
await self._binding.set_stream_sources(
|
|
37
|
+
chat_id,
|
|
38
|
+
StreamMode.CAPTURE,
|
|
39
|
+
media_description,
|
|
40
|
+
)
|
|
36
41
|
result_params = await self._app.join_group_call(
|
|
37
42
|
chat_id,
|
|
38
43
|
payload,
|
|
@@ -63,6 +68,10 @@ class ConnectCall(Scaffold):
|
|
|
63
68
|
)
|
|
64
69
|
await self._binding.create_p2p_call(
|
|
65
70
|
chat_id,
|
|
71
|
+
)
|
|
72
|
+
await self._binding.set_stream_sources(
|
|
73
|
+
chat_id,
|
|
74
|
+
StreamMode.CAPTURE,
|
|
66
75
|
media_description,
|
|
67
76
|
)
|
|
68
77
|
data.g_a_or_b = await self._binding.init_exchange(
|
|
@@ -72,7 +72,7 @@ class HandleMTProtoUpdates(Scaffold):
|
|
|
72
72
|
await self._clear_call(chat_id)
|
|
73
73
|
if isinstance(update, UpdatedGroupCallParticipant):
|
|
74
74
|
participant = update.participant
|
|
75
|
-
action =
|
|
75
|
+
action = update.action
|
|
76
76
|
chat_peer = self._cache_user_peer.get(chat_id)
|
|
77
77
|
user_id = participant.user_id
|
|
78
78
|
if chat_id in self._call_sources:
|
|
@@ -141,19 +141,12 @@ class HandleMTProtoUpdates(Scaffold):
|
|
|
141
141
|
chat_peer,
|
|
142
142
|
) == participant.user_id if chat_peer else False
|
|
143
143
|
if is_self:
|
|
144
|
-
if action == GroupCallParticipant.Action.
|
|
145
|
-
|
|
146
|
-
await self._propagate(
|
|
147
|
-
ChatUpdate(
|
|
148
|
-
chat_id,
|
|
149
|
-
ChatUpdate.Status.KICKED,
|
|
150
|
-
),
|
|
151
|
-
self,
|
|
152
|
-
)
|
|
144
|
+
if action == GroupCallParticipant.Action.KICKED:
|
|
145
|
+
await self._clear_call(chat_id)
|
|
153
146
|
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
147
|
+
chat_id in self._need_unmute and
|
|
148
|
+
action == GroupCallParticipant.Action.UPDATED
|
|
149
|
+
and not participant.muted_by_admin
|
|
157
150
|
):
|
|
158
151
|
await self._update_status(
|
|
159
152
|
chat_id,
|
|
@@ -162,8 +155,8 @@ class HandleMTProtoUpdates(Scaffold):
|
|
|
162
155
|
await self._switch_connection(chat_id)
|
|
163
156
|
|
|
164
157
|
if (
|
|
165
|
-
|
|
166
|
-
|
|
158
|
+
participant.muted_by_admin and
|
|
159
|
+
action != GroupCallParticipant.Action.LEFT
|
|
167
160
|
):
|
|
168
161
|
self._need_unmute.add(chat_id)
|
|
169
162
|
else:
|
pytgcalls/methods/stream/play.py
CHANGED
|
@@ -44,11 +44,12 @@ class Play(Scaffold):
|
|
|
44
44
|
|
|
45
45
|
if chat_id in await self._binding.calls():
|
|
46
46
|
try:
|
|
47
|
-
|
|
47
|
+
await self._binding.set_stream_sources(
|
|
48
48
|
chat_id,
|
|
49
49
|
StreamMode.CAPTURE,
|
|
50
50
|
media_description,
|
|
51
51
|
)
|
|
52
|
+
return
|
|
52
53
|
except FileError as e:
|
|
53
54
|
raise FileNotFoundError(e)
|
|
54
55
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import random
|
|
2
|
+
import re
|
|
2
3
|
from typing import Any
|
|
3
4
|
from typing import List
|
|
4
5
|
from typing import Optional
|
|
@@ -10,6 +11,7 @@ from ntgcalls import SsrcGroup
|
|
|
10
11
|
|
|
11
12
|
from ..handlers import HandlersHolder
|
|
12
13
|
from ..types import GroupCallParticipant
|
|
14
|
+
from ..types import UpdatedGroupCallParticipant
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class BridgedClient(HandlersHolder):
|
|
@@ -95,6 +97,12 @@ class BridgedClient(HandlersHolder):
|
|
|
95
97
|
):
|
|
96
98
|
pass
|
|
97
99
|
|
|
100
|
+
async def close_voice_chat(
|
|
101
|
+
self,
|
|
102
|
+
chat_id: int,
|
|
103
|
+
):
|
|
104
|
+
pass
|
|
105
|
+
|
|
98
106
|
async def get_group_call_participants(
|
|
99
107
|
self,
|
|
100
108
|
chat_id: int,
|
|
@@ -189,13 +197,56 @@ class BridgedClient(HandlersHolder):
|
|
|
189
197
|
bool(participant.raise_hand_rating),
|
|
190
198
|
participant.volume // 100
|
|
191
199
|
if participant.volume is not None else 100,
|
|
192
|
-
bool(participant.just_joined),
|
|
193
|
-
bool(participant.left),
|
|
194
200
|
participant.source,
|
|
195
201
|
BridgedClient.parse_source(participant.video),
|
|
196
202
|
BridgedClient.parse_source(participant.presentation),
|
|
197
203
|
)
|
|
198
204
|
|
|
205
|
+
@staticmethod
|
|
206
|
+
async def diff_participants_update(
|
|
207
|
+
cache,
|
|
208
|
+
chat_id: Optional[int],
|
|
209
|
+
participant,
|
|
210
|
+
) -> List[UpdatedGroupCallParticipant]:
|
|
211
|
+
if chat_id is None:
|
|
212
|
+
return []
|
|
213
|
+
user_id = BridgedClient.chat_id(participant.peer)
|
|
214
|
+
participants = await cache.get_participant_list(
|
|
215
|
+
chat_id,
|
|
216
|
+
True,
|
|
217
|
+
)
|
|
218
|
+
updates = []
|
|
219
|
+
for p in participants:
|
|
220
|
+
if p.user_id == user_id:
|
|
221
|
+
if p.source != participant.source:
|
|
222
|
+
updates.append(
|
|
223
|
+
UpdatedGroupCallParticipant(
|
|
224
|
+
chat_id,
|
|
225
|
+
GroupCallParticipant.Action.KICKED,
|
|
226
|
+
p,
|
|
227
|
+
),
|
|
228
|
+
)
|
|
229
|
+
participant.just_joined = True
|
|
230
|
+
break
|
|
231
|
+
|
|
232
|
+
updates.append(
|
|
233
|
+
UpdatedGroupCallParticipant(
|
|
234
|
+
chat_id,
|
|
235
|
+
BridgedClient.parse_participant_action(participant),
|
|
236
|
+
BridgedClient.parse_participant(participant),
|
|
237
|
+
),
|
|
238
|
+
)
|
|
239
|
+
return updates
|
|
240
|
+
|
|
241
|
+
@staticmethod
|
|
242
|
+
def parse_participant_action(participant):
|
|
243
|
+
if participant.just_joined:
|
|
244
|
+
return GroupCallParticipant.Action.JOINED
|
|
245
|
+
elif participant.left:
|
|
246
|
+
return GroupCallParticipant.Action.LEFT
|
|
247
|
+
else:
|
|
248
|
+
return GroupCallParticipant.Action.UPDATED
|
|
249
|
+
|
|
199
250
|
@staticmethod
|
|
200
251
|
def chat_id(input_peer) -> int:
|
|
201
252
|
class_name = input_peer.__class__.__name__
|
|
@@ -260,6 +311,17 @@ class BridgedClient(HandlersHolder):
|
|
|
260
311
|
else:
|
|
261
312
|
return None
|
|
262
313
|
|
|
314
|
+
@staticmethod
|
|
315
|
+
def extract_dc(error: str) -> Optional[int]:
|
|
316
|
+
dc_id = re.findall(
|
|
317
|
+
r'('
|
|
318
|
+
r'CALL_MIGRATE_|'
|
|
319
|
+
r'The file to be accessed is currently stored in DC *'
|
|
320
|
+
r')([0-9])',
|
|
321
|
+
error,
|
|
322
|
+
)
|
|
323
|
+
return int(dc_id[0][1]) if dc_id else None
|
|
324
|
+
|
|
263
325
|
@staticmethod
|
|
264
326
|
def rnd_id() -> int:
|
|
265
327
|
return random.randint(0, 0x7FFFFFFF - 1)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from time import time
|
|
3
2
|
from typing import Any
|
|
4
3
|
from typing import List
|
|
5
4
|
from typing import Optional
|
|
@@ -19,10 +18,12 @@ class ClientCache:
|
|
|
19
18
|
app: BridgedClient,
|
|
20
19
|
):
|
|
21
20
|
self._app: BridgedClient = app
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
self.
|
|
25
|
-
self.
|
|
21
|
+
cache_duration = 0 if app.no_updates() else cache_duration
|
|
22
|
+
full_chat_duration = 1 if app.no_updates() else cache_duration
|
|
23
|
+
self._full_chat_cache = Cache(full_chat_duration)
|
|
24
|
+
self._call_participants_cache = Cache(cache_duration)
|
|
25
|
+
self._dc_call_cache = Cache(full_chat_duration)
|
|
26
|
+
self._phone_calls = Cache(full_chat_duration)
|
|
26
27
|
|
|
27
28
|
async def get_full_chat(
|
|
28
29
|
self,
|
|
@@ -45,88 +46,64 @@ class ClientCache:
|
|
|
45
46
|
pass
|
|
46
47
|
return None
|
|
47
48
|
|
|
48
|
-
def
|
|
49
|
+
def set_participants_cache(
|
|
49
50
|
self,
|
|
50
|
-
|
|
51
|
-
participant: GroupCallParticipant,
|
|
52
|
-
) -> Optional[GroupCallParticipant]:
|
|
53
|
-
chat_id = self.get_chat_id(input_id)
|
|
54
|
-
if chat_id is not None:
|
|
55
|
-
return self._internal_set_participants_cache(
|
|
56
|
-
chat_id,
|
|
57
|
-
participant,
|
|
58
|
-
)
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
def set_participants_cache_chat(
|
|
62
|
-
self,
|
|
63
|
-
chat_id: int,
|
|
51
|
+
chat_id: Optional[int],
|
|
64
52
|
call_id: int,
|
|
53
|
+
action: GroupCallParticipant.Action,
|
|
65
54
|
participant: GroupCallParticipant,
|
|
66
55
|
) -> Optional[GroupCallParticipant]:
|
|
67
|
-
if
|
|
68
|
-
self._call_participants_cache.
|
|
56
|
+
if chat_id is not None:
|
|
57
|
+
if self._call_participants_cache.get(chat_id) is None:
|
|
58
|
+
self._call_participants_cache.put(
|
|
59
|
+
chat_id,
|
|
60
|
+
ParticipantList(
|
|
61
|
+
call_id,
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
participants: Optional[
|
|
65
|
+
ParticipantList
|
|
66
|
+
] = self._call_participants_cache.get(
|
|
69
67
|
chat_id,
|
|
70
|
-
ParticipantList(
|
|
71
|
-
call_id,
|
|
72
|
-
),
|
|
73
|
-
)
|
|
74
|
-
return self._internal_set_participants_cache(
|
|
75
|
-
chat_id,
|
|
76
|
-
participant,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
def _internal_set_participants_cache(
|
|
80
|
-
self,
|
|
81
|
-
chat_id: int,
|
|
82
|
-
participant: GroupCallParticipant,
|
|
83
|
-
) -> Optional[GroupCallParticipant]:
|
|
84
|
-
participants: Optional[
|
|
85
|
-
ParticipantList
|
|
86
|
-
] = self._call_participants_cache.get(
|
|
87
|
-
chat_id,
|
|
88
|
-
)
|
|
89
|
-
if participants is not None:
|
|
90
|
-
participants.last_mtproto_update = (
|
|
91
|
-
int(time()) + self._cache_duration
|
|
92
68
|
)
|
|
93
|
-
|
|
69
|
+
if participants is not None:
|
|
70
|
+
self._call_participants_cache.update_cache(chat_id)
|
|
71
|
+
return participants.update_participant(
|
|
72
|
+
action,
|
|
73
|
+
participant,
|
|
74
|
+
)
|
|
94
75
|
return None
|
|
95
76
|
|
|
96
77
|
async def get_participant_list(
|
|
97
78
|
self,
|
|
98
79
|
chat_id: int,
|
|
99
|
-
|
|
80
|
+
only_cached: bool = False,
|
|
81
|
+
) -> List[GroupCallParticipant]:
|
|
100
82
|
input_call = await self.get_full_chat(
|
|
101
83
|
chat_id,
|
|
102
84
|
)
|
|
103
85
|
if input_call is not None:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
86
|
+
if self._call_participants_cache.get(chat_id) is None:
|
|
87
|
+
if only_cached:
|
|
88
|
+
return []
|
|
89
|
+
py_logger.debug(
|
|
90
|
+
'GetParticipant cache miss for %d', chat_id,
|
|
91
|
+
)
|
|
92
|
+
list_participants = await self._app.get_participants(
|
|
93
|
+
input_call,
|
|
94
|
+
)
|
|
95
|
+
for participant in list_participants:
|
|
96
|
+
self.set_participants_cache(
|
|
97
|
+
chat_id,
|
|
98
|
+
input_call.id,
|
|
99
|
+
GroupCallParticipant.Action.UPDATED,
|
|
100
|
+
participant,
|
|
115
101
|
)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
self.set_participants_cache_call(
|
|
122
|
-
input_call.id,
|
|
123
|
-
participant,
|
|
124
|
-
)
|
|
125
|
-
except Exception as e:
|
|
126
|
-
py_logger.error('Error for %s in %d', e, chat_id)
|
|
127
|
-
else:
|
|
128
|
-
py_logger.debug('GetParticipant cache hit for %d', chat_id)
|
|
129
|
-
return participants.get_participants()
|
|
102
|
+
else:
|
|
103
|
+
py_logger.debug('GetParticipant cache hit for %d', chat_id)
|
|
104
|
+
return self._call_participants_cache.get(
|
|
105
|
+
chat_id,
|
|
106
|
+
).get_participants()
|
|
130
107
|
return []
|
|
131
108
|
|
|
132
109
|
def get_chat_id(
|
|
@@ -148,7 +125,6 @@ class ClientCache:
|
|
|
148
125
|
self._full_chat_cache.put(
|
|
149
126
|
chat_id,
|
|
150
127
|
input_call,
|
|
151
|
-
self._cache_duration,
|
|
152
128
|
)
|
|
153
129
|
if self._call_participants_cache.get(chat_id) is None:
|
|
154
130
|
self._call_participants_cache.put(
|
|
@@ -164,6 +140,23 @@ class ClientCache:
|
|
|
164
140
|
) -> None:
|
|
165
141
|
self._full_chat_cache.pop(chat_id)
|
|
166
142
|
self._call_participants_cache.pop(chat_id)
|
|
143
|
+
self._dc_call_cache.pop(chat_id)
|
|
144
|
+
|
|
145
|
+
def set_dc_call(
|
|
146
|
+
self,
|
|
147
|
+
chat_id: int,
|
|
148
|
+
dc_id: int,
|
|
149
|
+
) -> None:
|
|
150
|
+
self._dc_call_cache.put(
|
|
151
|
+
chat_id,
|
|
152
|
+
dc_id,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
def get_dc_call(
|
|
156
|
+
self,
|
|
157
|
+
chat_id: int,
|
|
158
|
+
) -> Optional[int]:
|
|
159
|
+
return self._dc_call_cache.get(chat_id)
|
|
167
160
|
|
|
168
161
|
def set_phone_call(
|
|
169
162
|
self,
|