py-tgcalls 2.1.2b2__py3-none-any.whl → 2.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/METADATA +2 -2
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/RECORD +32 -31
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/WHEEL +1 -1
- pytgcalls/__version__.py +1 -1
- pytgcalls/ffmpeg.py +2 -2
- pytgcalls/filters.py +6 -2
- pytgcalls/list_to_cmd.py +11 -0
- pytgcalls/methods/calls/leave_call.py +4 -0
- pytgcalls/methods/internal/connect_call.py +10 -1
- pytgcalls/methods/internal/handle_mtproto_updates.py +8 -15
- pytgcalls/methods/stream/play.py +2 -1
- pytgcalls/mtproto/bridged_client.py +64 -2
- pytgcalls/mtproto/client_cache.py +65 -72
- pytgcalls/mtproto/hydrogram_client.py +132 -35
- pytgcalls/mtproto/mtproto_client.py +11 -0
- pytgcalls/mtproto/pyrogram_client.py +135 -43
- pytgcalls/mtproto/telethon_client.py +95 -35
- pytgcalls/mutex.py +3 -1
- pytgcalls/types/cache.py +10 -5
- pytgcalls/types/chats/group_call_participant.py +1 -8
- pytgcalls/types/chats/updated_group_call_participant.py +2 -0
- pytgcalls/types/dict.py +1 -1
- pytgcalls/types/flag.py +4 -3
- pytgcalls/types/list.py +1 -1
- pytgcalls/types/participant_list.py +3 -3
- pytgcalls/types/py_object.py +4 -2
- pytgcalls/types/stream/media_stream.py +5 -4
- pytgcalls/types/stream/record_stream.py +3 -1
- pytgcalls/types/stream/video_quality.py +3 -1
- pytgcalls/ytdlp.py +3 -2
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {py_tgcalls-2.1.2b2.dist-info → py_tgcalls-2.2.0.dist-info}/top_level.txt +0 -0
|
@@ -4,14 +4,18 @@ from typing import List
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
from typing import Union
|
|
6
6
|
|
|
7
|
-
import pyrogram
|
|
8
7
|
from ntgcalls import MediaSegmentQuality
|
|
9
8
|
from ntgcalls import Protocol
|
|
10
9
|
from pyrogram import Client
|
|
11
10
|
from pyrogram import ContinuePropagation
|
|
11
|
+
from pyrogram.errors import AuthBytesInvalid
|
|
12
|
+
from pyrogram.errors import BadRequest
|
|
13
|
+
from pyrogram.errors import FileMigrate
|
|
12
14
|
from pyrogram.errors import FloodWait
|
|
13
15
|
from pyrogram.raw.base import InputPeer
|
|
14
16
|
from pyrogram.raw.base import InputUser
|
|
17
|
+
from pyrogram.raw.functions.auth import ExportAuthorization
|
|
18
|
+
from pyrogram.raw.functions.auth import ImportAuthorization
|
|
15
19
|
from pyrogram.raw.functions.channels import GetFullChannel
|
|
16
20
|
from pyrogram.raw.functions.messages import GetDhConfig
|
|
17
21
|
from pyrogram.raw.functions.messages import GetFullChat
|
|
@@ -19,6 +23,7 @@ from pyrogram.raw.functions.phone import AcceptCall
|
|
|
19
23
|
from pyrogram.raw.functions.phone import ConfirmCall
|
|
20
24
|
from pyrogram.raw.functions.phone import CreateGroupCall
|
|
21
25
|
from pyrogram.raw.functions.phone import DiscardCall
|
|
26
|
+
from pyrogram.raw.functions.phone import DiscardGroupCall
|
|
22
27
|
from pyrogram.raw.functions.phone import EditGroupCallParticipant
|
|
23
28
|
from pyrogram.raw.functions.phone import GetGroupCall
|
|
24
29
|
from pyrogram.raw.functions.phone import GetGroupCallStreamChannels
|
|
@@ -65,13 +70,13 @@ from pyrogram.raw.types import UpdatePhoneCall
|
|
|
65
70
|
from pyrogram.raw.types import UpdatePhoneCallSignalingData
|
|
66
71
|
from pyrogram.raw.types import Updates
|
|
67
72
|
from pyrogram.raw.types.messages import DhConfig
|
|
73
|
+
from pyrogram.session import Auth
|
|
74
|
+
from pyrogram.session import Session
|
|
68
75
|
|
|
69
76
|
from ..types import CallProtocol
|
|
70
77
|
from ..types import ChatUpdate
|
|
71
78
|
from ..types import GroupCallParticipant
|
|
72
79
|
from ..types import RawCallUpdate
|
|
73
|
-
from ..types import UpdatedGroupCallParticipant
|
|
74
|
-
from ..version_manager import VersionManager
|
|
75
80
|
from .bridged_client import BridgedClient
|
|
76
81
|
from .client_cache import ClientCache
|
|
77
82
|
|
|
@@ -84,18 +89,12 @@ class PyrogramClient(BridgedClient):
|
|
|
84
89
|
):
|
|
85
90
|
super().__init__()
|
|
86
91
|
self._app: Client = client
|
|
87
|
-
if VersionManager.version_tuple(
|
|
88
|
-
pyrogram.__version__,
|
|
89
|
-
) > VersionManager.version_tuple(
|
|
90
|
-
'2.0.0',
|
|
91
|
-
):
|
|
92
|
-
self._app.send = self._app.invoke
|
|
93
92
|
self._cache: ClientCache = ClientCache(
|
|
94
93
|
cache_duration,
|
|
95
94
|
self,
|
|
96
95
|
)
|
|
97
96
|
|
|
98
|
-
@self._app.on_raw_update(group=-
|
|
97
|
+
@self._app.on_raw_update(group=-9999)
|
|
99
98
|
async def on_update(_, update, __, chats):
|
|
100
99
|
if isinstance(
|
|
101
100
|
update,
|
|
@@ -187,19 +186,23 @@ class PyrogramClient(BridgedClient):
|
|
|
187
186
|
update,
|
|
188
187
|
UpdateGroupCallParticipants,
|
|
189
188
|
):
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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,
|
|
195
195
|
)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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,
|
|
202
202
|
)
|
|
203
|
+
if result is not None:
|
|
204
|
+
await self._propagate(p_update)
|
|
205
|
+
|
|
203
206
|
if isinstance(
|
|
204
207
|
update,
|
|
205
208
|
UpdateGroupCall,
|
|
@@ -325,7 +328,7 @@ class PyrogramClient(BridgedClient):
|
|
|
325
328
|
chat = await self._app.resolve_peer(chat_id)
|
|
326
329
|
if isinstance(chat, InputPeerChannel):
|
|
327
330
|
input_call = (
|
|
328
|
-
await self.
|
|
331
|
+
await self._invoke(
|
|
329
332
|
GetFullChannel(
|
|
330
333
|
channel=InputChannel(
|
|
331
334
|
channel_id=chat.channel_id,
|
|
@@ -336,14 +339,14 @@ class PyrogramClient(BridgedClient):
|
|
|
336
339
|
).full_chat.call
|
|
337
340
|
else:
|
|
338
341
|
input_call = (
|
|
339
|
-
await self.
|
|
342
|
+
await self._invoke(
|
|
340
343
|
GetFullChat(chat_id=chat.chat_id),
|
|
341
344
|
)
|
|
342
345
|
).full_chat.call
|
|
343
346
|
|
|
344
347
|
if input_call is not None:
|
|
345
348
|
raw_call = (
|
|
346
|
-
await self.
|
|
349
|
+
await self._invoke(
|
|
347
350
|
GetGroupCall(
|
|
348
351
|
call=input_call,
|
|
349
352
|
limit=-1,
|
|
@@ -353,9 +356,10 @@ class PyrogramClient(BridgedClient):
|
|
|
353
356
|
call: GroupCall = raw_call.call
|
|
354
357
|
participants: List[GroupCallParticipant] = raw_call.participants
|
|
355
358
|
for participant in participants:
|
|
356
|
-
self._cache.
|
|
359
|
+
self._cache.set_participants_cache(
|
|
357
360
|
chat_id,
|
|
358
361
|
call.id,
|
|
362
|
+
self.parse_participant_action(participant),
|
|
359
363
|
self.parse_participant(participant),
|
|
360
364
|
)
|
|
361
365
|
if call.schedule_date is not None:
|
|
@@ -364,7 +368,7 @@ class PyrogramClient(BridgedClient):
|
|
|
364
368
|
return input_call
|
|
365
369
|
|
|
366
370
|
async def get_dhc(self) -> DhConfig:
|
|
367
|
-
return await self.
|
|
371
|
+
return await self._invoke(
|
|
368
372
|
GetDhConfig(
|
|
369
373
|
version=0,
|
|
370
374
|
random_length=256,
|
|
@@ -386,7 +390,7 @@ class PyrogramClient(BridgedClient):
|
|
|
386
390
|
participants = []
|
|
387
391
|
next_offset = ''
|
|
388
392
|
while True:
|
|
389
|
-
result = await self.
|
|
393
|
+
result = await self._invoke(
|
|
390
394
|
GetGroupParticipants(
|
|
391
395
|
call=input_call,
|
|
392
396
|
ids=[],
|
|
@@ -413,7 +417,7 @@ class PyrogramClient(BridgedClient):
|
|
|
413
417
|
) -> str:
|
|
414
418
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
415
419
|
if chat_call is not None:
|
|
416
|
-
result: Updates = await self.
|
|
420
|
+
result: Updates = await self._invoke(
|
|
417
421
|
JoinGroupCall(
|
|
418
422
|
call=chat_call,
|
|
419
423
|
params=DataJSON(data=json_join),
|
|
@@ -430,8 +434,10 @@ class PyrogramClient(BridgedClient):
|
|
|
430
434
|
):
|
|
431
435
|
participants = update.participants
|
|
432
436
|
for participant in participants:
|
|
433
|
-
self._cache.
|
|
437
|
+
self._cache.set_participants_cache(
|
|
438
|
+
chat_id,
|
|
434
439
|
update.call.id,
|
|
440
|
+
self.parse_participant_action(participant),
|
|
435
441
|
self.parse_participant(participant),
|
|
436
442
|
)
|
|
437
443
|
if isinstance(update, UpdateGroupCallConnection):
|
|
@@ -446,7 +452,7 @@ class PyrogramClient(BridgedClient):
|
|
|
446
452
|
):
|
|
447
453
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
448
454
|
if chat_call is not None:
|
|
449
|
-
result: Updates = await self.
|
|
455
|
+
result: Updates = await self._invoke(
|
|
450
456
|
JoinGroupCallPresentation(
|
|
451
457
|
call=chat_call,
|
|
452
458
|
params=DataJSON(data=json_join),
|
|
@@ -464,7 +470,7 @@ class PyrogramClient(BridgedClient):
|
|
|
464
470
|
):
|
|
465
471
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
466
472
|
if chat_call is not None:
|
|
467
|
-
await self.
|
|
473
|
+
await self._invoke(
|
|
468
474
|
LeaveGroupCallPresentation(
|
|
469
475
|
call=chat_call,
|
|
470
476
|
),
|
|
@@ -477,7 +483,7 @@ class PyrogramClient(BridgedClient):
|
|
|
477
483
|
protocol: Protocol,
|
|
478
484
|
has_video: bool,
|
|
479
485
|
):
|
|
480
|
-
update = await self.
|
|
486
|
+
update = await self._invoke(
|
|
481
487
|
RequestCall(
|
|
482
488
|
user_id=await self.resolve_peer(user_id),
|
|
483
489
|
random_id=self.rnd_id(),
|
|
@@ -500,7 +506,7 @@ class PyrogramClient(BridgedClient):
|
|
|
500
506
|
g_b: bytes,
|
|
501
507
|
protocol: Protocol,
|
|
502
508
|
):
|
|
503
|
-
await self.
|
|
509
|
+
await self._invoke(
|
|
504
510
|
AcceptCall(
|
|
505
511
|
peer=self._cache.get_phone_call(user_id),
|
|
506
512
|
g_b=g_b,
|
|
@@ -516,7 +522,7 @@ class PyrogramClient(BridgedClient):
|
|
|
516
522
|
protocol: Protocol,
|
|
517
523
|
) -> CallProtocol:
|
|
518
524
|
res = (
|
|
519
|
-
await self.
|
|
525
|
+
await self._invoke(
|
|
520
526
|
ConfirmCall(
|
|
521
527
|
peer=self._cache.get_phone_call(user_id),
|
|
522
528
|
g_a=g_a,
|
|
@@ -536,7 +542,7 @@ class PyrogramClient(BridgedClient):
|
|
|
536
542
|
user_id: int,
|
|
537
543
|
data: bytes,
|
|
538
544
|
):
|
|
539
|
-
await self.
|
|
545
|
+
await self._invoke(
|
|
540
546
|
SendSignalingData(
|
|
541
547
|
peer=self._cache.get_phone_call(user_id),
|
|
542
548
|
data=data,
|
|
@@ -547,7 +553,7 @@ class PyrogramClient(BridgedClient):
|
|
|
547
553
|
self,
|
|
548
554
|
chat_id: int,
|
|
549
555
|
):
|
|
550
|
-
result: Updates = await self.
|
|
556
|
+
result: Updates = await self._invoke(
|
|
551
557
|
CreateGroupCall(
|
|
552
558
|
peer=await self.resolve_peer(chat_id),
|
|
553
559
|
random_id=self.rnd_id(),
|
|
@@ -577,13 +583,26 @@ class PyrogramClient(BridgedClient):
|
|
|
577
583
|
):
|
|
578
584
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
579
585
|
if chat_call is not None:
|
|
580
|
-
await self.
|
|
586
|
+
await self._invoke(
|
|
581
587
|
LeaveGroupCall(
|
|
582
588
|
call=chat_call,
|
|
583
589
|
source=0,
|
|
584
590
|
),
|
|
585
591
|
)
|
|
586
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
|
+
|
|
587
606
|
async def discard_call(
|
|
588
607
|
self,
|
|
589
608
|
chat_id: int,
|
|
@@ -597,7 +616,7 @@ class PyrogramClient(BridgedClient):
|
|
|
597
616
|
if is_missed
|
|
598
617
|
else PhoneCallDiscardReasonHangup()
|
|
599
618
|
)
|
|
600
|
-
await self.
|
|
619
|
+
await self._invoke(
|
|
601
620
|
DiscardCall(
|
|
602
621
|
peer=peer,
|
|
603
622
|
duration=0,
|
|
@@ -616,7 +635,7 @@ class PyrogramClient(BridgedClient):
|
|
|
616
635
|
):
|
|
617
636
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
618
637
|
if chat_call is not None:
|
|
619
|
-
await self.
|
|
638
|
+
await self._invoke(
|
|
620
639
|
EditGroupCallParticipant(
|
|
621
640
|
call=chat_call,
|
|
622
641
|
participant=participant,
|
|
@@ -637,7 +656,7 @@ class PyrogramClient(BridgedClient):
|
|
|
637
656
|
if chat_call is not None:
|
|
638
657
|
try:
|
|
639
658
|
return (
|
|
640
|
-
await self.
|
|
659
|
+
await self._invoke(
|
|
641
660
|
GetFile(
|
|
642
661
|
location=InputGroupCallStream(
|
|
643
662
|
call=chat_call,
|
|
@@ -651,6 +670,7 @@ class PyrogramClient(BridgedClient):
|
|
|
651
670
|
offset=0,
|
|
652
671
|
limit=limit,
|
|
653
672
|
),
|
|
673
|
+
chat_id=chat_id,
|
|
654
674
|
sleep_threshold=0,
|
|
655
675
|
)
|
|
656
676
|
).bytes
|
|
@@ -664,12 +684,12 @@ class PyrogramClient(BridgedClient):
|
|
|
664
684
|
):
|
|
665
685
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
666
686
|
if chat_call is not None:
|
|
667
|
-
# noinspection PyBroadException
|
|
668
687
|
channels = (
|
|
669
|
-
await self.
|
|
688
|
+
await self._invoke(
|
|
670
689
|
GetGroupCallStreamChannels(
|
|
671
690
|
call=chat_call,
|
|
672
691
|
),
|
|
692
|
+
chat_id=chat_id,
|
|
673
693
|
)
|
|
674
694
|
).channels
|
|
675
695
|
if len(channels) > 0:
|
|
@@ -688,7 +708,7 @@ class PyrogramClient(BridgedClient):
|
|
|
688
708
|
):
|
|
689
709
|
chat_call = await self._cache.get_full_chat(chat_id)
|
|
690
710
|
if chat_call is not None:
|
|
691
|
-
await self.
|
|
711
|
+
await self._invoke(
|
|
692
712
|
EditGroupCallParticipant(
|
|
693
713
|
call=chat_call,
|
|
694
714
|
participant=participant,
|
|
@@ -727,5 +747,77 @@ class PyrogramClient(BridgedClient):
|
|
|
727
747
|
def no_updates(self):
|
|
728
748
|
return self._app.no_updates
|
|
729
749
|
|
|
750
|
+
async def _invoke(
|
|
751
|
+
self,
|
|
752
|
+
request,
|
|
753
|
+
dc_id: Optional[int] = None,
|
|
754
|
+
chat_id: Optional[int] = None,
|
|
755
|
+
sleep_threshold: Optional[int] = None,
|
|
756
|
+
):
|
|
757
|
+
if chat_id is not None:
|
|
758
|
+
dc_id = self._cache.get_dc_call(chat_id)
|
|
759
|
+
if dc_id is None:
|
|
760
|
+
session = self._app
|
|
761
|
+
else:
|
|
762
|
+
session = self._app.media_sessions.get(dc_id)
|
|
763
|
+
if not session:
|
|
764
|
+
session = self._app.media_sessions[dc_id] = Session(
|
|
765
|
+
self._app,
|
|
766
|
+
dc_id,
|
|
767
|
+
await Auth(
|
|
768
|
+
self._app,
|
|
769
|
+
dc_id,
|
|
770
|
+
await self._app.storage.test_mode(),
|
|
771
|
+
).create()
|
|
772
|
+
if dc_id != await self._app.storage.dc_id()
|
|
773
|
+
else await self._app.storage.auth_key(),
|
|
774
|
+
await self._app.storage.test_mode(),
|
|
775
|
+
is_media=True,
|
|
776
|
+
)
|
|
777
|
+
await session.start()
|
|
778
|
+
if dc_id != await self._app.storage.dc_id():
|
|
779
|
+
for _ in range(3):
|
|
780
|
+
exported_auth = await self._invoke(
|
|
781
|
+
ExportAuthorization(
|
|
782
|
+
dc_id=dc_id,
|
|
783
|
+
),
|
|
784
|
+
)
|
|
785
|
+
|
|
786
|
+
try:
|
|
787
|
+
await session.invoke(
|
|
788
|
+
ImportAuthorization(
|
|
789
|
+
id=exported_auth.id,
|
|
790
|
+
bytes=exported_auth.bytes,
|
|
791
|
+
),
|
|
792
|
+
)
|
|
793
|
+
except AuthBytesInvalid:
|
|
794
|
+
continue
|
|
795
|
+
else:
|
|
796
|
+
break
|
|
797
|
+
else:
|
|
798
|
+
raise AuthBytesInvalid
|
|
799
|
+
try:
|
|
800
|
+
return await session.invoke(
|
|
801
|
+
request,
|
|
802
|
+
sleep_threshold=sleep_threshold,
|
|
803
|
+
)
|
|
804
|
+
except (BadRequest, FileMigrate) as e:
|
|
805
|
+
dc_new = BridgedClient.extract_dc(
|
|
806
|
+
str(e),
|
|
807
|
+
)
|
|
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
|
+
)
|
|
814
|
+
return await self._invoke(
|
|
815
|
+
request,
|
|
816
|
+
dc_new,
|
|
817
|
+
chat_id,
|
|
818
|
+
sleep_threshold,
|
|
819
|
+
)
|
|
820
|
+
raise
|
|
821
|
+
|
|
730
822
|
async def start(self):
|
|
731
823
|
await self._app.start()
|