telegram_libs 0.1.25__py3-none-any.whl → 0.1.27__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.
@@ -9,10 +9,10 @@ DEBUG = os.getenv("DEBUG", "False").lower() in ("true", "1", "yes")
9
9
  BOTS = {
10
10
  "https://t.me/MagMediaBot": "Remove Background",
11
11
  "https://t.me/UpscaleImageGBot": "Upscale Image",
12
- "https://t.me/GenerateBackgroundGBot": "Generate a Background",
13
- "https://t.me/kudapoyti_go_bot": "Recommend a place to visit",
12
+ "https://t.me/GenerateBackgroundGBot": "Generate Background",
13
+ "https://t.me/kudapoyti_go_bot": "Recommend Place to Visit",
14
14
  "https://t.me/TryOnOutfitGBot": "Try On Outfit",
15
- "https://t.me/CloneVoiceAIGBot": "Clone Voice AI",
15
+ "https://t.me/CloneVoiceAIGBot": "Clone Voice, Text to Speech AI",
16
16
  }
17
17
 
18
18
  BOTS_AMOUNT = len(BOTS)
telegram_libs/mongo.py CHANGED
@@ -1,6 +1,9 @@
1
+ from datetime import datetime
2
+ from telegram import Update
1
3
  from pymongo.mongo_client import MongoClient
2
4
  from pymongo.server_api import ServerApi
3
- from telegram_libs.constants import MONGO_URI, DEBUG
5
+ from telegram_libs.constants import MONGO_URI, DEBUG, SUBSCRIPTION_DB_NAME
6
+ from telegram import Update
4
7
 
5
8
 
6
9
  class MongoManager:
@@ -18,6 +21,11 @@ class MongoManager:
18
21
  self.users_collection = self.db["users_test"] if DEBUG else self.db["users"]
19
22
  self.payments_collection = self.db["order_test"] if DEBUG else self.db["order"]
20
23
  self.user_schema = {"user_id": None, **(kwargs.get("user_schema") or {})}
24
+ self.subscription_collection = (
25
+ self.client[SUBSCRIPTION_DB_NAME]["subscriptions"]
26
+ if not DEBUG
27
+ else self.client[SUBSCRIPTION_DB_NAME]["subscriptions_test"]
28
+ )
21
29
 
22
30
  def create_user(self, user_id: int) -> None:
23
31
  """Create a new user in the database."""
@@ -57,4 +65,56 @@ class MongoManager:
57
65
  """Update an order for a user."""
58
66
  self.payments_collection.update_one(
59
67
  {"user_id": user_id, "order_id": order_id}, {"$set": updates}
60
- )
68
+ )
69
+
70
+ def get_user_info(self, update: Update) -> dict:
71
+ """Get user information from the update object."""
72
+ user = update.effective_user
73
+ user_data = self.get_user_data(user.id)
74
+
75
+ return {
76
+ "user_id": user.id,
77
+ "username": user.username,
78
+ "first_name": user.first_name,
79
+ "last_name": user.last_name,
80
+ "lang": user_data.get("language", "en"),
81
+ **user_data,
82
+ }
83
+
84
+ def get_subscription(self, user_id: int) -> dict:
85
+ """Get user's subscription data from the shared subscription database."""
86
+ subscription = self.subscription_collection.find_one({"user_id": user_id})
87
+ if not subscription:
88
+ return {"user_id": user_id, "is_premium": False}
89
+ return subscription
90
+
91
+ def update_subscription(self, user_id: int, updates: dict) -> None:
92
+ """Update user's subscription data in the shared subscription database."""
93
+ self.subscription_collection.update_one(
94
+ {"user_id": user_id}, {"$set": updates}, upsert=True
95
+ )
96
+
97
+ def add_subscription_payment(self, user_id: int, payment_data: dict) -> None:
98
+ """Add a subscription payment record."""
99
+ self.subscription_collection.update_one(
100
+ {"user_id": user_id},
101
+ {
102
+ "$push": {"payments": payment_data},
103
+ "$set": {
104
+ "is_premium": True,
105
+ "premium_expiration": payment_data["expiration_date"],
106
+ "last_payment": payment_data["date"],
107
+ },
108
+ },
109
+ upsert=True,
110
+ )
111
+
112
+ def check_subscription_status(self, user_id: int) -> bool:
113
+ """Check if user has an active subscription."""
114
+ subscription = self.get_subscription(user_id)
115
+
116
+ if not subscription.get("is_premium"):
117
+ return False
118
+
119
+ expiration = datetime.fromisoformat(subscription["premium_expiration"])
120
+ return expiration > datetime.now()
telegram_libs/payment.py CHANGED
@@ -3,8 +3,6 @@ from logging import getLogger
3
3
  from telegram import Update
