mirror of
https://github.com/Mayuri-Chan/pyrofork.git
synced 2025-12-29 12:04:51 +00:00
Compare commits
7 commits
407e75316b
...
8fa8fce2fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fa8fce2fc | ||
|
|
12d9297c02 | ||
|
|
52abec6e01 | ||
|
|
fd4eb09f7a | ||
|
|
dbcbadc400 | ||
|
|
b65279046e | ||
|
|
9ff40dc90b |
14 changed files with 307 additions and 52 deletions
40
.github/workflows/python-publish.yml
vendored
40
.github/workflows/python-publish.yml
vendored
|
|
@ -1,40 +0,0 @@
|
|||
# This workflow will upload a Python Package using Twine when a release is created
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
|
||||
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
name: Upload Python Package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -e '.[dev]'
|
||||
- name: Build package
|
||||
run: hatch build
|
||||
- name: Publish package
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
|
@ -379,6 +379,10 @@ def pyrogram_api():
|
|||
upgrade_gift
|
||||
get_stars_balance
|
||||
""",
|
||||
phone="""
|
||||
Phone
|
||||
get_call_members
|
||||
""",
|
||||
password="""
|
||||
Password
|
||||
enable_cloud_password
|
||||
|
|
@ -514,6 +518,7 @@ def pyrogram_api():
|
|||
PeerUser
|
||||
PeerChannel
|
||||
BotInfo
|
||||
GroupCallMember
|
||||
ChatColor
|
||||
CollectibleItemInfo
|
||||
BotVerification
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
__fork_name__ = "PyroFork"
|
||||
__version__ = "2.3.66"
|
||||
__version__ = "2.3.67"
|
||||
__license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)"
|
||||
__copyright__ = "Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>"
|
||||
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ class Client(Methods):
|
|||
PARENT_DIR = Path(sys.argv[0]).parent
|
||||
|
||||
INVITE_LINK_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:joinchat/|\+))([\w-]+)$")
|
||||
UPGRADED_GIFT_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:nft/|\+))([\w-]+)$")
|
||||
WORKERS = min(32, (os.cpu_count() or 0) + 4) # os.cpu_count() can be None
|
||||
WORKDIR = PARENT_DIR
|
||||
|
||||
|
|
|
|||
|
|
@ -1035,7 +1035,7 @@ class user(Filter, set):
|
|||
|
||||
async def __call__(self, _, message: Message):
|
||||
is_usernames_in_filters = False
|
||||
if message.from_user.usernames:
|
||||
if message.from_user and message.from_user.usernames:
|
||||
for username in message.from_user.usernames:
|
||||
if (
|
||||
username.username in self
|
||||
|
|
@ -1078,7 +1078,7 @@ class chat(Filter, set):
|
|||
async def __call__(self, _, message: Union[Message, Story]):
|
||||
if isinstance(message, Story):
|
||||
is_usernames_in_filters = False
|
||||
if message.sender_chat.usernames:
|
||||
if message.sender_chat and message.sender_chat.usernames:
|
||||
for username in message.sender_chat.usernames:
|
||||
if (
|
||||
username.username in self
|
||||
|
|
@ -1107,7 +1107,7 @@ class chat(Filter, set):
|
|||
) or is_usernames_in_filters
|
||||
else:
|
||||
is_usernames_in_filters = False
|
||||
if message.chat.usernames:
|
||||
if message.chat and message.chat.usernames:
|
||||
for username in message.chat.usernames:
|
||||
if (
|
||||
username.username in self
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ from .password import Password
|
|||
from .pyromod import Pyromod
|
||||
from .stickers import Stickers
|
||||
from .payments import Payments
|
||||
from .phone import Phone
|
||||
from .users import Users
|
||||
from .utilities import Utilities
|
||||
from .business import TelegramBusiness
|
||||
|
|
@ -42,6 +43,7 @@ class Methods(
|
|||
Password,
|
||||
Pyromod,
|
||||
Payments,
|
||||
Phone,
|
||||
Chats,
|
||||
Stickers,
|
||||
Users,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ async def get_chunk(
|
|||
from_message_id: int = 0,
|
||||
from_date: datetime = utils.zero_datetime(),
|
||||
min_id: int = 0,
|
||||
max_id: int = 0
|
||||
max_id: int = 0,
|
||||
reverse: Optional[bool] = None
|
||||
):
|
||||
messages = await client.invoke(
|
||||
raw.functions.messages.GetHistory(
|
||||
|
|
@ -48,6 +49,8 @@ async def get_chunk(
|
|||
),
|
||||
sleep_threshold=60
|
||||
)
|
||||
if reverse:
|
||||
messages.messages.reverse()
|
||||
|
||||
return await utils.parse_messages(client, messages, replies=0)
|
||||
|
||||
|
|
@ -61,7 +64,8 @@ class GetChatHistory:
|
|||
offset_id: int = 0,
|
||||
offset_date: datetime = utils.zero_datetime(),
|
||||
min_id: int = 0,
|
||||
max_id: int = 0
|
||||
max_id: int = 0,
|
||||
reverse: Optional[bool] = None
|
||||
) -> Optional[AsyncGenerator["types.Message", None]]:
|
||||
"""Get messages from a chat history.
|
||||
|
||||
|
|
@ -96,6 +100,9 @@ class GetChatHistory:
|
|||
max_id: (``int``, *optional*):
|
||||
The maximum message id. you will not get any message which have id greater than max_id.
|
||||
|
||||
reverse (``bool``, *optional*):
|
||||
Pass True to retrieve the messages in reversed order (from older to most recent).
|
||||
|
||||
Returns:
|
||||
``Generator``: A generator yielding :obj:`~pyrogram.types.Message` objects.
|
||||
|
||||
|
|
@ -118,7 +125,8 @@ class GetChatHistory:
|
|||
from_message_id=offset_id,
|
||||
from_date=offset_date,
|
||||
min_id=min_id,
|
||||
max_id=max_id
|
||||
max_id=max_id,
|
||||
reverse=reverse
|
||||
)
|
||||
|
||||
if not messages:
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class GetUpgradedGift:
|
|||
# Get information about upgraded gift by slug
|
||||
gift = await client.get_upgraded_gift("SignetRing-903")
|
||||
"""
|
||||
match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:nft/|\+))([\w-]+)$", link)
|
||||
match = self.UPGRADED_GIFT_RE.match(link)
|
||||
|
||||
if match:
|
||||
slug = match.group(1)
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ class SetPinnedGifts:
|
|||
if not isinstance(gift, str):
|
||||
raise ValueError(f"gift id has to be str, but {type(gift)} was provided")
|
||||
|
||||
saved_gift_match = re.match(r"^(-\d+)_(\d+)$", gift)
|
||||
slug_match = self.UPGRADED_GIFT_RE.match(gift)
|
||||
saved_gift_match = re.match(r"^(\d+)_(\d+)$", str(gift))
|
||||
slug_match = self.UPGRADED_GIFT_RE.match(str(gift))
|
||||
|
||||
if saved_gift_match:
|
||||
stargifts.append(
|
||||
|
|
|
|||
25
pyrogram/methods/phone/__init__.py
Normal file
25
pyrogram/methods/phone/__init__.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .get_call_members import GetCallMembers
|
||||
|
||||
|
||||
class Phone(
|
||||
GetCallMembers
|
||||
):
|
||||
pass
|
||||
103
pyrogram/methods/phone/get_call_members.py
Normal file
103
pyrogram/methods/phone/get_call_members.py
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Union, AsyncGenerator
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import types, raw
|
||||
|
||||
|
||||
class GetCallMembers:
|
||||
async def get_call_members(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
limit: int = 0
|
||||
) -> AsyncGenerator["types.GroupCallMember", None]:
|
||||
"""Get the members list of a chat call.
|
||||
|
||||
A chat can be either a basic group or a supergroup.
|
||||
|
||||
.. include:: /_includes/usable-by/users.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
|
||||
limit (``int``, *optional*):
|
||||
Limits the number of members to be retrieved.
|
||||
|
||||
Returns:
|
||||
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.GroupCallMember` objects is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Get members
|
||||
async for member in app.get_call_members(chat_id):
|
||||
print(member)
|
||||
"""
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
|
||||
if isinstance(peer, raw.types.InputPeerChannel):
|
||||
r = await self.invoke(raw.functions.channels.GetFullChannel(channel=peer))
|
||||
elif isinstance(peer, raw.types.InputPeerChat):
|
||||
r = await self.invoke(raw.functions.messages.GetFullChat(chat_id=peer.chat_id))
|
||||
else:
|
||||
raise ValueError("Target chat should be group, supergroup or channel.")
|
||||
|
||||
full_chat = r.full_chat
|
||||
|
||||
if not getattr(full_chat, "call", None):
|
||||
raise ValueError("There is no active call in this chat.")
|
||||
|
||||
current = 0
|
||||
offset = ""
|
||||
total = abs(limit) or (1 << 31) - 1
|
||||
limit = min(20, total)
|
||||
|
||||
while True:
|
||||
r = await self.invoke(
|
||||
raw.functions.phone.GetGroupParticipants(
|
||||
call=full_chat.call,
|
||||
ids=[],
|
||||
sources=[],
|
||||
offset=offset,
|
||||
limit=limit
|
||||
),
|
||||
sleep_threshold=60
|
||||
)
|
||||
|
||||
users = {u.id: u for u in r.users}
|
||||
chats = {c.id: c for c in r.chats}
|
||||
members = [
|
||||
types.GroupCallMember._parse(self, member, users, chats)
|
||||
for member in r.participants
|
||||
]
|
||||
|
||||
if not members:
|
||||
return
|
||||
|
||||
offset = r.next_offset
|
||||
|
||||
for member in members:
|
||||
yield member
|
||||
|
||||
current += 1
|
||||
|
||||
if current >= total:
|
||||
return
|
||||
|
|
@ -143,8 +143,8 @@ class KeyboardButton(Object):
|
|||
elif self.request_location:
|
||||
return raw.types.KeyboardButtonRequestGeoLocation(text=self.text)
|
||||
elif self.request_chat:
|
||||
user_privileges = self.request_peer.user_privileges
|
||||
bot_privileges = self.request_peer.bot_privileges
|
||||
user_privileges = self.request_chat.user_privileges
|
||||
bot_privileges = self.request_chat.bot_privileges
|
||||
|
||||
user_admin_rights = raw.types.ChatAdminRights(
|
||||
change_info=user_privileges.can_change_info,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ from .chat_reactions import ChatReactions
|
|||
from .dialog import Dialog
|
||||
from .emoji_status import EmojiStatus
|
||||
from .folder import Folder
|
||||
from .group_call_member import GroupCallMember
|
||||
from .invite_link_importer import InviteLinkImporter
|
||||
from .restriction import Restriction
|
||||
from .user import User
|
||||
|
|
@ -106,5 +107,6 @@ __all__ = [
|
|||
"ChatPrivileges",
|
||||
"ChatJoiner",
|
||||
"EmojiStatus",
|
||||
"GroupCallMember",
|
||||
"ChatReactions"
|
||||
]
|
||||
|
|
|
|||
149
pyrogram/types/user_and_chats/group_call_member.py
Normal file
149
pyrogram/types/user_and_chats/group_call_member.py
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Dict
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, types, utils
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class GroupCallMember(Object):
|
||||
"""Contains information about one member of a group call.
|
||||
|
||||
Parameters:
|
||||
chat (:obj:`~pyrogram.types.Chat`, *optional*):
|
||||
Information about the user or chat.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when this participant join this group call.
|
||||
|
||||
active_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when this participant last active in this group call.
|
||||
|
||||
volume (``int``, *optional*):
|
||||
Volume, if not set the volume is set to 100%.
|
||||
|
||||
can_self_unmute (``bool``, *optional*):
|
||||
Whether the participant can unmute themselves.
|
||||
|
||||
is_muted (``bool``, *optional*):
|
||||
Whether the participant is muted.
|
||||
|
||||
is_left (``bool``, *optional*):
|
||||
Whether the participant has left.
|
||||
|
||||
is_just_joined (``bool``, *optional*):
|
||||
Whether the participant has just joined.
|
||||
|
||||
is_muted_by_you (``bool``, *optional*):
|
||||
Whether this participant was muted by the current user.
|
||||
|
||||
is_volume_by_admin (``bool``, *optional*):
|
||||
Whether our volume can only changed by an admin.
|
||||
|
||||
is_self (``bool``, *optional*):
|
||||
Whether this participant is the current user.
|
||||
|
||||
is_video_joined (``bool``, *optional*):
|
||||
Whether this participant is currently broadcasting video.
|
||||
|
||||
is_hand_raised (``bool``, *optional*):
|
||||
Whether this participant is raised hand.
|
||||
|
||||
is_video_enabled (``bool``, *optional*):
|
||||
Whether this participant is currently broadcasting video.
|
||||
|
||||
is_screen_sharing_enabled (``bool``, *optional*):
|
||||
Whether this participant is currently shared screen.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
client: "pyrogram.Client" = None,
|
||||
chat: "types.Chat" = None,
|
||||
date: datetime = None,
|
||||
active_date: datetime = None,
|
||||
volume: int = None,
|
||||
can_self_unmute: bool = None,
|
||||
is_muted: bool = None,
|
||||
is_left: bool = None,
|
||||
is_just_joined: bool = None,
|
||||
is_muted_by_you: bool = None,
|
||||
is_volume_by_admin: bool = None,
|
||||
is_self: bool = None,
|
||||
is_video_joined: bool = None,
|
||||
is_hand_raised: bool = None,
|
||||
is_video_enabled: bool = None,
|
||||
is_screen_sharing_enabled: bool = None
|
||||
):
|
||||
super().__init__(client)
|
||||
|
||||
self.chat = chat
|
||||
self.date = date
|
||||
self.active_date = active_date
|
||||
self.volume = volume
|
||||
self.can_self_unmute = can_self_unmute
|
||||
self.is_muted = is_muted
|
||||
self.is_left = is_left
|
||||
self.is_just_joined = is_just_joined
|
||||
self.is_muted_by_you = is_muted_by_you
|
||||
self.is_volume_by_admin = is_volume_by_admin
|
||||
self.is_self = is_self
|
||||
self.is_video_joined = is_video_joined
|
||||
self.is_hand_raised = is_hand_raised
|
||||
self.is_video_enabled = is_video_enabled
|
||||
self.is_screen_sharing_enabled = is_screen_sharing_enabled
|
||||
|
||||
@staticmethod
|
||||
def _parse(
|
||||
client: "pyrogram.Client",
|
||||
member: "raw.types.GroupCallParticipant",
|
||||
users: Dict[int, "raw.base.User"],
|
||||
chats: Dict[int, "raw.base.Chat"]
|
||||
) -> "GroupCallMember":
|
||||
peer = member.peer
|
||||
peer_id = utils.get_raw_peer_id(peer)
|
||||
|
||||
parsed_chat = types.Chat._parse_chat(
|
||||
client,
|
||||
users[peer_id] if isinstance(peer, raw.types.PeerUser) else chats[peer_id],
|
||||
)
|
||||
|
||||
parsed_chat.bio = getattr(member, "about", None)
|
||||
|
||||
return GroupCallMember(
|
||||
chat=parsed_chat,
|
||||
date=utils.timestamp_to_datetime(member.date),
|
||||
active_date=utils.timestamp_to_datetime(member.active_date),
|
||||
volume=getattr(member, "volume", None),
|
||||
can_self_unmute=member.can_self_unmute,
|
||||
is_muted=member.muted,
|
||||
is_left=member.left,
|
||||
is_just_joined=member.just_joined,
|
||||
is_muted_by_you=member.muted_by_you,
|
||||
is_volume_by_admin=member.volume_by_admin,
|
||||
is_self=member.is_self,
|
||||
is_video_joined=member.video_joined,
|
||||
is_hand_raised=bool(getattr(member, "raise_hand_rating", None)),
|
||||
is_video_enabled=bool(getattr(member, "video", None)),
|
||||
is_screen_sharing_enabled=bool(getattr(member, "presentation", None)),
|
||||
client=client
|
||||
)
|
||||
Loading…
Reference in a new issue