mirror of
https://github.com/TeamPGM/pyrogram.git
synced 2024-11-16 12:51:18 +00:00
Merge develop -> asyncio-dev
This commit is contained in:
commit
0257fb79c5
@ -49,8 +49,8 @@ inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int =
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
|
||||
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
|
||||
inputMediaPoll#abe9ca25 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> = InputMedia;
|
||||
inputMediaDice#aeffa807 = InputMedia;
|
||||
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||
|
||||
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
|
||||
inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto;
|
||||
@ -135,7 +135,7 @@ messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
||||
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
|
||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||
messageMediaDice#638fe46b value:int = MessageMedia;
|
||||
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
||||
|
||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
|
||||
@ -511,7 +511,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
|
||||
inputStickerSetDice#79e21a53 = InputStickerSet;
|
||||
inputStickerSetDice#e67f520e emoticon:string = InputStickerSet;
|
||||
|
||||
stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet;
|
||||
|
||||
@ -670,8 +670,8 @@ contacts.topPeersDisabled#b52c939d = contacts.TopPeers;
|
||||
draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage;
|
||||
draftMessage#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector<MessageEntity> date:int = DraftMessage;
|
||||
|
||||
messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers;
|
||||
messages.featuredStickers#f89d88e5 hash:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
||||
messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers;
|
||||
messages.featuredStickers#b6abc341 hash:int count:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
||||
|
||||
messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
|
||||
messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
|
||||
@ -1002,11 +1002,11 @@ help.userInfo#1eb3758 message:string entities:Vector<MessageEntity> author:strin
|
||||
|
||||
pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
|
||||
|
||||
poll#d5529d06 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:string answers:Vector<PollAnswer> = Poll;
|
||||
poll#86e18161 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:string answers:Vector<PollAnswer> close_period:flags.4?int close_date:flags.5?int = Poll;
|
||||
|
||||
pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true correct:flags.1?true option:bytes voters:int = PollAnswerVoters;
|
||||
|
||||
pollResults#c87024a2 flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int recent_voters:flags.3?Vector<int> = PollResults;
|
||||
pollResults#badcc1a3 flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int recent_voters:flags.3?Vector<int> solution:flags.4?string solution_entities:flags.4?Vector<MessageEntity> = PollResults;
|
||||
|
||||
chatOnlines#f041e250 onlines:int = ChatOnlines;
|
||||
|
||||
@ -1122,7 +1122,7 @@ stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueA
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
|
||||
initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
|
||||
initConnection#c1cd5ea9 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
|
||||
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
||||
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
|
||||
@ -1360,6 +1360,7 @@ messages.getDialogFilters#f19ed96d = Vector<DialogFilter>;
|
||||
messages.getSuggestedDialogFilters#a29cd42c = Vector<DialogFilterSuggested>;
|
||||
messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool;
|
||||
messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;
|
||||
messages.getOldFeaturedStickers#5fe7025b offset:int limit:int hash:int = messages.FeaturedStickers;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@ -1437,6 +1438,7 @@ channels.getInactiveChannels#11e831ee = messages.InactiveChats;
|
||||
|
||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||
bots.setBotCommands#805d46f6 commands:Vector<BotCommand> = Bool;
|
||||
|
||||
payments.getPaymentForm#99f09745 msg_id:int = payments.PaymentForm;
|
||||
payments.getPaymentReceipt#a092a980 msg_id:int = payments.PaymentReceipt;
|
||||
@ -1446,10 +1448,11 @@ payments.getSavedInfo#227d824b = payments.SavedInfo;
|
||||
payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool;
|
||||
payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
|
||||
|
||||
stickers.createStickerSet#9bd86e6a flags:# masks:flags.0?true user_id:InputUser title:string short_name:string stickers:Vector<InputStickerSetItem> = messages.StickerSet;
|
||||
stickers.createStickerSet#f1036780 flags:# masks:flags.0?true animated:flags.1?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> = messages.StickerSet;
|
||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||
stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = messages.StickerSet;
|
||||
stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet;
|
||||
stickers.setStickerSetThumb#9a364e30 stickerset:InputStickerSet thumb:InputDocument = messages.StickerSet;
|
||||
|
||||
phone.getCallConfig#55451fa9 = DataJSON;
|
||||
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
@ -1469,7 +1472,7 @@ langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLangua
|
||||
folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;
|
||||
folders.deleteFolder#1c295881 folder_id:int = Updates;
|
||||
|
||||
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
|
||||
stats.getBroadcastStats#e6300dba flags:# dark:flags.0?true channel:InputChannel tz_offset:int = stats.BroadcastStats;
|
||||
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
|
||||
|
||||
// LAYER 111
|
||||
// LAYER 112
|
@ -142,4 +142,6 @@ POLL_ANSWERS_INVALID The poll answers are invalid
|
||||
POLL_QUESTION_INVALID The poll question is invalid
|
||||
FRESH_CHANGE_ADMINS_FORBIDDEN Recently logged-in users cannot change admins
|
||||
BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in channels
|
||||
INPUT_FILTER_INVALID The filter is invalid for this query
|
||||
INPUT_FILTER_INVALID The filter is invalid for this query
|
||||
EMOTICON_EMPTY The emoticon parameter is empty
|
||||
EMOTICON_INVALID The emoticon parameter is invalid
|
|
@ -32,7 +32,8 @@ class ForwardMessages(BaseClient):
|
||||
message_ids: Union[int, Iterable[int]],
|
||||
disable_notification: bool = None,
|
||||
as_copy: bool = False,
|
||||
remove_caption: bool = False
|
||||
remove_caption: bool = False,
|
||||
schedule_date: int = None
|
||||
) -> List["pyrogram.Message"]:
|
||||
"""Forward messages of any kind.
|
||||
|
||||
@ -65,6 +66,9 @@ class ForwardMessages(BaseClient):
|
||||
message. Has no effect if *as_copy* is not enabled.
|
||||
Defaults to False.
|
||||
|
||||
schedule_date (``int``, *optional*):
|
||||
Date when the message will be automatically sent. Unix time.
|
||||
|
||||
Returns:
|
||||
:obj:`Message` | List of :obj:`Message`: In case *message_ids* was an integer, the single forwarded message
|
||||
is returned, otherwise, in case *message_ids* was an iterable, the returned value will be a list of
|
||||
@ -99,7 +103,8 @@ class ForwardMessages(BaseClient):
|
||||
chat_id,
|
||||
disable_notification=disable_notification,
|
||||
as_copy=True,
|
||||
remove_caption=remove_caption
|
||||
remove_caption=remove_caption,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
)
|
||||
|
||||
@ -111,7 +116,8 @@ class ForwardMessages(BaseClient):
|
||||
from_peer=await self.resolve_peer(from_chat_id),
|
||||
id=message_ids,
|
||||
silent=disable_notification or None,
|
||||
random_id=[self.rnd_id() for _ in message_ids]
|
||||
random_id=[self.rnd_id() for _ in message_ids],
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
)
|
||||
|
||||
@ -121,7 +127,7 @@ class ForwardMessages(BaseClient):
|
||||
chats = {i.id: i for i in r.chats}
|
||||
|
||||
for i in r.updates:
|
||||
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
|
||||
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
|
||||
forwarded_messages.append(
|
||||
await pyrogram.Message._parse(
|
||||
self, i.message,
|
||||
|
@ -27,6 +27,7 @@ class SendDice(BaseClient):
|
||||
async def send_dice(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
emoji: str = "🎲",
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: int = None,
|
||||
schedule_date: int = None,
|
||||
@ -45,6 +46,10 @@ class SendDice(BaseClient):
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
emoji (``str``, *optional*):
|
||||
Emoji on which the dice throw animation is based. Currently, must be one of "🎲" or "🎯".
|
||||
Defauts to "🎲".
|
||||
|
||||
disable_notification (``bool``, *optional*):
|
||||
Sends the message silently.
|
||||
Users will receive a notification with no sound.
|
||||
@ -65,13 +70,17 @@ class SendDice(BaseClient):
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Send a dice
|
||||
app.send_dice("pyrogramlounge")
|
||||
|
||||
# Send a dart
|
||||
app.send_dice("pyrogramlounge", "🎯")
|
||||
"""
|
||||
|
||||
r = await self.send(
|
||||
functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
media=types.InputMediaDice(),
|
||||
media=types.InputMediaDice(emoticon=emoji),
|
||||
silent=disable_notification or None,
|
||||
reply_to_msg_id=reply_to_message_id,
|
||||
random_id=self.rnd_id(),
|
||||
|
@ -27,18 +27,26 @@ from ...ext.utils import encode_file_id, encode_file_ref
|
||||
|
||||
|
||||
class Dice(Object):
|
||||
"""A dice containing a value that is randomly generated by Telegram.
|
||||
"""A dice with a random value from 1 to 6 for currently supported base emoji.
|
||||
|
||||
Parameters:
|
||||
emoji (``string``):
|
||||
Emoji on which the dice throw animation is based.
|
||||
|
||||
value (``int``):
|
||||
Dice value, 1-6.
|
||||
Value of the dice, 1-6 for currently supported base emoji.
|
||||
"""
|
||||
|
||||
def __init__(self, *, client: "pyrogram.BaseClient" = None, value: int):
|
||||
def __init__(self, *, client: "pyrogram.BaseClient" = None, emoji: str, value: int):
|
||||
super().__init__(client)
|
||||
|
||||
self.emoji = emoji
|
||||
self.value = value
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, dice: types.MessageMediaDice) -> "Dice":
|
||||
return Dice(value=dice.value, client=client)
|
||||
return Dice(
|
||||
emoji=dice.emoticon,
|
||||
value=dice.value,
|
||||
client=client
|
||||
)
|
||||
|
@ -561,7 +561,8 @@ class Message(Object, Update):
|
||||
if video_attributes.round_message:
|
||||
video_note = pyrogram.VideoNote._parse(client, doc, video_attributes)
|
||||
else:
|
||||
video = pyrogram.Video._parse(client, doc, video_attributes, file_name)
|
||||
video = pyrogram.Video._parse(client, doc, video_attributes, file_name,
|
||||
media.ttl_seconds)
|
||||
elif types.DocumentAttributeSticker in attributes:
|
||||
sticker = await pyrogram.Sticker._parse(
|
||||
client, doc,
|
||||
@ -2633,7 +2634,8 @@ class Message(Object, Update):
|
||||
chat_id: int or str,
|
||||
disable_notification: bool = None,
|
||||
as_copy: bool = False,
|
||||
remove_caption: bool = False
|
||||
remove_caption: bool = False,
|
||||
schedule_date: int = None
|
||||
) -> "Message":
|
||||
"""Bound method *forward* of :obj:`Message`.
|
||||
|
||||
@ -2671,6 +2673,9 @@ class Message(Object, Update):
|
||||
message. Has no effect if *as_copy* is not enabled.
|
||||
Defaults to False.
|
||||
|
||||
schedule_date (``int``, *optional*):
|
||||
Date when the message will be automatically sent. Unix time.
|
||||
|
||||
Returns:
|
||||
On success, the forwarded Message is returned.
|
||||
|
||||
@ -2690,7 +2695,8 @@ class Message(Object, Update):
|
||||
text=self.text.html,
|
||||
parse_mode="html",
|
||||
disable_web_page_preview=not self.web_page,
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
elif self.media:
|
||||
caption = self.caption.html if self.caption and not remove_caption else ""
|
||||
@ -2698,7 +2704,8 @@ class Message(Object, Update):
|
||||
send_media = partial(
|
||||
self._client.send_cached_media,
|
||||
chat_id=chat_id,
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
|
||||
if self.photo:
|
||||
@ -2732,14 +2739,16 @@ class Message(Object, Update):
|
||||
first_name=self.contact.first_name,
|
||||
last_name=self.contact.last_name,
|
||||
vcard=self.contact.vcard,
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
elif self.location:
|
||||
return await self._client.send_location(
|
||||
chat_id,
|
||||
latitude=self.location.latitude,
|
||||
longitude=self.location.longitude,
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
elif self.venue:
|
||||
return await self._client.send_venue(
|
||||
@ -2750,14 +2759,16 @@ class Message(Object, Update):
|
||||
address=self.venue.address,
|
||||
foursquare_id=self.venue.foursquare_id,
|
||||
foursquare_type=self.venue.foursquare_type,
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
elif self.poll:
|
||||
return await self._client.send_poll(
|
||||
chat_id,
|
||||
question=self.poll.question,
|
||||
options=[opt.text for opt in self.poll.options],
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
elif self.game:
|
||||
return await self._client.send_game(
|
||||
@ -2779,7 +2790,8 @@ class Message(Object, Update):
|
||||
chat_id=chat_id,
|
||||
from_chat_id=self.chat.id,
|
||||
message_ids=self.message_id,
|
||||
disable_notification=disable_notification
|
||||
disable_notification=disable_notification,
|
||||
schedule_date=schedule_date
|
||||
)
|
||||
|
||||
async def delete(self, revoke: bool = True):
|
||||
|
@ -42,15 +42,15 @@ class Photo(Object):
|
||||
height (``int``):
|
||||
Photo height.
|
||||
|
||||
ttl_seconds (``int``):
|
||||
Time-to-live seconds, for secret photos.
|
||||
|
||||
file_size (``int``):
|
||||
File size.
|
||||
|
||||
date (``int``):
|
||||
Date the photo was sent in Unix time.
|
||||
|
||||
ttl_seconds (``int``, *optional*):
|
||||
Time-to-live seconds, for secret photos.
|
||||
|
||||
thumbs (List of :obj:`Thumbnail`, *optional*):
|
||||
Available thumbnails of this photo.
|
||||
"""
|
||||
@ -63,10 +63,10 @@ class Photo(Object):
|
||||
file_ref: str,
|
||||
width: int,
|
||||
height: int,
|
||||
ttl_seconds: int,
|
||||
file_size: int,
|
||||
date: int,
|
||||
thumbs: List[Thumbnail]
|
||||
ttl_seconds: int = None,
|
||||
thumbs: List[Thumbnail] = None
|
||||
):
|
||||
super().__init__(client)
|
||||
|
||||
@ -74,9 +74,9 @@ class Photo(Object):
|
||||
self.file_ref = file_ref
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.ttl_seconds = ttl_seconds
|
||||
self.file_size = file_size
|
||||
self.date = date
|
||||
self.ttl_seconds = ttl_seconds
|
||||
self.thumbs = thumbs
|
||||
|
||||
@staticmethod
|
||||
@ -96,9 +96,9 @@ class Photo(Object):
|
||||
file_ref=encode_file_ref(photo.file_reference),
|
||||
width=big.w,
|
||||
height=big.h,
|
||||
ttl_seconds=ttl_seconds,
|
||||
file_size=big.size,
|
||||
date=photo.date,
|
||||
ttl_seconds=ttl_seconds,
|
||||
thumbs=Thumbnail._parse(client, photo),
|
||||
client=client
|
||||
)
|
||||
|
@ -60,6 +60,9 @@ class Video(Object):
|
||||
date (``int``, *optional*):
|
||||
Date the video was sent in Unix time.
|
||||
|
||||
ttl_seconds (``int``. *optional*):
|
||||
Time-to-live seconds, for secret photos.
|
||||
|
||||
thumbs (List of :obj:`Thumbnail`, *optional*):
|
||||
Video thumbnails.
|
||||
"""
|
||||
@ -78,6 +81,7 @@ class Video(Object):
|
||||
supports_streaming: bool = None,
|
||||
file_size: int = None,
|
||||
date: int = None,
|
||||
ttl_seconds: int = None,
|
||||
thumbs: List[Thumbnail] = None
|
||||
):
|
||||
super().__init__(client)
|
||||
@ -92,6 +96,7 @@ class Video(Object):
|
||||
self.supports_streaming = supports_streaming
|
||||
self.file_size = file_size
|
||||
self.date = date
|
||||
self.ttl_seconds = ttl_seconds
|
||||
self.thumbs = thumbs
|
||||
|
||||
@staticmethod
|
||||
@ -99,7 +104,8 @@ class Video(Object):
|
||||
client,
|
||||
video: types.Document,
|
||||
video_attributes: types.DocumentAttributeVideo,
|
||||
file_name: str
|
||||
file_name: str,
|
||||
ttl_seconds: int = None
|
||||
) -> "Video":
|
||||
return Video(
|
||||
file_id=encode_file_id(
|
||||
@ -120,6 +126,7 @@ class Video(Object):
|
||||
supports_streaming=video_attributes.supports_streaming,
|
||||
file_size=video.size,
|
||||
date=video.date,
|
||||
ttl_seconds=ttl_seconds,
|
||||
thumbs=Thumbnail._parse(client, video),
|
||||
client=client
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user