RubigramClient 1.5.5__py3-none-any.whl → 1.5.6__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.

Potentially problematic release.


This version of RubigramClient might be problematic. Click here for more details.

rubigram/client.py CHANGED
@@ -1,159 +1,115 @@
1
- from __future__ import annotations
2
- from typing import Optional, Callable, Literal
3
- from aiohttp import web
4
- from functools import wraps
1
+ from typing import Optional, Callable, Literal, Union
5
2
  from rubigram.models import Update, InlineMessage
6
3
  from rubigram.method import Method
7
4
  from rubigram.filters import Filter
8
5
  from rubigram.state import StateManager
9
6
  from datetime import datetime
7
+ from aiohttp import web
10
8
  import asyncio
11
- import logging
12
-
13
-
14
- logger = logging.getLogger(__name__)
15
-
16
9
 
17
10
  class Client(Method):
18
- def __init__(self, token: str, endpoint: Optional[str] = None, host: str = "0.0.0.0", port: int = 8000):
11
+ def __init__(
12
+ self,
13
+ token: str,
14
+ endpoint: Optional[str] = None,
15
+ host: str = "0.0.0.0",
16
+ port: int = 8000
17
+ ):
19
18
  self.token = token
20
19
  self.endpoint = endpoint
21
20
  self.host = host
22
21
  self.port = port
23
22
  self.offset_id = None
23
+ self.MESSAGE_HANDLER = []
24
+ self.INLINE_HANDLER = []
24
25
  self.state = StateManager()
25
- self.routes = web.RouteTableDef()
26
- self.message_handlers = []
27
- self.inline_handlers = []
28
26
  super().__init__(token)
29
-
30
- def on_message(self, *filters: Filter):
27
+
28
+
29
+ def create_handler(self, type: Literal["message", "inline"], filters: Optional[Filter] = None):
31
30
  def decorator(func: Callable) -> Callable:
32
- @wraps(func)
33
31
  async def wrapper(client: Client, update: Update):
34
- try:
35
- combined_filter = filters[0] if filters else None
36
- for filter in filters[1:]:
37
- combined_filter = combined_filter & filter
38
-
39
- if combined_filter is None or await combined_filter(update):
40
- await func(client, update)
41
- return True
42
- return False
43
- except Exception as error:
44
- logger.exception("Error {}: {}".format(func.__name__, error))
45
-
46
- self.message_handlers.append(wrapper)
32
+ if filters is None or await filters(update):
33
+ await func(client, update)
34
+ return True
35
+ return False
36
+ self.MESSAGE_HANDLER.append(wrapper) if type == "message" else self.INLINE_HANDLER.append(wrapper)
47
37
  return func
48
38
  return decorator
49
-
50
- def on_inline_message(self, *filters: Filter):
51
- def decorator(func: Callable) -> Callable:
52
- @wraps(func)
53
- async def wrapper(client: Client, update: InlineMessage):
54
- try:
55
- combined_filter = filters[0] if filters else None
56
- for filter in filters[1:]:
57
- combined_filter = combined_filter & filter
58
-
59
- if combined_filter is None or await combined_filter(update):
60
- await func(client, update)
61
- return True
62
- return False
63
- except Exception as error:
64
- logger.exception("Error {}: {}".format(func.__name__, error))
65
-
66
- self.inline_handlers.append(wrapper)
67
- return func
68
- return decorator
69
-
70
- async def dispatch(self, update: Update, type: Literal["update", "inline_message"] = "update"):
71
- handlers = self.message_handlers if type == "update" else self.inline_handlers
39
+
40
+ def on_message(self, filters: Optional[Filter] = None):
41
+ return self.create_handler("message", filters)
42
+
43
+ def on_inline_message(self, filters: Optional[Filter] = None):
44
+ return self.create_handler("inline", filters)
45
+
46
+ async def dispatch(self, update: Union[Update, InlineMessage], type: Literal["message", "inline"]):
47
+ handlers = self.MESSAGE_HANDLER if type == "message" else self.INLINE_HANDLER
72
48
  for handler in handlers:
73
- try:
74
- matched = await handler(self, update)
75
- if matched:
76
- return
77
- except Exception as error:
78
- logger.exception(f"Dispatch Error in handler [ {handler.__name__} ] : {error}")
49
+ matched = await handler(self, update)
50
+ if matched:
51
+ return
79
52
 
80
53
  async def updater(self, data: dict):
81
54
  if "inline_message" in data:
