mirror of
https://github.com/Mayuri-Chan/pyrofork.git
synced 2025-12-29 12:04:51 +00:00
Merge branch 'Mayuri-Chan:main' into main
This commit is contained in:
commit
42e9410aad
6 changed files with 148 additions and 60 deletions
|
|
@ -484,6 +484,7 @@ def pyrogram_api():
|
||||||
BusinessWeeklyOpen
|
BusinessWeeklyOpen
|
||||||
BusinessWorkingHours
|
BusinessWorkingHours
|
||||||
User
|
User
|
||||||
|
Username
|
||||||
Chat
|
Chat
|
||||||
ChatPreview
|
ChatPreview
|
||||||
ChatPhoto
|
ChatPhoto
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
__fork_name__ = "PyroFork"
|
__fork_name__ = "PyroFork"
|
||||||
__version__ = "2.3.63"
|
__version__ = "2.3.64"
|
||||||
__license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)"
|
__license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)"
|
||||||
__copyright__ = "Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>"
|
__copyright__ = "Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pyrogram
|
import pyrogram
|
||||||
from pyrogram import raw, types, utils
|
from pyrogram import raw, types, utils
|
||||||
|
|
@ -337,47 +338,12 @@ class Dispatcher:
|
||||||
async def handler_worker(self, lock: asyncio.Lock):
|
async def handler_worker(self, lock: asyncio.Lock):
|
||||||
while True:
|
while True:
|
||||||
packet = await self.updates_queue.get()
|
packet = await self.updates_queue.get()
|
||||||
|
|
||||||
if packet is None:
|
if packet is None:
|
||||||
break
|
break
|
||||||
await self._process_packet(packet, lock)
|
|
||||||
|
|
||||||
async def _process_packet(
|
|
||||||
self,
|
|
||||||
packet: tuple[raw.core.TLObject, dict[int, types.Update], dict[int, types.Update]],
|
|
||||||
lock: asyncio.Lock,
|
|
||||||
):
|
|
||||||
try:
|
try:
|
||||||
update, users, chats = packet
|
await self._handle_packet(packet, lock)
|
||||||
parser = self.update_parsers.get(type(update))
|
|
||||||
|
|
||||||
if parser is not None:
|
|
||||||
parsed_result = parser(update, users, chats)
|
|
||||||
if inspect.isawaitable(parsed_result):
|
|
||||||
parsed_update, handler_type = await parsed_result
|
|
||||||
else:
|
|
||||||
parsed_update, handler_type = parsed_result
|
|
||||||
else:
|
|
||||||
parsed_update, handler_type = (None, type(None))
|
|
||||||
|
|
||||||
async with lock:
|
|
||||||
for group in self.groups.values():
|
|
||||||
for handler in group:
|
|
||||||
try:
|
|
||||||
if parsed_update is not None:
|
|
||||||
if isinstance(handler, handler_type) and await handler.check(
|
|
||||||
self.client, parsed_update
|
|
||||||
):
|
|
||||||
await self._execute_callback(handler, parsed_update)
|
|
||||||
break
|
|
||||||
elif isinstance(handler, RawUpdateHandler):
|
|
||||||
await self._execute_callback(handler, update, users, chats)
|
|
||||||
break
|
|
||||||
except (pyrogram.StopPropagation, pyrogram.ContinuePropagation) as e:
|
|
||||||
if isinstance(e, pyrogram.StopPropagation):
|
|
||||||
raise
|
|
||||||
except Exception as exception:
|
|
||||||
if parsed_update is not None:
|
|
||||||
await self._handle_exception(parsed_update, exception)
|
|
||||||
except pyrogram.StopPropagation:
|
except pyrogram.StopPropagation:
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -385,11 +351,75 @@ class Dispatcher:
|
||||||
finally:
|
finally:
|
||||||
self.updates_queue.task_done()
|
self.updates_queue.task_done()
|
||||||
|
|
||||||
async def _handle_exception(self, parsed_update: types.Update, exception: Exception):
|
async def _handle_packet(self, packet, lock: asyncio.Lock):
|
||||||
|
update, users, chats = packet
|
||||||
|
parser = self.update_parsers.get(type(update))
|
||||||
|
|
||||||
|
parsed_update, handler_type = (
|
||||||
|
await parser(update, users, chats)
|
||||||
|
if parser is not None else (None, type(None))
|
||||||
|
)
|
||||||
|
async with lock:
|
||||||
|
await self._dispatch_to_handlers(update, users, chats, parsed_update, handler_type)
|
||||||
|
|
||||||
|
|
||||||
|
async def _dispatch_to_handlers(
|
||||||
|
self, update, users, chats, parsed_update, handler_type,
|
||||||
|
):
|
||||||
|
for group in self.groups.values():
|
||||||
|
for handler in group:
|
||||||
|
args = await self._match_handler(
|
||||||
|
handler, update, users, chats, parsed_update, handler_type,
|
||||||
|
)
|
||||||
|
if args is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self._execute_handler(handler, *args)
|
||||||
|
except pyrogram.StopPropagation:
|
||||||
|
raise
|
||||||
|
except pyrogram.ContinuePropagation:
|
||||||
|
continue
|
||||||
|
except Exception as error:
|
||||||
|
if parsed_update is not None:
|
||||||
|
await self._handle_exception(parsed_update, error)
|
||||||
|
break
|
||||||
|
|
||||||
|
async def _match_handler(
|
||||||
|
self, handler, update, users, chats, parsed_update, handler_type,
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if isinstance(handler, handler_type):
|
||||||
|
if await handler.check(self.client, parsed_update):
|
||||||
|
return (parsed_update,)
|
||||||
|
elif isinstance(handler, RawUpdateHandler):
|
||||||
|
if await handler.check(self.client, update):
|
||||||
|
return (update, users, chats)
|
||||||
|
except Exception as e:
|
||||||
|
log.exception(e)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def _execute_handler(self, handler, *args: Any):
|
||||||
|
if inspect.iscoroutinefunction(handler.callback):
|
||||||
|
await handler.callback(self.client, *args)
|
||||||
|
else:
|
||||||
|
await self.loop.run_in_executor(
|
||||||
|
self.client.executor,
|
||||||
|
handler.callback,
|
||||||
|
self.client,
|
||||||
|
*args
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _handle_exception(
|
||||||
|
self, parsed_update: types.Update, exception: Exception,
|
||||||
|
):
|
||||||
handled_error = False
|
handled_error = False
|
||||||
for error_handler in self.error_handlers:
|
for error_handler in self.error_handlers:
|
||||||
try:
|
try:
|
||||||
if await error_handler.check(self.client, parsed_update, exception):
|
if await error_handler.check(
|
||||||
|
self.client, parsed_update, exception,
|
||||||
|
):
|
||||||
handled_error = True
|
handled_error = True
|
||||||
break
|
break
|
||||||
except pyrogram.StopPropagation:
|
except pyrogram.StopPropagation:
|
||||||
|
|
@ -401,11 +431,3 @@ class Dispatcher:
|
||||||
|
|
||||||
if not handled_error:
|
if not handled_error:
|
||||||
log.exception("Unhandled exception: %s", exception)
|
log.exception("Unhandled exception: %s", exception)
|
||||||
|
|
||||||
async def _execute_callback(self, handler: Handler, *args):
|
|
||||||
if inspect.iscoroutinefunction(handler.callback):
|
|
||||||
await handler.callback(self.client, *args)
|
|
||||||
else:
|
|
||||||
await self.client.loop.run_in_executor(
|
|
||||||
self.client.executor, handler.callback, self.client, *args
|
|
||||||
)
|
|
||||||
|
|
@ -890,7 +890,12 @@ def command(commands: Union[str, List[str]], prefixes: Union[str, List[str]] = "
|
||||||
command_re = re.compile(r"([\"'])(.*?)(?<!\\)\1|(\S+)")
|
command_re = re.compile(r"([\"'])(.*?)(?<!\\)\1|(\S+)")
|
||||||
|
|
||||||
async def func(flt, client: pyrogram.Client, message: Message):
|
async def func(flt, client: pyrogram.Client, message: Message):
|
||||||
|
usernames = []
|
||||||
username = client.me.username or ""
|
username = client.me.username or ""
|
||||||
|
if client.me.usernames:
|
||||||
|
usernames.append(username)
|
||||||
|
for user in client.me.usernames:
|
||||||
|
usernames.append(user.username)
|
||||||
text = message.text or message.caption
|
text = message.text or message.caption
|
||||||
message.command = None
|
message.command = None
|
||||||
|
|
||||||
|
|
@ -904,6 +909,24 @@ def command(commands: Union[str, List[str]], prefixes: Union[str, List[str]] = "
|
||||||
without_prefix = text[len(prefix):]
|
without_prefix = text[len(prefix):]
|
||||||
|
|
||||||
for cmd in flt.commands:
|
for cmd in flt.commands:
|
||||||
|
if usernames:
|
||||||
|
for username in usernames:
|
||||||
|
if not re.match(rf"^(?:{cmd}(?:@?{username})?)(?:\s|$)", without_prefix,
|
||||||
|
flags=re.IGNORECASE if not flt.case_sensitive else 0):
|
||||||
|
continue
|
||||||
|
|
||||||
|
without_command = re.sub(rf"{cmd}(?:@?{username})?\s?", "", without_prefix, count=1,
|
||||||
|
flags=re.IGNORECASE if not flt.case_sensitive else 0)
|
||||||
|
|
||||||
|
# match.groups are 1-indexed, group(1) is the quote, group(2) is the text
|
||||||
|
# between the quotes, group(3) is unquoted, whitespace-split text
|
||||||
|
|
||||||
|
# Remove the escape character from the arguments
|
||||||
|
message.command = [cmd] + [
|
||||||
|
re.sub(r"\\([\"'])", r"\1", m.group(2) or m.group(3) or "")
|
||||||
|
for m in command_re.finditer(without_command)
|
||||||
|
]
|
||||||
|
return True
|
||||||
if not re.match(rf"^(?:{cmd}(?:@?{username})?)(?:\s|$)", without_prefix,
|
if not re.match(rf"^(?:{cmd}(?:@?{username})?)(?:\s|$)", without_prefix,
|
||||||
flags=re.IGNORECASE if not flt.case_sensitive else 0):
|
flags=re.IGNORECASE if not flt.case_sensitive else 0):
|
||||||
continue
|
continue
|
||||||
|
|
@ -1011,12 +1034,22 @@ class user(Filter, set):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def __call__(self, _, message: Message):
|
async def __call__(self, _, message: Message):
|
||||||
|
is_usernames_in_filters = False
|
||||||
|
if message.from_user.usernames:
|
||||||
|
for username in message.from_user.usernames:
|
||||||
|
if (
|
||||||
|
username.username in self
|
||||||
|
or username.username.lower() in self
|
||||||
|
):
|
||||||
|
is_usernames_in_filters = True
|
||||||
|
break
|
||||||
return (message.from_user
|
return (message.from_user
|
||||||
and (message.from_user.id in self
|
and (message.from_user.id in self
|
||||||
or (message.from_user.username
|
or (message.from_user.username
|
||||||
and message.from_user.username.lower() in self)
|
and message.from_user.username.lower() in self)
|
||||||
or ("me" in self
|
or ("me" in self
|
||||||
and message.from_user.is_self)))
|
and message.from_user.is_self))
|
||||||
|
or is_usernames_in_filters)
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyPep8Naming
|
# noinspection PyPep8Naming
|
||||||
|
|
@ -1044,6 +1077,15 @@ class chat(Filter, set):
|
||||||
|
|
||||||
async def __call__(self, _, message: Union[Message, Story]):
|
async def __call__(self, _, message: Union[Message, Story]):
|
||||||
if isinstance(message, Story):
|
if isinstance(message, Story):
|
||||||
|
is_usernames_in_filters = False
|
||||||
|
if message.sender_chat.usernames:
|
||||||
|
for username in message.sender_chat.usernames:
|
||||||
|
if (
|
||||||
|
username.username in self
|
||||||
|
or username.username.lower() in self
|
||||||
|
):
|
||||||
|
is_usernames_in_filters = True
|
||||||
|
break
|
||||||
return (
|
return (
|
||||||
message.sender_chat
|
message.sender_chat
|
||||||
and (
|
and (
|
||||||
|
|
@ -1062,8 +1104,17 @@ class chat(Filter, set):
|
||||||
and message.from_user.username.lower() in self
|
and message.from_user.username.lower() in self
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
) or is_usernames_in_filters
|
||||||
else:
|
else:
|
||||||
|
is_usernames_in_filters = False
|
||||||
|
if message.chat.usernames:
|
||||||
|
for username in message._chat.usernames:
|
||||||
|
if (
|
||||||
|
username.username in self
|
||||||
|
or username.username.lower() in self
|
||||||
|
):
|
||||||
|
is_usernames_in_filters = True
|
||||||
|
break
|
||||||
return (message.chat
|
return (message.chat
|
||||||
and (message.chat.id in self
|
and (message.chat.id in self
|
||||||
or (message.chat.username
|
or (message.chat.username
|
||||||
|
|
@ -1071,7 +1122,10 @@ class chat(Filter, set):
|
||||||
or ("me" in self
|
or ("me" in self
|
||||||
and message.from_user
|
and message.from_user
|
||||||
and message.from_user.is_self
|
and message.from_user.is_self
|
||||||
and not message.outgoing)))
|
and not message.outgoing))
|
||||||
|
or (is_usernames_in_filters
|
||||||
|
and not message.outgoing)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyPep8Naming
|
# noinspection PyPep8Naming
|
||||||
|
|
|
||||||
|
|
@ -808,7 +808,7 @@ class Message(Object, Update):
|
||||||
service_type = enums.MessageServiceType.BOT_ALLOWED
|
service_type = enums.MessageServiceType.BOT_ALLOWED
|
||||||
elif isinstance(action, raw.types.MessageActionRequestedPeer) or isinstance(action, raw.types.MessageActionRequestedPeerSentMe):
|
elif isinstance(action, raw.types.MessageActionRequestedPeer) or isinstance(action, raw.types.MessageActionRequestedPeerSentMe):
|
||||||
chats_shared = await types.RequestedChats._parse(client, action)
|
chats_shared = await types.RequestedChats._parse(client, action)
|
||||||
service_type = enums.MessageServiceType.ChatShared
|
service_type = enums.MessageServiceType.CHAT_SHARED
|
||||||
elif isinstance(action, raw.types.MessageActionTopicCreate):
|
elif isinstance(action, raw.types.MessageActionTopicCreate):
|
||||||
forum_topic_created = types.ForumTopicCreated._parse(message)
|
forum_topic_created = types.ForumTopicCreated._parse(message)
|
||||||
service_type = enums.MessageServiceType.FORUM_TOPIC_CREATED
|
service_type = enums.MessageServiceType.FORUM_TOPIC_CREATED
|
||||||
|
|
|
||||||
|
|
@ -77,13 +77,16 @@ class Gift(Object):
|
||||||
User who sent the star gift.
|
User who sent the star gift.
|
||||||
|
|
||||||
owner (:obj:`~pyrogram.types.Chat`, *optional*):
|
owner (:obj:`~pyrogram.types.Chat`, *optional*):
|
||||||
Current gift owner.
|
Only available if the nfts is in telegram.
|
||||||
|
|
||||||
owner_name (``str``, *optional*):
|
owner_name (``str``, *optional*):
|
||||||
Name of the user who received the star gift.
|
Name of the user who received the star gift.
|
||||||
|
|
||||||
owner_address (``str``, *optional*):
|
owner_address (``str``, *optional*):
|
||||||
Address of the gift owner in TON blockchain.
|
Only available if the nfts is in ton network.
|
||||||
|
|
||||||
|
ton_address (``str``, *optional*):
|
||||||
|
Only available if the nfts is in ton network.
|
||||||
|
|
||||||
price (``int``, *optional*):
|
price (``int``, *optional*):
|
||||||
Price of this gift in stars.
|
Price of this gift in stars.
|
||||||
|
|
@ -163,6 +166,7 @@ class Gift(Object):
|
||||||
owner: Optional["types.Chat"] = None,
|
owner: Optional["types.Chat"] = None,
|
||||||
owner_name: Optional[str] = None,
|
owner_name: Optional[str] = None,
|
||||||
owner_address: Optional[str] = None,
|
owner_address: Optional[str] = None,
|
||||||
|
ton_address: Optional[str] = None,
|
||||||
price: Optional[int] = None,
|
price: Optional[int] = None,
|
||||||
convert_price: Optional[int] = None,
|
convert_price: Optional[int] = None,
|
||||||
upgrade_price: Optional[int] = None,
|
upgrade_price: Optional[int] = None,
|
||||||
|
|
@ -201,6 +205,7 @@ class Gift(Object):
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.owner_name = owner_name
|
self.owner_name = owner_name
|
||||||
self.owner_address = owner_address
|
self.owner_address = owner_address
|
||||||
|
self.ton_address = ton_address
|
||||||
self.price = price
|
self.price = price
|
||||||
self.convert_price = convert_price
|
self.convert_price = convert_price
|
||||||
self.upgrade_price = upgrade_price
|
self.upgrade_price = upgrade_price
|
||||||
|
|
@ -277,9 +282,15 @@ class Gift(Object):
|
||||||
) or None,
|
) or None,
|
||||||
available_amount=getattr(star_gift, "availability_issued", None),
|
available_amount=getattr(star_gift, "availability_issued", None),
|
||||||
total_amount=getattr(star_gift, "availability_total", None),
|
total_amount=getattr(star_gift, "availability_total", None),
|
||||||
owner=types.Chat._parse_chat(client, users.get(owner_id) or chats.get(owner_id)),
|
owner=(
|
||||||
|
types.Chat._parse_chat(client, users.get(owner_id) or
|
||||||
|
chats.get(owner_id))
|
||||||
|
if owner_id is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
owner_name=getattr(star_gift, "owner_name", None),
|
owner_name=getattr(star_gift, "owner_name", None),
|
||||||
owner_address=getattr(star_gift, "owner_address", None),
|
owner_address=getattr(star_gift, "owner_address", None),
|
||||||
|
ton_address=getattr(star_gift, "gift_address", None),
|
||||||
is_upgraded=True,
|
is_upgraded=True,
|
||||||
raw=star_gift,
|
raw=star_gift,
|
||||||
client=client
|
client=client
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue