pyrobale 0.2.9.2__tar.gz → 0.2.9.4.1__tar.gz
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-0.2.9.2 → pyrobale-0.2.9.4.1}/PKG-INFO +1 -1
- {pyrobale-0.2.9.2 → pyrobale-0.2.9.4.1}/pyproject.toml +1 -1
- {pyrobale-0.2.9.2 → pyrobale-0.2.9.4.1}/pyrobale.py +94 -5
- {pyrobale-0.2.9.2 → pyrobale-0.2.9.4.1}/LICENSE +0 -0
- {pyrobale-0.2.9.2 → pyrobale-0.2.9.4.1}/README.md +0 -0
- {pyrobale-0.2.9.2 → pyrobale-0.2.9.4.1}/pyrobale.png +0 -0
- {pyrobale-0.2.9.2 → pyrobale-0.2.9.4.1}/pyrobaletext.png +0 -0
@@ -26,8 +26,11 @@ from typing import Union, Optional, Dict, Any, List, Tuple, Callable
|
|
26
26
|
import sqlite3
|
27
27
|
import json
|
28
28
|
import traceback
|
29
|
+
import asyncio
|
30
|
+
import queue
|
31
|
+
|
32
|
+
__version__ = '0.2.9.4.1'
|
29
33
|
|
30
|
-
__version__ = '0.2.9.2'
|
31
34
|
|
32
35
|
class BaleException(Exception):
|
33
36
|
"""Base exception for Bale API errors"""
|
@@ -54,6 +57,8 @@ class BaleException(Exception):
|
|
54
57
|
class BaleAPIError(BaleException):
|
55
58
|
"""Exception raised when Bale API returns an error response"""
|
56
59
|
pass
|
60
|
+
|
61
|
+
|
57
62
|
class BaleNetworkError(BaleException):
|
58
63
|
"""Exception raised when network-related issues occur during API calls"""
|
59
64
|
pass
|
@@ -103,6 +108,7 @@ class BaleUnknownError(BaleException):
|
|
103
108
|
"""Exception raised for unexpected or unknown errors"""
|
104
109
|
pass
|
105
110
|
|
111
|
+
|
106
112
|
class ChatActions:
|
107
113
|
"""Represents different chat action states that can be sent to Bale"""
|
108
114
|
TYPING: str = 'typing'
|
@@ -110,6 +116,26 @@ class ChatActions:
|
|
110
116
|
VIDEO: str = 'record_video'
|
111
117
|
CHOOSE_STICKER: str = 'choose_sticker'
|
112
118
|
|
119
|
+
|
120
|
+
class Sticker:
|
121
|
+
def __init__(self, data: dict):
|
122
|
+
self.file_id = data.get('file_id')
|
123
|
+
self.file_unique_id = data.get('file_unique_id')
|
124
|
+
self.type = data.get('type')
|
125
|
+
self.width = data.get('width')
|
126
|
+
self.height = data.get('height')
|
127
|
+
self.file_size = data.get('file_size')
|
128
|
+
|
129
|
+
|
130
|
+
class StickerSet:
|
131
|
+
def __init__(self, data: dict):
|
132
|
+
self.name = data.get('name')
|
133
|
+
self.title = data.get('title')
|
134
|
+
self.stickers = [Sticker(sticker)
|
135
|
+
for sticker in data.get('stickers', [])]
|
136
|
+
self.thumbnail = data.get('thumbnail')
|
137
|
+
|
138
|
+
|
113
139
|
class DataBase:
|
114
140
|
|
115
141
|
"""
|
@@ -483,7 +509,7 @@ class Chat:
|
|
483
509
|
reply_to_message: Union[int,
|
484
510
|
str,
|
485
511
|
'Message'] = None,
|
486
|
-
reply_markup: Union['MenuKeyboardMarkup'
|
512
|
+
reply_markup: Union['MenuKeyboardMarkup', 'InlineKeyboardMarkup'] = None):
|
487
513
|
return self.client.send_invoice(
|
488
514
|
self.id,
|
489
515
|
title,
|
@@ -892,7 +918,7 @@ class User:
|
|
892
918
|
reply_to_message: Union[int,
|
893
919
|
str,
|
894
920
|
'Message'] = None,
|
895
|
-
reply_markup: Union['MenuKeyboardMarkup'
|
921
|
+
reply_markup: Union['MenuKeyboardMarkup', 'InlineKeyboardMarkup'] = None):
|
896
922
|
return self.client.send_invoice(
|
897
923
|
self.id,
|
898
924
|
title,
|
@@ -1170,7 +1196,7 @@ class Message:
|
|
1170
1196
|
provider_token: str,
|
1171
1197
|
prices: list,
|
1172
1198
|
photo_url: Optional[str] = None,
|
1173
|
-
reply_markup: Union['MenuKeyboardMarkup'
|
1199
|
+
reply_markup: Union['MenuKeyboardMarkup', 'InlineKeyboardMarkup'] = None):
|
1174
1200
|
return self.client.send_invoice(
|
1175
1201
|
self.chat.id,
|
1176
1202
|
title,
|
@@ -1182,6 +1208,13 @@ class Message:
|
|
1182
1208
|
self,
|
1183
1209
|
reply_markup)
|
1184
1210
|
|
1211
|
+
def forward(self,
|
1212
|
+
chat_id: Union[str, int]) -> 'Message':
|
1213
|
+
"""Forward a message to this user"""
|
1214
|
+
return self.client.forward_message(
|
1215
|
+
chat_id,
|
1216
|
+
self.chat.id,
|
1217
|
+
self.message_id)
|
1185
1218
|
|
1186
1219
|
|
1187
1220
|
class LabeledPrice:
|
@@ -1547,7 +1580,7 @@ class InputMediaDocument(InputMedia):
|
|
1547
1580
|
|
1548
1581
|
|
1549
1582
|
class CallbackQuery:
|
1550
|
-
|
1583
|
+
|
1551
1584
|
"""Represents a callback query from a callback button"""
|
1552
1585
|
|
1553
1586
|
def __init__(self, client: 'Client', data: Dict[str, Any]):
|
@@ -1587,6 +1620,7 @@ class CallbackQuery:
|
|
1587
1620
|
reply_markup=reply_markup,
|
1588
1621
|
reply_to_message=self.message.id)
|
1589
1622
|
|
1623
|
+
|
1590
1624
|
class Client:
|
1591
1625
|
"""Main client class for interacting with Bale API"""
|
1592
1626
|
|
@@ -1613,6 +1647,10 @@ class Client:
|
|
1613
1647
|
self._threads = []
|
1614
1648
|
self._polling = False
|
1615
1649
|
self.user = None
|
1650
|
+
self.event_handlers = []
|
1651
|
+
self.message_queue = queue.Queue()
|
1652
|
+
self.lock = threading.Lock()
|
1653
|
+
self.waiting_events = {}
|
1616
1654
|
|
1617
1655
|
def set_state(self,
|
1618
1656
|
chat_or_user_id: Union[Chat,
|
@@ -2149,6 +2187,44 @@ class Client:
|
|
2149
2187
|
response = self._make_request('GET', 'getChatMembersCount', json=data)
|
2150
2188
|
return response['result']
|
2151
2189
|
|
2190
|
+
def upload_sticker_file(self, user_id: int, sticker: 'InputFile'):
|
2191
|
+
"""Upload a file for future use in sticker sets"""
|
2192
|
+
data = {
|
2193
|
+
'user_id': user_id
|
2194
|
+
}
|
2195
|
+
files = {
|
2196
|
+
'sticker': sticker
|
2197
|
+
}
|
2198
|
+
response = self._make_request('POST', 'uploadStickerFile', data=data, files=files)
|
2199
|
+
return response['result']
|
2200
|
+
|
2201
|
+
def create_new_sticker_set(
|
2202
|
+
self, user_id: int, name: str, title: str, stickers: List['InputFile']) -> bool:
|
2203
|
+
"""Create a new sticker set owned by a user"""
|
2204
|
+
data = {
|
2205
|
+
'user_id': user_id,
|
2206
|
+
'name': name,
|
2207
|
+
'title': title
|
2208
|
+
}
|
2209
|
+
files = {}
|
2210
|
+
for i, sticker in enumerate(stickers):
|
2211
|
+
files[f'stickers[{i}]'] = sticker
|
2212
|
+
response = self._make_request('POST', 'createNewStickerSet', data=data, files=files)
|
2213
|
+
return response['result']
|
2214
|
+
|
2215
|
+
def add_sticker_to_set(self, user_id: int, name: str,
|
2216
|
+
sticker: 'InputFile') -> bool:
|
2217
|
+
"""Add a new sticker to a set created by the bot"""
|
2218
|
+
data = {
|
2219
|
+
'user_id': user_id,
|
2220
|
+
'name': name
|
2221
|
+
}
|
2222
|
+
files = {
|
2223
|
+
'sticker': sticker
|
2224
|
+
}
|
2225
|
+
response = self._make_request('POST', 'addStickerToSet', data=data, files=files)
|
2226
|
+
return response['result']
|
2227
|
+
|
2152
2228
|
def is_joined(self, user: Union[User, int, str],
|
2153
2229
|
chat: Union[Chat, int, str]) -> bool:
|
2154
2230
|
"""Check if user is a member of the chat"""
|
@@ -2234,6 +2310,9 @@ class Client:
|
|
2234
2310
|
"""Handle different types of messages"""
|
2235
2311
|
msg_data = update.get('message', {})
|
2236
2312
|
|
2313
|
+
if 'message' in update:
|
2314
|
+
message = Message(self, {'ok': True, 'result': update['message']})
|
2315
|
+
|
2237
2316
|
if 'new_chat_members' in msg_data and hasattr(
|
2238
2317
|
self, '_member_join_handler'):
|
2239
2318
|
chat, user = msg_data['chat'], msg_data['new_chat_members'][0]
|
@@ -2347,6 +2426,9 @@ class Client:
|
|
2347
2426
|
|
2348
2427
|
self._polling = True
|
2349
2428
|
self._threads = []
|
2429
|
+
self.message_queue = queue.Queue()
|
2430
|
+
self.event_handlers = []
|
2431
|
+
self.lock = threading.Lock()
|
2350
2432
|
offset = 0
|
2351
2433
|
past_updates = collections.deque(maxlen=100)
|
2352
2434
|
source_file = inspect.getfile(self.__class__)
|
@@ -2371,6 +2453,9 @@ class Client:
|
|
2371
2453
|
update_id = update['update_id']
|
2372
2454
|
if update_id not in past_updates:
|
2373
2455
|
past_updates.append(update_id)
|
2456
|
+
if 'message' in update:
|
2457
|
+
message = Message(
|
2458
|
+
self, {'ok': True, 'result': update['message']})
|
2374
2459
|
self._handle_update(update)
|
2375
2460
|
offset = update_id + 1
|
2376
2461
|
|
@@ -2413,11 +2498,15 @@ class Client:
|
|
2413
2498
|
self._close_handler()
|
2414
2499
|
except Exception as e:
|
2415
2500
|
print(f"Error in close handler: {e}")
|
2501
|
+
|
2502
|
+
def wait_for_message(self, checker=Any):
|
2503
|
+
self.waiting_events[checker]
|
2416
2504
|
|
2417
2505
|
def create_ref_link(self, data: str) -> str:
|
2418
2506
|
"""Create a reference link for the bot"""
|
2419
2507
|
return f"https://ble.ir/{self.get_me().username}?start={data}"
|
2420
2508
|
|
2509
|
+
|
2421
2510
|
def run_multiple_bots(bots: List[Client]) -> List[Client]:
|
2422
2511
|
"""
|
2423
2512
|
Run multiple bots concurrently in separate threads.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|