82
- event = InlineMessage.from_dict(data.get("inline_message", {}))
83
- event.client = self
84
- await self.dispatch(event, "inline_message")
55
+ event = InlineMessage.from_dict(data["inline_message"])
56
+ type = "inline"
85
57
  elif "update" in data:
86
- event = Update.from_dict(data.get("update", {}))
87
- event.client = self
88
- await self.dispatch(event)
89
- else:
90
- return
91
-
58
+ event = Update.from_dict(data["update"])
59
+ type = "message"
60
+ else: return
61
+ event.client = self
62
+ await self.dispatch(event, type)
63
+
92
64
  async def set_endpoints(self):
65
+ endpoint_type = ["ReceiveUpdate", "ReceiveInlineMessage"]
93
66
  if self.endpoint:
94
- await self.update_bot_endpoint(f"{self.endpoint}/ReceiveUpdate", "ReceiveUpdate")
95
- await self.update_bot_endpoint(f"{self.endpoint}/ReceiveInlineMessage", "ReceiveInlineMessage")
96
-
67
+ for i in endpoint_type:
68
+ await self.update_bot_endpoint(f"{self.endpoint}/{i}", i)
69
+
70
+ async def on_startup(self, app):
71
+ await self.set_endpoints()
72
+ await self.state.start()
73
+ await self.start()
74
+
75
+ async def on_cleanup(self, app):
76
+ await self.state.stop()
77
+ await self.stop()
78
+
79
+ def create_request_handler(self):
80
+ async def wrapper(request: web.Request):
81
+ data = await request.json()
82
+ await self.updater(data)
83
+ return web.json_response({"status": "OK"})
84
+ return wrapper
85
+
86
+ async def runner(self):
87
+ try:
88
+ await self.state.start()
89
+ while True:
90
+ get_updates = await self.get_update(100, self.offset_id)
91
+ if get_updates.updates:
92
+ updates = get_updates.updates
93
+ for update in updates:
94
+ time = int(update.new_message.time) if update.type == "NewMessage" else int(update.updated_message.time) if update.type == "UpdatedMessage" else None
95
+ now = int(datetime.now().timestamp())
96
+ if time and time >= now or time + 2 >= now:
97
+ update.client = self
98
+ await self.dispatch(update, "message")
99
+ self.offset_id = get_updates.next_offset_id
100
+ except Exception as error:
101
+ print(f"ERROR : {error}")
102
+ finally:
103
+ await self.state.stop()
104
+ await self.stop()
105
+
97
106
  def run(self):
98
107
  if self.endpoint:
99
- @self.routes.post("/ReceiveUpdate")
100
- async def receive_update(request: web.Request):
101
- data = await request.json()
102
- await self.updater(data)
103
- return web.json_response({"status": "OK"})
104
-
105
- @self.routes.post("/ReceiveInlineMessage")
106
- async def receive_inline_message(request: web.Request):
107
- data = await request.json()
108
- await self.updater(data)
109
- return web.json_response({"status": "OK"})
110
-
111
- app = web.Application()
112
- app.add_routes(self.routes)
113
-
114
- async def on_startup(app):
115
- await self.set_endpoints()
116
- await self.state.start()
117
- await self.start()
118
-
119
- async def on_cleanup(app):
120
- await self.state.stop()
121
- await self.stop()
122
-
123
- app.on_startup.append(on_startup)
124
- app.on_cleanup.append(on_cleanup)
108
+ app = web.Application()
109
+ app.router.add_post("/ReceiveUpdate", self.create_request_handler())
110
+ app.router.add_post("/ReceiveInlineMessage", self.create_request_handler())
125
111
  web.run_app(app, host=self.host, port=self.port)
126
-
127
112
  else:
128
- async def polling():
129
- try:
130
- await self.state.start()
131
- while True:
132
- try:
133
- get_update = await self.get_update(100, self.offset_id)
134
- if get_update.updates:
135
- updates = get_update.updates
136
- for update in updates:
137
- if update.type == "NewMessage":
138
- message_time = int(update.new_message.time)
139
- elif update.type == "UpdatedMessage":
140
- message_time = int(update.updated_message.time)
141
- else:continue
142
-
143
- now = int(datetime.now().timestamp())
144
- if message_time >= now or message_time + 2 >= now:
145
- if isinstance(update, Update):
146
- update.client = self
147
- await self.dispatch(update)
148
-
149
- self.offset_id = get_update.next_offset_id
150
- except Exception as error:
151
- logger.exception("Polling Error : {}".format(error))
152
- await asyncio.sleep(1)
153
-
154
- except:
155
- pass
156
- finally:
157
- await self.state.stop()
158
- await self.stop()
159
- asyncio.run(polling())
113
+ try:
114
+ asyncio.run(self.runner())
115
+ except:pass
rubigram/filters.py CHANGED
@@ -3,6 +3,9 @@ from typing import Union, Callable, Awaitable
3
3
  import re