4
4
  from telegram.ext import ContextTypes
5
5
  from telegram_libs.translation import t
6
- from telegram_libs.subscription import add_subscription_payment
7
- from telegram_libs.utils import get_user_info
8
6
  from telegram_libs.mongo import MongoManager
9
7
  from telegram_libs.logger import BotLogger
10
8
 
@@ -36,7 +34,7 @@ async def precheckout_handler(update: Update, context: ContextTypes.DEFAULT_TYPE
36
34
 
37
35
  async def successful_payment(update: Update, context: ContextTypes.DEFAULT_TYPE, mongo_manager: MongoManager, bot_logger: BotLogger) -> None:
38
36
  """Handle successful payments"""
39
- user_info = get_user_info(update, mongo_manager)
37
+ user_info = mongo_manager.get_user_info(update)
40
38
  user_id = user_info["user_id"]
41
39
  lang = user_info["lang"]
42
40
  payment_info = update.message.successful_payment
@@ -72,7 +70,7 @@ async def successful_payment(update: Update, context: ContextTypes.DEFAULT_TYPE,
72
70
  current_time = datetime.now()
73
71
 
74
72
  # Add subscription payment to shared subscription database
75
- add_subscription_payment(
73
+ mongo_manager.add_subscription_payment(
76
74
  user_id,
77
75
  {
78
76
  "order_id": payment_info.provider_payment_charge_id,
@@ -1,64 +1,12 @@
1
- from datetime import datetime
1
+ from datetime import datetime, timedelta
2
2
  from telegram import Update, LabeledPrice, InlineKeyboardMarkup, InlineKeyboardButton
3
3
  from telegram.ext import ContextTypes
4
- from telegram_libs.constants import SUBSCRIPTION_DB_NAME, DEBUG, BOTS_AMOUNT
4
+ from telegram_libs.constants import BOTS_AMOUNT, DEBUG
5
5
  from telegram_libs.mongo import MongoManager
6
- from telegram_libs.utils import get_user_info
7
6
  from telegram_libs.translation import t
8
7
  from telegram_libs.logger import BotLogger
9
8
 
10
9
 
11
- # Define the subscription database and collection
12
- mongo_manager_instance = MongoManager(mongo_database_name=SUBSCRIPTION_DB_NAME)
13
- subscription_collection = (
14
- mongo_manager_instance.client[SUBSCRIPTION_DB_NAME]["subscriptions"]
15
- if not DEBUG
16
- else mongo_manager_instance.client[SUBSCRIPTION_DB_NAME]["subscriptions_test"]
17
- )
18
-
19
-
20
- def get_subscription(user_id: int) -> dict:
21
- """Get user's subscription data from the shared subscription database."""
22
- subscription = subscription_collection.find_one({"user_id": user_id})
23
- if not subscription:
24
- return {"user_id": user_id, "is_premium": False}
25
- return subscription
26
-
27
-
28
- def update_subscription(user_id: int, updates: dict) -> None:
29
- """Update user's subscription data in the shared subscription database."""
30
- subscription_collection.update_one(
31
- {"user_id": user_id}, {"$set": updates}, upsert=True
32
- )
33
-
34
-
35
- def add_subscription_payment(user_id: int, payment_data: dict) -> None:
36
- """Add a subscription payment record."""
37
- subscription_collection.update_one(
38
- {"user_id": user_id},
39
- {
40
- "$push": {"payments": payment_data},
41
- "$set": {
42
- "is_premium": True,
43
- "premium_expiration": payment_data["expiration_date"],
44
- "last_payment": payment_data["date"],
45
- },
46
- },
47
- upsert=True,
48
- )
49
-
50
-
51
- def check_subscription_status(user_id: int) -> bool:
52
- """Check if user has an active subscription."""
53
- subscription = get_subscription(user_id)
54
-
55
- if not subscription.get("is_premium"):
56
- return False
57
-
58
- expiration = datetime.fromisoformat(subscription["premium_expiration"])
59
- return expiration > datetime.now()
60
-
61
-
62
10
  async def get_subscription_keyboard(update: Update, lang: str) -> InlineKeyboardMarkup:
63
11
  """Get subscription keyboard
64
12
 
@@ -149,7 +97,7 @@ async def subscribe_command(
149
97
  update: Update, context: ContextTypes.DEFAULT_TYPE, mongo_manager: MongoManager, bot_logger: BotLogger
150
98
  ) -> None:
151
99
  """Show subscription options"""
152
- user_info = get_user_info(update, mongo_manager)
100
+ user_info = mongo_manager.get_user_info(update)
153
101
  user_id = user_info["user_id"]
154
102
  lang = user_info["lang"]
155
103
  bot_name = context.bot.name
@@ -166,11 +114,11 @@ async def check_subscription_command(
166
114
  update: Update, context: ContextTypes.DEFAULT_TYPE, mongo_manager: MongoManager
167
115
  ):
168
116
  """Check user's subscription status"""
169
- user_info = get_user_info(update, mongo_manager)
117
+ user_info = mongo_manager.get_user_info(update)
170
118
  user_id = user_info["user_id"]
171
119
  lang = user_info["lang"]
172
120
 
173
- subscription = get_subscription(user_id)
121
+ subscription = mongo_manager.get_subscription(user_id)
174
122
  if subscription.get("is_premium"):
175
123
  expiration = datetime.fromisoformat(subscription["premium_expiration"])
176
124
  remaining = (expiration - datetime.now()).days
@@ -183,7 +131,7 @@ async def check_subscription_command(
183
131
  )
184
132
  )
185
133
  else:
186
- update_subscription(user_id, {"is_premium": False})
134
+ mongo_manager.update_subscription(user_id, {"is_premium": False})
187
135
  await update.message.reply_text(t("subscription.expired", lang))
188
136
  else:
189
137
  await update.message.reply_text(t("subscription.none", lang))
telegram_libs/utils.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from logging import basicConfig, getLogger, INFO
2
+ from datetime import datetime
2
3
  from telegram import (
3
4
  InlineKeyboardButton,
4
5
  InlineKeyboardMarkup,
@@ -11,6 +12,7 @@ from telegram_libs.mongo import MongoManager
11
12
  from telegram_libs.logger import BotLogger
12
13
 
13
14
 
15
+
14
16
  basicConfig(
15
17
  format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=INFO
16
18
  )
@@ -59,16 +61,49 @@ async def more_bots_list_command(update: Update, context: ContextTypes.DEFAULT_T
59
61
  await update.message.reply_text(message, disable_web_page_preview=True, parse_mode='HTML')
60
62
 
61
63
 
62
- def get_user_info(update: Update, mongo_manager: MongoManager) -> dict:
63
- """Get user information from the update object."""
64
- user = update.effective_user
65
- user_data = mongo_manager.get_user_data(user.id)
64
+ class RateLimitManager:
65
+ """Rate limit manager to handle user rate limits."""
66
66
 
67
- return {
68
- "user_id": user.id,
69
- "username": user.username,
70
- "first_name": user.first_name,
71
- "last_name": user.last_name,
72
- "lang": user_data.get("language", "en"),
73
- **user_data,
74
- }
67
+ def __init__(self, mongo_manager: MongoManager, rate_limit: int = 5):
68
+ self.mongo_manager = mongo_manager
69
+ self.rate_limit = rate_limit
70
+
71
+ def check_limit(self, user_id: int) -> bool:
72
+ """Check if user has exceeded the daily rate limit."""
73
+ # Premium users have no limits
74
+ if self.mongo_manager.check_subscription_status(user_id):
75
+ return True
76
+
77
+ # Get today's date and reset time to midnight
78
+ today = datetime.now().date()
79
+
80
+ # If last action date is not today, reset the counter
81
+ user_data = self.mongo_manager.get_user_data(user_id)
82
+ last_action_date_str = user_data.get("last_action_date")
83
+ if last_action_date_str:
84
+ last_action_date = datetime.fromisoformat(last_action_date_str).date()
85
+ if last_action_date != today:
86
+ self.mongo_manager.update_user_data(
87
+ user_id,
88
+ {
89
+ "actions_today": 0,
90
+ "last_action_date": datetime.now().isoformat(),
91
+ },
92
+ )
93
+ return True
94
+
95
+ # Check if user has exceeded the limit
96
+ actions_today = user_data.get("actions_today", 0)
97
+ if actions_today >= self.rate_limit:
98
+ return False
99
+
100
+ return True
101
+
102
+ def increment_action_count(self, user_id: int) -> None:
103
+ """Increment the daily action count for the user."""
104
+ user_data = self.mongo_manager.get_user_data(user_id)
105
+ current_actions = user_data.get("actions_today", 0)
106
+ self.mongo_manager.update_user_data(
107
+ user_id,
108
+ {"actions_today": current_actions + 1, "last_action_date": datetime.now().isoformat()},
109
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: telegram_libs
3
- Version: 0.1.25
3
+ Version: 0.1.27
4
4
  Summary: Common libraries for Telegram bots
5
5
  Author: Andrey Gritsaenko gricaenko.95a@gmail.com
6
6
  Requires-Python: >=3.11,<4.0
@@ -1,17 +1,17 @@
1
1
  telegram_libs/__init__.py,sha256=xrsD5r6ZiJxPapHf1UhQ61z2gHtCCWrzW0CZHvlvXRc,82
2
- telegram_libs/constants.py,sha256=GUh8G7CGyI_ZoGBBBiTv3Ku6ad9ecIczjSjLcI8sLo0,946
2
+ telegram_libs/constants.py,sha256=mATa2Pr4YzPGNrqw29kOHK7sSefWvENZ-byPPZCBTc8,958
3
3
  telegram_libs/error.py,sha256=uomabeEiSP4v4AEpKYbi_gR0l3G003sio6lKl72AinY,453
4
4
  telegram_libs/handlers.py,sha256=d5-4FvjyWcJeN1i3dHTYhF-2P4j7PbM1QElloFR_llg,2417
5
5
  telegram_libs/locales/en.json,sha256=4VVkME7lCKW6ZjkopaoA6Uq3DLbEVkWacGei3GNSXFM,843
6
6
  telegram_libs/locales/ru.json,sha256=LYI6rAlwdNLaTGgkrALn31Lt7jC3SZteei8P_i7ZpQI,1208
7
7
  telegram_libs/logger.py,sha256=oikvkZMk2kOLvQI9hVMUGMCoSnOPf_fhMvv2SbO-STo,891
8
- telegram_libs/mongo.py,sha256=MmnW7wgdZNz4jyhjYSx_CLsLasdiXt2tGenOFhTTVTw,2450
9
- telegram_libs/payment.py,sha256=PSoagCTUt4xad-39kVYc2tcFgaPMQsP9eplCVqI9hnc,3661
10
- telegram_libs/subscription.py,sha256=PFgoWKgjRrjzBjK-AMrESt_7aFk0pa8Qr_Wl1aQIoW8,6430
8
+ telegram_libs/mongo.py,sha256=j1UIGnldvaNZaFPltCvEUcUOOCoquBWvqPh7Q2HTrvY,4776
9
+ telegram_libs/payment.py,sha256=cNb2vnBlYI_6KnTGz-PCM0uKahW2uGjHVn1mGYlYG-4,3564
10
+ telegram_libs/subscription.py,sha256=NJlh1kcDfasX1XLpkVfe1UbZslpWSC1hXHaum0kfG8A,4693
11
11
  telegram_libs/support.py,sha256=a3BA7g3seVBUMasv65SzxebLayLigA069wvDcStYbCM,2748
12
12
  telegram_libs/translation.py,sha256=8Kb2cgqKKZH4X_i2Le0V_K1imZdoaCzYAca831DOBig,2049
13
- telegram_libs/utils.py,sha256=9TzQt6PD_BAO5uHoYpReIM5mNeW0AcEHe-bihmIueEk,2382
14
- telegram_libs-0.1.25.dist-info/LICENSE,sha256=ZXkWPZbCc61L29Gz6ZHPwn1c4Pm0TnfIqtx8jGWi9F4,1069
15
- telegram_libs-0.1.25.dist-info/METADATA,sha256=PGXZNQT0UTM3ahHdZ3DriNY4PZOjiv2ah4bCVGLlNV8,804
16
- telegram_libs-0.1.25.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
17
- telegram_libs-0.1.25.dist-info/RECORD,,
13
+ telegram_libs/utils.py,sha256=YnxeZFBLEb95swNlER6Vulv3-TXXVgUTGmzpYUROVY0,3796
14
+ telegram_libs-0.1.27.dist-info/LICENSE,sha256=ZXkWPZbCc61L29Gz6ZHPwn1c4Pm0TnfIqtx8jGWi9F4,1069
15
+ telegram_libs-0.1.27.dist-info/METADATA,sha256=DhniNOJ1-RW0DhJNn2QvH6lWL0tH56SvRNMrJPVUbOw,804
16
+ telegram_libs-0.1.27.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
17
+ telegram_libs-0.1.27.dist-info/RECORD,,