RubigramClient 1.5.0__tar.gz → 1.5.2__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.
Potentially problematic release.
This version of RubigramClient might be problematic. Click here for more details.
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/PKG-INFO +4 -3
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/README.md +2 -2
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/RubigramClient.egg-info/PKG-INFO +4 -3
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/RubigramClient.egg-info/SOURCES.txt +2 -1
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/RubigramClient.egg-info/requires.txt +1 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/pyproject.toml +2 -1
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/rubigram/__init__.py +2 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/rubigram/client.py +13 -7
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/rubigram/filters.py +17 -6
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/rubigram/method.py +1 -1
- rubigramclient-1.5.2/rubigram/state.py +107 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/LICENSE +0 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/RubigramClient.egg-info/dependency_links.txt +0 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/RubigramClient.egg-info/top_level.txt +0 -0
- /rubigramclient-1.5.0/rubigram/types.py → /rubigramclient-1.5.2/rubigram/models.py +0 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/rubigram/network.py +0 -0
- {rubigramclient-1.5.0 → rubigramclient-1.5.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: RubigramClient
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
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
|
|
@@ -11,6 +11,7 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: aiohttp
|
|
13
13
|
Requires-Dist: aiofiles
|
|
14
|
+
Requires-Dist: aiosqlite
|
|
14
15
|
Dynamic: license-file
|
|
15
16
|
|
|
16
17
|
# Rubigram
|
|
@@ -24,7 +25,7 @@ pip install RubigramClient
|
|
|
24
25
|
## Send Message
|
|
25
26
|
```python
|
|
26
27
|
from rubigram import Client, filters
|
|
27
|
-
from rubigram.
|
|
28
|
+
from rubigram.models import Update
|
|
28
29
|
|
|
29
30
|
bot = Client("your_bot_token", "you_endpoint_url")
|
|
30
31
|
|
|
@@ -38,7 +39,7 @@ bot.run()
|
|
|
38
39
|
## Send Message & Get receiveInlineMessage
|
|
39
40
|
```python
|
|
40
41
|
from rubigram import Client, filters
|
|
41
|
-
from rubigram.
|
|
42
|
+
from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
bot = Client(token="bot_token", endpoint="endpoint_url")
|
|
@@ -9,7 +9,7 @@ pip install RubigramClient
|
|
|
9
9
|
## Send Message
|
|
10
10
|
```python
|
|
11
11
|
from rubigram import Client, filters
|
|
12
|
-
from rubigram.
|
|
12
|
+
from rubigram.models import Update
|
|
13
13
|
|
|
14
14
|
bot = Client("your_bot_token", "you_endpoint_url")
|
|
15
15
|
|
|
@@ -23,7 +23,7 @@ bot.run()
|
|
|
23
23
|
## Send Message & Get receiveInlineMessage
|
|
24
24
|
```python
|
|
25
25
|
from rubigram import Client, filters
|
|
26
|
-
from rubigram.
|
|
26
|
+
from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
bot = Client(token="bot_token", endpoint="endpoint_url")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: RubigramClient
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
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
|
|
@@ -11,6 +11,7 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: aiohttp
|
|
13
13
|
Requires-Dist: aiofiles
|
|
14
|
+
Requires-Dist: aiosqlite
|
|
14
15
|
Dynamic: license-file
|
|
15
16
|
|
|
16
17
|
# Rubigram
|
|
@@ -24,7 +25,7 @@ pip install RubigramClient
|
|
|
24
25
|
## Send Message
|
|
25
26
|
```python
|
|
26
27
|
from rubigram import Client, filters
|
|
27
|
-
from rubigram.
|
|
28
|
+
from rubigram.models import Update
|
|
28
29
|
|
|
29
30
|
bot = Client("your_bot_token", "you_endpoint_url")
|
|
30
31
|
|
|
@@ -38,7 +39,7 @@ bot.run()
|
|
|
38
39
|
## Send Message & Get receiveInlineMessage
|
|
39
40
|
```python
|
|
40
41
|
from rubigram import Client, filters
|
|
41
|
-
from rubigram.
|
|
42
|
+
from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
bot = Client(token="bot_token", endpoint="endpoint_url")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "RubigramClient"
|
|
3
|
-
version = "1.5.
|
|
3
|
+
version = "1.5.2"
|
|
4
4
|
description = "A simple and flexible Python library for building advanced Rubika bots with powerful message handling, inline buttons, and custom filters."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.7"
|
|
@@ -16,5 +16,6 @@ classifiers = [
|
|
|
16
16
|
dependencies = [
|
|
17
17
|
"aiohttp",
|
|
18
18
|
"aiofiles",
|
|
19
|
+
"aiosqlite",
|
|
19
20
|
|
|
20
21
|
]
|
|
@@ -2,9 +2,10 @@ from __future__ import annotations
|
|
|
2
2
|
from typing import Optional, Callable, Literal
|
|
3
3
|
from aiohttp import web
|
|
4
4
|
from functools import wraps
|
|
5
|
-
from rubigram.
|
|
5
|
+
from rubigram.models import Update, InlineMessage
|
|
6
6
|
from rubigram.method import Method
|
|
7
7
|
from rubigram.filters import Filter
|
|
8
|
+
from rubigram.state import StateManager
|
|
8
9
|
from datetime import datetime
|
|
9
10
|
import asyncio
|
|
10
11
|
import logging
|
|
@@ -20,6 +21,7 @@ class Client(Method):
|
|
|
20
21
|
self.host = host
|
|
21
22
|
self.port = port
|
|
22
23
|
self.offset_id = None
|
|
24
|
+
self.state = StateManager()
|
|
23
25
|
self.routes = web.RouteTableDef()
|
|
24
26
|
self.message_handlers = []
|
|
25
27
|
self.inline_handlers = []
|
|
@@ -111,9 +113,11 @@ class Client(Method):
|
|
|
111
113
|
|
|
112
114
|
async def on_startup(app):
|
|
113
115
|
await self.set_endpoints()
|
|
116
|
+
await self.state.start()
|
|
114
117
|
await self.start()
|
|
115
118
|
|
|
116
119
|
async def on_cleanup(app):
|
|
120
|
+
await self.state.stop()
|
|
117
121
|
await self.stop()
|
|
118
122
|
|
|
119
123
|
app.on_startup.append(on_startup)
|
|
@@ -123,6 +127,7 @@ class Client(Method):
|
|
|
123
127
|
else:
|
|
124
128
|
async def polling():
|
|
125
129
|
try:
|
|
130
|
+
await self.state.start()
|
|
126
131
|
while True:
|
|
127
132
|
try:
|
|
128
133
|
get_update = await self.get_update(100, self.offset_id)
|
|
@@ -132,10 +137,8 @@ class Client(Method):
|
|
|
132
137
|
if update.type == "NewMessage":
|
|
133
138
|
message_time = int(update.new_message.time)
|
|
134
139
|
elif update.type == "UpdatedMessage":
|
|
135
|
-
message_time = int(
|
|
136
|
-
|
|
137
|
-
else:
|
|
138
|
-
continue
|
|
140
|
+
message_time = int(update.updated_message.time)
|
|
141
|
+
else:continue
|
|
139
142
|
|
|
140
143
|
now = int(datetime.now().timestamp())
|
|
141
144
|
if message_time >= now or message_time + 2 >= now:
|
|
@@ -148,6 +151,9 @@ class Client(Method):
|
|
|
148
151
|
logger.exception("Polling Error : {}".format(error))
|
|
149
152
|
await asyncio.sleep(1)
|
|
150
153
|
|
|
151
|
-
except:
|
|
152
|
-
|
|
154
|
+
except:
|
|
155
|
+
pass
|
|
156
|
+
finally:
|
|
157
|
+
await self.state.stop()
|
|
158
|
+
await self.stop()
|
|
153
159
|
asyncio.run(polling())
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from rubigram.
|
|
1
|
+
from rubigram.models import Update, InlineMessage
|
|
2
2
|
from typing import Union, Callable, Awaitable
|
|
3
3
|
import re
|
|
4
4
|
|
|
@@ -24,6 +24,19 @@ class Filter:
|
|
|
24
24
|
return Filter(combined)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
class state(Filter):
|
|
28
|
+
def __init__(self, states: Union[str, list[str]]):
|
|
29
|
+
self.states = states
|
|
30
|
+
super().__init__(self.filter)
|
|
31
|
+
|
|
32
|
+
async def filter(self, update: Update):
|
|
33
|
+
states = self.states if isinstance(self.states, list) else [self.states]
|
|
34
|
+
if isinstance(update, Update):
|
|
35
|
+
user = await update.client.state.get_state(update.chat_id)
|
|
36
|
+
return user.lower() in states if user else False
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
|
|
27
40
|
class command(Filter):
|
|
28
41
|
def __init__(self, cmd: Union[str, list[str]], prefix: str = "/"):
|
|
29
42
|
self.cmd = cmd
|
|
@@ -31,7 +44,7 @@ class command(Filter):
|
|
|
31
44
|
super().__init__(self.filter)
|
|
32
45
|
|
|
33
46
|
def filter(self, update: Update):
|
|
34
|
-
commands =
|
|
47
|
+
commands = self.cmd if isinstance(self.cmd, list) else [self.cmd]
|
|
35
48
|
text = ""
|
|
36
49
|
if isinstance(update, Update):
|
|
37
50
|
if update.type == "NewMessage":
|
|
@@ -71,8 +84,7 @@ class chat(Filter):
|
|
|
71
84
|
super().__init__(self.filter)
|
|
72
85
|
|
|
73
86
|
def filter(self, update: Union[Update, InlineMessage]):
|
|
74
|
-
chat_ids =
|
|
75
|
-
self.chat_id, str) else self.chat_id
|
|
87
|
+
chat_ids = self.chat_id if isinstance(self.chat_id, list) else [self.chat_id]
|
|
76
88
|
return update.chat_id in chat_ids
|
|
77
89
|
|
|
78
90
|
|
|
@@ -83,8 +95,7 @@ class button(Filter):
|
|
|
83
95
|
|
|
84
96
|
def filter(self, update: InlineMessage):
|
|
85
97
|
if isinstance(update, InlineMessage):
|
|
86
|
-
button_ids =
|
|
87
|
-
self.button_id, str) else self.button_id
|
|
98
|
+
button_ids = self.button_id if isinstance(self.button_id, list) else [self.button_id]
|
|
88
99
|
return update.aux_data.button_id in button_ids
|
|
89
100
|
|
|
90
101
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from aiosqlite import connect as conn, Connection
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ManageDB:
|
|
6
|
+
def __init__(self, database: str):
|
|
7
|
+
self.database = database
|
|
8
|
+
self.connection: Optional[Connection] = None
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async def connect(self):
|
|
12
|
+
if not self.connection:
|
|
13
|
+
self.connection = await conn(self.database)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def disconnect(self):
|
|
17
|
+
if self.connection:
|
|
18
|
+
await self.connection.close()
|
|
19
|
+
self.connection = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def create(self):
|
|
23
|
+
await self.connect()
|
|
24
|
+
await self.connection.execute("""CREATE TABLE IF NOT EXISTS states (user_id TEXT PRIMARY KEY, state TEXT)""")
|
|
25
|
+
await self.connection.execute("CREATE TABLE IF NOT EXISTS user_data (user_id TEXT, var TEXT, res TEXT, PRIMARY KEY (user_id, var))")
|
|
26
|
+
await self.connection.commit()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def set_state(self, user_id: str, state: str) -> None:
|
|
30
|
+
await self.connect()
|
|
31
|
+
await self.connection.execute("INSERT INTO states (user_id, state) VALUES (?, ?) ON CONFLICT(user_id) DO UPDATE SET state=excluded.state ", (user_id, str(state)))
|
|
32
|
+
await self.connection.commit()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
async def get_state(self, user_id: str) -> Optional[str]:
|
|
36
|
+
await self.connect()
|
|
37
|
+
async with self.connection.execute("SELECT state FROM states WHERE user_id = ?", (user_id,)) as cursor:
|
|
38
|
+
data = await cursor.fetchone()
|
|
39
|
+
return data[0] if data else None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async def remove_state(self, user_id: str):
|
|
43
|
+
await self.connect()
|
|
44
|
+
await self.connection.execute("DELETE FROM states WHERE user_id = ?", (user_id,))
|
|
45
|
+
await self.connection.commit()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
async def set_data(self, user_id: str, key: str, value: str):
|
|
49
|
+
await self.connect()
|
|
50
|
+
await self.connection.execute("INSERT OR REPLACE INTO user_data (user_id, var, res) VALUES (?, ?, ?)", (user_id, key, str(value)))
|
|
51
|
+
await self.connection.commit()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async def get_data(self, user_id: str, key: str = None):
|
|
55
|
+
await self.connect()
|
|
56
|
+
if key:
|
|
57
|
+
async with self.connection.execute("SELECT res FROM user_data WHERE user_id = ? AND var = ?", (user_id, key)) as cursor:
|
|
58
|
+
data = await cursor.fetchone()
|
|
59
|
+
return data[0] if data else None
|
|
60
|
+
else:
|
|
61
|
+
async with self.connection.execute("SELECT var, res FROM user_data WHERE user_id = ?", (user_id,)) as cursor:
|
|
62
|
+
data = await cursor.fetchall()
|
|
63
|
+
return {k: v for k, v in data} if data else {}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def remove_data(self, user_id: str, key: str = None):
|
|
68
|
+
await self.connect()
|
|
69
|
+
if key:
|
|
70
|
+
await self.connection.execute("DELETE FROM user_data WHERE user_id = ? AND var = ?", (user_id, key))
|
|
71
|
+
else:
|
|
72
|
+
await self.connection.execute("DELETE FROM user_data WHERE user_id = ?", (user_id,))
|
|
73
|
+
await self.connection.commit()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class StateManager:
|
|
78
|
+
def __init__(self):
|
|
79
|
+
self.db = ManageDB("rubigram.db")
|
|
80
|
+
|
|
81
|
+
async def start(self):
|
|
82
|
+
await self.db.create()
|
|
83
|
+
|
|
84
|
+
async def stop(self):
|
|
85
|
+
await self.db.disconnect()
|
|
86
|
+
|
|
87
|
+
async def set_state(self, user_id: str, state: str):
|
|
88
|
+
await self.db.set_state(user_id, state)
|
|
89
|
+
|
|
90
|
+
async def get_state(self, user_id: str):
|
|
91
|
+
return await self.db.get_state(user_id)
|
|
92
|
+
|
|
93
|
+
async def remove_state(self, user_id: str):
|
|
94
|
+
await self.db.remove_state(user_id)
|
|
95
|
+
|
|
96
|
+
async def set_data(self, user_id: str, **data):
|
|
97
|
+
data = list(data.items())
|
|
98
|
+
if not data:
|
|
99
|
+
return
|
|
100
|
+
key, value = data[0]
|
|
101
|
+
await self.db.set_data(user_id, key, value)
|
|
102
|
+
|
|
103
|
+
async def get_data(self, user_id: str, key: str = None):
|
|
104
|
+
return await self.db.get_data(user_id, key)
|
|
105
|
+
|
|
106
|
+
async def remove_data(self, user_id: str, key: str = None):
|
|
107
|
+
await self.db.remove_data(user_id, key)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|