Fixed story parsing

This commit is contained in:
KurimuzonAkuma 2023-10-17 15:39:29 +03:00
parent 23c1b491a0
commit 9cc09b295f
8 changed files with 78 additions and 47 deletions

View File

@ -66,7 +66,7 @@ class Dispatcher:
async def message_parser(update, users, chats): async def message_parser(update, users, chats):
return ( return (
await pyrogram.types.Message._parse(self.client, update.message, users, chats, await pyrogram.types.Message._parse(self.client, update.message, users, chats, None,
isinstance(update, UpdateNewScheduledMessage)), isinstance(update, UpdateNewScheduledMessage)),
MessageHandler MessageHandler
) )
@ -128,9 +128,9 @@ class Dispatcher:
ChatJoinRequestHandler ChatJoinRequestHandler
) )
async def story_parser(update, _, __): async def story_parser(update, users, chats):
return ( return (
await pyrogram.types.Story._parse(self.client, update.story, update.peer), await pyrogram.types.Story._parse(self.client, update.story, users, chats, update.peer),
StoryHandler StoryHandler
) )

View File

@ -228,6 +228,12 @@ class EditStory:
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, raw.types.UpdateStory): if isinstance(i, raw.types.UpdateStory):
return await types.Story._parse(self, i.story, i.peer) return await types.Story._parse(
self,
i.story,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
i.peer
)
except StopTransmission: except StopTransmission:
return None return None

View File

@ -58,4 +58,10 @@ class GetAllStories:
for peer_story in r.peer_stories: for peer_story in r.peer_stories:
for story in peer_story.stories: for story in peer_story.stories:
yield await types.Story._parse(self, story, peer_story.peer) yield await types.Story._parse(
self,
story,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
peer_story.peer
)

View File

@ -60,4 +60,10 @@ class GetPeerStories:
) )
for story in r.stories.stories: for story in r.stories.stories:
yield await types.Story._parse(self, story, peer) yield await types.Story._parse(
self,
story,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
peer
)

View File

@ -71,6 +71,14 @@ class GetStories:
for i in r.updates: for i in r.updates:
if isinstance(i, raw.types.stories.PeerStories): if isinstance(i, raw.types.stories.PeerStories):
stories = [await types.Story._parse(self, story, peer) for story in r.stories] stories = [
await types.Story._parse(
self,
story,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
peer
) for story in r.stories
]
return types.List(stories) if is_iterable else stories[0] return types.List(stories) if is_iterable else stories[0]

View File

@ -71,4 +71,10 @@ class GetStoriesArchive:
) )
for story in r.stories: for story in r.stories:
yield await types.Story._parse(self, story, peer) yield await types.Story._parse(
self,
story,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
peer
)

View File

@ -247,6 +247,12 @@ class SendStory:
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, raw.types.UpdateStory): if isinstance(i, raw.types.UpdateStory):
return await types.Story._parse(self, i.story, i.peer) return await types.Story._parse(
self,
i.story,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
i.peer
)
except StopTransmission: except StopTransmission:
return None return None

View File

