RubigramClient 1.5.0__py3-none-any.whl → 1.5.1__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/__init__.py CHANGED
@@ -1,4 +1,6 @@
1
1
  from .network import Network
2
2
  from .method import Method
3
3
  from .client import Client
4
+ from .state import StateManager
5
+ from . import models
4
6
  from . import filters
rubigram/client.py CHANGED
@@ -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.types import Update, InlineMessage
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
- update.updated_message.time)
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: pass
152
- finally: await self.stop()
154
+ except:
155
+ pass
156
+ finally:
157
+ await self.state.stop()
158
+ await self.stop()
153
159
  asyncio.run(polling())
rubigram/filters.py CHANGED
@@ -1,4 +1,4 @@
1
- from rubigram.types import Update, InlineMessage
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 = [self.cmd] if isinstance(self.cmd, str) else self.cmd
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 = [self.chat_id] if isinstance(
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 = [self.button_id] if isinstance(
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
 
rubigram/method.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from .network import Network
2
2
  from typing import Literal, Optional
3
- from .types import Bot, Chat, Keypad, MessageId, Updates
3
+ from rubigram.models import Bot, Chat, Keypad, MessageId, Updates
4
4
 
5
5
 
6
6
 
rubigram/state.py ADDED
@@ -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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RubigramClient
3
- Version: 1.5.0
3
+ Version: 1.5.1
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
@@ -24,7 +24,7 @@ pip install RubigramClient
24
24
  ## Send Message
25
25
  ```python
26
26
  from rubigram import Client, filters
27
- from rubigram.types import Update
27
+ from rubigram.models import Update
28
28
 
29
29
  bot = Client("your_bot_token", "you_endpoint_url")
30
30
 
@@ -38,7 +38,7 @@ bot.run()
38
38
  ## Send Message & Get receiveInlineMessage
39
39
  ```python
40
40
  from rubigram import Client, filters
41
- from rubigram.types import Update, Button, Keypad, KeypadRow, InlineMessage
41
+ from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
42
42
 
43
43
 
44
44
  bot = Client(token="bot_token", endpoint="endpoint_url")
@@ -0,0 +1,12 @@
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=SGnC_vzcMiLfyNzDACTwjSG8igRHljNsoCg5Foiolfo,10373
5
+ rubigram/models.py,sha256=QJ-nzd0HNhxCwhCOC6_fuBmJBG2M6Cg9oWH9sIFRNdA,13603
6
+ rubigram/network.py,sha256=Dy2M4NSdN2iaNP0wwlmVcS408Omq6QhiWUWExrp9Ers,2340
7
+ rubigram/state.py,sha256=oRk5xXuO4k-cK0qRI2Rz2mdoivJkANlo20zQAkdqFSY,4081
8
+ rubigramclient-1.5.1.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ rubigramclient-1.5.1.dist-info/METADATA,sha256=7a3V0tPhLjSXKKiDXEA_49W6oOE2FR5apoZi2JVL3Tg,2294
10
+ rubigramclient-1.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ rubigramclient-1.5.1.dist-info/top_level.txt,sha256=Mhg5HfkL6rLec5sI4ClGmwoqYUANAZUz8sVa1sT_cas,9
12
+ rubigramclient-1.5.1.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- rubigram/__init__.py,sha256=Z0foTm6Hpy4CDEH5am-IFWifi0bo4jLvpkfj3JQQHPc,107
2
- rubigram/client.py,sha256=nHwZ01CjF5V8HryByI2Mn0eC2FALmkaMmeHwQw7PNT4,6304
3
- rubigram/filters.py,sha256=YS1fUmtZON8XTMc6IwzXUH3Qw58uMhXD9cbTeP8cjr4,5750
4
- rubigram/method.py,sha256=bPK2VMtJtRnrN-wrEXH7ijcPzovm_pqFObmViNfWUHM,10364
5
- rubigram/network.py,sha256=Dy2M4NSdN2iaNP0wwlmVcS408Omq6QhiWUWExrp9Ers,2340
6
- rubigram/types.py,sha256=QJ-nzd0HNhxCwhCOC6_fuBmJBG2M6Cg9oWH9sIFRNdA,13603
7
- rubigramclient-1.5.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- rubigramclient-1.5.0.dist-info/METADATA,sha256=l7FTCFdjK7uNkJql1YN1yozDqTk3pW_3nwYw0_r35Nk,2292
9
- rubigramclient-1.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- rubigramclient-1.5.0.dist-info/top_level.txt,sha256=Mhg5HfkL6rLec5sI4ClGmwoqYUANAZUz8sVa1sT_cas,9
11
- rubigramclient-1.5.0.dist-info/RECORD,,
File without changes