d4rktg 0.5.0__tar.gz → 0.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.
Files changed (33) hide show
  1. {d4rktg-0.5.0 → d4rktg-0.5.2}/PKG-INFO +1 -1
  2. d4rktg-0.5.2/VERSION.txt +1 -0
  3. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Handlers/_bot.py +23 -7
  4. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_round.py +21 -16
  5. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rktg.egg-info/PKG-INFO +1 -1
  6. d4rktg-0.5.0/VERSION.txt +0 -1
  7. {d4rktg-0.5.0 → d4rktg-0.5.2}/MANIFEST.in +0 -0
  8. {d4rktg-0.5.0 → d4rktg-0.5.2}/README.rst +0 -0
  9. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Database/__init__.py +0 -0
  10. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Database/db.py +0 -0
  11. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Handlers/__init__.py +0 -0
  12. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Handlers/_scheduler.py +0 -0
  13. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Logs/__init__.py +0 -0
  14. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Logs/_logger.py +0 -0
  15. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Models/__init__.py +0 -0
  16. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Models/_commands.py +0 -0
  17. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Models/_movie_title.py +0 -0
  18. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/__init__.py +0 -0
  19. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_decorators.py +0 -0
  20. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_delete.py +0 -0
  21. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_fonts.py +0 -0
  22. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_ip.py +0 -0
  23. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_movie_parser.py +0 -0
  24. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_ractions.py +0 -0
  25. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/Utils/_terminal.py +0 -0
  26. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rk/__init__.py +0 -0
  27. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rktg.egg-info/SOURCES.txt +0 -0
  28. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rktg.egg-info/dependency_links.txt +0 -0
  29. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rktg.egg-info/requires.txt +0 -0
  30. {d4rktg-0.5.0 → d4rktg-0.5.2}/d4rktg.egg-info/top_level.txt +0 -0
  31. {d4rktg-0.5.0 → d4rktg-0.5.2}/requirements.txt +0 -0
  32. {d4rktg-0.5.0 → d4rktg-0.5.2}/setup.cfg +0 -0
  33. {d4rktg-0.5.0 → d4rktg-0.5.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: d4rktg
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: A module for create with easy and fast
5
5
  Author: D4rkShell
6
6
  Author-email: premiumqtrst@gmail.com
@@ -0,0 +1 @@
1
+ 0.5.2
@@ -12,6 +12,9 @@ from pyrogram.errors.exceptions.bad_request_400 import AccessTokenExpired
12
12
 
13
13
  from d4rk.Logs import setup_logger
14
14
 
15
+ logs_sent = False
16
+ logs_lock = asyncio.Lock()
17
+
15
18
  logger = setup_logger(__name__)
16
19
 
17
20
  class BotManager(Client):
@@ -98,22 +101,35 @@ class BotManager(Client):
98
101
  await self.setup_webserver()
99
102
 
100
103
  async def powerdown(self, *args):
104
+ global logs_sent, logs_lock
101
105
  logger.info("Initiating APP to stop...")
102
106
  if self._rename:await super().set_bot_info(lang_code='en',name=self.app_name + " (Offline)")
103
107
  self.stop_scheduler()
104
108
  today = self.TZ_now.strftime("%Y-%m-%d")
105
109
  if hasattr(self, '_web_runner') and self._web_runner:
106
110
  await self.web_server.cleanup()
107
- if self._is_connected:
108
- logger.info("Stopping bot client...")
111
+
112
+ logger.info("Stopping bot client...")
113
+ if self._is_connected and self.LOGS:
109
114
  try:
110
- if self.LOGS:
111
- await self.send_message(chat_id=self.LOGS, text=f"{self._bot_info.mention} stopping...")
115
+ await self.send_message(chat_id=self.LOGS, text=f"{self._bot_info.mention} stopping...")
116
+ except Exception as e:
117
+ logger.error(f"Error sending stop message for {self._bot_info.first_name}: {e}")
118
+
119
+ async with logs_lock:
120
+ if not logs_sent and self._is_connected:
121
+ logs_sent = True
122
+ try:
112
123
  await self.send_document(chat_id=self.LOGS, document=f"logs/log-{today}.txt")
113
- await self.send_message(chat_id=self.LOGS, text=f"{self._bot_info.mention} stopped successfully!")
124
+ logger.info("Log document sent successfully")
125
+ except Exception as e:
126
+ logger.error(f"Error sending log document: {e}")
127
+
128
+ if self._is_connected and self.LOGS:
129
+ try:
130
+ await self.send_message(chat_id=self.LOGS, text=f"{self._bot_info.mention} stopped successfully!")
114
131
  except Exception as e:
115
- logger.error(f"Error sending stop notification: {e}")
116
- logger.info(f"{self._bot_info.first_name} - @{self._bot_info.username} Stoped")
132
+ logger.error(f"Error sending stop confirmation for {self._bot_info.first_name}: {e}")
117
133
  await super().stop()
118
134
  sys.exit(0)
119
135
 
@@ -1,5 +1,6 @@
1
1
  from functools import wraps
2
2
  from pyrogram.types import Message
3
+ import asyncio
3
4
 
4
5
  # Track last bot index per chat
5
6
  last_index_per_chat = {}
@@ -7,6 +8,8 @@ last_index_per_chat = {}
7
8
  bot_order_per_chat = {}
8
9
  # Track messages already responded to: chat_id -> set of message_ids
9
10
  responded_messages = {}
11
+ # Lock per chat to prevent race conditions
12
+ chat_locks = {}
10
13
 
11
14
  def round_robin():
12
15
  def decorator(func):
@@ -24,26 +27,28 @@ def round_robin():
24
27
  bot_order_per_chat[chat_id] = [client.me.id]
25
28
  last_index_per_chat[chat_id] = 0
26
29
  responded_messages[chat_id] = set()
30
+ chat_locks[chat_id] = asyncio.Lock()
27
31
 
28
- # Skip if message already responded by any bot
29
- if msg_id in responded_messages[chat_id]:
30
- return
31
-
32
- # Add new bots if not in the chat
32
+ # Add new bot if not in the chat
33
33
  if client.me.id not in bot_order_per_chat[chat_id]:
34
34
  bot_order_per_chat[chat_id].append(client.me.id)
35
35
 
36
- current_index = last_index_per_chat[chat_id]
37
- selected_bot_id = bot_order_per_chat[chat_id][current_index]
38
-
39
- # Only selected bot responds
40
- if client.me.id == selected_bot_id:
41
- result = await func(client, message, *args, **kwargs)
42
- # Mark message as responded
43
- responded_messages[chat_id].add(msg_id)
44
- # Rotate index
45
- last_index_per_chat[chat_id] = (current_index + 1) % len(bot_order_per_chat[chat_id])
46
- return result
36
+ async with chat_locks[chat_id]:
37
+ # Skip if message already responded
38
+ if msg_id in responded_messages[chat_id]:
39
+ return
40
+
41
+ # Decide which bot should respond
42
+ current_index = last_index_per_chat[chat_id]
43
+ selected_bot_id = bot_order_per_chat[chat_id][current_index]
44
+
45
+ if client.me.id == selected_bot_id:
46
+ result = await func(client, message, *args, **kwargs)
47
+ # Mark message as responded
48
+ responded_messages[chat_id].add(msg_id)
49
+ # Rotate for next message
50
+ last_index_per_chat[chat_id] = (current_index + 1) % len(bot_order_per_chat[chat_id])
51
+ return result
47
52
 
48
53
  return wrapper
49
54
  return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: d4rktg
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: A module for create with easy and fast
5
5
  Author: D4rkShell
6
6
  Author-email: premiumqtrst@gmail.com
d4rktg-0.5.0/VERSION.txt DELETED
@@ -1 +0,0 @@
1
- 0.5.0
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
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