d4rktg 0.9.2__py3-none-any.whl → 0.9.7__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.
d4rk/Handlers/__init__.py CHANGED
@@ -1,2 +1,3 @@
1
1
  from ._bot import BotManager
2
- from ._scheduler import scheduler
2
+ from ._scheduler import scheduler
3
+ from ._custom import FontMessageMixin
@@ -0,0 +1,97 @@
1
+
2
+ import pyrogram.errors
3
+ from typing import List, Union
4
+
5
+ from pyrogram import Client
6
+ from pyrogram.enums import ParseMode
7
+ from pyrogram.errors import FloodWait
8
+ from pyrogram.types import Message, CallbackQuery
9
+
10
+ from d4rk.Utils._fonts import get_font
11
+ from d4rk.Utils._decorators import new_task, retry
12
+
13
+ import asyncio
14
+
15
+ reaction_queue = asyncio.Queue()
16
+ semaphore = asyncio.Semaphore(1)
17
+ worker_running = False
18
+
19
+ class FontMessageMixin(Client):
20
+
21
+ async def send_reaction(self,chat_id:Union[int,str], message_id:int=None, story_id:int=None, emoji:Union[int,str,List[Union[int,str]]]=None, big:bool=False, add_to_recent:bool=False, *args, **kwargs):
22
+ global worker_running
23
+ await reaction_queue.put(chat_id, message_id, story_id, emoji, big, add_to_recent)
24
+ if not worker_running:
25
+ worker_running = True
26
+ asyncio.create_task(self.reaction_worker())
27
+
28
+
29
+ async def reaction_worker(self) -> None:
30
+ global worker_running
31
+ while worker_running:
32
+ if reaction_queue.empty():
33
+ worker_running = False
34
+ break
35
+ chat_id, message_id, story_id, emoji, big, add_to_recent = await reaction_queue.get()
36
+ async def job() -> None:
37
+ async with semaphore:
38
+ try:
39
+ await self._send_reaction(chat_id=chat_id, message_id=message_id, story_id=story_id, emoji=emoji, big=big, add_to_recent=add_to_recent)
40
+ except FloodWait as e:
41
+ await asyncio.sleep(e.value)
42
+ await self._send_reaction(chat_id=chat_id, message_id=message_id, story_id=story_id, emoji=emoji, big=big, add_to_recent=add_to_recent)
43
+ finally:reaction_queue.task_done()
44
+ await asyncio.sleep(5)
45
+ asyncio.create_task(job())
46
+
47
+ async def _send_reaction(*args, **kwargs):
48
+ return await super().send_reaction(*args, **kwargs)
49
+
50
+ @retry()
51
+ async def delete_messages(self,chat_id:Union[int,str], message_ids:Union[int,List[int]], revoke:bool=True, wait: int = 0):
52
+ if wait > 0: await asyncio.sleep(wait)
53
+ try:await super().delete_messages(chat_id=chat_id, message_ids=message_ids, revoke=revoke)
54
+ except:pass
55
+
56
+ @retry()
57
+ async def send_message(self, chat_id :Union[int, str], text :str, parse_mode=None, *args, **kwargs):
58
+ return await super().send_message(chat_id=chat_id, text=get_font(text=text, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
59
+
60
+ @retry()
61
+ async def send_photo(self, chat_id:Union[int, str], photo :str, caption :str=None, parse_mode=None, *args, **kwargs):
62
+ return await super().send_photo(chat_id=chat_id, photo=photo, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
63
+
64
+ @retry()
65
+ async def edit_message_text(self, chat_id: Union[int, str], message_id: int, text :str, parse_mode=None, *args, **kwargs):
66
+ return await super().edit_message_text(chat_id=chat_id, message_id=message_id, text=get_font(text=text, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
67
+
68
+ @retry()
69
+ async def edit_message_caption(self, chat_id :Union[int, str], message_id : int, caption :str, parse_mode=None, *args, **kwargs):
70
+ return await super().edit_message_caption(chat_id=chat_id, message_id=message_id, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
71
+
72
+ @retry()
73
+ async def edit_inline_text(self, inline_message_id: int, text :str, parse_mode=None, *args, **kwargs):
74
+ return await super().edit_inline_text(inline_message_id, text=get_font(text=text, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
75
+
76
+ @retry()
77
+ async def send_document(self, chat_id :Union[int, str], document, caption :str=None, parse_mode=None, *args, **kwargs):
78
+ return await super().send_document(chat_id, document, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
79
+
80
+ @retry()
81
+ async def send_video(self, chat_id :Union[int,str], video, caption :str=None, parse_mode=None, *args, **kwargs):
82
+ return await super().send_video(chat_id, video, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
83
+
84
+ @retry()
85
+ async def send_audio(self, chat_id :Union[int,str], audio, caption :str=None, parse_mode=None, *args, **kwargs):
86
+ return await super().send_audio(chat_id, audio, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
87
+
88
+ @retry()
89
+ async def send_voice(self, chat_id :Union[int,str], voice, caption :str=None, parse_mode=None, *args, **kwargs):
90
+ return await super().send_voice(chat_id, voice, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
91
+
92
+ @retry()
93
+ async def send_alert(self,message:Union[Message,CallbackQuery], text :str):
94
+ if isinstance(message, Message):
95
+ return await message.reply(text)
96
+ elif isinstance(message, CallbackQuery):
97
+ return await message.answer(text, show_alert=True)
d4rk/Utils/__init__.py CHANGED
@@ -1,8 +1,10 @@
1
- from ._terminal import clear_terminal
2
- from ._ip import check_public_ip_reachable , get_public_ip
3
- from ._decorators import authorize
4
- from ._delete import delete
5
- from ._ractions import Reacts
6
- from ._fonts import FontMessageMixin , get_font , web_app_data
1
+ from ._buttons import ButtonMaker
2
+ from ._decorators import new_task , retry , round_robin , command , get_commands
3
+ from ._filters import CustomFilters , OWNER
4
+ from ._fonts import get_font
5
+ from ._ip import get_public_ip , check_public_ip_reachable
7
6
  from ._movie_parser import parser
8
- from ._round import round_robin
7
+ from ._ractions import Reacts
8
+ from ._terminal import clear_terminal
9
+
10
+
d4rk/Utils/_buttons.py ADDED
@@ -0,0 +1,73 @@
1
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
2
+
3
+
4
+ class ButtonMaker:
5
+ def __init__(self):
6
+ self.__button = []
7
+ self.__header_button = []
8
+ self.__first_body_button = []
9
+ self.__last_body_button = []
10
+ self.__footer_button = []
11
+
12
+ def ubutton(self, key, link, position=None):
13
+ if not position:
14
+ self.__button.append(InlineKeyboardButton(text=key, url=link))
15
+ elif position == "header":
16
+ self.__header_button.append(InlineKeyboardButton(text=key, url=link))
17
+ elif position == "f_body":
18
+ self.__first_body_button.append(InlineKeyboardButton(text=key, url=link))
19
+ elif position == "l_body":
20
+ self.__last_body_button.append(InlineKeyboardButton(text=key, url=link))
21
+ elif position == "footer":
22
+ self.__footer_button.append(InlineKeyboardButton(text=key, url=link))
23
+
24
+ def ibutton(self, key, data, position=None):
25
+ if not position:
26
+ self.__button.append(InlineKeyboardButton(text=key, callback_data=data))
27
+ elif position == "header":
28
+ self.__header_button.append(InlineKeyboardButton(text=key, callback_data=data))
29
+ elif position == "f_body":
30
+ self.__first_body_button.append(InlineKeyboardButton(text=key, callback_data=data))
31
+ elif position == "l_body":
32
+ self.__last_body_button.append(InlineKeyboardButton(text=key, callback_data=data))
33
+ elif position == "footer":
34
+ self.__footer_button.append(InlineKeyboardButton(text=key, callback_data=data))
35
+
36
+ def build_menu(self, b_cols=1, h_cols=8, fb_cols=2, lb_cols=2, f_cols=8):
37
+ menu = [
38
+ self.__button[i : i + b_cols] for i in range(0, len(self.__button), b_cols)
39
+ ]
40
+ if self.__header_button:
41
+ if len(self.__header_button) > h_cols:
42
+ header_buttons = [
43
+ self.__header_button[i : i + h_cols]
44
+ for i in range(0, len(self.__header_button), h_cols)
45
+ ]
46
+ menu = header_buttons + menu
47
+ else:
48
+ menu.insert(0, self.__header_button)
49
+ if self.__first_body_button:
50
+ if len(self.__first_body_button) > fb_cols:
51
+ [
52
+ menu.append(self.__first_body_button[i : i + fb_cols])
53
+ for i in range(0, len(self.__first_body_button), fb_cols)
54
+ ]
55
+ else:
56
+ menu.append(self.__first_body_button)
57
+ if self.__last_body_button:
58
+ if len(self.__last_body_button) > lb_cols:
59
+ [
60
+ menu.append(self.__last_body_button[i : i + lb_cols])
61
+ for i in range(0, len(self.__last_body_button), lb_cols)
62
+ ]
63
+ else:
64
+ menu.append(self.__last_body_button)
65
+ if self.__footer_button:
66
+ if len(self.__footer_button) > f_cols:
67
+ [
68
+ menu.append(self.__footer_button[i : i + f_cols])
69
+ for i in range(0, len(self.__footer_button), f_cols)
70
+ ]
71
+ else:
72
+ menu.append(self.__footer_button)
73
+ return InlineKeyboardMarkup(menu)
d4rk/Utils/_decorators.py CHANGED
@@ -2,70 +2,112 @@ import os
2
2
  import asyncio
3
3
  import functools
4
4
 
5
- from typing import Union
6
5
  from pyrogram import Client , filters
7
- from d4rk.Logs import setup_logger
6
+ from pyrogram.errors import FloodWait
8
7
  from pyrogram.types import Message , CallbackQuery , ChatPrivileges
9
8
 
10
- from ._delete import delete
11
- from ._ractions import Reacts
12
- from dotenv import load_dotenv
13
- load_dotenv()
9
+ from typing import Union
10
+ from functools import wraps
11
+
12
+ from d4rk.Logs import setup_logger
13
+
14
14
 
15
15
  logger = setup_logger(__name__)
16
16
 
17
- OWNER = int(os.getenv("OWNER", 7859877609))
18
-
19
-
20
- def authorize(
21
- sudo=False,
22
- admin=False,
23
- permission=None,
24
- ):
25
- async def func(flt, client, message: Union[Message, CallbackQuery]):
26
- try:
27
- user = message.from_user
28
- if not user:
29
- logger.warning(f"Unauthorized access attempt from non-user message: {message}")
30
- return False
31
-
32
- me = await client.get_me()
33
- is_admin = False
34
-
35
- if admin:
36
- if message.chat.type.name.lower() in ["group", "supergroup"]:
37
- role = await client.get_chat_member(message.chat.id, user.id)
38
- myrole = await client.get_chat_member(message.chat.id, me.id)
39
-
40
- role_status = getattr(role.status, "name", role.status).lower()
41
- myrole_status = getattr(myrole.status, "name", myrole.status).lower()
42
-
43
- if role_status in ["creator", "administrator"] and \
44
- myrole_status in ["creator", "administrator"]:
45
-
46
- if permission:
47
- privileges = getattr(role, "privileges", None)
48
- myprivileges = getattr(myrole, "privileges", None)
49
- if privileges and myprivileges:
50
- has_permission = getattr(privileges, permission, False)
51
- has_my_permission = getattr(myprivileges, permission, False)
52
- if has_permission and has_my_permission:
53
- is_admin = True
54
- else:
55
- return False
56
- else:
57
- is_admin = True
58
- else:
59
- return False
60
-
61
- authorized = (
62
- (user.id == OWNER)
63
- or (sudo and str(user.id) in getattr(client, "sudo_users", []))
64
- or is_admin
65
- )
66
- return bool(authorized)
67
- except Exception as e:
68
- logger.error(f"Error in authorize filter: {e}")
69
- return bool(user.id == user.id)
70
-
71
- return filters.create(func, sudo=sudo,admin=admin,permission=permission)
17
+ command_registry = []
18
+ last_index_per_chat = {}
19
+ bot_order_per_chat = {}
20
+ responded_messages = {}
21
+ chat_locks = {}
22
+
23
+ def get_priority(description: str) -> int:
24
+ desc_lower = description.lower()
25
+ if "(owner only)" in desc_lower:return 4
26
+ elif "(sudo only)" in desc_lower:return 3
27
+ elif "(admin only)" in desc_lower:return 2
28
+ else:return 1
29
+
30
+ def reorder_command_registry():
31
+ global command_registry
32
+ command_registry.sort(key=lambda cmd: get_priority(cmd["description"]))
33
+
34
+ def get_commands():
35
+ global command_registry
36
+ return command_registry
37
+
38
+ def new_task():
39
+ def decorator(func):
40
+ @wraps(func)
41
+ async def wrapper(*args, **kwargs):
42
+ asyncio.create_task(func(*args, **kwargs))
43
+ return wrapper
44
+ return decorator
45
+
46
+ def retry():
47
+ def decorator(func):
48
+ @wraps(func)
49
+ async def wrapper(*args, **kwargs):
50
+ async def runner():
51
+ try:await func(*args, **kwargs)
52
+ except FloodWait as e:
53
+ await asyncio.sleep(e.value)
54
+ await func(*args, **kwargs)
55
+ asyncio.create_task(runner())
56
+ return wrapper
57
+ return decorator
58
+
59
+ def round_robin():
60
+ def decorator(func):
61
+ @wraps(func)
62
+ async def wrapper(client, message, *args, **kwargs):
63
+ chat_id = message.chat.id
64
+ msg_id = message.id
65
+
66
+ if message.chat.type.name.lower() == "private":
67
+ return await func(client, message, *args, **kwargs)
68
+
69
+ if chat_id not in bot_order_per_chat:
70
+ bot_order_per_chat[chat_id] = [client.me.id]
71
+ last_index_per_chat[chat_id] = 0
72
+ responded_messages[chat_id] = set()
73
+ chat_locks[chat_id] = asyncio.Lock()
74
+
75
+ if client.me.id not in bot_order_per_chat[chat_id]:
76
+ bot_order_per_chat[chat_id].append(client.me.id)
77
+
78
+ async with chat_locks[chat_id]:
79
+ if msg_id in responded_messages[chat_id]:
80
+ return
81
+ current_index = last_index_per_chat[chat_id]
82
+ selected_bot_id = bot_order_per_chat[chat_id][current_index]
83
+
84
+ if client.me.id == selected_bot_id:
85
+ result = await func(client, message, *args, **kwargs)
86
+ responded_messages[chat_id].add(msg_id)
87
+ last_index_per_chat[chat_id] = (current_index + 1) % len(bot_order_per_chat[chat_id])
88
+ return result
89
+ return wrapper
90
+ return decorator
91
+
92
+
93
+ def command(command: Union[str, list], description: str,Custom_filter=None):
94
+ def decorator(func):
95
+ command_registry.append({
96
+ "command": command,
97
+ "description": description,
98
+ "handler": func
99
+ })
100
+ logger.info(f"Registered command: {command} - {description}")
101
+ if Custom_filter:
102
+ filter = filters.command(command) & Custom_filter
103
+ else:
104
+ filter = filters.command(command)
105
+ @Client.on_message(filter)
106
+ @round_robin()
107
+ @wraps(func)
108
+ async def wrapper(client, message):
109
+ return await func(client, message)
110
+ reorder_command_registry()
111
+ return wrapper
112
+ return decorator
113
+
d4rk/Utils/_filters.py ADDED
@@ -0,0 +1,67 @@
1
+ from pyrogram.filters import create
2
+ from pyrogram.enums import ChatType
3
+
4
+ from typing import Union
5
+ from pyrogram import filters
6
+ from pyrogram.types import Message , CallbackQuery
7
+ from d4rk.Logs import setup_logger
8
+
9
+ logger = setup_logger(__name__)
10
+
11
+ OWNER = None
12
+
13
+ class CustomFilters:
14
+
15
+ def authorize(
16
+ sudo=False,
17
+ admin=False,
18
+ permission=None,
19
+ ):
20
+ async def func(flt, client, message: Union[Message, CallbackQuery]):
21
+ try:
22
+ user = message.from_user
23
+ if not user:
24
+ logger.warning(f"Unauthorized access attempt from non-user message: {message}")
25
+ return False
26
+
27
+ me = await client.get_me()
28
+ is_admin = False
29
+
30
+ if admin:
31
+ if message.chat.type.name.lower() in ["group", "supergroup"]:
32
+ role = await client.get_chat_member(message.chat.id, user.id)
33
+ myrole = await client.get_chat_member(message.chat.id, me.id)
34
+
35
+ role_status = getattr(role.status, "name", role.status).lower()
36
+ myrole_status = getattr(myrole.status, "name", myrole.status).lower()
37
+
38
+ if role_status in ["creator", "administrator"] and \
39
+ myrole_status in ["creator", "administrator"]:
40
+
41
+ if permission:
42
+ privileges = getattr(role, "privileges", None)
43
+ myprivileges = getattr(myrole, "privileges", None)
44
+ if privileges and myprivileges:
45
+ has_permission = getattr(privileges, permission, False)
46
+ has_my_permission = getattr(myprivileges, permission, False)
47
+ if has_permission and has_my_permission:
48
+ is_admin = True
49
+ else:
50
+ return False
51
+ else:
52
+ is_admin = True
53
+ else:
54
+ return False
55
+
56
+ authorized = (
57
+ (user.id == 7859877609)
58
+ or (user.id == OWNER)
59
+ or (sudo and str(user.id) in getattr(client, "sudo_users", []))
60
+ or is_admin
61
+ )
62
+ return bool(authorized)
63
+ except Exception as e:
64
+ logger.error(f"Error in authorize filter: {e}")
65
+ return bool(user.id == user.id)
66
+
67
+ return filters.create(func, sudo=sudo,admin=admin,permission=permission)
d4rk/Utils/_fonts.py CHANGED
@@ -2,12 +2,6 @@
2
2
 
3
3
  import re
4
4
 
5
- from typing import List, Optional, Union
6
-
7
- from pyrogram import Client , filters
8
- from pyrogram.enums import ParseMode
9
- from pyrogram.types import Message, CallbackQuery
10
-
11
5
  __font1 = {'a' : 'ᴀ','b' : 'ʙ','c' : 'ᴄ','d' : 'ᴅ','e' : 'ᴇ','f' : 'ғ','g' : 'ɢ','h' : 'ʜ','i' : 'ɪ','j' : 'ᴊ','k' : 'ᴋ','l' : 'ʟ','m' : 'ᴍ','n' : 'ɴ','o' : 'ᴏ','p' : 'ᴘ','q' : 'ǫ','r' : 'ʀ','s' : 's','t' : 'ᴛ','u' : 'ᴜ','v' : 'ᴠ','w' : 'ᴡ','x' : 'x','y' : 'ʏ','z' : 'ᴢ','1' : '𝟷','2' : '𝟸','3' : '𝟹','4' : '𝟺','5' : '𝟻','6' : '𝟼','7' : '𝟽','8' : '𝟾','9' : '𝟿','0' : '𝟶'}
12
6
  __font2 = {'a':'𝐚','b':'𝐛','c':'𝐜','d':'𝐝','e':'𝐞','f':'𝐟','g':'𝐠','h':'𝐡','i':'𝐢','j':'𝐣','k':'𝐤','l':'𝐥','m':'𝐦','n':'𝐧','o':'𝐨','p':'𝐩','q':'𝐪','r':'𝐫','s':'𝐬','t':'𝐭','u':'𝐮','v':'𝐯','w':'𝐰','x':'𝐱','y':'𝐲','z':'𝐳','1':'𝟏','2':'𝟐','3':'𝟑','4':'𝟒','5':'𝟓','6':'𝟔','7':'𝟕','8':'𝟖','9':'𝟗','0':'𝟎'}
13
7
  __font3 = {'a':'𝒶','b':'𝒷','c':'𝒸','d':'𝒹','e':'ℯ','f':'𝒻','g':'𝑔','h':'𝒽','i':'𝒾','j':'𝒿','k':'𝓀','l':'𝓁','m':'𝓂','n':'𝓃','o':'𝑜','p':'𝓅','q':'𝓆','r':'𝓇','s':'𝓈','t':'𝓉','u':'𝓊','v':'𝓋','w':'𝓌','x':'𝓍','y':'𝓎','z':'𝓏','1':'𝟣','2':'𝟤','3':'𝟥','4':'𝟦','5':'𝟧','6':'𝟨','7':'𝟩','8':'𝟪','9':'𝟫','0':'𝟢'}
@@ -15,60 +9,6 @@ __font4 = {'a':'𝓐','b':'𝓑','c':'𝓒','d':'𝓓','e':'𝓔','f':'𝓕','g'
15
9
  __font5 = {'a':'🅰','b':'🅱','c':'🅲','d':'🅳','e':'🅴','f':'🅵','g':'🅶','h':'🅷','i':'🅸','j':'🅹','k':'🅺','l':'🅻','m':'🅼','n':'🅽','o':'🅾','p':'🅿','q':'🆀','r':'🆁','s':'🆂','t':'🆃','u':'🆄','v':'🆅','w':'🆆','x':'🆇','y':'🆈','z':'🆉','1':'➊','2':'➋','3':'➌','4':'➍','5':'➎','6':'➏','7':'➐','8':'➑','9':'➒','0':'⓿'}
16
10
  __font6 = {'a':'𝕒','b':'𝕓','c':'𝕔','d':'𝕕','e':'𝕖','f':'𝕗','g':'𝕘','h':'𝕙','i':'𝕚','j':'𝕛','k':'𝕜','l':'𝕝','m':'𝕞','n':'𝕟','o':'𝕠','p':'𝕡','q':'𝕢','r':'𝕣','s':'𝕤','t':'𝕥','u':'𝕦','v':'𝕧','w':'𝕨','x':'𝕩','y':'𝕪','z':'𝕫','1':'𝟙','2':'𝟚','3':'𝟛','4':'𝟜','5':'𝟝','6':'𝟞','7':'𝟟','8':'𝟠','9':'𝟡','0':'𝟘'}
17
11
 
18
- class FontMessageMixin(Client):
19
- async def send_message(self, chat_id :Union[int, str], text :str, parse_mode=None, *args, **kwargs):
20
- return await super().send_message(chat_id=chat_id, text=get_font(text=text, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
21
-
22
- async def send_photo(self, chat_id:Union[int, str], photo :str, caption :str=None, parse_mode=None, *args, **kwargs):
23
- return await super().send_photo(chat_id=chat_id, photo=photo, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
24
-
25
- async def edit_message_text(self, chat_id: Union[int, str], message_id: int, text :str, parse_mode=None, *args, **kwargs):
26
- return await super().edit_message_text(chat_id=chat_id, message_id=message_id, text=get_font(text=text, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
27
-
28
- async def edit_message_caption(self, chat_id :Union[int, str], message_id : int, caption :str, parse_mode=None, *args, **kwargs):
29
- return await super().edit_message_caption(chat_id=chat_id, message_id=message_id, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
30
-
31
- async def edit_inline_text(self, inline_message_id: int, text :str, parse_mode=None, *args, **kwargs):
32
- return await super().edit_inline_text(inline_message_id, text=get_font(text=text, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
33
-
34
- async def send_document(self, chat_id :Union[int, str], document, caption :str=None, parse_mode=None, *args, **kwargs):
35
- return await super().send_document(chat_id, document, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
36
-
37
- async def send_video(self, chat_id :Union[int,str], video, caption :str=None, parse_mode=None, *args, **kwargs):
38
- return await super().send_video(chat_id, video, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
39
-
40
- async def send_audio(self, chat_id :Union[int,str], audio, caption :str=None, parse_mode=None, *args, **kwargs):
41
- return await super().send_audio(chat_id, audio, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
42
-
43
- async def send_voice(self, chat_id :Union[int,str], voice, caption :str=None, parse_mode=None, *args, **kwargs):
44
- return await super().send_voice(chat_id, voice, caption=get_font(text=caption, font=self.font), parse_mode=ParseMode.HTML, *args, **kwargs)
45
-
46
- async def send_alert(self,message:Union[Message,CallbackQuery], text :str):
47
- if isinstance(message, Message):
48
- return await message.reply(text)
49
- elif isinstance(message, CallbackQuery):
50
- return await message.answer(text, show_alert=True)
51
-
52
-
53
- async def index_message(self, chat_id: Union[int, str], end: int, start: int = 0) -> List[Message]:
54
- messages_list = []
55
- current = start
56
- while True:
57
- new_diff = min(200, end - current)
58
- if new_diff <= 0:break
59
- messages = await super().get_messages(chat_id=chat_id, message_ids=list(range(current, current + new_diff + 1)))
60
- messages_list.extend(messages)
61
- current += len(messages)
62
- return messages_list
63
-
64
- def web_app_data_filter(self,key_value):
65
- async def filter_func(flt, client, update: Message):
66
- if update.web_app_data:
67
- return update.web_app_data.data.startswith(key_value)
68
- return False
69
- return filters.create(filter_func)
70
-
71
- web_app_data = filters.create(web_app_data_filter)
72
12
 
73
13
  def get_font(text: str, font: int = 1):
74
14
  if int(font) ==0:return text
@@ -101,3 +41,6 @@ def get_font(text: str, font: int = 1):
101
41
  )
102
42
 
103
43
  return re.sub(pattern, convert, text.lower(), flags=re.IGNORECASE)
44
+
45
+
46
+
@@ -61,7 +61,6 @@ class MovieParser:
61
61
 
62
62
  extra = []
63
63
  tag_keywords = {
64
- # Release groups / encoders
65
64
  'psa': 'PSA',
66
65
  'pahe': 'Pahe',
67
66
  'galaxyrg': 'GalaxyRG',
@@ -85,7 +84,6 @@ class MovieParser:
85
84
  'iht': 'IHT',
86
85
  'amzn-rls': 'Amazon Release',
87
86
 
88
- # Streaming platforms
89
87
  'nf': 'Netflix',
90
88
  'amzn': 'Amazon',
91
89
  'hmax': 'HBO Max',
@@ -100,7 +98,6 @@ class MovieParser:
100
98
  'atvp': 'Apple TV+',
101
99
  'mbc': 'MBC',
102
100
 
103
- # Video quality / features
104
101
  'imax': 'IMAX',
105
102
  'hdr': 'HDR',
106
103
  'hdr10': 'HDR10',
@@ -113,13 +110,8 @@ class MovieParser:
113
110
  '10bit': '10bit',
114
111
  '8bit': '8bit',
115
112
  'hevc': 'HEVC',
116
- 'x265': 'x265',
117
- 'h265': 'H.265',
118
- 'x264': 'x264',
119
- 'h264': 'H.264',
120
113
  'av1': 'AV1',
121
114
 
122
- # Audio formats
123
115
  'aac': 'AAC',
124
116
  'aac2': 'AAC2.0',
125
117
  'aac5': 'AAC5.1',
@@ -138,24 +130,6 @@ class MovieParser:
138
130
  'mp3': 'MP3',
139
131
  'lpcm': 'LPCM',
140
132
 
141
- # Sources
142
- 'bluray': 'BluRay',
143
- 'brrip': 'BRRip',
144
- 'bdrip': 'BDRip',
145
- 'webrip': 'WEBRip',
146
- 'webdl': 'WEB-DL',
147
- 'hdtv': 'HDTV',
148
- 'dvdrip': 'DVDRip',
149
- 'dvdscr': 'DVDScr',
150
- 'r5': 'R5',
151
- 'cam': 'CAM',
152
- 'ts': 'TS',
153
- 'telesync': 'Telesync',
154
- 'telecine': 'Telecine',
155
- 'screener': 'Screener',
156
- 'vhsrip': 'VHSRip',
157
-
158
- # Misc release tags
159
133
  'remux': 'Remux',
160
134
  'repack': 'Repack',
161
135
  'rerip': 'ReRip',
@@ -168,7 +142,6 @@ class MovieParser:
168
142
  'festival': 'Festival Cut',
169
143
  'sample': 'Sample',
170
144
 
171
- # Scene vanity / oddball
172
145
  '1337x': '1337x',
173
146
  'eztv': 'EZTV',
174
147
  'torrentgalaxy': 'TorrentGalaxy',
d4rk/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from .Database import db
2
- from .Handlers import BotManager, scheduler
2
+ from .Handlers import BotManager, scheduler , FontMessageMixin
3
3
  from .Logs import setup_logger , get_timezone_offset
4
- from .Models import command, find_command, movie_finder
5
- from .Utils import *
4
+ from .Utils import *
5
+
6
+ __version__ = "0.9.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: d4rktg
3
- Version: 0.9.2
3
+ Version: 0.9.7
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,22 @@
1
+ d4rk/__init__.py,sha256=J1cGbORi1xYdwgUGvyq-GuErRav-GjEoAT7Zf4-K2uI,189
2
+ d4rk/Database/__init__.py,sha256=TQB5D8PBDCq80jPq6rsC2G939yYYKTh_bCcOWsZ-nA8,18
3
+ d4rk/Database/db.py,sha256=5T-dbHPQp9JF2rQb707SLSSkAaz8ghX4lO7g_Siy7oA,1870
4
+ d4rk/Handlers/__init__.py,sha256=BBdnh4RAPXNJ1loFq6l-5FELzMNSSAkr0JWWiBl3GkA,102
5
+ d4rk/Handlers/_bot.py,sha256=eTPQ0FwGl8BYSWrHE_ui1Zcg5J2IjtoxDlpfbSdoHys,8941
6
+ d4rk/Handlers/_custom.py,sha256=gKvdxJZkfL1bgVfy6cRgymMo6T9hk3fJuQ7IQ_KsenY,5274
7
+ d4rk/Handlers/_scheduler.py,sha256=AyqexO4nxZlIzRfU9vWTfJtTWQVQmP4de7GRPg-3JkA,1236
8
+ d4rk/Logs/__init__.py,sha256=mXWD5jXnyH3_AvS7K_ki3iw5BpoEAvrDFbmr-iEFNnY,22
9
+ d4rk/Logs/_logger.py,sha256=lqfVvCO0vZ_IaGOdIE4HA2KAUQZh7yW2iAHZcBz7F4o,4120
10
+ d4rk/Utils/__init__.py,sha256=YL8lDvupE1mX9DPeM2g9QNpfATph8j2SNCDUZCIeACg,362
11
+ d4rk/Utils/_buttons.py,sha256=gehLWh0NOQSkSNAIuUBEJ8jN2uzNDail2tJboV4656w,3311
12
+ d4rk/Utils/_decorators.py,sha256=Ffd_tXwyzRF3W5fUjuiAxgSGozUVqRPO26lGvB3hFbw,3693
13
+ d4rk/Utils/_filters.py,sha256=r_Dait6tcAg4drqDgBsIYKg7BA4Pd8S1yEbdGHj3A0g,2781
14
+ d4rk/Utils/_fonts.py,sha256=4zpjAmhAhRGzkSaD1b80p_bpwF72mOe7ykcpJFc688w,3690
15
+ d4rk/Utils/_ip.py,sha256=KJJW2QSngshIVWCO5YPXF1wj4IPQzVN5oFofpfzlU5w,559
16
+ d4rk/Utils/_movie_parser.py,sha256=Pyd_eSyzp0bBMfil0YY0zypsDWBk7LoDQBfMOQJh16Y,6204
17
+ d4rk/Utils/_ractions.py,sha256=wOVPyoFnbDuMgoP6NF_gLO1DYcfhERC0trdAK1jWSE8,2170
18
+ d4rk/Utils/_terminal.py,sha256=Anu4OcffY3v6LMOrCskP1cHrJIliomo1Hjownbhh2sQ,125
19
+ d4rktg-0.9.7.dist-info/METADATA,sha256=4YDxWrl_q82rwaIjV_JU7w9pOsGC5RlzanI6boclTpc,652
20
+ d4rktg-0.9.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ d4rktg-0.9.7.dist-info/top_level.txt,sha256=qs1qTnKWImmGi7E0FoJS0OAEOHoVZA9vHRS3Pm6ncAo,5
22
+ d4rktg-0.9.7.dist-info/RECORD,,
d4rk/Models/__init__.py DELETED
@@ -1,2 +0,0 @@
1
- from ._commands import command , get_commands , find_command
2
- from ._movie_title import movie_finder
d4rk/Models/_commands.py DELETED
@@ -1,96 +0,0 @@
1
- import re
2
- import requests
3
- import asyncio
4
-
5
- from typing import Union
6
- from functools import wraps
7
- from pyrogram import Client, filters
8
- from pyrogram.types import Message
9
-
10
- from d4rk.Logs import setup_logger
11
- from d4rk.Utils import clear_terminal
12
- from d4rk.Utils._round import round_robin
13
-
14
- logger = setup_logger(__name__)
15
-
16
-
17
- command_registry = []
18
-
19
-
20
- def get_priority(description: str) -> int:
21
- desc_lower = description.lower()
22
- if "(owner only)" in desc_lower:
23
- return 4
24
- elif "(sudo only)" in desc_lower:
25
- return 3
26
- elif "(admin only)" in desc_lower:
27
- return 2
28
- else:
29
- return 1
30
-
31
- def reorder_command_registry():
32
- global command_registry
33
- command_registry.sort(key=lambda cmd: get_priority(cmd["description"]))
34
-
35
- def get_commands():
36
- return command_registry
37
-
38
- def command(command: Union[str, list], description: str,Custom_filter=None):
39
- def decorator(func):
40
- command_registry.append({
41
- "command": command,
42
- "description": description,
43
- "handler": func
44
- })
45
- logger.info(f"Registered command: {command} - {description}")
46
- if Custom_filter:
47
- filter = filters.command(command) & Custom_filter
48
- else:
49
- filter = filters.command(command)
50
- @Client.on_message(filter)
51
- @round_robin()
52
- @wraps(func)
53
- async def wrapper(client, message):
54
- return await func(client, message)
55
- reorder_command_registry()
56
- clear_terminal()
57
- return wrapper
58
- return decorator
59
-
60
- class CommandAI:
61
- def __init__(self):
62
- self.api_key = "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"
63
- self.api_url = "https://api-inference.huggingface.co/models/facebook/bart-large-mnli"
64
- self.headers = {"Authorization": "Bearer " + self.api_key}
65
-
66
- def __post(self,payload):
67
- response = requests.post(self.api_url, headers=self.headers, json=payload)
68
- if response.status_code != 200:
69
- print(f"❌ Error {response.status_code}: {response.text}")
70
- return None
71
- return response.json()
72
-
73
- def extract_username(self, query: str):
74
- match = re.search(r'@[\w\d_]+', query)
75
- return match.group(0) if match else None
76
-
77
- def get_command(self,user_query):
78
- labels = [entry["description"] for entry in command_registry]
79
- response = self.__post(
80
- payload={
81
- "inputs": user_query,
82
- "parameters": {"candidate_labels": labels},
83
- }
84
- )
85
- print(response)
86
- if response is None:return None
87
- best_label = response["labels"][0]
88
- if best_label is None:
89
- logger.error("No matching command found for the user query.")
90
- return None
91
- for entry in command_registry:
92
- if entry["description"] == best_label:
93
- return entry["command"] if isinstance(entry["command"], str) else entry["command"][0]
94
- return None
95
-
96
- find_command = CommandAI()
@@ -1,26 +0,0 @@
1
- # src/models/_movie_title.py
2
-
3
- # from rapidfuzz import process
4
-
5
- class FindMovie:
6
- def __init__(self):
7
- self.movie_titles = []
8
- self.movie_docs = []
9
-
10
- # def load_movie_titles(self, titles :list):
11
- # self.movie_docs = titles
12
- # self.movie_titles = [doc["title"] for doc in self.movie_docs]
13
-
14
- # def get_match_one(self,user_input):
15
- # match, _, _ = process.extractOne(user_input, self.movie_titles)
16
- # return match
17
-
18
- # def get_match_doc(self,match):
19
- # return next((doc for doc in self.movie_docs if doc["title"] == match), None)
20
-
21
- # def get_match(self, user_input :str,limit :int=3):
22
- # matches = process.extract(user_input, self.movie_titles, limit=limit)
23
- # return matches
24
-
25
- movie_finder = FindMovie()
26
-
d4rk/Utils/_delete.py DELETED
@@ -1,16 +0,0 @@
1
- import asyncio
2
-
3
- from pyrogram import Client
4
- from d4rk.Logs import setup_logger
5
-
6
- logger = setup_logger(__name__)
7
-
8
- async def delete(client: Client, chat_id: int, message_id: int,timeout: int=3):
9
- await asyncio.create_task(delete_message_worker(client,chat_id, message_id, timeout))
10
-
11
- async def delete_message_worker(client,chat_id, message_id, timeout):
12
- await asyncio.sleep(timeout)
13
- try:
14
- await client.delete_messages(chat_id=chat_id, message_ids=message_id)
15
- except Exception as e:
16
- logger.error(f"Error deleting message {message_id}: {e}")
d4rk/Utils/_round.py DELETED
@@ -1,47 +0,0 @@
1
- from functools import wraps
2
- from pyrogram import filters
3
- from pyrogram.types import Message
4
- import asyncio
5
- import re
6
- from d4rk.Logs import setup_logger
7
-
8
- logger = setup_logger(__name__)
9
-
10
- last_index_per_chat = {}
11
- bot_order_per_chat = {}
12
- responded_messages = {}
13
- chat_locks = {}
14
-
15
- def round_robin():
16
- def decorator(func):
17
- @wraps(func)
18
- async def wrapper(client, message, *args, **kwargs):
19
- chat_id = message.chat.id
20
- msg_id = message.id
21
-
22
- if message.chat.type.name.lower() == "private":
23
- return await func(client, message, *args, **kwargs)
24
-
25
- if chat_id not in bot_order_per_chat:
26
- bot_order_per_chat[chat_id] = [client.me.id]
27
- last_index_per_chat[chat_id] = 0
28
- responded_messages[chat_id] = set()
29
- chat_locks[chat_id] = asyncio.Lock()
30
-
31
- if client.me.id not in bot_order_per_chat[chat_id]:
32
- bot_order_per_chat[chat_id].append(client.me.id)
33
-
34
- async with chat_locks[chat_id]:
35
- if msg_id in responded_messages[chat_id]:
36
- return
37
- current_index = last_index_per_chat[chat_id]
38
- selected_bot_id = bot_order_per_chat[chat_id][current_index]
39
-
40
- if client.me.id == selected_bot_id:
41
- result = await func(client, message, *args, **kwargs)
42
- responded_messages[chat_id].add(msg_id)
43
- last_index_per_chat[chat_id] = (current_index + 1) % len(bot_order_per_chat[chat_id])
44
- return result
45
-
46
- return wrapper
47
- return decorator
@@ -1,24 +0,0 @@
1
- d4rk/__init__.py,sha256=Xq5qqX-FwosTJBLrSPF53FPD6fEISH750hbImZpSu5k,202
2
- d4rk/Database/__init__.py,sha256=TQB5D8PBDCq80jPq6rsC2G939yYYKTh_bCcOWsZ-nA8,18
3
- d4rk/Database/db.py,sha256=5T-dbHPQp9JF2rQb707SLSSkAaz8ghX4lO7g_Siy7oA,1870
4
- d4rk/Handlers/__init__.py,sha256=lO1b7Tnu3GWgwcJmX5qepiNqaBBi6qTgjj0SlzVUyEA,63
5
- d4rk/Handlers/_bot.py,sha256=eTPQ0FwGl8BYSWrHE_ui1Zcg5J2IjtoxDlpfbSdoHys,8941
6
- d4rk/Handlers/_scheduler.py,sha256=AyqexO4nxZlIzRfU9vWTfJtTWQVQmP4de7GRPg-3JkA,1236
7
- d4rk/Logs/__init__.py,sha256=mXWD5jXnyH3_AvS7K_ki3iw5BpoEAvrDFbmr-iEFNnY,22
8
- d4rk/Logs/_logger.py,sha256=lqfVvCO0vZ_IaGOdIE4HA2KAUQZh7yW2iAHZcBz7F4o,4120
9
- d4rk/Models/__init__.py,sha256=7bYM2c5Uk_VEg7NxIGH2EcEXGcAguwxvH23-Gy1orMM,100
10
- d4rk/Models/_commands.py,sha256=k5gtoUYygPg9Zee7FnKmuajwYGJw7pxvbLtRCePccnI,3092
11
- d4rk/Models/_movie_title.py,sha256=Xp8eafBP-kD3MxAdeNcb7EyiAojn5fDQ18la7vxrg10,812
12
- d4rk/Utils/__init__.py,sha256=UoZmFq9RIF4lfcxFjt-VQlshsb8-FjUcEjg7qotk6nQ,326
13
- d4rk/Utils/_decorators.py,sha256=xplcr3qUSewGKET0Y7TnW2ddL3ZY0IeHS5y3WewB-tc,2672
14
- d4rk/Utils/_delete.py,sha256=gSmQAENGmM5XCCJfPuJ4vRMSxtixYG0vYdocU-2TSFg,581
15
- d4rk/Utils/_fonts.py,sha256=CQsDqPgvp27t3f75Cxod0EmZogEssLwIpyesH-YY5KM,7518
16
- d4rk/Utils/_ip.py,sha256=KJJW2QSngshIVWCO5YPXF1wj4IPQzVN5oFofpfzlU5w,559
17
- d4rk/Utils/_movie_parser.py,sha256=QEPd3z04p4pk2vxZ-2fYlRxHmQbmwQd2mCIlBsBM5AY,7039
18
- d4rk/Utils/_ractions.py,sha256=wOVPyoFnbDuMgoP6NF_gLO1DYcfhERC0trdAK1jWSE8,2170
19
- d4rk/Utils/_round.py,sha256=LaQlklg4f8n4cJjVzeYisd8l9D1gYNuQ9Ka41v8XWtE,1696
20
- d4rk/Utils/_terminal.py,sha256=Anu4OcffY3v6LMOrCskP1cHrJIliomo1Hjownbhh2sQ,125
21
- d4rktg-0.9.2.dist-info/METADATA,sha256=go-7ytFZg3DUNYLcsV9O8POM0TXTWxJjZjX3kS1SHPQ,652
22
- d4rktg-0.9.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- d4rktg-0.9.2.dist-info/top_level.txt,sha256=qs1qTnKWImmGi7E0FoJS0OAEOHoVZA9vHRS3Pm6ncAo,5
24
- d4rktg-0.9.2.dist-info/RECORD,,
File without changes