Rubka 1.4.0__tar.gz → 1.5.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Rubka
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: A Python library for interacting with Rubika Bot API.
5
5
  Home-page: https://github.com/Mahdy-Ahmadi/Rubka
6
6
  Download-URL: https://github.com/Mahdy-Ahmadi/Rubka/archive/refs/tags/v0.1.0.tar.gz
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Rubka
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: A Python library for interacting with Rubika Bot API.
5
5
  Home-page: https://github.com/Mahdy-Ahmadi/Rubka
6
6
  Download-URL: https://github.com/Mahdy-Ahmadi/Rubka/archive/refs/tags/v0.1.0.tar.gz
@@ -8,8 +8,11 @@ Rubka.egg-info/top_level.txt
8
8
  rubka/__init__.py
9
9
  rubka/api.py
10
10
  rubka/config.py
11
+ rubka/context.py
11
12
  rubka/decorators.py
12
13
  rubka/exceptions.py
14
+ rubka/jobs.py
13
15
  rubka/keyboards.py
16
+ rubka/keypad.py
14
17
  rubka/logger.py
15
18
  rubka/utils.py
@@ -3,7 +3,7 @@ from typing import List, Optional, Dict, Any, Literal
3
3
  from .exceptions import APIRequestError
4
4
  from .logger import logger
5
5
  from typing import Callable
6
-
6
+ from .context import MessageContext
7
7
  API_URL = "https://botapi.rubika.ir/v3"
8
8
 
9
9
  class Robot:
@@ -16,6 +16,7 @@ class Robot:
16
16
  self.token = token
17
17
  self._offset_id = None
18
18
  self.session = requests.Session()
19
+ self.sessions: Dict[str, Dict[str, Any]] = {}
19
20
  logger.info(f"Initialized RubikaBot with token: {token[:8]}***")
20
21
 
21
22
  def _post(self, method: str, data: Dict[str, Any]) -> Dict[str, Any]:
@@ -33,28 +34,49 @@ class Robot:
33
34
  def get_me(self) -> Dict[str, Any]:
34
35
  """Get info about the bot itself."""
35
36
  return self._post("getMe", {})
36
- def on_message(self):
37
- def decorator(func: Callable):
38
- self._message_handler = func
37
+ def on_message(self, filters: Optional[Callable[[MessageContext], bool]] = None, commands: Optional[List[str]] = None):
38
+ def decorator(func: Callable[[Any, MessageContext], None]):
39
+ self._message_handler = {
40
+ "func": func,
41
+ "filters": filters,
42
+ "commands": commands
43
+ }
39
44
  return func
40
45
  return decorator
41
46
 
47
+
48
+
42
49
  def _process_update(self, update: Dict[str, Any]):
43
- if 'update' in update and update['update'].get('type') == 'NewMessage':
44
- msg = update['update']['new_message']
45
- chat_id = update['update']['chat_id']
50
+ update_data = update.get('update', {})
51
+ if update_data.get('type') == 'NewMessage':
52
+ msg = update_data.get('new_message', {})
53
+ chat_id = update_data.get('chat_id')
46
54
  message_id = msg.get('message_id')
47
- text = msg.get('text')
48
55
  sender_id = msg.get('sender_id')
56
+ text = msg.get('text')
49
57
 
50
58
  if self._message_handler:
51
- self._message_handler(
52
- bot=self,
53
- chat_id=chat_id,
54
- message_id=message_id,
55
- text=text,
56
- sender_id=sender_id
57
- )
59
+ handler = self._message_handler
60
+ context = MessageContext(self, chat_id, message_id, sender_id, text)
61
+
62
+
63
+ if handler["commands"]:
64
+ if not context.text or not context.text.startswith("/"):
65
+ return
66
+ parts = context.text.split()
67
+ cmd = parts[0][1:]
68
+ if cmd not in handler["commands"]:
69
+ return
70
+ context.args = parts[1:]
71
+
72
+ if handler["filters"]:
73
+ if not handler["filters"](context):
74
+ return
75
+
76
+ handler["func"](self, context)
77
+
78
+
79
+
58
80
 
59
81
  def run(self):
60
82
  print("Bot started running...")
