Skip to content

Commit

Permalink
Update topic parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
KurimuzonAkuma committed Dec 2, 2023
1 parent 523774b commit 97c9fa6
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 48 deletions.
2 changes: 1 addition & 1 deletion pyrogram/methods/chats/get_dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# 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 AsyncGenerator, Optional
from typing import AsyncGenerator

import pyrogram
from pyrogram import types, raw, utils
Expand Down
69 changes: 54 additions & 15 deletions pyrogram/methods/chats/get_forum_topics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
# 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, Optional, AsyncGenerator
from typing import Union, AsyncGenerator

import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import types, raw, utils


class GetForumTopics:
Expand All @@ -39,26 +38,66 @@ async def get_forum_topics(
limit (``int``, *optional*):
Limits the number of topics to be retrieved.
By default, no limit is applied and all topics are returned.
Returns:
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.ForumTopic` objects is returned.
``Generator``: A generator yielding :obj:`~pyrogram.types.ForumTopic` objects.
Example:
.. code-block:: python
# get all forum topics
# Iterate through all topics
async for topic in app.get_forum_topics(chat_id):
print(topic)
"""
r = await self.invoke(
raw.functions.channels.GetForumTopics(
channel=await self.resolve_peer(chat_id),
offset_date=0,
offset_id=0,
offset_topic=0,
limit=limit
current = 0
total = limit or (1 << 31) - 1
limit = min(100, total)

offset_date = 0
offset_id = 0
offset_topic = 0

while True:
r = await self.invoke(
raw.functions.channels.GetForumTopics(
channel=await self.resolve_peer(chat_id),
offset_date=offset_date,
offset_id=offset_id,
offset_topic=offset_topic,
limit=limit
)
)
)

for topic in r.topics:
yield types.ForumTopic._parse(topic)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}

messages = {}

for message in r.messages:
if isinstance(message, raw.types.MessageEmpty):
continue

messages[message.id] = await types.Message._parse(self, message, users, chats)

topics = []

for topic in r.topics:
topics.append(types.ForumTopic._parse(self, topic, messages, users, chats))

if not topics:
return

last = topics[-1]

offset_id = last.top_message.id
offset_date = utils.datetime_to_timestamp(last.top_message.date)
offset_topic = last.id

for topic in topics:
yield topic

current += 1

if current >= total:
return
17 changes: 14 additions & 3 deletions pyrogram/methods/chats/get_forum_topics_by_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,20 @@ async def get_forum_topics_by_id(
)
)

users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}

messages = {}

for message in r.messages:
if isinstance(message, raw.types.MessageEmpty):
continue

messages[message.id] = await types.Message._parse(self, message, users, chats)

topics = types.List()

for i in r:
topics.append(types.ForumTopic._parse(i))
for i in r.topics:
topics.append(types.ForumTopic._parse(self, i, messages, users, chats))

return topics if is_iterable else topics[0]
return topics if is_iterable else topics[0] if topics else None
75 changes: 53 additions & 22 deletions pyrogram/types/messages_and_media/forum_topic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
# 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 pyrogram import raw, utils
import pyrogram
from pyrogram import types, raw, utils
from ..object import Object


Expand All @@ -27,28 +28,31 @@ class ForumTopic(Object):
id (``int``):
Unique topic identifier inside this chat.
date (``int``):
Date when the topic was created.
title (``str``):
The topic title.
icon_color (``int``):
Color of the topic icon in RGB format
date (``int``, *optional*):
Date when the topic was created.
icon_color (``str``, *optional*):
Color of the topic icon in HEX format
icon_emoji_id (``int``, *optional*):
Unique identifier of the custom emoji shown as the topic icon
top_message (``int``):
creator (:obj:`~pyrogram.types.Chat`, *optional*):
Topic creator.
top_message (:obj:`~pyrogram.types.Message`, *optional*):
The last message sent in the topic at this time.
unread_count (``int``):
unread_count (``int``, *optional*):
Amount of unread messages in this topic.
unread_mentions_count (``int``):
unread_mentions_count (``int``, *optional*):
Amount of unread messages containing a mention in this topic.
unread_reactions_count (``int``):
unread_reactions_count (``int``, *optional*):
Amount of unread messages containing a reaction in this topic.
is_my (``bool``, *optional*):
Expand All @@ -59,52 +63,79 @@ class ForumTopic(Object):
is_pinned (``bool``, *optional*):
True, if the topic is pinned.
is_short (``bool``, *optional*):
True, if the topic is short.
is_hidden (``bool``, *optional*):
True, if the topic is hidden.
"""

def __init__(
self,
*,
id: int,
date: int,
title: str,
icon_color: int,
title: str = None,
date: int = None,
icon_color: str = None,
icon_emoji_id: int = None,
top_message: int,
unread_count: int,
unread_mentions_count: int,
unread_reactions_count: int,
creator: "types.Chat" = None,
top_message: "types.Message" = None,
unread_count: int = None,
unread_mentions_count: int = None,
unread_reactions_count: int = None,
is_my: bool = None,
is_closed: bool = None,
is_pinned: bool = None,
is_short: bool = None,
is_hidden: bool = None
):
super().__init__()

self.id = id
self.date = date
self.title = title
self.date = date
self.icon_color = icon_color
self.icon_emoji_id = icon_emoji_id
self.creator = creator
self.top_message = top_message
self.unread_count = unread_count
self.unread_mentions_count = unread_mentions_count
self.unread_reactions_count = unread_reactions_count
self.is_my = is_my
self.is_closed = is_closed
self.is_pinned = is_pinned
self.is_short = is_short
self.is_hidden = is_hidden

@staticmethod
def _parse(forum_topic: "raw.types.ForumTopic") -> "ForumTopic":
def _parse(client: "pyrogram.Client", forum_topic: "raw.types.ForumTopic", messages: dict = {}, users: dict = {}, chats: dict = {}) -> "ForumTopic":
creator = None

peer = getattr(forum_topic, "from_id", None)

if peer:
peer_id = utils.get_raw_peer_id(peer)

if isinstance(peer, raw.types.PeerUser):
creator = types.Chat._parse_user_chat(client, users[peer_id])
else:
creator = types.Chat._parse_channel_chat(client, chats[peer_id])

return ForumTopic(
id=forum_topic.id,
date=utils.timestamp_to_datetime(forum_topic.date),
title=forum_topic.title,
icon_color=getattr(forum_topic, "icon_color", None),
date=utils.timestamp_to_datetime(forum_topic.date),
icon_color=format(forum_topic.icon_color, "x") if getattr(forum_topic, "icon_color", None) else None,
icon_emoji_id=getattr(forum_topic, "icon_emoji_id", None),
top_message=getattr(forum_topic, "top_message", None),
creator=creator,
top_message=messages.get(getattr(forum_topic, "top_message", None)),
unread_count=getattr(forum_topic, "unread_count", None),
unread_mentions_count=getattr(forum_topic, "unread_mentions_count", None),
unread_reactions_count=getattr(forum_topic, "unread_reactions_count", None),
is_my=getattr(forum_topic, "my", None),
is_closed=getattr(forum_topic, "closed", None),
is_pinned=getattr(forum_topic, "pinned", None),
is_short=getattr(forum_topic, "short", None),
is_hidden=getattr(forum_topic, "hidden", None),
)
7 changes: 5 additions & 2 deletions pyrogram/types/messages_and_media/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,12 +1025,14 @@ async def _parse(
parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id
else:
thread_id = message.reply_to.reply_to_msg_id

parsed_message.message_thread_id = thread_id

if topics:
parsed_message.topic = types.ForumTopic._parse(topics[thread_id])
parsed_message.topic = types.ForumTopic._parse(client, topics[thread_id], users=users, chats=chats)
else:
try:
msg = await client.get_messages(parsed_message.chat.id,message.id)
msg = await client.get_messages(parsed_message.chat.id, message.id, replies=0)
if msg.topic:
parsed_message.topic = msg.topic
except Exception:
Expand All @@ -1051,6 +1053,7 @@ async def _parse(
if media is None or web_page is not None
else None
)

parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id
parsed_message.reply_to_top_message_id = message.reply_to.reply_to_top_id
else:
Expand Down
10 changes: 5 additions & 5 deletions pyrogram/types/user_and_chats/chat_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,16 +454,16 @@ async def _parse(
action = enums.ChatEventAction.INVITE_LINK_DELETED

elif isinstance(action, raw.types.ChannelAdminLogEventActionCreateTopic):
created_forum_topic = types.ForumTopic._parse(action.topic)
created_forum_topic = types.ForumTopic._parse(client, action.topic, users=users, chats=chats)
action = enums.ChatEventAction.CREATED_FORUM_TOPIC

elif isinstance(action, raw.types.ChannelAdminLogEventActionEditTopic):
old_forum_topic = types.ForumTopic._parse(action.prev_topic)
new_forum_topic = types.ForumTopic._parse(action.new_topic)
old_forum_topic = types.ForumTopic._parse(client, action.prev_topic, users=users, chats=chats)
new_forum_topic = types.ForumTopic._parse(client, action.new_topic, users=users, chats=chats)
action = enums.ChatEventAction.EDITED_FORUM_TOPIC

elif isinstance(action, raw.types.ChannelAdminLogEventActionDeleteTopic):
created_forum_topic = types.ForumTopic._parse(action.topic)
created_forum_topic = types.ForumTopic._parse(client, action.topic, users=users, chats=chats)
action = enums.ChatEventAction.DELETED_FORUM_TOPIC

else:
Expand Down Expand Up @@ -526,7 +526,7 @@ async def _parse(
new_invite_link=new_invite_link,
revoked_invite_link=revoked_invite_link,
deleted_invite_link=deleted_invite_link,

created_forum_topic=created_forum_topic,
old_forum_topic=old_forum_topic,
new_forum_topic=new_forum_topic,
Expand Down

0 comments on commit 97c9fa6

Please sign in to comment.