pyrobale 0.3.8__py3-none-any.whl → 0.3.9__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.
- pyrobale/client/__init__.py +125 -3
- pyrobale/objects/chat.py +11 -0
- pyrobale/objects/peerdata.py +25 -0
- {pyrobale-0.3.8.dist-info → pyrobale-0.3.9.dist-info}/METADATA +3 -2
- {pyrobale-0.3.8.dist-info → pyrobale-0.3.9.dist-info}/RECORD +7 -6
- {pyrobale-0.3.8.dist-info → pyrobale-0.3.9.dist-info}/WHEEL +0 -0
- {pyrobale-0.3.8.dist-info → pyrobale-0.3.9.dist-info}/licenses/LICENSE +0 -0
pyrobale/client/__init__.py
CHANGED
@@ -37,13 +37,16 @@ from ..objects.voice import Voice
|
|
37
37
|
from ..objects.webappdata import WebAppData
|
38
38
|
from ..objects.webappinfo import WebAppInfo
|
39
39
|
from ..objects.utils import *
|
40
|
-
import asyncio
|
41
|
-
from enum import Enum
|
42
40
|
from ..objects.enums import UpdatesTypes, ChatAction, ChatType
|
41
|
+
from ..objects.peerdata import PeerData
|
43
42
|
from ..filters import Filters, equals
|
44
43
|
from ..StateMachine import StateMachine
|
45
44
|
from ..exceptions import NotFoundException, InvalidTokenException, PyroBaleException
|
46
45
|
|
46
|
+
from enum import Enum
|
47
|
+
import asyncio
|
48
|
+
from bs4 import BeautifulSoup
|
49
|
+
from json import loads, JSONDecodeError
|
47
50
|
|
48
51
|
class Client:
|
49
52
|
"""A client for interacting with the Bale messenger API.
|
@@ -64,6 +67,9 @@ class Client:
|
|
64
67
|
self.last_update_id = 0
|
65
68
|
self.state_machine = StateMachine()
|
66
69
|
|
70
|
+
self.check_defined_message = True
|
71
|
+
self.defined_messages = {}
|
72
|
+
|
67
73
|
async def get_updates(
|
68
74
|
self,
|
69
75
|
offset: Optional[int] = None,
|
@@ -695,6 +701,22 @@ class Client:
|
|
695
701
|
self.requests_base + "/leaveChat", data={"chat_id": chat_id}
|
696
702
|
)
|
697
703
|
return data.get("ok", False)
|
704
|
+
|
705
|
+
async def is_joined(self, user_id: int, chat_id: int) -> bool:
|
706
|
+
"""Check if a user is joined to a chat.
|
707
|
+
|
708
|
+
Args:
|
709
|
+
user_id (int): Unique identifier for the target chat
|
710
|
+
chat_id (int): Unique identifier for the target chat
|
711
|
+
|
712
|
+
Returns:
|
713
|
+
bool: True if the user is joined to the chat, False otherwise
|
714
|
+
"""
|
715
|
+
data = await make_post(
|
716
|
+
self.requests_base + "/getChatMember",
|
717
|
+
data={"chat_id": chat_id, "user_id": user_id},
|
718
|
+
)
|
719
|
+
return data.get("result", {}).get("status") in ["member", "creator", "administrator"]
|
698
720
|
|
699
721
|
async def get_chat(self, chat_id: int) -> Chat:
|
700
722
|
"""Get up to date information about the chat.
|
@@ -709,7 +731,100 @@ class Client:
|
|
709
731
|
self.requests_base + "/getChat", data={"chat_id": chat_id}
|
710
732
|
)
|
711
733
|
return Chat(**pythonize(data["result"]))
|
712
|
-
|
734
|
+
|
735
|
+
@staticmethod
|
736
|
+
async def get_ble_ir_page(username_or_phone_number: str) -> Union[dict, PeerData]:
|
737
|
+
"""Get BleIR user/group information.
|
738
|
+
|
739
|
+
Args:
|
740
|
+
username_or_phone_number (str): Username or phone number
|
741
|
+
|
742
|
+
Returns:
|
743
|
+
Union[dict, PeerData]: User/group information or error dict
|
744
|
+
"""
|
745
|
+
url = f"https://ble.ir/{username_or_phone_number}"
|
746
|
+
|
747
|
+
async with aiohttp.ClientSession() as session:
|
748
|
+
async with session.get(url) as response:
|
749
|
+
req = await response.text()
|
750
|
+
|
751
|
+
if """<p class="__404_title__lxIKL">گفتگوی مورد نظر وجود ندارد.</p>""" in req:
|
752
|
+
return PeerData(
|
753
|
+
is_ok=False,
|
754
|
+
avatar=None,
|
755
|
+
description=None,
|
756
|
+
name=None,
|
757
|
+
is_bot=None,
|
758
|
+
is_verified=None,
|
759
|
+
is_private=None,
|
760
|
+
members=None,
|
761
|
+
last_message=None,
|
762
|
+
user_id=None,
|
763
|
+
username=None,
|
764
|
+
)
|
765
|
+
|
766
|
+
soup = BeautifulSoup(req, "html.parser")
|
767
|
+
json_data = {}
|
768
|
+
|
769
|
+
try:
|
770
|
+
json_script = soup.find("script", id="__NEXT_DATA__").text
|
771
|
+
json_data = loads(json_script)
|
772
|
+
page_props = json_data.get("props", {}).get("pageProps", {})
|
773
|
+
user_data = page_props.get("user", {})
|
774
|
+
group_data = page_props.get("group", {})
|
775
|
+
messages = page_props.get("messages", [])
|
776
|
+
except (AttributeError, KeyError, JSONDecodeError):
|
777
|
+
pass
|
778
|
+
|
779
|
+
try:
|
780
|
+
avatar = soup.find("img", class_="Avatar_img___C2_3")["src"]
|
781
|
+
except (AttributeError, KeyError):
|
782
|
+
avatar = None
|
783
|
+
|
784
|
+
try:
|
785
|
+
description = soup.find("div", class_="Profile_description__YTAr_").text
|
786
|
+
except AttributeError:
|
787
|
+
description = None
|
788
|
+
|
789
|
+
try:
|
790
|
+
name = soup.find("h1", class_="Profile_name__pQglx").text
|
791
|
+
except AttributeError:
|
792
|
+
name = None
|
793
|
+
|
794
|
+
is_bot = user_data.get("isBot", False)
|
795
|
+
is_verified = user_data.get("isVerified", group_data.get("isVerified", False))
|
796
|
+
is_private = user_data.get("isPrivate", group_data.get("isPrivate", False))
|
797
|
+
members = group_data.get("members")
|
798
|
+
username = user_data.get("nick")
|
799
|
+
user_id = page_props.get("peer", {}).get("id")
|
800
|
+
|
801
|
+
last_message = None
|
802
|
+
if messages:
|
803
|
+
try:
|
804
|
+
last_msg = messages[-1]["message"]
|
805
|
+
last_message = (
|
806
|
+
last_msg.get("documentMessage", {}).get("caption", {}).get("text")
|
807
|
+
or last_msg.get("textMessage", {}).get("text")
|
808
|
+
)
|
809
|
+
if last_message:
|
810
|
+
last_message = last_message.replace("‌", "")
|
811
|
+
except (KeyError, IndexError):
|
812
|
+
pass
|
813
|
+
|
814
|
+
return PeerData(
|
815
|
+
True,
|
816
|
+
avatar,
|
817
|
+
description,
|
818
|
+
name,
|
819
|
+
is_bot,
|
820
|
+
is_verified,
|
821
|
+
is_private,
|
822
|
+
members,
|
823
|
+
last_message,
|
824
|
+
user_id,
|
825
|
+
username
|
826
|
+
)
|
827
|
+
|
713
828
|
async def get_chat_members_count(self, chat_id: int) -> int:
|
714
829
|
"""Get the number of members in a chat.
|
715
830
|
|
@@ -925,6 +1040,11 @@ class Client:
|
|
925
1040
|
if update_id:
|
926
1041
|
self.last_update_id = update_id + 1
|
927
1042
|
|
1043
|
+
if self.check_defined_message:
|
1044
|
+
update_raw = update['message']
|
1045
|
+
if update_raw.get("text") in self.defined_messages.keys():
|
1046
|
+
await self.send_message(update_raw.get('chat').get('id'), self.defined_messages.get(update_raw.get("text")), update.get('message_id'))
|
1047
|
+
|
928
1048
|
for waiter in list(self._waiters):
|
929
1049
|
w_type, check, future = waiter
|
930
1050
|
if w_type.value in update:
|
@@ -940,6 +1060,8 @@ class Client:
|
|
940
1060
|
update_type = handler["type"].value
|
941
1061
|
if update_type in update:
|
942
1062
|
raw_event = update[update_type]
|
1063
|
+
|
1064
|
+
|
943
1065
|
event = self._convert_event(handler["type"], raw_event)
|
944
1066
|
|
945
1067
|
if handler["type"] == UpdatesTypes.COMMAND:
|
pyrobale/objects/chat.py
CHANGED
@@ -386,6 +386,17 @@ class Chat:
|
|
386
386
|
bool: True on success
|
387
387
|
"""
|
388
388
|
return await self.client.leave_chat(chat_id=self.id)
|
389
|
+
|
390
|
+
async def is_joined(self, user_id: int) -> bool:
|
391
|
+
"""Check if a user is joined to the chat.
|
392
|
+
|
393
|
+
Parameters:
|
394
|
+
user_id (int): Unique identifier of the target user
|
395
|
+
|
396
|
+
Returns:
|
397
|
+
bool: True if the user is joined to the chat, False otherwise
|
398
|
+
"""
|
399
|
+
return await self.client.is_joined(user_id, self.id)
|
389
400
|
|
390
401
|
async def pin(self, message_id: int) -> bool:
|
391
402
|
"""Pin a message in the chat.
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class PeerData:
|
2
|
+
"""A class to parse data received from ble.ir pages."""
|
3
|
+
def __init__(self,
|
4
|
+
is_ok: bool,
|
5
|
+
avatar: str,
|
6
|
+
description: str,
|
7
|
+
name: str,
|
8
|
+
is_bot: bool,
|
9
|
+
is_verified: bool,
|
10
|
+
is_private: bool,
|
11
|
+
members: int,
|
12
|
+
last_message: str,
|
13
|
+
user_id: int,
|
14
|
+
username: str):
|
15
|
+
self.is_ok = is_ok
|
16
|
+
self.avatar = avatar
|
17
|
+
self.description = description
|
18
|
+
self.name = name
|
19
|
+
self.is_bot = is_bot
|
20
|
+
self.is_verified = is_verified
|
21
|
+
self.is_private = is_private
|
22
|
+
self.members = members
|
23
|
+
self.last_message = last_message
|
24
|
+
self.user_id = user_id
|
25
|
+
self.username = username
|
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pyrobale
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.9
|
4
4
|
Summary: A python wrapper for bale api
|
5
5
|
Project-URL: github, https://github.com/pyrobale/pyrobale
|
6
6
|
Project-URL: website, https://pyrobale.github.io
|
7
|
-
Author-email: Ali Safamanesh <
|
7
|
+
Author-email: Ali Safamanesh <daradege@proton.me>, Aydin Rahbaran <codewizaard9@gmail.com>
|
8
8
|
License: MIT License
|
9
9
|
|
10
10
|
Copyright (c) 2025 PyroBale Team
|
@@ -32,6 +32,7 @@ Classifier: Operating System :: OS Independent
|
|
32
32
|
Classifier: Programming Language :: Python :: 3
|
33
33
|
Requires-Python: >=3.9
|
34
34
|
Requires-Dist: aiohttp
|
35
|
+
Requires-Dist: beautifulsoup4
|
35
36
|
Description-Content-Type: text/markdown
|
36
37
|
|
37
38
|

|
@@ -1,6 +1,6 @@
|
|
1
1
|
pyrobale/__init__.py,sha256=tC4gr6RIg4tYdzoBDFQCU2CDigXytc-MQ7yH6BJzTzM,3651
|
2
2
|
pyrobale/StateMachine/__init__.py,sha256=TRCBwcr4UlnpU2Olik0vOtNASUOK7_O6RMAG6RrVYlM,1911
|
3
|
-
pyrobale/client/__init__.py,sha256=
|
3
|
+
pyrobale/client/__init__.py,sha256=y_S4MU8nHZ6k77OYR8_ONmscm0EvlvaCpgCWR3ic5wQ,49921
|
4
4
|
pyrobale/exceptions/__init__.py,sha256=oa412OuokRm9Vf3XlCJLqpZjz9ZcuxAKxnEBvOK7u2M,21
|
5
5
|
pyrobale/exceptions/common.py,sha256=6ubWjGNmbRbNuzM_ohPuLvGhLdCiCZ-RscEERnv3JMA,273
|
6
6
|
pyrobale/filters/__init__.py,sha256=Q-VFK1U5W9jMWneAqNLNlYSTZI2gjnAkwA-lcqF9GbU,55
|
@@ -10,7 +10,7 @@ pyrobale/objects/__init__.py,sha256=uy0xBJc5d-1TnlPD6CgxAaUjBnIvQs-GuAgLeEKoXSQ,
|
|
10
10
|
pyrobale/objects/animation.py,sha256=jpM9V8AOaGLWkcENTDmsxKf57Abf-MArYBLfU6GwkD0,978
|
11
11
|
pyrobale/objects/audio.py,sha256=q14wz5WpC3SgKZkAlH-D9M554RYQNDwuCT2z7v7IZYU,696
|
12
12
|
pyrobale/objects/callbackquery.py,sha256=jALmTVXU6tc6OppTTrhGERCzugzazYrT39AhhGE-UeI,1018
|
13
|
-
pyrobale/objects/chat.py,sha256=
|
13
|
+
pyrobale/objects/chat.py,sha256=w9_RyluyavgqLET5buArZWOPjKUNhj1RaINQyNhbY-A,16940
|
14
14
|
pyrobale/objects/chatmember.py,sha256=IyAGmuZZ5HlJVYjrfXEKbLoNc7etMytrK-gOeKKo0CU,6895
|
15
15
|
pyrobale/objects/chatphoto.py,sha256=vOb5xzpr3oBiCloi2_ufBnVlUfmcPqSTmMMMTTBYdJo,533
|
16
16
|
pyrobale/objects/contact.py,sha256=6LDxT5RoGbY5Tsw64lg5-jvKSRmmvOiIJha1HqdTaG4,411
|
@@ -28,6 +28,7 @@ pyrobale/objects/labeledprice.py,sha256=d-fbOLzpkBslfor13BXGeVoySKCcSxsXY4QVwub2
|
|
28
28
|
pyrobale/objects/location.py,sha256=w_9sRJRntLpNbn8Jk6JhRJVVigD9Bd4BxbjFyglxWhU,143
|
29
29
|
pyrobale/objects/message.py,sha256=cCe0qU0ClGc66S7tW6TexnDzqyAafeKgN_h0h8UZMfs,14532
|
30
30
|
pyrobale/objects/messageid.py,sha256=DrWKV8y9m9H8G_Fj68KgiJKwDJOGduNJGJ-Dyn8N580,95
|
31
|
+
pyrobale/objects/peerdata.py,sha256=-_uBrv1saKkwb_yyEf3FwpYsT5LLMHFcuETO8SCf_YA,815
|
31
32
|
pyrobale/objects/photosize.py,sha256=I4hnmi46uoU-cW7hPN_tTT9kn0u80BtG5QJ3uRjoUiE,298
|
32
33
|
pyrobale/objects/precheckoutquery.py,sha256=Rtjh1qqRc9TRZMJU1W5r0B8y7K5dayLMXX6WH9h1Ul4,470
|
33
34
|
pyrobale/objects/replykeyboardmarkup.py,sha256=3dBiOs29q54tf281qKYcoO1Yjvn63WZfdkrbIoDUfck,1645
|
@@ -41,7 +42,7 @@ pyrobale/objects/video.py,sha256=DuZMGHio_w8yQvi87Vc3XpJOpEaltkM4_bNRSeocPZo,509
|
|
41
42
|
pyrobale/objects/voice.py,sha256=ZdsJFH2IsBwelEk4rb4oZfX9xrfJ2_DgfjsMc0e4Tmg,148
|
42
43
|
pyrobale/objects/webappdata.py,sha256=QlZlCa8Mylt8VmcdgdoHeyita5CVnz2WsT1yueEY1tY,78
|
43
44
|
pyrobale/objects/webappinfo.py,sha256=qnTvfNqx91Yzbc1gO5y4XQ3w6g0RpMUqMuF5wk_EZMc,75
|
44
|
-
pyrobale-0.3.
|
45
|
-
pyrobale-0.3.
|
46
|
-
pyrobale-0.3.
|
47
|
-
pyrobale-0.3.
|
45
|
+
pyrobale-0.3.9.dist-info/METADATA,sha256=pjpHk7TtpgPg_hFCi7t7KOWG5oyvTiCyfqu4eCJZbyM,5290
|
46
|
+
pyrobale-0.3.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
47
|
+
pyrobale-0.3.9.dist-info/licenses/LICENSE,sha256=rf_1ZkId-bcjw1kHBq6bV5t5TVob3RgjUyjfKr1CHAk,1070
|
48
|
+
pyrobale-0.3.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|