@@ -0,0 +1,99 @@
1
+ from typing import Any, Dict, List
2
+
3
+
4
+ class Message:
5
+ def __init__(self, bot, chat_id, message_id, sender_id, text):
6
+ self.bot = bot
7
+ self.chat_id = chat_id
8
+ self.message_id = message_id
9
+ self.sender_id = sender_id
10
+ self.text = text
11
+ self.args = []
12
+ @property
13
+ def session(self):
14
+ if self.chat_id not in self.bot.sessions:
15
+ self.bot.sessions[self.chat_id] = {}
16
+ return self.bot.sessions[self.chat_id]
17
+ def reply(self, text: str, **kwargs):
18
+ return self.bot.send_message(
19
+ self.chat_id,
20
+ text,
21
+ reply_to_message_id=self.message_id,
22
+ **kwargs
23
+ )
24
+
25
+ def reply_poll(self, question: str, options: List[str], **kwargs) -> Dict[str, Any]:
26
+ return self.bot._post("sendPoll", {
27
+ "chat_id": self.chat_id,
28
+ "question": question,
29
+ "options": options,
30
+ "reply_to_message_id": self.message_id,
31
+ **kwargs
32
+ })
33
+
34
+ def reply_location(self, latitude: str, longitude: str, **kwargs) -> Dict[str, Any]:
35
+ return self.bot.send_location(
36
+ chat_id=self.chat_id,
37
+ latitude=latitude,
38
+ longitude=longitude,
39
+ reply_to_message_id=self.message_id,
40
+ **kwargs
41
+ )
42
+
43
+ def reply_contact(self, first_name: str, last_name: str, phone_number: str, **kwargs) -> Dict[str, Any]:
44
+ return self.bot.send_contact(
45
+ chat_id=self.chat_id,
46
+ first_name=first_name,
47
+ last_name=last_name,
48
+ phone_number=phone_number,
49
+ reply_to_message_id=self.message_id,
50
+ **kwargs
51
+ )
52
+
53
+ def reply_keypad(self, text: str, keypad: Dict[str, Any], **kwargs) -> Dict[str, Any]:
54
+ return self.bot.send_message(
55
+ chat_id=self.chat_id,
56
+ text=text,
57
+ chat_keypad_type="New",
58
+ chat_keypad=keypad,
59
+ reply_to_message_id=self.message_id,
60
+ **kwargs
61
+ )
62
+
63
+ def reply_inline(self, text: str, inline_keypad: Dict[str, Any], **kwargs) -> Dict[str, Any]:
64
+ return self.bot.send_message(
65
+ chat_id=self.chat_id,
66
+ text=text,
67
+ inline_keypad=inline_keypad,
68
+ reply_to_message_id=self.message_id,
69
+ **kwargs
70
+ )
71
+
72
+ def reply_sticker(self, sticker_id: str, **kwargs) -> Dict[str, Any]:
73
+ return self.bot._post("sendSticker", {
74
+ "chat_id": self.chat_id,
75
+ "sticker_id": sticker_id,
76
+ "reply_to_message_id": self.message_id,
77
+ **kwargs
78
+ })
79
+
80
+ def reply_file(self, file_id: str, **kwargs) -> Dict[str, Any]:
81
+ return self.bot._post("sendFile", {
82
+ "chat_id": self.chat_id,
83
+ "file_id": file_id,
84
+ "reply_to_message_id": self.message_id,
85
+ **kwargs
86
+ })
87
+
88
+ def edit(self, new_text: str) -> Dict[str, Any]:
89
+ return self.bot.edit_message_text(
90
+ chat_id=self.chat_id,
91
+ message_id=self.message_id,
92
+ text=new_text
93
+ )
94
+
95
+ def delete(self) -> Dict[str, Any]:
96
+ return self.bot.delete_message(
97
+ chat_id=self.chat_id,
98
+ message_id=self.message_id
99
+ )
@@ -0,0 +1,15 @@
1
+ import threading
2
+ import time
3
+ from typing import Callable
4
+
5
+ class Job:
6
+ def __init__(self, delay: int, callback: Callable):
7
+ self.delay = delay
8
+ self.callback = callback
9
+ thread = threading.Thread(target=self.run)
10
+ thread.daemon = True
11
+ thread.start()
12
+
13
+ def run(self):
14
+ time.sleep(self.delay)
15
+ self.callback()
@@ -0,0 +1,15 @@
1
+ from typing import Dict
2
+
3
+ class InlineBuilder:
4
+ def __init__(self):
5
+ self.rows = []
6
+
7
+ def row(self, *buttons: Dict[str, str]):
8
+ self.rows.append({"buttons": list(buttons)})
9
+ return self
10
+
11
+ def button(self, id: str, text: str, type: str = "Simple") -> Dict[str, str]:
12
+ return {"id": id, "type": type, "button_text": text}
13
+
14
+ def build(self):
15
+ return {"rows": self.rows}
@@ -8,7 +8,7 @@ except FileNotFoundError:
8
8
 
9
9
  setup(
10
10
  name='Rubka',
11
- version='1.4.0',
11
+ version='1.5.0',
12
12
  description='A Python library for interacting with Rubika Bot API.',
13
13
  long_description=long_description,
14
14
  long_description_content_type='text/markdown',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes