py-tgcalls 2.0.0rc2__py3-none-any.whl → 2.0.0rc4__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.0.0rc2.dist-info → py_tgcalls-2.0.0rc4.dist-info}/METADATA +2 -2
- {py_tgcalls-2.0.0rc2.dist-info → py_tgcalls-2.0.0rc4.dist-info}/RECORD +24 -24
- pytgcalls/__version__.py +1 -1
- pytgcalls/exceptions.py +16 -2
- pytgcalls/methods/calls/leave_call.py +2 -2
- pytgcalls/methods/stream/mute_stream.py +2 -2
- pytgcalls/methods/stream/pause_stream.py +2 -2
- pytgcalls/methods/stream/play.py +8 -9
- pytgcalls/methods/stream/played_time.py +2 -2
- pytgcalls/methods/stream/resume_stream.py +2 -2
- pytgcalls/methods/stream/unmute_stream.py +2 -2
- pytgcalls/methods/utilities/call_holder.py +3 -3
- pytgcalls/methods/utilities/start.py +47 -9
- pytgcalls/mtproto/bridged_client.py +5 -11
- pytgcalls/mtproto/hydrogram_client.py +7 -4
- pytgcalls/mtproto/mtproto_client.py +0 -2
- pytgcalls/mtproto/pyrogram_client.py +29 -26
- pytgcalls/mtproto/telethon_client.py +7 -4
- pytgcalls/pytgcalls.py +1 -4
- pytgcalls/scaffold.py +1 -0
- pytgcalls/types/stream/media_stream.py +2 -2
- {py_tgcalls-2.0.0rc2.dist-info → py_tgcalls-2.0.0rc4.dist-info}/LICENSE +0 -0
- {py_tgcalls-2.0.0rc2.dist-info → py_tgcalls-2.0.0rc4.dist-info}/WHEEL +0 -0
- {py_tgcalls-2.0.0rc2.dist-info → py_tgcalls-2.0.0rc4.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py-tgcalls
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0rc4
|
|
4
4
|
Summary: UNKNOWN
|
|
5
5
|
Home-page: https://github.com/pytgcalls/pytgcalls
|
|
6
6
|
Author: Laky-64
|
|
@@ -22,7 +22,7 @@ Description-Content-Type: text/markdown
|
|
|
22
22
|
License-File: LICENSE
|
|
23
23
|
Requires-Dist: aiohttp (>=3.9.3)
|
|
24
24
|
Requires-Dist: deprecation
|
|
25
|
-
Requires-Dist: ntgcalls (>=1.
|
|
25
|
+
Requires-Dist: ntgcalls (>=1.2.0.b6)
|
|
26
26
|
Requires-Dist: psutil
|
|
27
27
|
Requires-Dist: screeninfo
|
|
28
28
|
Requires-Dist: setuptools
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
pytgcalls/__init__.py,sha256=TfZGf1enqqs50mBB406vygB6zYgn3vAjBYFUDO4Pviw,248
|
|
2
|
-
pytgcalls/__version__.py,sha256=
|
|
2
|
+
pytgcalls/__version__.py,sha256=TZk9uVn2m_Mjhob6LWvtgl022cEas816bZCaV4pwe-c,25
|
|
3
3
|
pytgcalls/environment.py,sha256=ctCHACvG6l8SdpPewSBhOvc70kbwpv18maC0TwLvZ08,1924
|
|
4
|
-
pytgcalls/exceptions.py,sha256
|
|
4
|
+
pytgcalls/exceptions.py,sha256=0MmAktc53ajYAc7ThjD2tJ9PDyibUi0iHZMfUy2IoKs,4109
|
|
5
5
|
pytgcalls/ffmpeg.py,sha256=1GavkVf562Y_8cT4EZxxj_b7Y0-l8yyGkX0D5eUHeas,8520
|
|
6
6
|
pytgcalls/filters.py,sha256=cmFWhRkgjQMk1WQqnd-hOAvM6x3dufJ1xjQAEL1vKLQ,4409
|
|
7
7
|
pytgcalls/mtproto_required.py,sha256=6B-31p5qH_6oekUgypV4nK3hqPS6Nr-pA8S81wjnbaY,630
|
|
8
8
|
pytgcalls/mutex.py,sha256=fSsAL4NuB7esBG90k4eUX388Knpr1_76Mz5BZlkSC0w,1119
|
|
9
|
-
pytgcalls/pytgcalls.py,sha256=
|
|
9
|
+
pytgcalls/pytgcalls.py,sha256=VI9aRwPE-Lo1lh18ByOnkFxf1_8tq2ECyz5igPo1r8w,1443
|
|
10
10
|
pytgcalls/pytgcalls_session.py,sha256=_BGJWvf7t3mki2DhlEPjh9cypvYuSFkMSxzTsfepwUk,2719
|
|
11
|
-
pytgcalls/scaffold.py,sha256=
|
|
11
|
+
pytgcalls/scaffold.py,sha256=d5NFFm-Ntlu07fpXOE_OI4ULrvNb3Y4WDtM0nsKjqk4,986
|
|
12
12
|
pytgcalls/statictypes.py,sha256=CdlqgQNhTZ_uTE8-B8m01fJ7TlD2B42EI2QBPxDdAtA,3842
|
|
13
13
|
pytgcalls/sync.py,sha256=IsOH3TD7cxUg_-zdGt12HoS8sBlXvcGayPZAoxxKM48,3396
|
|
14
14
|
pytgcalls/version_manager.py,sha256=egeGgvb66zWlLTMuw2U-b0x8MfnRzMm1xAEVN87HF5c,296
|
|
@@ -25,34 +25,34 @@ pytgcalls/methods/__init__.py,sha256=hk1blAT5u_Isemdrg0nqInLsdRzTTZnak5NdAfkBPAk
|
|
|
25
25
|
pytgcalls/methods/calls/__init__.py,sha256=xg4DZZClEnxwaj-DAq3e8gSR-g-MiYBdUEBth64lSXA,214
|
|
26
26
|
pytgcalls/methods/calls/change_volume_call.py,sha256=viA3yHVxPJ421yE1dfFTh-kNEFTxMlaVFxVjC-PeX-0,719
|
|
27
27
|
pytgcalls/methods/calls/get_participants.py,sha256=dT725XXn9oiTbWV6mFradIydoQUx_COPButivDhzAxE,568
|
|
28
|
-
pytgcalls/methods/calls/leave_call.py,sha256=
|
|
28
|
+
pytgcalls/methods/calls/leave_call.py,sha256=ZjZbjlQn8KuX3mUjzXfX42EpL9_iU3fsXYdidfqUrUM,1091
|
|
29
29
|
pytgcalls/methods/decorators/__init__.py,sha256=TCGaEVZnHjtOwv-3PNfaCVm0kyFhJApUPUNntt6MwyM,78
|
|
30
30
|
pytgcalls/methods/decorators/on_update.py,sha256=ZTL4YcQk0N4Ru56a5WItUvkSN5SAqr6_RDZvXmZMIHs,316
|
|
31
31
|
pytgcalls/methods/stream/__init__.py,sha256=_4j-CEby4_2Kadva86tFMC4GSSzhBBjKLXfrgTk4gzo,343
|
|
32
|
-
pytgcalls/methods/stream/mute_stream.py,sha256=
|
|
33
|
-
pytgcalls/methods/stream/pause_stream.py,sha256=
|
|
34
|
-
pytgcalls/methods/stream/play.py,sha256=
|
|
35
|
-
pytgcalls/methods/stream/played_time.py,sha256=
|
|
36
|
-
pytgcalls/methods/stream/resume_stream.py,sha256=
|
|
37
|
-
pytgcalls/methods/stream/unmute_stream.py,sha256=
|
|
32
|
+
pytgcalls/methods/stream/mute_stream.py,sha256=auo2aAazfEC90Ab6MzaiPdddiJ1w4fN_9HaORkAeOBY,570
|
|
33
|
+
pytgcalls/methods/stream/pause_stream.py,sha256=z_AIWABrQMHmTwvlah_PrH9EjXbro8gKxZni4Km5ICg,573
|
|
34
|
+
pytgcalls/methods/stream/play.py,sha256=acuav8C9wEyur8FMAT7zFxkEvNDu45gnodUmGFrfIKA,7376
|
|
35
|
+
pytgcalls/methods/stream/played_time.py,sha256=IkUdyHrqpzpRl9uf0uZhg1COo4zsHnQOPu3nipjVatI,570
|
|
36
|
+
pytgcalls/methods/stream/resume_stream.py,sha256=z_DgP4cDExjEqEeX_ZL--50MXQ9lrATK876SIwE71PQ,576
|
|
37
|
+
pytgcalls/methods/stream/unmute_stream.py,sha256=KUMhfMbhsPmZsmpF4cGWC1FVW7YwXha2MmQnqrBhM8s,576
|
|
38
38
|
pytgcalls/methods/utilities/__init__.py,sha256=JcKwqNo6fFXXfuab94fNEraKF1P9fnSSgr0WQDRjF2w,339
|
|
39
39
|
pytgcalls/methods/utilities/cache_peer.py,sha256=Ylt0wCCJOoNKf1wZEXjfE8aBZKUIIgdRUFOMTGA5DfE,140
|
|
40
|
-
pytgcalls/methods/utilities/call_holder.py,sha256=
|
|
40
|
+
pytgcalls/methods/utilities/call_holder.py,sha256=RZ9DFhZO66ghtGqxLbYS86hq2UCjTzTiN_xzL5bgD-M,903
|
|
41
41
|
pytgcalls/methods/utilities/compose.py,sha256=Nzdv8orMmka5NIBZ1SW1nsqXRzArZl4m6FdZU7syaR4,334
|
|
42
42
|
pytgcalls/methods/utilities/cpu_usage.py,sha256=Mbga4MFCIwuh7WC8sqBbv1Pa6ALcp5AIDyfYMH_Bix4,162
|
|
43
43
|
pytgcalls/methods/utilities/idle.py,sha256=lkjbYzpU7iz-maE0kS6RVtHJ4h1PsmGqnZmaENGIKeE,768
|
|
44
44
|
pytgcalls/methods/utilities/ping.py,sha256=hhIMSHk2BzMB-IKpwLdZFVrsEvGm2ftJwKLs1k4anh8,244
|
|
45
45
|
pytgcalls/methods/utilities/resolve_chat_id.py,sha256=92x2LHbUlnJMm-kS3fXOYmzYpY2TZbqtQD2rw3eBXDY,382
|
|
46
46
|
pytgcalls/methods/utilities/run.py,sha256=cnYQd2xB5Cr_WS0Q2cXJZPGiN6JOCULzj1r4xXVyrlg,152
|
|
47
|
-
pytgcalls/methods/utilities/start.py,sha256=
|
|
47
|
+
pytgcalls/methods/utilities/start.py,sha256=0TjW64IDYulevNTJIp4ZHWa9pkKCcgeyFhL47PehoqI,8534
|
|
48
48
|
pytgcalls/methods/utilities/stream_params.py,sha256=hYcNxx__McmPeHgOUDEuNcN7ThgDjukejQYHrfmWm-A,1519
|
|
49
49
|
pytgcalls/mtproto/__init__.py,sha256=X4zvzFG7km7qHyE0fdvA550WcOVO_xl_p__gvIfDGmw,130
|
|
50
|
-
pytgcalls/mtproto/bridged_client.py,sha256=
|
|
50
|
+
pytgcalls/mtproto/bridged_client.py,sha256=kK22n-CKjtfmtNE6bXCpuL6kWAUK2_Ul7cGgx_HNuHQ,4975
|
|
51
51
|
pytgcalls/mtproto/client_cache.py,sha256=LYjmvhgaaEyczoJFZ35vGXFlN4ADwXYvt1bhrVS4ipw,5088
|
|
52
|
-
pytgcalls/mtproto/hydrogram_client.py,sha256=
|
|
53
|
-
pytgcalls/mtproto/mtproto_client.py,sha256=
|
|
54
|
-
pytgcalls/mtproto/pyrogram_client.py,sha256=
|
|
55
|
-
pytgcalls/mtproto/telethon_client.py,sha256=
|
|
52
|
+
pytgcalls/mtproto/hydrogram_client.py,sha256=TgItS6KKPJna1yIXJ7iXflfRWRpPvMXHoRKzo6q09lE,21014
|
|
53
|
+
pytgcalls/mtproto/mtproto_client.py,sha256=rqsUOE7llTXSAru9GfBMhUKufEgWQL65QLHRj4TEfgw,6884
|
|
54
|
+
pytgcalls/mtproto/pyrogram_client.py,sha256=cNaQu00rZTFVTj3CE2V_eL5yT1XcGwkgwcGfb6aa53s,21203
|
|
55
|
+
pytgcalls/mtproto/telethon_client.py,sha256=GFZ0LM8PXRVXwJfYV_gVVZ_qjEmWCJD_nmqiPE8oCCo,20105
|
|
56
56
|
pytgcalls/types/__init__.py,sha256=JTMTa2flwWkBSEjhAAXE0oL4IJFRb12XU0npp9Neypc,1071
|
|
57
57
|
pytgcalls/types/browsers.py,sha256=47Kr5q96n4Q4WvVhA6IUlS2egEcA9GRLlDeFcQYyc9M,9545
|
|
58
58
|
pytgcalls/types/cache.py,sha256=FfsOcmYnsBGPlJoTPIXXYcUSpGE3rhx6cjIH77hyUL0,1059
|
|
@@ -82,12 +82,12 @@ pytgcalls/types/raw/video_parameters.py,sha256=LXBpdaw5vyNayVfgtmF-gRkCY_ATwAnun
|
|
|
82
82
|
pytgcalls/types/raw/video_stream.py,sha256=2Chrk7NFWF1H9V7hH71RZ5rF3iBhT53syFkHKw4-5gc,433
|
|
83
83
|
pytgcalls/types/stream/__init__.py,sha256=xfF-9ZulOLk3E6G1nw1Ky0ZRWXlFuER0Uj8HQn3650w,338
|
|
84
84
|
pytgcalls/types/stream/audio_quality.py,sha256=4X94ErmTeLP4TVcE3eLtPPdtluSPxgxbgTosuNJOVhc,141
|
|
85
|
-
pytgcalls/types/stream/media_stream.py,sha256=
|
|
85
|
+
pytgcalls/types/stream/media_stream.py,sha256=vH32FrwdMSA9-S54bvessVHewh_l-5WXqupQE8pe-x4,8979
|
|
86
86
|
pytgcalls/types/stream/stream_audio_ended.py,sha256=2_EFa98F0vWu0d0jBmLtzp4NH_xBkDO_6yP9UtyKuCs,164
|
|
87
87
|
pytgcalls/types/stream/stream_video_ended.py,sha256=9YFTTZPMDpB95eb815rGtgDrzBGfTeazJ5mZwP6Hvks,164
|
|
88
88
|
pytgcalls/types/stream/video_quality.py,sha256=HBfWq005kh-D19MaVE9VzVdnODzrXf4IJUimCfslfiU,231
|
|
89
|
-
py_tgcalls-2.0.
|
|
90
|
-
py_tgcalls-2.0.
|
|
91
|
-
py_tgcalls-2.0.
|
|
92
|
-
py_tgcalls-2.0.
|
|
93
|
-
py_tgcalls-2.0.
|
|
89
|
+
py_tgcalls-2.0.0rc4.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
90
|
+
py_tgcalls-2.0.0rc4.dist-info/METADATA,sha256=WRIeNUG7mRIALS23Oi0h_2bzY5o0eLfzuQAZpjaATtg,4886
|
|
91
|
+
py_tgcalls-2.0.0rc4.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
92
|
+
py_tgcalls-2.0.0rc4.dist-info/top_level.txt,sha256=IUDUwn0KkcbUYZbCe9R5AUb2Ob-lmllNUGQqyeXXd8A,10
|
|
93
|
+
py_tgcalls-2.0.0rc4.dist-info/RECORD,,
|
pytgcalls/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.0.
|
|
1
|
+
__version__ = '2.0.0rc4'
|
pytgcalls/exceptions.py
CHANGED
|
@@ -65,10 +65,24 @@ class TimedOutAnswer(Exception):
|
|
|
65
65
|
)
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
class
|
|
68
|
+
class CallDeclined(Exception):
|
|
69
|
+
def __init__(self, user_id: int):
|
|
70
|
+
super().__init__(
|
|
71
|
+
f'Call declined by {user_id}',
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class CallDiscarded(Exception):
|
|
76
|
+
def __init__(self, user_id: int):
|
|
77
|
+
super().__init__(
|
|
78
|
+
f'Call discarded by {user_id}',
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class NotInCallError(Exception):
|
|
69
83
|
def __init__(self):
|
|
70
84
|
super().__init__(
|
|
71
|
-
'The userbot
|
|
85
|
+
'The userbot is not in a call',
|
|
72
86
|
)
|
|
73
87
|
|
|
74
88
|
|
|
@@ -3,7 +3,7 @@ from typing import Union
|
|
|
3
3
|
from ntgcalls import ConnectionNotFound
|
|
4
4
|
|
|
5
5
|
from ...exceptions import NoActiveGroupCall
|
|
6
|
-
from ...exceptions import
|
|
6
|
+
from ...exceptions import NotInCallError
|
|
7
7
|
from ...mtproto_required import mtproto_required
|
|
8
8
|
from ...mutex import mutex
|
|
9
9
|
from ...scaffold import Scaffold
|
|
@@ -35,6 +35,6 @@ class LeaveCall(Scaffold):
|
|
|
35
35
|
try:
|
|
36
36
|
await self._binding.stop(chat_id)
|
|
37
37
|
except ConnectionNotFound:
|
|
38
|
-
raise
|
|
38
|
+
raise NotInCallError()
|
|
39
39
|
if chat_id < 0: # type: ignore
|
|
40
40
|
self._need_unmute.discard(chat_id)
|
|
@@ -2,7 +2,7 @@ from typing import Union
|
|
|
2
2
|
|
|
3
3
|
from ntgcalls import ConnectionNotFound
|
|
4
4
|
|
|
5
|
-
from ...exceptions import
|
|
5
|
+
from ...exceptions import NotInCallError
|
|
6
6
|
from ...mtproto_required import mtproto_required
|
|
7
7
|
from ...scaffold import Scaffold
|
|
8
8
|
from ...statictypes import statictypes
|
|
@@ -19,4 +19,4 @@ class MuteStream(Scaffold):
|
|
|
19
19
|
try:
|
|
20
20
|
return await self._binding.mute(chat_id)
|
|
21
21
|
except ConnectionNotFound:
|
|
22
|
-
raise
|
|
22
|
+
raise NotInCallError()
|
|
@@ -2,7 +2,7 @@ from typing import Union
|
|
|
2
2
|
|
|
3
3
|
from ntgcalls import ConnectionNotFound
|
|
4
4
|
|
|
5
|
-
from ...exceptions import
|
|
5
|
+
from ...exceptions import NotInCallError
|
|
6
6
|
from ...mtproto_required import mtproto_required
|
|
7
7
|
from ...scaffold import Scaffold
|
|
8
8
|
from ...statictypes import statictypes
|
|
@@ -19,4 +19,4 @@ class PauseStream(Scaffold):
|
|
|
19
19
|
try:
|
|
20
20
|
return await self._binding.pause(chat_id)
|
|
21
21
|
except ConnectionNotFound:
|
|
22
|
-
raise
|
|
22
|
+
raise NotInCallError()
|
pytgcalls/methods/stream/play.py
CHANGED
|
@@ -37,13 +37,10 @@ class Play(Scaffold):
|
|
|
37
37
|
config: Optional[Union[CallConfig, GroupCallConfig]] = None,
|
|
38
38
|
):
|
|
39
39
|
chat_id = await self.resolve_chat_id(chat_id)
|
|
40
|
+
is_p2p = chat_id > 0 # type: ignore
|
|
40
41
|
if config is None:
|
|
41
|
-
config = GroupCallConfig()
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
chat_id < 0 and # type: ignore
|
|
45
|
-
not isinstance(config, GroupCallConfig)
|
|
46
|
-
):
|
|
42
|
+
config = GroupCallConfig() if not is_p2p else CallConfig()
|
|
43
|
+
if not is_p2p and not isinstance(config, GroupCallConfig):
|
|
47
44
|
raise ValueError(
|
|
48
45
|
'Group call config must be provided for group calls',
|
|
49
46
|
)
|
|
@@ -81,6 +78,7 @@ class Play(Scaffold):
|
|
|
81
78
|
try:
|
|
82
79
|
for retries in range(4):
|
|
83
80
|
try:
|
|
81
|
+
self._wait_connect[chat_id] = self.loop.create_future()
|
|
84
82
|
if isinstance(config, GroupCallConfig):
|
|
85
83
|
call_params: str = await self._binding.create_call(
|
|
86
84
|
chat_id,
|
|
@@ -121,7 +119,6 @@ class Play(Scaffold):
|
|
|
121
119
|
chat_id,
|
|
122
120
|
data.g_a_or_b,
|
|
123
121
|
self._binding.get_protocol(),
|
|
124
|
-
media_description.video is not None,
|
|
125
122
|
)
|
|
126
123
|
|
|
127
124
|
try:
|
|
@@ -131,7 +128,6 @@ class Play(Scaffold):
|
|
|
131
128
|
)
|
|
132
129
|
auth_params = await self._binding.exchange_keys(
|
|
133
130
|
chat_id,
|
|
134
|
-
data.p,
|
|
135
131
|
result.g_a_or_b,
|
|
136
132
|
result.fingerprint,
|
|
137
133
|
)
|
|
@@ -153,9 +149,10 @@ class Play(Scaffold):
|
|
|
153
149
|
raise TimedOutAnswer()
|
|
154
150
|
finally:
|
|
155
151
|
self._p2p_configs.pop(chat_id, None)
|
|
152
|
+
await self._wait_connect[chat_id]
|
|
156
153
|
break
|
|
157
154
|
except TelegramServerError:
|
|
158
|
-
if retries == 3:
|
|
155
|
+
if retries == 3 or is_p2p:
|
|
159
156
|
raise
|
|
160
157
|
(py_logger.warning if retries >= 1 else py_logger.info)(
|
|
161
158
|
f'Telegram is having some internal server issues. '
|
|
@@ -167,6 +164,8 @@ class Play(Scaffold):
|
|
|
167
164
|
except ConnectionNotFound:
|
|
168
165
|
pass
|
|
169
166
|
raise
|
|
167
|
+
finally:
|
|
168
|
+
self._wait_connect.pop(chat_id, None)
|
|
170
169
|
|
|
171
170
|
if isinstance(config, GroupCallConfig):
|
|
172
171
|
participants = await self._app.get_group_call_participants(
|
|
@@ -2,7 +2,7 @@ from typing import Union
|
|
|
2
2
|
|
|
3
3
|
from ntgcalls import ConnectionNotFound
|
|
4
4
|
|
|
5
|
-
from ...exceptions import
|
|
5
|
+
from ...exceptions import NotInCallError
|
|
6
6
|
from ...mtproto_required import mtproto_required
|
|
7
7
|
from ...scaffold import Scaffold
|
|
8
8
|
from ...statictypes import statictypes
|
|
@@ -19,4 +19,4 @@ class PlayedTime(Scaffold):
|
|
|
19
19
|
try:
|
|
20
20
|
return await self._binding.time(chat_id)
|
|
21
21
|
except ConnectionNotFound:
|
|
22
|
-
raise
|
|
22
|
+
raise NotInCallError()
|
|
@@ -2,7 +2,7 @@ from typing import Union
|
|
|
2
2
|
|
|
3
3
|
from ntgcalls import ConnectionNotFound
|
|
4
4
|
|
|
5
|
-
from ...exceptions import
|
|
5
|
+
from ...exceptions import NotInCallError
|
|
6
6
|
from ...mtproto_required import mtproto_required
|
|
7
7
|
from ...scaffold import Scaffold
|
|
8
8
|
from ...statictypes import statictypes
|
|
@@ -19,4 +19,4 @@ class ResumeStream(Scaffold):
|
|
|
19
19
|
try:
|
|
20
20
|
return await self._binding.resume(chat_id)
|
|
21
21
|
except ConnectionNotFound:
|
|
22
|
-
raise
|
|
22
|
+
raise NotInCallError()
|
|
@@ -2,7 +2,7 @@ from typing import Union
|
|
|
2
2
|
|
|
3
3
|
from ntgcalls import ConnectionNotFound
|
|
4
4
|
|
|
5
|
-
from ...exceptions import
|
|
5
|
+
from ...exceptions import NotInCallError
|
|
6
6
|
from ...mtproto_required import mtproto_required
|
|
7
7
|
from ...scaffold import Scaffold
|
|
8
8
|
from ...statictypes import statictypes
|
|
@@ -19,4 +19,4 @@ class UnMuteStream(Scaffold):
|
|
|
19
19
|
try:
|
|
20
20
|
return await self._binding.unmute(chat_id)
|
|
21
21
|
except ConnectionNotFound:
|
|
22
|
-
raise
|
|
22
|
+
raise NotInCallError()
|
|
@@ -9,9 +9,9 @@ class CallHolder(Scaffold):
|
|
|
9
9
|
def __init__(self):
|
|
10
10
|
super().__init__()
|
|
11
11
|
self._conversions = {
|
|
12
|
-
StreamStatus.
|
|
13
|
-
StreamStatus.
|
|
14
|
-
StreamStatus.
|
|
12
|
+
StreamStatus.PLAYING: Call.Status.PLAYING,
|
|
13
|
+
StreamStatus.PAUSED: Call.Status.PAUSED,
|
|
14
|
+
StreamStatus.IDLING: Call.Status.IDLE,
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
@property
|
|
@@ -2,9 +2,13 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
4
|
from ntgcalls import ConnectionNotFound
|
|
5
|
+
from ntgcalls import ConnectionState
|
|
5
6
|
from ntgcalls import MediaState
|
|
6
7
|
from ntgcalls import StreamType
|
|
8
|
+
from ntgcalls import TelegramServerError
|
|
7
9
|
|
|
10
|
+
from ...exceptions import CallDeclined
|
|
11
|
+
from ...exceptions import CallDiscarded
|
|
8
12
|
from ...exceptions import PyTgCallsAlreadyRunning
|
|
9
13
|
from ...mtproto import BridgedClient
|
|
10
14
|
from ...pytgcalls_session import PyTgCallsSession
|
|
@@ -26,13 +30,29 @@ class Start(Scaffold):
|
|
|
26
30
|
@self._app.on_update()
|
|
27
31
|
async def update_handler(update: Update):
|
|
28
32
|
chat_id = update.chat_id
|
|
29
|
-
if
|
|
30
|
-
if
|
|
31
|
-
if update
|
|
32
|
-
if
|
|
33
|
+
if update.chat_id in self._p2p_configs:
|
|
34
|
+
if not self._p2p_configs[chat_id].wait_data.done():
|
|
35
|
+
if isinstance(update, RawCallUpdate):
|
|
36
|
+
if update.status & RawCallUpdate.Type.UPDATED_CALL:
|
|
33
37
|
self._p2p_configs[chat_id].wait_data.set_result(
|
|
34
38
|
update,
|
|
35
39
|
)
|
|
40
|
+
if isinstance(update, ChatUpdate):
|
|
41
|
+
if update.status & ChatUpdate.Status.DISCARDED_CALL:
|
|
42
|
+
self._p2p_configs[chat_id].wait_data.set_exception(
|
|
43
|
+
CallDeclined(
|
|
44
|
+
chat_id,
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
if chat_id in self._wait_connect and \
|
|
48
|
+
not self._wait_connect[chat_id].done():
|
|
49
|
+
if isinstance(update, ChatUpdate):
|
|
50
|
+
if update.status & ChatUpdate.Status.DISCARDED_CALL:
|
|
51
|
+
self._wait_connect[chat_id].set_exception(
|
|
52
|
+
CallDiscarded(
|
|
53
|
+
chat_id,
|
|
54
|
+
),
|
|
55
|
+
)
|
|
36
56
|
if isinstance(update, RawCallUpdate):
|
|
37
57
|
if update.status & RawCallUpdate.Type.REQUESTED:
|
|
38
58
|
self._p2p_configs[chat_id] = CallData(
|
|
@@ -86,7 +106,6 @@ class Start(Scaffold):
|
|
|
86
106
|
)
|
|
87
107
|
|
|
88
108
|
async def clear_call(chat_id):
|
|
89
|
-
self._p2p_configs.pop(chat_id, None)
|
|
90
109
|
try:
|
|
91
110
|
await self._binding.stop(chat_id)
|
|
92
111
|
except ConnectionNotFound:
|
|
@@ -109,7 +128,7 @@ class Start(Scaffold):
|
|
|
109
128
|
await self.propagate(
|
|
110
129
|
StreamAudioEnded(
|
|
111
130
|
chat_id,
|
|
112
|
-
) if stream ==
|
|
131
|
+
) if stream == StreamType.AUDIO else
|
|
113
132
|
StreamVideoEnded(
|
|
114
133
|
chat_id,
|
|
115
134
|
),
|
|
@@ -123,7 +142,26 @@ class Start(Scaffold):
|
|
|
123
142
|
data,
|
|
124
143
|
)
|
|
125
144
|
|
|
145
|
+
async def connection_changed(chat_id: int, state: ConnectionState):
|
|
146
|
+
if chat_id in self._wait_connect:
|
|
147
|
+
if state == ConnectionState.CONNECTED:
|
|
148
|
+
self._wait_connect[chat_id].set_result(None)
|
|
149
|
+
elif state == ConnectionState.FAILED or\
|
|
150
|
+
state == ConnectionState.TIMEOUT:
|
|
151
|
+
self._wait_connect[chat_id].set_exception(
|
|
152
|
+
TelegramServerError(),
|
|
153
|
+
)
|
|
154
|
+
await clear_call(chat_id)
|
|
155
|
+
|
|
156
|
+
if state == ConnectionState.FAILED or \
|
|
157
|
+
state == ConnectionState.TIMEOUT or \
|
|
158
|
+
state == ConnectionState.CLOSED:
|
|
159
|
+
if chat_id > 0:
|
|
160
|
+
await self._app.discard_call(chat_id)
|
|
161
|
+
await clear_call(chat_id)
|
|
162
|
+
|
|
126
163
|
async def clear_cache(chat_id: int):
|
|
164
|
+
self._p2p_configs.pop(chat_id, None)
|
|
127
165
|
self._cache_user_peer.pop(chat_id)
|
|
128
166
|
self._need_unmute.discard(chat_id)
|
|
129
167
|
|
|
@@ -159,9 +197,9 @@ class Start(Scaffold):
|
|
|
159
197
|
self.loop,
|
|
160
198
|
),
|
|
161
199
|
)
|
|
162
|
-
self._binding.
|
|
163
|
-
lambda chat_id: asyncio.run_coroutine_threadsafe(
|
|
164
|
-
|
|
200
|
+
self._binding.on_connection_change(
|
|
201
|
+
lambda chat_id, state: asyncio.run_coroutine_threadsafe(
|
|
202
|
+
connection_changed(chat_id, state),
|
|
165
203
|
self.loop,
|
|
166
204
|
),
|
|
167
205
|
)
|
|
@@ -34,7 +34,6 @@ class BridgedClient(HandlersHolder):
|
|
|
34
34
|
user_id: int,
|
|
35
35
|
g_a_hash: bytes,
|
|
36
36
|
protocol: Protocol,
|
|
37
|
-
video: bool,
|
|
38
37
|
):
|
|
39
38
|
pass
|
|
40
39
|
|
|
@@ -151,15 +150,10 @@ class BridgedClient(HandlersHolder):
|
|
|
151
150
|
class_name = input_peer.__class__.__name__
|
|
152
151
|
if class_name in ['PeerUser', 'InputPeerUser']:
|
|
153
152
|
return input_peer.user_id
|
|
154
|
-
elif
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return -1000000000000 - getattr(
|
|
159
|
-
input_peer,
|
|
160
|
-
'channel_id',
|
|
161
|
-
input_peer.id,
|
|
162
|
-
)
|
|
153
|
+
elif class_name in ['Channel', 'ChannelForbidden']:
|
|
154
|
+
return -1000000000000 - input_peer.id
|
|
155
|
+
elif hasattr(input_peer, 'channel_id'):
|
|
156
|
+
return -1000000000000 - input_peer.channel_id
|
|
163
157
|
elif class_name == 'Chat':
|
|
164
158
|
return -input_peer.id
|
|
165
159
|
else:
|
|
@@ -168,7 +162,7 @@ class BridgedClient(HandlersHolder):
|
|
|
168
162
|
@staticmethod
|
|
169
163
|
def user_from_call(call) -> Optional[int]:
|
|
170
164
|
class_name = call.__class__.__name__
|
|
171
|
-
if class_name
|
|
165
|
+
if class_name in ['PhoneCallAccepted', 'PhoneCallWaiting']:
|
|
172
166
|
return call.participant_id
|
|
173
167
|
elif class_name in ['PhoneCallRequested', 'PhoneCall']:
|
|
174
168
|
return call.admin_id
|
|
@@ -43,6 +43,7 @@ from hydrogram.raw.types import PhoneCallDiscarded
|
|
|
43
43
|
from hydrogram.raw.types import PhoneCallDiscardReasonHangup
|
|
44
44
|
from hydrogram.raw.types import PhoneCallProtocol
|
|
45
45
|
from hydrogram.raw.types import PhoneCallRequested
|
|
46
|
+
from hydrogram.raw.types import PhoneCallWaiting
|
|
46
47
|
from hydrogram.raw.types import UpdateChannel
|
|
47
48
|
from hydrogram.raw.types import UpdateGroupCall
|
|
48
49
|
from hydrogram.raw.types import UpdateGroupCallConnection
|
|
@@ -97,7 +98,7 @@ class HydrogramClient(BridgedClient):
|
|
|
97
98
|
):
|
|
98
99
|
if isinstance(
|
|
99
100
|
update.phone_call,
|
|
100
|
-
(PhoneCallAccepted, PhoneCallRequested),
|
|
101
|
+
(PhoneCallAccepted, PhoneCallRequested, PhoneCallWaiting),
|
|
101
102
|
):
|
|
102
103
|
self._cache.set_phone_call(
|
|
103
104
|
self.user_from_call(update.phone_call),
|
|
@@ -406,7 +407,6 @@ class HydrogramClient(BridgedClient):
|
|
|
406
407
|
user_id: int,
|
|
407
408
|
g_a_hash: bytes,
|
|
408
409
|
protocol: Protocol,
|
|
409
|
-
video: bool,
|
|
410
410
|
):
|
|
411
411
|
await self._app.invoke(
|
|
412
412
|
RequestCall(
|
|
@@ -414,7 +414,7 @@ class HydrogramClient(BridgedClient):
|
|
|
414
414
|
random_id=self.rnd_id(),
|
|
415
415
|
g_a_hash=g_a_hash,
|
|
416
416
|
protocol=self.parse_protocol(protocol),
|
|
417
|
-
video=
|
|
417
|
+
video=False,
|
|
418
418
|
),
|
|
419
419
|
)
|
|
420
420
|
|
|
@@ -512,9 +512,12 @@ class HydrogramClient(BridgedClient):
|
|
|
512
512
|
self,
|
|
513
513
|
chat_id: int,
|
|
514
514
|
):
|
|
515
|
+
peer = self._cache.get_phone_call(chat_id)
|
|
516
|
+
if peer is None:
|
|
517
|
+
return
|
|
515
518
|
await self._app.invoke(
|
|
516
519
|
DiscardCall(
|
|
517
|
-
peer=
|
|
520
|
+
peer=peer,
|
|
518
521
|
duration=0,
|
|
519
522
|
reason=PhoneCallDiscardReasonHangup(),
|
|
520
523
|
connection_id=0,
|
|
@@ -74,14 +74,12 @@ class MtProtoClient:
|
|
|
74
74
|
user_id: int,
|
|
75
75
|
g_a_hash: bytes,
|
|
76
76
|
protocol: Protocol,
|
|
77
|
-
video: bool,
|
|
78
77
|
):
|
|
79
78
|
if self._bind_client is not None:
|
|
80
79
|
return await self._bind_client.request_call(
|
|
81
80
|
user_id,
|
|
82
81
|
g_a_hash,
|
|
83
82
|
protocol,
|
|
84
|
-
video,
|
|
85
83
|
)
|
|
86
84
|
else:
|
|
87
85
|
raise InvalidMTProtoClient()
|
|
@@ -45,6 +45,7 @@ from pyrogram.raw.types import PhoneCallDiscarded
|
|
|
45
45
|
from pyrogram.raw.types import PhoneCallDiscardReasonHangup
|
|
46
46
|
from pyrogram.raw.types import PhoneCallProtocol
|
|
47
47
|
from pyrogram.raw.types import PhoneCallRequested
|
|
48
|
+
from pyrogram.raw.types import PhoneCallWaiting
|
|
48
49
|
from pyrogram.raw.types import UpdateChannel
|
|
49
50
|
from pyrogram.raw.types import UpdateGroupCall
|
|
50
51
|
from pyrogram.raw.types import UpdateGroupCallConnection
|
|
@@ -105,7 +106,7 @@ class PyrogramClient(BridgedClient):
|
|
|
105
106
|
):
|
|
106
107
|
if isinstance(
|
|
107
108
|
update.phone_call,
|
|
108
|
-
(PhoneCallAccepted, PhoneCallRequested),
|
|
109
|
+
(PhoneCallAccepted, PhoneCallRequested, PhoneCallWaiting),
|
|
109
110
|
):
|
|
110
111
|
self._cache.set_phone_call(
|
|
111
112
|
self.user_from_call(update.phone_call),
|
|
@@ -301,8 +302,8 @@ class PyrogramClient(BridgedClient):
|
|
|
301
302
|
raise ContinuePropagation()
|
|
302
303
|
|
|
303
304
|
async def get_call(
|
|
304
|
-
|
|
305
|
-
|
|
305
|
+
self,
|
|
306
|
+
chat_id: int,
|
|
306
307
|
) -> Optional[InputGroupCall]:
|
|
307
308
|
chat = await self._app.resolve_peer(chat_id)
|
|
308
309
|
if isinstance(chat, InputPeerChannel):
|
|
@@ -347,16 +348,16 @@ class PyrogramClient(BridgedClient):
|
|
|
347
348
|
)
|
|
348
349
|
|
|
349
350
|
async def get_group_call_participants(
|
|
350
|
-
|
|
351
|
-
|
|
351
|
+
self,
|
|
352
|
+
chat_id: int,
|
|
352
353
|
):
|
|
353
354
|
return await self._cache.get_participant_list(
|
|
354
355
|
chat_id,
|
|
355
356
|
)
|
|
356
357
|
|
|
357
358
|
async def get_participants(
|
|
358
|
-
|
|
359
|
-
|
|
359
|
+
self,
|
|
360
|
+
input_call: InputGroupCall,
|
|
360
361
|
) -> List[GroupCallParticipant]:
|
|
361
362
|
return [
|
|
362
363
|
self.parse_participant(participant)
|
|
@@ -374,12 +375,12 @@ class PyrogramClient(BridgedClient):
|
|
|
374
375
|
]
|
|
375
376
|
|
|
376
377
|
async def join_group_call(
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
378
|
+
self,
|
|
379
|
+
chat_id: int,
|
|
380
|
+
json_join: str,
|
|
381
|
+
invite_hash: str,
|
|
382
|
+
have_video: bool,
|
|
383
|
+
join_as: InputPeer,
|
|
383
384
|
) -> str:
|
|
384
385
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
385
386
|
if chat_call is not None:
|
|
@@ -414,7 +415,6 @@ class PyrogramClient(BridgedClient):
|
|
|
414
415
|
user_id: int,
|
|
415
416
|
g_a_hash: bytes,
|
|
416
417
|
protocol: Protocol,
|
|
417
|
-
video: bool,
|
|
418
418
|
):
|
|
419
419
|
await self._app.invoke(
|
|
420
420
|
RequestCall(
|
|
@@ -422,7 +422,7 @@ class PyrogramClient(BridgedClient):
|
|
|
422
422
|
random_id=self.rnd_id(),
|
|
423
423
|
g_a_hash=g_a_hash,
|
|
424
424
|
protocol=self.parse_protocol(protocol),
|
|
425
|
-
video=
|
|
425
|
+
video=False,
|
|
426
426
|
),
|
|
427
427
|
)
|
|
428
428
|
|
|
@@ -520,9 +520,12 @@ class PyrogramClient(BridgedClient):
|
|
|
520
520
|
self,
|
|
521
521
|
chat_id: int,
|
|
522
522
|
):
|
|
523
|
+
peer = self._cache.get_phone_call(chat_id)
|
|
524
|
+
if peer is None:
|
|
525
|
+
return
|
|
523
526
|
await self._app.invoke(
|
|
524
527
|
DiscardCall(
|
|
525
|
-
peer=
|
|
528
|
+
peer=peer,
|
|
526
529
|
duration=0,
|
|
527
530
|
reason=PhoneCallDiscardReasonHangup(),
|
|
528
531
|
connection_id=0,
|
|
@@ -532,10 +535,10 @@ class PyrogramClient(BridgedClient):
|
|
|
532
535
|
self._cache.drop_phone_call(chat_id)
|
|
533
536
|
|
|
534
537
|
async def change_volume(
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
538
|
+
self,
|
|
539
|
+
chat_id: int,
|
|
540
|
+
volume: int,
|
|
541
|
+
participant: InputPeer,
|
|
539
542
|
):
|
|
540
543
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
541
544
|
if chat_call is not None:
|
|
@@ -549,12 +552,12 @@ class PyrogramClient(BridgedClient):
|
|
|
549
552
|
)
|
|
550
553
|
|
|
551
554
|
async def set_call_status(
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
555
|
+
self,
|
|
556
|
+
chat_id: int,
|
|
557
|
+
muted_status: Optional[bool],
|
|
558
|
+
paused_status: Optional[bool],
|
|
559
|
+
stopped_status: Optional[bool],
|
|
560
|
+
participant: InputPeer,
|
|
558
561
|
):
|
|
559
562
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
560
563
|
if chat_call is not None:
|
|
@@ -39,6 +39,7 @@ from telethon.tl.types import PhoneCallDiscarded
|
|
|
39
39
|
from telethon.tl.types import PhoneCallDiscardReasonHangup
|
|
40
40
|
from telethon.tl.types import PhoneCallProtocol
|
|
41
41
|
from telethon.tl.types import PhoneCallRequested
|
|
42
|
+
from telethon.tl.types import PhoneCallWaiting
|
|
42
43
|
from telethon.tl.types import TypeInputChannel
|
|
43
44
|
from telethon.tl.types import TypeInputPeer
|
|
44
45
|
from telethon.tl.types import TypeInputUser
|
|
@@ -95,7 +96,7 @@ class TelethonClient(BridgedClient):
|
|
|
95
96
|
):
|
|
96
97
|
if isinstance(
|
|
97
98
|
update.phone_call,
|
|
98
|
-
(PhoneCallAccepted, PhoneCallRequested),
|
|
99
|
+
(PhoneCallAccepted, PhoneCallRequested, PhoneCallWaiting),
|
|
99
100
|
):
|
|
100
101
|
self._cache.set_phone_call(
|
|
101
102
|
self.user_from_call(update.phone_call),
|
|
@@ -383,7 +384,6 @@ class TelethonClient(BridgedClient):
|
|
|
383
384
|
user_id: int,
|
|
384
385
|
g_a_hash: bytes,
|
|
385
386
|
protocol: Protocol,
|
|
386
|
-
video: bool,
|
|
387
387
|
):
|
|
388
388
|
return await self._app(
|
|
389
389
|
RequestCallRequest(
|
|
@@ -391,7 +391,7 @@ class TelethonClient(BridgedClient):
|
|
|
391
391
|
random_id=self.rnd_id(),
|
|
392
392
|
g_a_hash=g_a_hash,
|
|
393
393
|
protocol=self.parse_protocol(protocol),
|
|
394
|
-
video=
|
|
394
|
+
video=False,
|
|
395
395
|
),
|
|
396
396
|
)
|
|
397
397
|
|
|
@@ -489,9 +489,12 @@ class TelethonClient(BridgedClient):
|
|
|
489
489
|
self,
|
|
490
490
|
chat_id: int,
|
|
491
491
|
):
|
|
492
|
+
peer = self._cache.get_phone_call(chat_id)
|
|
493
|
+
if peer is None:
|
|
494
|
+
return
|
|
492
495
|
await self._app(
|
|
493
496
|
DiscardCallRequest(
|
|
494
|
-
peer=
|
|
497
|
+
peer=peer,
|
|
495
498
|
duration=0,
|
|
496
499
|
reason=PhoneCallDiscardReasonHangup(),
|
|
497
500
|
connection_id=0,
|
pytgcalls/pytgcalls.py
CHANGED
|
@@ -2,7 +2,6 @@ import asyncio
|
|
|
2
2
|
import os
|
|
3
3
|
from concurrent.futures import ThreadPoolExecutor
|
|
4
4
|
from typing import Any
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
from ntgcalls import NTgCalls
|
|
8
7
|
|
|
@@ -24,8 +23,6 @@ class PyTgCalls(Methods, Scaffold):
|
|
|
24
23
|
app: Any,
|
|
25
24
|
workers: int = WORKERS,
|
|
26
25
|
cache_duration: int = CACHE_DURATION,
|
|
27
|
-
ntg_logs_path: Optional[str] = None,
|
|
28
|
-
allow_rtc_logs: bool = False,
|
|
29
26
|
):
|
|
30
27
|
super().__init__()
|
|
31
28
|
self._mtproto = app
|
|
@@ -41,7 +38,7 @@ class PyTgCalls(Methods, Scaffold):
|
|
|
41
38
|
self._app.package_name,
|
|
42
39
|
)
|
|
43
40
|
self._cache_user_peer = Cache()
|
|
44
|
-
self._binding = NTgCalls(
|
|
41
|
+
self._binding = NTgCalls()
|
|
45
42
|
self.loop = asyncio.get_event_loop()
|
|
46
43
|
self.workers = workers
|
|
47
44
|
self.executor = ThreadPoolExecutor(
|
pytgcalls/scaffold.py
CHANGED
|
@@ -240,7 +240,7 @@ class MediaStream(Stream):
|
|
|
240
240
|
|
|
241
241
|
@staticmethod
|
|
242
242
|
def _flags(flags: Flags) -> InputMode:
|
|
243
|
-
new_flags = InputMode.
|
|
243
|
+
new_flags = InputMode.SHELL
|
|
244
244
|
if flags & MediaStream.Flags.NO_LATENCY:
|
|
245
|
-
new_flags |= InputMode.
|
|
245
|
+
new_flags |= InputMode.NO_LATENCY
|
|
246
246
|
return new_flags
|
|
File without changes
|
|
File without changes
|
|
File without changes
|