py-tgcalls 2.2.0rc2__py3-none-any.whl → 2.2.1__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.0rc2.dist-info → py_tgcalls-2.2.1.dist-info}/METADATA +2 -2
- {py_tgcalls-2.2.0rc2.dist-info → py_tgcalls-2.2.1.dist-info}/RECORD +25 -25
- {py_tgcalls-2.2.0rc2.dist-info → py_tgcalls-2.2.1.dist-info}/WHEEL +1 -1
- pytgcalls/__version__.py +1 -1
- pytgcalls/filters.py +6 -2
- pytgcalls/methods/calls/leave_call.py +4 -0
- pytgcalls/methods/internal/handle_mtproto_updates.py +8 -15
- pytgcalls/methods/stream/play.py +2 -1
- pytgcalls/mtproto/bridged_client.py +52 -2
- pytgcalls/mtproto/client_cache.py +48 -73
- pytgcalls/mtproto/hydrogram_client.py +39 -21
- pytgcalls/mtproto/mtproto_client.py +11 -0
- pytgcalls/mtproto/pyrogram_client.py +40 -21
- pytgcalls/mtproto/telethon_client.py +39 -20
- 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/video_quality.py +3 -1
- {py_tgcalls-2.2.0rc2.dist-info → py_tgcalls-2.2.1.dist-info}/licenses/LICENSE +0 -0
- {py_tgcalls-2.2.0rc2.dist-info → py_tgcalls-2.2.1.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.1
|
|
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.1
|
|
24
24
|
Requires-Dist: deprecation
|
|
25
25
|
Provides-Extra: pyrogram
|
|
26
26
|
Requires-Dist: pyrogram>=1.2.20; extra == "pyrogram"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
py_tgcalls-2.2.
|
|
1
|
+
py_tgcalls-2.2.1.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=-7agX4LcQ0956RU4mY0EYyxYQU9llH7JklZOsqoujdU,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
|
|
7
|
-
pytgcalls/filters.py,sha256=
|
|
7
|
+
pytgcalls/filters.py,sha256=8Fq_gvHHdqhIk_XwMJ9wneeZOwrvBkSOKaMJ60r3bZU,6157
|
|
8
8
|
pytgcalls/list_to_cmd.py,sha256=rGJLsejbAQdDb8pctMbLnwea5NkitlfVKc3IpoGi4V4,240
|
|
9
9
|
pytgcalls/mtproto_required.py,sha256=6B-31p5qH_6oekUgypV4nK3hqPS6Nr-pA8S81wjnbaY,630
|
|
10
10
|
pytgcalls/mutex.py,sha256=vWqji9IAHtAc61FUTVXncx5rZ3rVf5qG_7PI4LmuYmU,733
|
|
@@ -30,7 +30,7 @@ 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
|
|
@@ -39,7 +39,7 @@ pytgcalls/methods/internal/clear_call.py,sha256=yElvn3i6_j14Q7n9kcLSl-muYAGcaIZa
|
|
|
39
39
|
pytgcalls/methods/internal/connect_call.py,sha256=Py-sB_ImH839tK9GxNUCJDJUNizsZtlm5m6kuiUX3lE,5739
|
|
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=ZPGvenIjWiNnTTTKdhQdapHsxwYn4pSKOgKm8bPcPOk,7415
|
|
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
45
|
pytgcalls/methods/internal/join_presentation.py,sha256=dLB2kolIIm2KQH8yBQbEPJi_y1_cVLWpE52_Rwjn_KE,2178
|
|
@@ -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
|
|
@@ -70,20 +70,20 @@ pytgcalls/methods/utilities/run.py,sha256=cnYQd2xB5Cr_WS0Q2cXJZPGiN6JOCULzj1r4xX
|
|
|
70
70
|
pytgcalls/methods/utilities/start.py,sha256=mn0kQZhTUuc-9CCJDbFIVsEtJ8kfnfZOGbVC505qVRM,3232
|
|
71
71
|
pytgcalls/methods/utilities/stream_params.py,sha256=fOSloo1A7WTxaZEtOiPXjdexMeoJjq8CZtfHuIFX7Ns,3325
|
|
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
|
|
@@ -97,8 +97,8 @@ pytgcalls/types/calls/pending_connection.py,sha256=qRRmutInj70rtzbThM7CNznFhEPqT
|
|
|
97
97
|
pytgcalls/types/calls/raw_call_update.py,sha256=hpNw6HrTW8Z36Lh2HinS-wzprryRtsIxyIFbIfjGgeI,795
|
|
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=
|
|
101
|
-
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
|
|
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
|
|
104
104
|
pytgcalls/types/raw/audio_stream.py,sha256=oN7Sx9oLbNFuNXiGYpoNabMwqWKGquLiHEywef28o7c,488
|
|
@@ -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.1.dist-info/METADATA,sha256=7j-AgY6sI6uL623U_ZbjjXwbfu7_KymRphdpSLssPJE,5280
|
|
120
|
+
py_tgcalls-2.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
121
|
+
py_tgcalls-2.2.1.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
|
|
122
|
+
py_tgcalls-2.2.1.dist-info/RECORD,,
|
pytgcalls/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.2.
|
|
1
|
+
__version__ = '2.2.1'
|
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
|
|
|
@@ -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)
|
|
@@ -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
|
|
|
@@ -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,
|
|
@@ -190,13 +197,56 @@ class BridgedClient(HandlersHolder):
|
|
|
190
197
|
bool(participant.raise_hand_rating),
|
|
191
198
|
participant.volume // 100
|
|
192
199
|
if participant.volume is not None else 100,
|
|
193
|
-
bool(participant.just_joined),
|
|
194
|
-
bool(participant.left),
|
|
195
200
|
participant.source,
|
|
196
201
|
BridgedClient.parse_source(participant.video),
|
|
197
202
|
BridgedClient.parse_source(participant.presentation),
|
|
198
203
|
)
|
|
199
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
|
+
|
|
200
250
|
@staticmethod
|
|
201
251
|
def chat_id(input_peer) -> int:
|
|
202
252
|
class_name = input_peer.__class__.__name__
|
|
@@ -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,88 +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
|
-
participant: GroupCallParticipant,
|
|
53
|
-
) -> Optional[GroupCallParticipant]:
|
|
54
|
-
chat_id = self.get_chat_id(input_id)
|
|
55
|
-
if chat_id is not None:
|
|
56
|
-
return self._internal_set_participants_cache(
|
|
57
|
-
chat_id,
|
|
58
|
-
participant,
|
|
59
|
-
)
|
|
60
|
-
return None
|
|
61
|
-
|
|
62
|
-
def set_participants_cache_chat(
|
|
63
|
-
self,
|
|
64
|
-
chat_id: int,
|
|
51
|
+
chat_id: Optional[int],
|
|
65
52
|
call_id: int,
|
|
53
|
+
action: GroupCallParticipant.Action,
|
|
66
54
|
participant: GroupCallParticipant,
|
|
67
55
|
) -> Optional[GroupCallParticipant]:
|
|
68
|
-
if
|
|
69
|
-
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(
|
|
70
67
|
chat_id,
|
|
71
|
-
ParticipantList(
|
|
72
|
-
call_id,
|
|
73
|
-
),
|
|
74
|
-
)
|
|
75
|
-
return self._internal_set_participants_cache(
|
|
76
|
-
chat_id,
|
|
77
|
-
participant,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
def _internal_set_participants_cache(
|
|
81
|
-
self,
|
|
82
|
-
chat_id: int,
|
|
83
|
-
participant: GroupCallParticipant,
|
|
84
|
-
) -> Optional[GroupCallParticipant]:
|
|
85
|
-
participants: Optional[
|
|
86
|
-
ParticipantList
|
|
87
|
-
] = self._call_participants_cache.get(
|
|
88
|
-
chat_id,
|
|
89
|
-
)
|
|
90
|
-
if participants is not None:
|
|
91
|
-
participants.last_mtproto_update = (
|
|
92
|
-
int(time()) + self._cache_duration
|
|
93
68
|
)
|
|
94
|
-
|
|
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
|
+
)
|
|
95
75
|
return None
|
|
96
76
|
|
|
97
77
|
async def get_participant_list(
|
|
98
78
|
self,
|
|
99
79
|
chat_id: int,
|
|
100
|
-
|
|
80
|
+
only_cached: bool = False,
|
|
81
|
+
) -> List[GroupCallParticipant]:
|
|
101
82
|
input_call = await self.get_full_chat(
|
|
102
83
|
chat_id,
|
|
103
84
|
)
|
|
104
85
|
if input_call is not None:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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,
|
|
116
101
|
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
self.set_participants_cache_call(
|
|
123
|
-
input_call.id,
|
|
124
|
-
participant,
|
|
125
|
-
)
|
|
126
|
-
except Exception as e:
|
|
127
|
-
py_logger.error('Error for %s in %d', e, chat_id)
|
|
128
|
-
else:
|
|
129
|
-
py_logger.debug('GetParticipant cache hit for %d', chat_id)
|
|
130
|
-
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()
|
|
131
107
|
return []
|
|
132
108
|
|
|
133
109
|
def get_chat_id(
|
|
@@ -149,7 +125,6 @@ class ClientCache:
|
|
|
149
125
|
self._full_chat_cache.put(
|
|
150
126
|
chat_id,
|
|
151
127
|
input_call,
|
|
152
|
-
self._cache_duration,
|
|
153
128
|
)
|
|
154
129
|
if self._call_participants_cache.get(chat_id) is None:
|
|
155
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
|
|
|
@@ -94,7 +94,7 @@ class HydrogramClient(BridgedClient):
|
|
|
94
94
|
self,
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
@self._app.on_raw_update(group=-
|
|
97
|
+
@self._app.on_raw_update(group=-9999)
|
|
98
98
|
async def on_update(_, update, __, chats):
|
|
99
99
|
if isinstance(
|
|
100
100
|
update,
|
|
@@ -186,19 +186,22 @@ class HydrogramClient(BridgedClient):
|
|
|
186
186
|
update,
|
|
187
187
|
UpdateGroupCallParticipants,
|
|
188
188
|
):
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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,
|
|
194
195
|
)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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,
|
|
201
202
|
)
|
|
203
|
+
if result is not None:
|
|
204
|
+
await self._propagate(p_update)
|
|
202
205
|
if isinstance(
|
|
203
206
|
update,
|
|
204
207
|
UpdateGroupCall,
|
|
@@ -352,9 +355,10 @@ class HydrogramClient(BridgedClient):
|
|
|
352
355
|
call: GroupCall = raw_call.call
|
|
353
356
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
354
357
|
for participant in participants:
|
|
355
|
-
self._cache.
|
|
358
|
+
self._cache.set_participants_cache(
|
|
356
359
|
chat_id,
|
|
357
360
|
call.id,
|
|
361
|
+
self.parse_participant_action(participant),
|
|
358
362
|
self.parse_participant(participant),
|
|
359
363
|
)
|
|
360
364
|
if call.schedule_date is not None:
|
|
@@ -429,8 +433,10 @@ class HydrogramClient(BridgedClient):
|
|
|
429
433
|
):
|
|
430
434
|
participants = update.participants
|
|
431
435
|
for participant in participants:
|
|
432
|
-
self._cache.
|
|
436
|
+
self._cache.set_participants_cache(
|
|
437
|
+
chat_id,
|
|
433
438
|
update.call.id,
|
|
439
|
+
self.parse_participant_action(participant),
|
|
434
440
|
self.parse_participant(participant),
|
|
435
441
|
)
|
|
436
442
|
if isinstance(update, UpdateGroupCallConnection):
|
|
@@ -583,6 +589,19 @@ class HydrogramClient(BridgedClient):
|
|
|
583
589
|
),
|
|
584
590
|
)
|
|
585
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
|
+
|
|
586
605
|
async def discard_call(
|
|
587
606
|
self,
|
|
588
607
|
chat_id: int,
|
|
@@ -734,7 +753,6 @@ class HydrogramClient(BridgedClient):
|
|
|
734
753
|
):
|
|
735
754
|
if chat_id is not None:
|
|
736
755
|
dc_id = self._cache.get_dc_call(chat_id)
|
|
737
|
-
|
|
738
756
|
if dc_id is None:
|
|
739
757
|
session = self._app
|
|
740
758
|
else:
|
|
@@ -784,12 +802,12 @@ class HydrogramClient(BridgedClient):
|
|
|
784
802
|
dc_new = BridgedClient.extract_dc(
|
|
785
803
|
str(e),
|
|
786
804
|
)
|
|
787
|
-
if chat_id is not None and dc_new is not None:
|
|
788
|
-
self._cache.set_dc_call(
|
|
789
|
-
chat_id,
|
|
790
|
-
dc_new,
|
|
791
|
-
)
|
|
792
805
|
if dc_new is not None:
|
|
806
|
+
if chat_id is not None:
|
|
807
|
+
self._cache.set_dc_call(
|
|
808
|
+
chat_id,
|
|
809
|
+
dc_new,
|
|
810
|
+
)
|
|
793
811
|
return await self._invoke(
|
|
794
812
|
request,
|
|
795
813
|
dc_new,
|
|
@@ -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
|
|
|
@@ -94,7 +94,7 @@ class PyrogramClient(BridgedClient):
|
|
|
94
94
|
self,
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
@self._app.on_raw_update(group=-
|
|
97
|
+
@self._app.on_raw_update(group=-9999)
|
|
98
98
|
async def on_update(_, update, __, chats):
|
|
99
99
|
if isinstance(
|
|
100
100
|
update,
|
|
@@ -186,19 +186,23 @@ class PyrogramClient(BridgedClient):
|
|
|
186
186
|
update,
|
|
187
187
|
UpdateGroupCallParticipants,
|
|
188
188
|
):
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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,
|
|
194
195
|
)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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,
|
|
201
202
|
)
|
|
203
|
+
if result is not None:
|
|
204
|
+
await self._propagate(p_update)
|
|
205
|
+
|
|
202
206
|
if isinstance(
|
|
203
207
|
update,
|
|
204
208
|
UpdateGroupCall,
|
|
@@ -352,9 +356,10 @@ class PyrogramClient(BridgedClient):
|
|
|
352
356
|
call: GroupCall = raw_call.call
|
|
353
357
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
354
358
|
for participant in participants:
|
|
355
|
-
self._cache.
|
|
359
|
+
self._cache.set_participants_cache(
|
|
356
360
|
chat_id,
|
|
357
361
|
call.id,
|
|
362
|
+
self.parse_participant_action(participant),
|
|
358
363
|
self.parse_participant(participant),
|
|
359
364
|
)
|
|
360
365
|
if call.schedule_date is not None:
|
|
@@ -429,8 +434,10 @@ class PyrogramClient(BridgedClient):
|
|
|
429
434
|
):
|
|
430
435
|
participants = update.participants
|
|
431
436
|
for participant in participants:
|
|
432
|
-
self._cache.
|
|
437
|
+
self._cache.set_participants_cache(
|
|
438
|
+
chat_id,
|
|
433
439
|
update.call.id,
|
|
440
|
+
self.parse_participant_action(participant),
|
|
434
441
|
self.parse_participant(participant),
|
|
435
442
|
)
|
|
436
443
|
if isinstance(update, UpdateGroupCallConnection):
|
|
@@ -583,6 +590,19 @@ class PyrogramClient(BridgedClient):
|
|
|
583
590
|
),
|
|
584
591
|
)
|
|
585
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
|
+
|
|
586
606
|
async def discard_call(
|
|
587
607
|
self,
|
|
588
608
|
chat_id: int,
|
|
@@ -736,7 +756,6 @@ class PyrogramClient(BridgedClient):
|
|
|
736
756
|
):
|
|
737
757
|
if chat_id is not None:
|
|
738
758
|
dc_id = self._cache.get_dc_call(chat_id)
|
|
739
|
-
|
|
740
759
|
if dc_id is None:
|
|
741
760
|
session = self._app
|
|
742
761
|
else:
|
|
@@ -786,12 +805,12 @@ class PyrogramClient(BridgedClient):
|
|
|
786
805
|
dc_new = BridgedClient.extract_dc(
|
|
787
806
|
str(e),
|
|
788
807
|
)
|
|
789
|
-
if chat_id is not None and dc_new is not None:
|
|
790
|
-
self._cache.set_dc_call(
|
|
791
|
-
chat_id,
|
|
792
|
-
dc_new,
|
|
793
|
-
)
|
|
794
808
|
if dc_new is not None:
|
|
809
|
+
if chat_id is not None:
|
|
810
|
+
self._cache.set_dc_call(
|
|
811
|
+
chat_id,
|
|
812
|
+
dc_new,
|
|
813
|
+
)
|
|
795
814
|
return await self._invoke(
|
|
796
815
|
request,
|
|
797
816
|
dc_new,
|
|
@@ -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,19 +180,22 @@ class TelethonClient(BridgedClient):
|
|
|
180
180
|
update,
|
|
181
181
|
UpdateGroupCallParticipants,
|
|
182
182
|
):
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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,
|
|
188
189
|
)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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,
|
|
195
196
|
)
|
|
197
|
+
if result is not None:
|
|
198
|
+
await self._propagate(p_update)
|
|
196
199
|
if isinstance(
|
|
197
200
|
update,
|
|
198
201
|
UpdateGroupCall,
|
|
@@ -339,9 +342,10 @@ class TelethonClient(BridgedClient):
|
|
|
339
342
|
call: GroupCall = raw_call.call
|
|
340
343
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
341
344
|
for participant in participants:
|
|
342
|
-
self._cache.
|
|
345
|
+
self._cache.set_participants_cache(
|
|
343
346
|
chat_id,
|
|
344
347
|
call.id,
|
|
348
|
+
self.parse_participant_action(participant),
|
|
345
349
|
self.parse_participant(participant),
|
|
346
350
|
)
|
|
347
351
|
if call.schedule_date is not None:
|
|
@@ -416,8 +420,10 @@ class TelethonClient(BridgedClient):
|
|
|
416
420
|
):
|
|
417
421
|
participants = update.participants
|
|
418
422
|
for participant in participants:
|
|
419
|
-
self._cache.
|
|
423
|
+
self._cache.set_participants_cache(
|
|
424
|
+
chat_id,
|
|
420
425
|
update.call.id,
|
|
426
|
+
self.parse_participant_action(participant),
|
|
421
427
|
self.parse_participant(participant),
|
|
422
428
|
)
|
|
423
429
|
if isinstance(update, UpdateGroupCallConnection):
|
|
@@ -570,6 +576,19 @@ class TelethonClient(BridgedClient):
|
|
|
570
576
|
),
|
|
571
577
|
)
|
|
572
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
|
+
|
|
573
592
|
async def discard_call(
|
|
574
593
|
self,
|
|
575
594
|
chat_id: int,
|
|
@@ -714,7 +733,7 @@ class TelethonClient(BridgedClient):
|
|
|
714
733
|
def no_updates(self):
|
|
715
734
|
return False
|
|
716
735
|
|
|
717
|
-
# noinspection PyProtectedMember
|
|
736
|
+
# noinspection PyProtectedMember,PyUnresolvedReferences
|
|
718
737
|
async def _invoke(
|
|
719
738
|
self,
|
|
720
739
|
request,
|
|
@@ -738,12 +757,12 @@ class TelethonClient(BridgedClient):
|
|
|
738
757
|
dc_new = BridgedClient.extract_dc(
|
|
739
758
|
str(e),
|
|
740
759
|
)
|
|
741
|
-
if chat_id is not None and dc_new is not None:
|
|
742
|
-
self._cache.set_dc_call(
|
|
743
|
-
chat_id,
|
|
744
|
-
dc_new,
|
|
745
|
-
)
|
|
746
760
|
if dc_new is not None:
|
|
761
|
+
if chat_id is not None:
|
|
762
|
+
self._cache.set_dc_call(
|
|
763
|
+
chat_id,
|
|
764
|
+
dc_new,
|
|
765
|
+
)
|
|
747
766
|
return await self._invoke(
|
|
748
767
|
request,
|
|
749
768
|
dc_new,
|
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)
|
|
@@ -12,6 +12,7 @@ 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):
|
|
@@ -33,8 +34,6 @@ class GroupCallParticipant(PyObject):
|
|
|
33
34
|
video_camera: bool,
|
|
34
35
|
raised_hand: bool,
|
|
35
36
|
volume: int,
|
|
36
|
-
joined: bool,
|
|
37
|
-
left: bool,
|
|
38
37
|
source: int,
|
|
39
38
|
video_info: Optional[SourceInfo],
|
|
40
39
|
presentation_info: Optional[SourceInfo],
|
|
@@ -48,12 +47,6 @@ class GroupCallParticipant(PyObject):
|
|
|
48
47
|
self.video_camera: bool = video_camera
|
|
49
48
|
self.raised_hand: bool = raised_hand
|
|
50
49
|
self.volume: int = volume
|
|
51
|
-
if joined:
|
|
52
|
-
self.action = self.Action.JOINED
|
|
53
|
-
elif left:
|
|
54
|
-
self.action = self.Action.LEFT
|
|
55
|
-
else:
|
|
56
|
-
self.action = self.Action.UPDATED
|
|
57
50
|
self.video_info: Optional[
|
|
58
51
|
GroupCallParticipant.SourceInfo
|
|
59
52
|
] = video_info
|
pytgcalls/types/dict.py
CHANGED
pytgcalls/types/flag.py
CHANGED
pytgcalls/types/list.py
CHANGED
|
@@ -10,14 +10,14 @@ 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,
|
|
17
|
+
action: GroupCallParticipant.Action,
|
|
18
18
|
participant: GroupCallParticipant,
|
|
19
|
-
):
|
|
20
|
-
if
|
|
19
|
+
) -> GroupCallParticipant:
|
|
20
|
+
if action == GroupCallParticipant.Action.LEFT:
|
|
21
21
|
if participant.user_id in self._list_participants:
|
|
22
22
|
del self._list_participants[participant.user_id]
|
|
23
23
|
else:
|
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
|