@ -20,6 +20,7 @@ import pyrogram
from datetime import datetime from datetime import datetime
from pyrogram import enums, raw, types, utils from pyrogram import enums, raw, types, utils
from pyrogram.errors import PeerIdInvalid
from typing import BinaryIO, Callable, List, Optional, Union from typing import BinaryIO, Callable, List, Optional, Union
from ..object import Object from ..object import Object
from ..update import Update from ..update import Update
@ -48,9 +49,6 @@ class Story(Object, Update):
has_protected_content (``bool``, *optional*): has_protected_content (``bool``, *optional*):
True, if the story can't be forwarded. True, if the story can't be forwarded.
animation (:obj:`~pyrogram.types.Animation`, *optional*):
Story is an animation, information about the animation.
photo (:obj:`~pyrogram.types.Photo`, *optional*): photo (:obj:`~pyrogram.types.Photo`, *optional*):
Story is a photo, information about the photo. Story is a photo, information about the photo.
@ -113,7 +111,6 @@ class Story(Object, Update):
expire_date: datetime = None, expire_date: datetime = None,
media: "enums.MessageMediaType", media: "enums.MessageMediaType",
has_protected_content: bool = None, has_protected_content: bool = None,
animation: "types.Animation" = None,
photo: "types.Photo" = None, photo: "types.Photo" = None,
video: "types.Video" = None, video: "types.Video" = None,
edited: bool = None, edited: bool = None,
@ -140,7 +137,6 @@ class Story(Object, Update):
self.expire_date = expire_date self.expire_date = expire_date
self.media = media self.media = media
self.has_protected_content = has_protected_content self.has_protected_content = has_protected_content
self.animation = animation
self.photo = photo self.photo = photo
self.video = video self.video = video
self.edited = edited self.edited = edited
@ -162,6 +158,8 @@ class Story(Object, Update):
async def _parse( async def _parse(
client: "pyrogram.Client", client: "pyrogram.Client",
stories: raw.base.StoryItem, stories: raw.base.StoryItem,
users: dict,
chats: dict,
peer: Union["raw.types.PeerChannel", "raw.types.PeerUser"] peer: Union["raw.types.PeerChannel", "raw.types.PeerUser"]
) -> "Story": ) -> "Story":
if isinstance(stories, raw.types.StoryItemSkipped): if isinstance(stories, raw.types.StoryItemSkipped):
@ -172,7 +170,22 @@ class Story(Object, Update):
entities = [types.MessageEntity._parse(client, entity, {}) for entity in stories.entities] entities = [types.MessageEntity._parse(client, entity, {}) for entity in stories.entities]
entities = types.List(filter(lambda x: x is not None, entities)) or None entities = types.List(filter(lambda x: x is not None, entities)) or None
animation = None peer_id = utils.get_raw_peer_id(peer)
if isinstance(peer, raw.types.PeerUser) and peer_id not in users:
try:
r = await client.invoke(
raw.functions.users.GetUsers(
id=[
await client.resolve_peer(peer_id)
]
)
)
except PeerIdInvalid:
pass
else:
users.update({i.id: i for i in r})
photo = None photo = None
video = None video = None
from_user = None from_user = None
@ -190,30 +203,25 @@ class Story(Object, Update):
media_type = enums.MessageMediaType.PHOTO media_type = enums.MessageMediaType.PHOTO
else: else:
doc = stories.media.document doc = stories.media.document
video = types.Video._parse(client, doc, doc.attributes, None) attributes = {type(i): i for i in doc.attributes}
video_attributes = attributes.get(raw.types.DocumentAttributeVideo, None)
video = types.Video._parse(client, doc, video_attributes, None)
media_type = enums.MessageMediaType.VIDEO media_type = enums.MessageMediaType.VIDEO
# if isinstance(peer, raw.types.PeerChannel): from_user = types.User._parse(client, users.get(peer_id, None))
# print(peer) sender_chat = types.Chat._parse_channel_chat(client, chats.get(peer_id, None)) if not from_user else None
# sender_chat = await client.get_chat(peer.channel_id)
# elif isinstance(peer, raw.types.InputPeerSelf):
# from_user = client.me
# else:
# from_user = await client.get_users(peer.user_id)
sender_chat = getattr(peer, "channel_id", None)
from_user = getattr(peer, "user_id", None)
for priv in stories.privacy: for priv in stories.privacy:
if isinstance(priv, raw.types.PrivacyValueAllowAll): if isinstance(priv, raw.types.PrivacyValueAllowAll):
privacy = enums.StoriesPrivacyRules.PUBLIC privacy = enums.StoriesPrivacy.PUBLIC
elif isinstance(priv, raw.types.PrivacyValueAllowCloseFriends): elif isinstance(priv, raw.types.PrivacyValueAllowCloseFriends):
privacy = enums.StoriesPrivacyRules.CLOSE_FRIENDS privacy = enums.StoriesPrivacy.CLOSE_FRIENDS
elif isinstance(priv, raw.types.PrivacyValueAllowContacts): elif isinstance(priv, raw.types.PrivacyValueAllowContacts):
privacy = enums.StoriesPrivacyRules.CONTACTS privacy = enums.StoriesPrivacy.CONTACTS
elif isinstance(priv, raw.types.PrivacyValueDisallowAll): elif isinstance(priv, raw.types.PrivacyValueDisallowAll):
privacy = enums.StoriesPrivacyRules.PRIVATE privacy = enums.StoriesPrivacy.PRIVATE
elif isinstance(priv, raw.types.PrivacyValueDisallowContacts): elif isinstance(priv, raw.types.PrivacyValueDisallowContacts):
privacy = enums.StoriesPrivacyRules.NO_CONTACTS privacy = enums.StoriesPrivacy.NO_CONTACTS
if isinstance(priv, raw.types.PrivacyValueAllowUsers): if isinstance(priv, raw.types.PrivacyValueAllowUsers):
allowed_users = priv.users allowed_users = priv.users
@ -228,7 +236,6 @@ class Story(Object, Update):
expire_date=utils.timestamp_to_datetime(stories.expire_date), expire_date=utils.timestamp_to_datetime(stories.expire_date),
media=media_type, media=media_type,
has_protected_content=stories.noforwards, has_protected_content=stories.noforwards,
animation=animation,
photo=photo, photo=photo,
video=video, video=video,
edited=stories.edited, edited=stories.edited,
@ -1331,27 +1338,13 @@ class Story(Object, Update):
story_id (``int``): story_id (``int``):
Unique identifier (int) of the target story. Unique identifier (int) of the target story.
animation (``str`` | ``BinaryIO``, *optional*): media (``str`` | ``BinaryIO``, *optional*):
New story Animation. New story media.
Pass a file_id as string to send a animation that exists on the Telegram servers,
pass an HTTP URL as a string for Telegram to get a animation from the Internet,
pass a file path as string to upload a new animation that exists on your local machine, or
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
photo (``str`` | ``BinaryIO``, *optional*):
New story photo.
Pass a file_id as string to send a photo that exists on the Telegram servers, Pass a file_id as string to send a photo that exists on the Telegram servers,
pass an HTTP URL as a string for Telegram to get a photo from the Internet, pass an HTTP URL as a string for Telegram to get a photo from the Internet,
pass a file path as string to upload a new photo that exists on your local machine, or pass a file path as string to upload a new photo that exists on your local machine, or
pass a binary file-like object with its attribute ".name" set for in-memory uploads. pass a binary file-like object with its attribute ".name" set for in-memory uploads.
video (``str`` | ``BinaryIO``, *optional*):
New story video.
Pass a file_id as string to send a video that exists on the Telegram servers,
pass an HTTP URL as a string for Telegram to get a video from the Internet,
pass a file path as string to upload a new video that exists on your local machine, or
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*): privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*):
Story privacy. Story privacy.