py-tgcalls 2.2.0rc3__py3-none-any.whl → 2.2.2__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.2.0rc3.dist-info → py_tgcalls-2.2.2.dist-info}/METADATA +2 -2
- {py_tgcalls-2.2.0rc3.dist-info → py_tgcalls-2.2.2.dist-info}/RECORD +29 -29
- {py_tgcalls-2.2.0rc3.dist-info → py_tgcalls-2.2.2.dist-info}/WHEEL +1 -1
- pytgcalls/__version__.py +1 -1
- pytgcalls/methods/calls/leave_call.py +4 -0
- pytgcalls/methods/internal/clear_cache.py +2 -0
- pytgcalls/methods/internal/clear_call.py +0 -3
- pytgcalls/methods/internal/connect_call.py +1 -0
- pytgcalls/methods/internal/handle_mtproto_updates.py +7 -10
- pytgcalls/methods/internal/join_presentation.py +2 -2
- pytgcalls/methods/stream/play.py +2 -1
- pytgcalls/methods/utilities/stream_params.py +1 -1
- pytgcalls/mtproto/bridged_client.py +43 -0
- pytgcalls/mtproto/client_cache.py +47 -81
- pytgcalls/mtproto/hydrogram_client.py +31 -17
- pytgcalls/mtproto/mtproto_client.py +11 -0
- pytgcalls/mtproto/pyrogram_client.py +31 -17
- pytgcalls/mtproto/telethon_client.py +31 -17
- pytgcalls/types/cache.py +10 -5
- pytgcalls/types/calls/raw_call_update.py +1 -1
- pytgcalls/types/chats/group_call_participant.py +2 -1
- pytgcalls/types/dict.py +1 -1
- pytgcalls/types/flag.py +4 -3
- pytgcalls/types/list.py +1 -1
- pytgcalls/types/participant_list.py +1 -2
- pytgcalls/types/py_object.py +4 -2
- pytgcalls/types/stream/video_quality.py +3 -1
- {py_tgcalls-2.2.0rc3.dist-info → py_tgcalls-2.2.2.dist-info}/licenses/LICENSE +0 -0
- {py_tgcalls-2.2.0rc3.dist-info → py_tgcalls-2.2.2.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.2.
|
|
3
|
+
Version: 2.2.2
|
|
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<3.0.0,>=2.0.
|
|
23
|
+
Requires-Dist: ntgcalls<3.0.0,>=2.0.2
|
|
24
24
|
Requires-Dist: deprecation
|
|
25
25
|
Provides-Extra: pyrogram
|
|
26
26
|
Requires-Dist: pyrogram>=1.2.20; extra == "pyrogram"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
py_tgcalls-2.2.
|
|
1
|
+
py_tgcalls-2.2.2.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=jsJ9CNIuUt8dDFB4i0PiBf07nzBU0RtG1CVRQ7TdoQ0,22
|
|
4
4
|
pytgcalls/environment.py,sha256=ctCHACvG6l8SdpPewSBhOvc70kbwpv18maC0TwLvZ08,1924
|
|
5
5
|
pytgcalls/exceptions.py,sha256=Rijc-8T93WEWJxNW9jncU8_M6mYZZZcs8F2bqitEIeI,3787
|
|
6
6
|
pytgcalls/ffmpeg.py,sha256=CZvSyuztc-TGKbKI9_2G7CLITe1ITf315YPyprWu_Pg,8645
|
|
@@ -30,19 +30,19 @@ pytgcalls/methods/__init__.py,sha256=KKnG3uI_3oKKBByQ96kHJiabjxk2J6YLs4HDfOKvQ0A
|
|
|
30
30
|
pytgcalls/methods/calls/__init__.py,sha256=xg4DZZClEnxwaj-DAq3e8gSR-g-MiYBdUEBth64lSXA,214
|
|
31
31
|
pytgcalls/methods/calls/change_volume_call.py,sha256=xMUszg44Gs1RgTXGCwcWEESnwu3XVkW8Kx9HGLDGSEo,842
|
|
32
32
|
pytgcalls/methods/calls/get_participants.py,sha256=HDEMwZwNZM7KSb76P5XVH46qNONvBEVg4x_e-rgJscI,716
|
|
33
|
-
pytgcalls/methods/calls/leave_call.py,sha256=
|
|
33
|
+
pytgcalls/methods/calls/leave_call.py,sha256=XiaKrnSgaItbAIUpdGXCo1HgXY7V7FcDjRsi5OwNweY,1609
|
|
34
34
|
pytgcalls/methods/decorators/__init__.py,sha256=TCGaEVZnHjtOwv-3PNfaCVm0kyFhJApUPUNntt6MwyM,78
|
|
35
35
|
pytgcalls/methods/decorators/on_update.py,sha256=ZTL4YcQk0N4Ru56a5WItUvkSN5SAqr6_RDZvXmZMIHs,316
|
|
36
36
|
pytgcalls/methods/internal/__init__.py,sha256=fcgIxUJKT6QJD30ltnOfzKsLhzTTTklD2qxKlwCvyv0,1057
|
|
37
|
-
pytgcalls/methods/internal/clear_cache.py,sha256=
|
|
38
|
-
pytgcalls/methods/internal/clear_call.py,sha256=
|
|
39
|
-
pytgcalls/methods/internal/connect_call.py,sha256=
|
|
37
|
+
pytgcalls/methods/internal/clear_cache.py,sha256=IbcDOGiBJbmqOnGJWkIe8c6P_Y6e0YPkui4Hg4PAZlA,334
|
|
38
|
+
pytgcalls/methods/internal/clear_call.py,sha256=u84SdZb5z6lGRxf7dbrcAcf-xObGVgMsHqSmvdzoAbQ,487
|
|
39
|
+
pytgcalls/methods/internal/connect_call.py,sha256=O5BqayOFJInC0eWdeofAimyY6JONpe6Iw4TYtSSMf3c,5800
|
|
40
40
|
pytgcalls/methods/internal/emit_sig_data.py,sha256=ucIsknhJHB-0x7lcymXvwQ647AJQ852zH2W6MdlC3ws,216
|
|
41
41
|
pytgcalls/methods/internal/handle_connection_changed.py,sha256=_1u3J6_Pjl1Gs1u_WkhG2FAUl_hxlHUiflaMkKkJDsc,866
|
|
42
|
-
pytgcalls/methods/internal/handle_mtproto_updates.py,sha256=
|
|
42
|
+
pytgcalls/methods/internal/handle_mtproto_updates.py,sha256=mdj8N4GXX1J650dE7OThSAVCmtB4wwByqd95P6vmbU8,7461
|
|
43
43
|
pytgcalls/methods/internal/handle_stream_ended.py,sha256=DllD1ZfGQbwVh-S0neocwnN-8lQtwwyrzWl9teSrZbY,561
|
|
44
44
|
pytgcalls/methods/internal/handle_stream_frame.py,sha256=_FA782qlOT3tUqnySm7RBpjbgfEEzt1oEBDm-iADsbQ,1145
|
|
45
|
-
pytgcalls/methods/internal/join_presentation.py,sha256=
|
|
45
|
+
pytgcalls/methods/internal/join_presentation.py,sha256=sXhmzbLWwVFi3gFl1rv0OgJsRJBrvjzRcl60N6ydNW8,2184
|
|
46
46
|
pytgcalls/methods/internal/log_retries.py,sha256=6nD9J3350t82I0PKzK1pVx3ZaCBHATReiXYMs3PuVhQ,342
|
|
47
47
|
pytgcalls/methods/internal/request_broadcast_part.py,sha256=oh-SqMCuQQErpF9Gd8ubPDoZeaz4bKw0dK--JrjXK9s,1313
|
|
48
48
|
pytgcalls/methods/internal/request_broadcast_timestamp.py,sha256=yEEmtyLR-EsEO1aXMcRAD34LRH63gY6ZQvn_Sw9quLk,642
|
|
@@ -52,7 +52,7 @@ pytgcalls/methods/internal/update_status.py,sha256=6zH7oMM_qPE-88mdC5CBhT07gPvay
|
|
|
52
52
|
pytgcalls/methods/stream/__init__.py,sha256=mAcOih0-NT6T_Gspej6mySpJNPuEe46sUwgKV3vSvYM,336
|
|
53
53
|
pytgcalls/methods/stream/mute.py,sha256=ZrZS_EeNUeUxb6UgbdhwXUdRX826u-qSjH5a6sg7LsE,557
|
|
54
54
|
pytgcalls/methods/stream/pause.py,sha256=-kNvWQuv5VlssNcL-M6rkT5TKFmXlbOzJrDny95qsUc,560
|
|
55
|
-
pytgcalls/methods/stream/play.py,sha256=
|
|
55
|
+
pytgcalls/methods/stream/play.py,sha256=XJB7o4Y5ImY1Qh_tHCkT70cUKOr9JlinWtVKwE8W5Rw,2951
|
|
56
56
|
pytgcalls/methods/stream/record.py,sha256=geYSVtSbp0yRIR1Nmj-L1s-6nqQAh0x0IcA1OuFvuyA,1306
|
|
57
57
|
pytgcalls/methods/stream/resume.py,sha256=AUHU3AtpXO2rtp2V1EKSC_KAWTk2KHMiHaqHluYy31M,563
|
|
58
58
|
pytgcalls/methods/stream/send_frame.py,sha256=Kj9R8OqUM-g7pt-FiWP-US7sCFkH5ciPr9S8v-WPtLg,1062
|
|
@@ -68,22 +68,22 @@ pytgcalls/methods/utilities/ping.py,sha256=hhIMSHk2BzMB-IKpwLdZFVrsEvGm2ftJwKLs1
|
|
|
68
68
|
pytgcalls/methods/utilities/resolve_chat_id.py,sha256=92x2LHbUlnJMm-kS3fXOYmzYpY2TZbqtQD2rw3eBXDY,382
|
|
69
69
|
pytgcalls/methods/utilities/run.py,sha256=cnYQd2xB5Cr_WS0Q2cXJZPGiN6JOCULzj1r4xXVyrlg,152
|
|
70
70
|
pytgcalls/methods/utilities/start.py,sha256=mn0kQZhTUuc-9CCJDbFIVsEtJ8kfnfZOGbVC505qVRM,3232
|
|
71
|
-
pytgcalls/methods/utilities/stream_params.py,sha256=
|
|
71
|
+
pytgcalls/methods/utilities/stream_params.py,sha256=PUnctLhdCeBAg52v95vpxj-42Le5XzbnRtcfm71FDBM,3341
|
|
72
72
|
pytgcalls/mtproto/__init__.py,sha256=X4zvzFG7km7qHyE0fdvA550WcOVO_xl_p__gvIfDGmw,130
|
|
73
|
-
pytgcalls/mtproto/bridged_client.py,sha256=
|
|
74
|
-
pytgcalls/mtproto/client_cache.py,sha256=
|
|
75
|
-
pytgcalls/mtproto/hydrogram_client.py,sha256=
|
|
76
|
-
pytgcalls/mtproto/mtproto_client.py,sha256=
|
|
77
|
-
pytgcalls/mtproto/pyrogram_client.py,sha256=
|
|
78
|
-
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
|
|
79
79
|
pytgcalls/types/__init__.py,sha256=GlgBBXAwbNopXSeTTmiXktrEJhhN_rMBtuAllTBbN3k,1189
|
|
80
80
|
pytgcalls/types/browsers.py,sha256=47Kr5q96n4Q4WvVhA6IUlS2egEcA9GRLlDeFcQYyc9M,9545
|
|
81
|
-
pytgcalls/types/cache.py,sha256=
|
|
82
|
-
pytgcalls/types/dict.py,sha256
|
|
83
|
-
pytgcalls/types/flag.py,sha256=
|
|
84
|
-
pytgcalls/types/list.py,sha256=
|
|
85
|
-
pytgcalls/types/participant_list.py,sha256=
|
|
86
|
-
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
|
|
87
87
|
pytgcalls/types/update.py,sha256=wPCzWLhrsScZ3ksRTyt8IuDaaG5YI-ItG_Yw-OqzK2Y,157
|
|
88
88
|
pytgcalls/types/user_agent.py,sha256=sSfeGqUe0v0wqBgdVszNFK0iOC_0Tdyto9CglBXlY4U,1086
|
|
89
89
|
pytgcalls/types/calls/__init__.py,sha256=lgFG89_NGhWHOQqhfw3adPaQZMzsMKI1f-MyZW3TBBU,478
|
|
@@ -94,10 +94,10 @@ pytgcalls/types/calls/call_protocol.py,sha256=OVIQs1VgdY-DWbZbNr41hjLA4pGQvHx8Rg
|
|
|
94
94
|
pytgcalls/types/calls/call_sources.py,sha256=sBhumPgEaN8uAKjBwb1Zf_Ag0qrceti2mURXqMhBusg,107
|
|
95
95
|
pytgcalls/types/calls/group_call_config.py,sha256=auKH-hZJWj8PhTkyeQ_VK2z9NpNvNC7Scl_IhEUMnQM,353
|
|
96
96
|
pytgcalls/types/calls/pending_connection.py,sha256=qRRmutInj70rtzbThM7CNznFhEPqTNZQc6LUWnqpZ9I,432
|
|
97
|
-
pytgcalls/types/calls/raw_call_update.py,sha256=
|
|
97
|
+
pytgcalls/types/calls/raw_call_update.py,sha256=pxcNY-spHXdATwdYu73HQuK2xUeoZ44naD10uoG_PtM,797
|
|
98
98
|
pytgcalls/types/chats/__init__.py,sha256=v8pUp_vbr2kQpyHtAQc80N-YqzmXHe9SbllUsa6njkU,261
|
|
99
99
|
pytgcalls/types/chats/chat_update.py,sha256=lzrqNDPv4a_yXpKIfUnhocXqZyIy8XgZladOQTYrrYA,730
|
|
100
|
-
pytgcalls/types/chats/group_call_participant.py,sha256=
|
|
100
|
+
pytgcalls/types/chats/group_call_participant.py,sha256=aK7nvI0Jy93g9A_FVeFzk1BZFXzhFry06h8xR4VpqXY,1507
|
|
101
101
|
pytgcalls/types/chats/updated_group_call_participant.py,sha256=bZQsZAsMv_i4k8DJW3phyuHqpa9Dp6IbheHCvj3M630,365
|
|
102
102
|
pytgcalls/types/raw/__init__.py,sha256=ROHsKFeUMUtlFbx2rhfrdB-TuVm0zBuvNo29Ccn5614,308
|
|
103
103
|
pytgcalls/types/raw/audio_parameters.py,sha256=1DsBPwdn_Ukd2Tbkb3whP_ILo9xJY_3XNNmbO4_NO9Q,449
|
|
@@ -115,8 +115,8 @@ pytgcalls/types/stream/media_stream.py,sha256=zcRVpNXfL8mhg-SEfAi-f0lDUZMyNYLeto
|
|
|
115
115
|
pytgcalls/types/stream/record_stream.py,sha256=f4VQ6MY8HtOxt7vz0hWBFmbbAIvTRHpAIU2nmj0TF6Y,3197
|
|
116
116
|
pytgcalls/types/stream/stream_ended.py,sha256=xR_kZwFf03hA6rw_nvI7Be7GwoCKzQf_1MKaGpPDXqY,716
|
|
117
117
|
pytgcalls/types/stream/stream_frames.py,sha256=028ZhNV-mN3BGqMlmxusAV1xDQpXRYCeM0WXBZhRUhA,446
|
|
118
|
-
pytgcalls/types/stream/video_quality.py,sha256=
|
|
119
|
-
py_tgcalls-2.2.
|
|
120
|
-
py_tgcalls-2.2.
|
|
121
|
-
py_tgcalls-2.2.
|
|
122
|
-
py_tgcalls-2.2.
|
|
118
|
+
pytgcalls/types/stream/video_quality.py,sha256=eMCBFPwh5meX3UVEaozcGlwmgaujfpiTa3vBVSBBP_8,275
|
|
119
|
+
py_tgcalls-2.2.2.dist-info/METADATA,sha256=7YhuQ_QZCvKS6g0emehCYG8Tb9RllKZrkZpNYjzVJEY,5280
|
|
120
|
+
py_tgcalls-2.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
121
|
+
py_tgcalls-2.2.2.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
|
|
122
|
+
py_tgcalls-2.2.2.dist-info/RECORD,,
|
pytgcalls/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.2.
|
|
1
|
+
__version__ = '2.2.2'
|
|
@@ -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
|
+
await self._app.close_voice_chat(chat_id)
|
|
@@ -6,15 +6,12 @@ from ...scaffold import Scaffold
|
|
|
6
6
|
|
|
7
7
|
class ClearCall(Scaffold):
|
|
8
8
|
async def _clear_call(self, chat_id: int):
|
|
9
|
-
res = False
|
|
10
9
|
if chat_id in self._wait_connect:
|
|
11
10
|
self._wait_connect[chat_id].set_exception(
|
|
12
11
|
TelegramServerError(),
|
|
13
12
|
)
|
|
14
13
|
try:
|
|
15
14
|
await self._binding.stop(chat_id)
|
|
16
|
-
res = True
|
|
17
15
|
except ConnectionNotFound:
|
|
18
16
|
pass
|
|
19
17
|
self._clear_cache(chat_id)
|
|
20
|
-
return res
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
1
3
|
from ntgcalls import ConnectionError
|
|
2
4
|
from ntgcalls import ConnectionNotFound
|
|
3
5
|
|
|
@@ -13,9 +15,12 @@ from ...types import RawCallUpdate
|
|
|
13
15
|
from ...types import Update
|
|
14
16
|
from ...types import UpdatedGroupCallParticipant
|
|
15
17
|
|
|
18
|
+
py_logger = logging.getLogger('pytgcalls')
|
|
19
|
+
|
|
16
20
|
|
|
17
21
|
class HandleMTProtoUpdates(Scaffold):
|
|
18
22
|
async def _handle_mtproto_updates(self, update: Update):
|
|
23
|
+
py_logger.debug('Received: %s', update)
|
|
19
24
|
chat_id = update.chat_id
|
|
20
25
|
if update.chat_id in self._p2p_configs:
|
|
21
26
|
p2p_config = self._p2p_configs[chat_id]
|
|
@@ -28,7 +33,6 @@ class HandleMTProtoUpdates(Scaffold):
|
|
|
28
33
|
if isinstance(update, ChatUpdate) and \
|
|
29
34
|
p2p_config.outgoing:
|
|
30
35
|
if update.status & ChatUpdate.Status.DISCARDED_CALL:
|
|
31
|
-
self._wait_connect.pop(chat_id, None)
|
|
32
36
|
p2p_config.wait_data.set_exception(
|
|
33
37
|
CallBusy(
|
|
34
38
|
chat_id,
|
|
@@ -141,15 +145,8 @@ class HandleMTProtoUpdates(Scaffold):
|
|
|
141
145
|
chat_peer,
|
|
142
146
|
) == participant.user_id if chat_peer else False
|
|
143
147
|
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
|
-
)
|
|
148
|
+
if action == GroupCallParticipant.Action.KICKED:
|
|
149
|
+
await self._clear_call(chat_id)
|
|
153
150
|
if (
|
|
154
151
|
chat_id in self._need_unmute and
|
|
155
152
|
action == GroupCallParticipant.Action.UPDATED
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Union
|
|
2
2
|
|
|
3
|
-
from ntgcalls import ConnectionError
|
|
4
3
|
from ntgcalls import ConnectionMode
|
|
4
|
+
from ntgcalls import ConnectionNotFound
|
|
5
5
|
from ntgcalls import TelegramServerError
|
|
6
6
|
|
|
7
7
|
from ...scaffold import Scaffold
|
|
@@ -53,6 +53,6 @@ class JoinPresentation(Scaffold):
|
|
|
53
53
|
try:
|
|
54
54
|
await self._binding.stop_presentation(chat_id)
|
|
55
55
|
await self._app.leave_presentation(chat_id)
|
|
56
|
-
except
|
|
56
|
+
except ConnectionNotFound:
|
|
57
57
|
pass
|
|
58
58
|
self._presentations.discard(chat_id)
|
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
|
|
|
@@ -11,6 +11,7 @@ from ntgcalls import SsrcGroup
|
|
|
11
11
|
|
|
12
12
|
from ..handlers import HandlersHolder
|
|
13
13
|
from ..types import GroupCallParticipant
|
|
14
|
+
from ..types import UpdatedGroupCallParticipant
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class BridgedClient(HandlersHolder):
|
|
@@ -96,6 +97,12 @@ class BridgedClient(HandlersHolder):
|
|
|
96
97
|
):
|
|
97
98
|
pass
|
|
98
99
|
|
|
100
|
+
async def close_voice_chat(
|
|
101
|
+
self,
|
|
102
|
+
chat_id: int,
|
|
103
|
+
):
|
|
104
|
+
pass
|
|
105
|
+
|
|
99
106
|
async def get_group_call_participants(
|
|
100
107
|
self,
|
|
101
108
|
chat_id: int,
|
|
@@ -195,6 +202,42 @@ class BridgedClient(HandlersHolder):
|
|
|
195
202
|
BridgedClient.parse_source(participant.presentation),
|
|
196
203
|
)
|
|
197
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
|
+
|
|
198
241
|
@staticmethod
|
|
199
242
|
def parse_participant_action(participant):
|
|
200
243
|
if participant.just_joined:
|
|
@@ -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,11 +18,12 @@ class ClientCache:
|
|
|
19
18
|
app: BridgedClient,
|
|
20
19
|
):
|
|
21
20
|
self._app: BridgedClient = app
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
self.
|
|
25
|
-
self.
|
|
26
|
-
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)
|
|
27
27
|
|
|
28
28
|
async def get_full_chat(
|
|
29
29
|
self,
|
|
@@ -46,97 +46,64 @@ class ClientCache:
|
|
|
46
46
|
pass
|
|
47
47
|
return None
|
|
48
48
|
|
|
49
|
-
def
|
|
49
|
+
def set_participants_cache(
|
|
50
50
|
self,
|
|
51
|
-
|
|
52
|
-
action: GroupCallParticipant.Action,
|
|
53
|
-
participant: GroupCallParticipant,
|
|
54
|
-
) -> Optional[GroupCallParticipant]:
|
|
55
|
-
chat_id = self.get_chat_id(input_id)
|
|
56
|
-
if chat_id is not None:
|
|
57
|
-
return self._internal_set_participants_cache(
|
|
58
|
-
chat_id,
|
|
59
|
-
action,
|
|
60
|
-
participant,
|
|
61
|
-
)
|
|
62
|
-
return None
|
|
63
|
-
|
|
64
|
-
def set_participants_cache_chat(
|
|
65
|
-
self,
|
|
66
|
-
chat_id: int,
|
|
51
|
+
chat_id: Optional[int],
|
|
67
52
|
call_id: int,
|
|
68
53
|
action: GroupCallParticipant.Action,
|
|
69
54
|
participant: GroupCallParticipant,
|
|
70
55
|
) -> Optional[GroupCallParticipant]:
|
|
71
|
-
if
|
|
72
|
-
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(
|
|
73
67
|
chat_id,
|
|
74
|
-
ParticipantList(
|
|
75
|
-
call_id,
|
|
76
|
-
),
|
|
77
|
-
)
|
|
78
|
-
return self._internal_set_participants_cache(
|
|
79
|
-
chat_id,
|
|
80
|
-
action,
|
|
81
|
-
participant,
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
def _internal_set_participants_cache(
|
|
85
|
-
self,
|
|
86
|
-
chat_id: int,
|
|
87
|
-
action: GroupCallParticipant.Action,
|
|
88
|
-
participant: GroupCallParticipant,
|
|
89
|
-
) -> Optional[GroupCallParticipant]:
|
|
90
|
-
participants: Optional[
|
|
91
|
-
ParticipantList
|
|
92
|
-
] = self._call_participants_cache.get(
|
|
93
|
-
chat_id,
|
|
94
|
-
)
|
|
95
|
-
if participants is not None:
|
|
96
|
-
participants.last_mtproto_update = (
|
|
97
|
-
int(time()) + self._cache_duration
|
|
98
|
-
)
|
|
99
|
-
return participants.update_participant(
|
|
100
|
-
action,
|
|
101
|
-
participant,
|
|
102
68
|
)
|
|
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
|
+
)
|
|
103
75
|
return None
|
|
104
76
|
|
|
105
77
|
async def get_participant_list(
|
|
106
78
|
self,
|
|
107
79
|
chat_id: int,
|
|
108
|
-
|
|
80
|
+
only_cached: bool = False,
|
|
81
|
+
) -> List[GroupCallParticipant]:
|
|
109
82
|
input_call = await self.get_full_chat(
|
|
110
83
|
chat_id,
|
|
111
84
|
)
|
|
112
85
|
if input_call is not None:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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,
|
|
124
101
|
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
self.set_participants_cache_call(
|
|
131
|
-
input_call.id,
|
|
132
|
-
GroupCallParticipant.Action.UPDATED,
|
|
133
|
-
participant,
|
|
134
|
-
)
|
|
135
|
-
except Exception as e:
|
|
136
|
-
py_logger.error('Error for %s in %d', e, chat_id)
|
|
137
|
-
else:
|
|
138
|
-
py_logger.debug('GetParticipant cache hit for %d', chat_id)
|
|
139
|
-
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()
|
|
140
107
|
return []
|
|
141
108
|
|
|
142
109
|
def get_chat_id(
|
|
@@ -158,7 +125,6 @@ class ClientCache:
|
|
|
158
125
|
self._full_chat_cache.put(
|
|
159
126
|
chat_id,
|
|
160
127
|
input_call,
|
|
161
|
-
self._cache_duration,
|
|
162
128
|
)
|
|
163
129
|
if self._call_participants_cache.get(chat_id) is None:
|
|
164
130
|
self._call_participants_cache.put(
|
|
@@ -21,6 +21,7 @@ from hydrogram.raw.functions.phone import AcceptCall
|
|
|
21
21
|
from hydrogram.raw.functions.phone import ConfirmCall
|
|
22
22
|
from hydrogram.raw.functions.phone import CreateGroupCall
|
|
23
23
|
from hydrogram.raw.functions.phone import DiscardCall
|
|
24
|
+
from hydrogram.raw.functions.phone import DiscardGroupCall
|
|
24
25
|
from hydrogram.raw.functions.phone import EditGroupCallParticipant
|
|
25
26
|
from hydrogram.raw.functions.phone import GetGroupCall
|
|
26
27
|
from hydrogram.raw.functions.phone import GetGroupCallStreamChannels
|
|
@@ -76,7 +77,6 @@ from ..types import CallProtocol
|
|
|
76
77
|
from ..types import ChatUpdate
|
|
77
78
|
from ..types import GroupCallParticipant
|
|
78
79
|
from ..types import RawCallUpdate
|
|
79
|
-
from ..types import UpdatedGroupCallParticipant
|
|
80
80
|
from .bridged_client import BridgedClient
|
|
81
81
|
from .client_cache import ClientCache
|
|
82
82
|
|
|
@@ -186,22 +186,22 @@ class HydrogramClient(BridgedClient):
|
|
|
186
186
|
update,
|
|
187
187
|
UpdateGroupCallParticipants,
|
|
188
188
|
):
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
self.parse_participant(participant),
|
|
189
|
+
for participant in update.participants:
|
|
190
|
+
chat_id = self._cache.get_chat_id(update.call.id)
|
|
191
|
+
p_updates = await self.diff_participants_update(
|
|
192
|
+
self._cache,
|
|
193
|
+
chat_id,
|
|
194
|
+
participant,
|
|
196
195
|
)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
),
|
|
196
|
+
for p_update in p_updates:
|
|
197
|
+
result = self._cache.set_participants_cache(
|
|
198
|
+
chat_id,
|
|
199
|
+
update.call.id,
|
|
200
|
+
p_update.action,
|
|
201
|
+
p_update.participant,
|
|
204
202
|
)
|
|
203
|
+
if result is not None:
|
|
204
|
+
await self._propagate(p_update)
|
|
205
205
|
if isinstance(
|
|
206
206
|
update,
|
|
207
207
|
UpdateGroupCall,
|
|
@@ -355,7 +355,7 @@ class HydrogramClient(BridgedClient):
|
|
|
355
355
|
call: GroupCall = raw_call.call
|
|
356
356
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
357
357
|
for participant in participants:
|
|
358
|
-
self._cache.
|
|
358
|
+
self._cache.set_participants_cache(
|
|
359
359
|
chat_id,
|
|
360
360
|
call.id,
|
|
361
361
|
self.parse_participant_action(participant),
|
|
@@ -433,7 +433,8 @@ class HydrogramClient(BridgedClient):
|
|
|
433
433
|
):
|
|
434
434
|
participants = update.participants
|
|
435
435
|
for participant in participants:
|
|
436
|
-
self._cache.
|
|
436
|
+
self._cache.set_participants_cache(
|
|
437
|
+
chat_id,
|
|
437
438
|
update.call.id,
|
|
438
439
|
self.parse_participant_action(participant),
|
|
439
440
|
self.parse_participant(participant),
|
|
@@ -588,6 +589,19 @@ class HydrogramClient(BridgedClient):
|
|
|
588
589
|
),
|
|
589
590
|
)
|
|
590
591
|
|
|
592
|
+
async def close_voice_chat(
|
|
593
|
+
self,
|
|
594
|
+
chat_id: int,
|
|
595
|
+
):
|
|
596
|
+
chat_call = await self._cache.get_full_chat(chat_id)
|
|
597
|
+
if chat_call is not None:
|
|
598
|
+
await self._invoke(
|
|
599
|
+
DiscardGroupCall(
|
|
600
|
+
call=chat_call,
|
|
601
|
+
),
|
|
602
|
+
)
|
|
603
|
+
self._cache.drop_cache(chat_id)
|
|
604
|
+
|
|
591
605
|
async def discard_call(
|
|
592
606
|
self,
|
|
593
607
|
chat_id: int,
|
|
@@ -197,6 +197,17 @@ class MtProtoClient:
|
|
|
197
197
|
else:
|
|
198
198
|
raise InvalidMTProtoClient()
|
|
199
199
|
|
|
200
|
+
async def close_voice_chat(
|
|
201
|
+
self,
|
|
202
|
+
chat_id: int,
|
|
203
|
+
):
|
|
204
|
+
if self._bind_client is not None:
|
|
205
|
+
await self._bind_client.close_voice_chat(
|
|
206
|
+
chat_id,
|
|
207
|
+
)
|
|
208
|
+
else:
|
|
209
|
+
raise InvalidMTProtoClient()
|
|
210
|
+
|
|
200
211
|
async def change_volume(
|
|
201
212
|
self,
|
|
202
213
|
chat_id: int,
|
|
@@ -23,6 +23,7 @@ from pyrogram.raw.functions.phone import AcceptCall
|
|
|
23
23
|
from pyrogram.raw.functions.phone import ConfirmCall
|
|
24
24
|
from pyrogram.raw.functions.phone import CreateGroupCall
|
|
25
25
|
from pyrogram.raw.functions.phone import DiscardCall
|
|
26
|
+
from pyrogram.raw.functions.phone import DiscardGroupCall
|
|
26
27
|
from pyrogram.raw.functions.phone import EditGroupCallParticipant
|
|
27
28
|
from pyrogram.raw.functions.phone import GetGroupCall
|
|
28
29
|
from pyrogram.raw.functions.phone import GetGroupCallStreamChannels
|
|
@@ -76,7 +77,6 @@ from ..types import CallProtocol
|
|
|
76
77
|
from ..types import ChatUpdate
|
|
77
78
|
from ..types import GroupCallParticipant
|
|
78
79
|
from ..types import RawCallUpdate
|
|
79
|
-
from ..types import UpdatedGroupCallParticipant
|
|
80
80
|
from .bridged_client import BridgedClient
|
|
81
81
|
from .client_cache import ClientCache
|
|
82
82
|
|
|
@@ -186,22 +186,22 @@ class PyrogramClient(BridgedClient):
|
|
|
186
186
|
update,
|
|
187
187
|
UpdateGroupCallParticipants,
|
|
188
188
|
):
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
self.parse_participant(participant),
|
|
189
|
+
for participant in update.participants:
|
|
190
|
+
chat_id = self._cache.get_chat_id(update.call.id)
|
|
191
|
+
p_updates = await self.diff_participants_update(
|
|
192
|
+
self._cache,
|
|
193
|
+
chat_id,
|
|
194
|
+
participant,
|
|
196
195
|
)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
),
|
|
196
|
+
for p_update in p_updates:
|
|
197
|
+
result = self._cache.set_participants_cache(
|
|
198
|
+
chat_id,
|
|
199
|
+
update.call.id,
|
|
200
|
+
p_update.action,
|
|
201
|
+
p_update.participant,
|
|
204
202
|
)
|
|
203
|
+
if result is not None:
|
|
204
|
+
await self._propagate(p_update)
|
|
205
205
|
|
|
206
206
|
if isinstance(
|
|
207
207
|
update,
|
|
@@ -356,7 +356,7 @@ class PyrogramClient(BridgedClient):
|
|
|
356
356
|
call: GroupCall = raw_call.call
|
|
357
357
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
358
358
|
for participant in participants:
|
|
359
|
-
self._cache.
|
|
359
|
+
self._cache.set_participants_cache(
|
|
360
360
|
chat_id,
|
|
361
361
|
call.id,
|
|
362
362
|
self.parse_participant_action(participant),
|
|
@@ -434,7 +434,8 @@ class PyrogramClient(BridgedClient):
|
|
|
434
434
|
):
|
|
435
435
|
participants = update.participants
|
|
436
436
|
for participant in participants:
|
|
437
|
-
self._cache.
|
|
437
|
+
self._cache.set_participants_cache(
|
|
438
|
+
chat_id,
|
|
438
439
|
update.call.id,
|
|
439
440
|
self.parse_participant_action(participant),
|
|
440
441
|
self.parse_participant(participant),
|
|
@@ -589,6 +590,19 @@ class PyrogramClient(BridgedClient):
|
|
|
589
590
|
),
|
|
590
591
|
)
|
|
591
592
|
|
|
593
|
+
async def close_voice_chat(
|
|
594
|
+
self,
|
|
595
|
+
chat_id: int,
|
|
596
|
+
):
|
|
597
|
+
chat_call = await self._cache.get_full_chat(chat_id)
|
|
598
|
+
if chat_call is not None:
|
|
599
|
+
await self._invoke(
|
|
600
|
+
DiscardGroupCall(
|
|
601
|
+
call=chat_call,
|
|
602
|
+
),
|
|
603
|
+
)
|
|
604
|
+
self._cache.drop_cache(chat_id)
|
|
605
|
+
|
|
592
606
|
async def discard_call(
|
|
593
607
|
self,
|
|
594
608
|
chat_id: int,
|
|
@@ -18,6 +18,7 @@ from telethon.tl.functions.phone import AcceptCallRequest
|
|
|
18
18
|
from telethon.tl.functions.phone import ConfirmCallRequest
|
|
19
19
|
from telethon.tl.functions.phone import CreateGroupCallRequest
|
|
20
20
|
from telethon.tl.functions.phone import DiscardCallRequest
|
|
21
|
+
from telethon.tl.functions.phone import DiscardGroupCallRequest
|
|
21
22
|
from telethon.tl.functions.phone import EditGroupCallParticipantRequest
|
|
22
23
|
from telethon.tl.functions.phone import GetGroupCallRequest
|
|
23
24
|
from telethon.tl.functions.phone import GetGroupCallStreamChannelsRequest
|
|
@@ -70,7 +71,6 @@ from ..types import CallProtocol
|
|
|
70
71
|
from ..types import ChatUpdate
|
|
71
72
|
from ..types import GroupCallParticipant
|
|
72
73
|
from ..types import RawCallUpdate
|
|
73
|
-
from ..types import UpdatedGroupCallParticipant
|
|
74
74
|
from .bridged_client import BridgedClient
|
|
75
75
|
from .client_cache import ClientCache
|
|
76
76
|
|
|
@@ -180,22 +180,22 @@ class TelethonClient(BridgedClient):
|
|
|
180
180
|
update,
|
|
181
181
|
UpdateGroupCallParticipants,
|
|
182
182
|
):
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
self.parse_participant(participant),
|
|
183
|
+
for participant in update.participants:
|
|
184
|
+
chat_id = self._cache.get_chat_id(update.call.id)
|
|
185
|
+
p_updates = await self.diff_participants_update(
|
|
186
|
+
self._cache,
|
|
187
|
+
chat_id,
|
|
188
|
+
participant,
|
|
190
189
|
)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
),
|
|
190
|
+
for p_update in p_updates:
|
|
191
|
+
result = self._cache.set_participants_cache(
|
|
192
|
+
chat_id,
|
|
193
|
+
update.call.id,
|
|
194
|
+
p_update.action,
|
|
195
|
+
p_update.participant,
|
|
198
196
|
)
|
|
197
|
+
if result is not None:
|
|
198
|
+
await self._propagate(p_update)
|
|
199
199
|
if isinstance(
|
|
200
200
|
update,
|
|
201
201
|
UpdateGroupCall,
|
|
@@ -342,7 +342,7 @@ class TelethonClient(BridgedClient):
|
|
|
342
342
|
call: GroupCall = raw_call.call
|
|
343
343
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
344
344
|
for participant in participants:
|
|
345
|
-
self._cache.
|
|
345
|
+
self._cache.set_participants_cache(
|
|
346
346
|
chat_id,
|
|
347
347
|
call.id,
|
|
348
348
|
self.parse_participant_action(participant),
|
|
@@ -420,7 +420,8 @@ class TelethonClient(BridgedClient):
|
|
|
420
420
|
):
|
|
421
421
|
participants = update.participants
|
|
422
422
|
for participant in participants:
|
|
423
|
-
self._cache.
|
|
423
|
+
self._cache.set_participants_cache(
|
|
424
|
+
chat_id,
|
|
424
425
|
update.call.id,
|
|
425
426
|
self.parse_participant_action(participant),
|
|
426
427
|
self.parse_participant(participant),
|
|
@@ -575,6 +576,19 @@ class TelethonClient(BridgedClient):
|
|
|
575
576
|
),
|
|
576
577
|
)
|
|
577
578
|
|
|
579
|
+
async def close_voice_chat(
|
|
580
|
+
self,
|
|
581
|
+
chat_id: int,
|
|
582
|
+
):
|
|
583
|
+
chat_call = await self._cache.get_full_chat(chat_id)
|
|
584
|
+
if chat_call is not None:
|
|
585
|
+
await self._invoke(
|
|
586
|
+
DiscardGroupCallRequest(
|
|
587
|
+
call=chat_call,
|
|
588
|
+
),
|
|
589
|
+
)
|
|
590
|
+
self._cache.drop_cache(chat_id)
|
|
591
|
+
|
|
578
592
|
async def discard_call(
|
|
579
593
|
self,
|
|
580
594
|
chat_id: int,
|
pytgcalls/types/cache.py
CHANGED
|
@@ -8,13 +8,13 @@ from typing import Optional
|
|
|
8
8
|
@dataclass
|
|
9
9
|
class CacheEntry:
|
|
10
10
|
time: int
|
|
11
|
-
expiry_time: int
|
|
12
11
|
data: Any
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class Cache:
|
|
16
|
-
def __init__(self):
|
|
15
|
+
def __init__(self, expiry_time: int = 0):
|
|
17
16
|
self._store: Dict[int, CacheEntry] = {} # type: ignore
|
|
17
|
+
self._expiry_time = expiry_time
|
|
18
18
|
|
|
19
19
|
def get(self, chat_id: int):
|
|
20
20
|
if chat_id in self._store:
|
|
@@ -25,13 +25,18 @@ class Cache:
|
|
|
25
25
|
self._store.pop(chat_id, None)
|
|
26
26
|
return None
|
|
27
27
|
|
|
28
|
-
def put(self, chat_id: int, data: Any
|
|
28
|
+
def put(self, chat_id: int, data: Any) -> None:
|
|
29
29
|
self._store[chat_id] = CacheEntry(
|
|
30
|
-
time=0
|
|
31
|
-
|
|
30
|
+
time=0
|
|
31
|
+
if self._expiry_time == 0 else
|
|
32
|
+
(int(time()) + self._expiry_time),
|
|
32
33
|
data=data,
|
|
33
34
|
)
|
|
34
35
|
|
|
36
|
+
def update_cache(self, chat_id: int) -> None:
|
|
37
|
+
if chat_id in self._store:
|
|
38
|
+
self._store[chat_id].time = int(time()) + self._expiry_time
|
|
39
|
+
|
|
35
40
|
@property
|
|
36
41
|
def keys(self):
|
|
37
42
|
return list(self._store)
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
from enum import auto
|
|
2
|
-
from enum import Flag
|
|
3
2
|
from typing import List
|
|
4
3
|
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from ntgcalls import SsrcGroup
|
|
7
6
|
|
|
8
7
|
from ...types.py_object import PyObject
|
|
8
|
+
from ..flag import Flag
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class GroupCallParticipant(PyObject):
|
|
12
12
|
class Action(Flag):
|
|
13
13
|
JOINED = auto()
|
|
14
14
|
LEFT = auto()
|
|
15
|
+
KICKED = auto()
|
|
15
16
|
UPDATED = auto()
|
|
16
17
|
|
|
17
18
|
class SourceInfo(PyObject):
|
pytgcalls/types/dict.py
CHANGED
pytgcalls/types/flag.py
CHANGED
pytgcalls/types/list.py
CHANGED
|
@@ -10,14 +10,13 @@ class ParticipantList:
|
|
|
10
10
|
input_id: int,
|
|
11
11
|
):
|
|
12
12
|
self._list_participants: Dict[int, GroupCallParticipant] = {}
|
|
13
|
-
self.last_mtproto_update: int = 0
|
|
14
13
|
self.input_id: int = input_id
|
|
15
14
|
|
|
16
15
|
def update_participant(
|
|
17
16
|
self,
|
|
18
17
|
action: GroupCallParticipant.Action,
|
|
19
18
|
participant: GroupCallParticipant,
|
|
20
|
-
):
|
|
19
|
+
) -> GroupCallParticipant:
|
|
21
20
|
if action == GroupCallParticipant.Action.LEFT:
|
|
22
21
|
if participant.user_id in self._list_participants:
|
|
23
22
|
del self._list_participants[participant.user_id]
|
pytgcalls/types/py_object.py
CHANGED
|
@@ -11,8 +11,10 @@ class PyObject:
|
|
|
11
11
|
def default(obj) -> Union[str, Dict[str, str], List[Any]]:
|
|
12
12
|
if isinstance(obj, bytes):
|
|
13
13
|
return repr(obj)
|
|
14
|
-
|
|
15
|
-
return
|
|
14
|
+
elif isinstance(obj, Enum):
|
|
15
|
+
return ' | '.join(
|
|
16
|
+
[f"{obj.__class__.__name__}.{x}" for x in obj.name.split('|')],
|
|
17
|
+
)
|
|
16
18
|
return {
|
|
17
19
|
'_': obj.__class__.__name__,
|
|
18
20
|
**{
|
|
File without changes
|
|
File without changes
|