4
4
 
5
5
 
6
+
7
+
8
+
6
9
  class Filter:
7
10
  def __init__(self, func: Callable[[Union[Update, InlineMessage]], Union[bool, Awaitable[bool]]]):
8
11
  self.func = func
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RubigramClient
3
- Version: 1.5.5
3
+ Version: 1.5.6
4
4
  Summary: A simple and flexible Python library for building advanced Rubika bots with powerful message handling, inline buttons, and custom filters.
5
5
  Author-email: Javad RZ <Javad.Py1385@gmail.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -51,8 +51,8 @@ async def start(_, message: Update):
51
51
  rows=[
52
52
  KeypadRow(
53
53
  buttons=[
54
- Button("1", "Simple", "Button 1"),
55
- Button("2", "Simple", "Button 2")
54
+ Button("1", "Button 1"),
55
+ Button("2", "Button 2")
56
56
  ]
57
57
  )
58
58
  ]
@@ -0,0 +1,12 @@
1
+ rubigram/__init__.py,sha256=IWNCN7oDaIBzaP54cGiA-4Sa31ehGBlqj0SuqhNQVgU,162
2
+ rubigram/client.py,sha256=AGb7PaXBdFIoUTB3mTWHgdCQAO0anAjgoAuY2tPph0U,4469
3
+ rubigram/filters.py,sha256=LWc_qCLExsQqqucFCeNKi_3okfyIx6yAVQHMAzAskc8,6224
4
+ rubigram/method.py,sha256=PUP9DTX6XpWVbersiLv12GdlwOFaXzrgx582nJd4i_I,10613
5
+ rubigram/models.py,sha256=42WK68VPKqgKCy14jrRyoP_XRsZ-04S5rUbdpO_UfaQ,13831
6
+ rubigram/network.py,sha256=ErrGwtKpMHN1Dq4IvPHSrMOcDN-TFjUk1CfU-2EuPAY,2364
7
+ rubigram/state.py,sha256=oRk5xXuO4k-cK0qRI2Rz2mdoivJkANlo20zQAkdqFSY,4081
8
+ rubigramclient-1.5.6.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ rubigramclient-1.5.6.dist-info/METADATA,sha256=eoRk-VQNt67olSWe9IsX36MnlKHSQDMuCjay_8NeYws,2300
10
+ rubigramclient-1.5.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ rubigramclient-1.5.6.dist-info/top_level.txt,sha256=Mhg5HfkL6rLec5sI4ClGmwoqYUANAZUz8sVa1sT_cas,9
12
+ rubigramclient-1.5.6.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- rubigram/__init__.py,sha256=IWNCN7oDaIBzaP54cGiA-4Sa31ehGBlqj0SuqhNQVgU,162
2
- rubigram/client.py,sha256=GDdlGzCeSwBAzEP3Truat1g2il5l3nPWbmFw2hRhYoc,6511
3
- rubigram/filters.py,sha256=EyrcKbEIwqDwf18lucusUoZYP0KIkaKkZc7PnaA0GcU,6218
4
- rubigram/method.py,sha256=PUP9DTX6XpWVbersiLv12GdlwOFaXzrgx582nJd4i_I,10613
5
- rubigram/models.py,sha256=42WK68VPKqgKCy14jrRyoP_XRsZ-04S5rUbdpO_UfaQ,13831
6
- rubigram/network.py,sha256=ErrGwtKpMHN1Dq4IvPHSrMOcDN-TFjUk1CfU-2EuPAY,2364
7
- rubigram/state.py,sha256=oRk5xXuO4k-cK0qRI2Rz2mdoivJkANlo20zQAkdqFSY,4081
8
- rubigramclient-1.5.5.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- rubigramclient-1.5.5.dist-info/METADATA,sha256=Abido_4uhjv1iK3kIoUv49ulhGE8DmKfgzfRPoVcED8,2320
10
- rubigramclient-1.5.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- rubigramclient-1.5.5.dist-info/top_level.txt,sha256=Mhg5HfkL6rLec5sI4ClGmwoqYUANAZUz8sVa1sT_cas,9
12
- rubigramclient-1.5.5.dist-info/RECORD,,