示例#1
0
    async def respond(self, event: NewMessage.Event,
                      msg: Union[str, KanTeXDocument],
                      reply: bool = True, delete: Optional[str] = None, link_preview: bool = False) -> Message:
        """Respond to the message an event caused or to the message that was replied to

        Args:
            event: The event of the message
            msg: The message text
            reply: If it should reply to the message that was replied to
            delete: Seconds until the sent message should be deleted

        Returns: None

        """
        msg = str(msg)
        if reply:
            if isinstance(event, ChatAction.Event):
                reply_to = event.action_message.id
            else:
                reply_to = (event.reply_to_msg_id or event.message.id)
            sent_msg: Message = await event.respond(msg, reply_to=reply_to, link_preview=link_preview)
        else:
            sent_msg: Message = await event.respond(msg, link_preview=link_preview)
        if delete is not None:
            delete_in = parsers.time(delete)
            # While asyncio.sleep would work it would stop the function from returning which is annoying
            await self.send_message(sent_msg.chat, f'{self.config.prefix}delete [Scheduled deletion]',
                                    schedule=datetime.timedelta(seconds=delete_in), reply_to=sent_msg.id,
                                    link_preview=link_preview)
        return sent_msg
示例#2
0
async def time(args: List[str]) -> MDTeXDocument:
    """Parse specified duration expressions into timedeltas
    Arguments:
        `exprs`: Time expressions

    Examples:
        {cmd} 1d
        {cmd} 1h30m 20s1m
        {cmd} 2w3d3h5s
    """
    m = Section('Parsed Durations')
    for arg in args:
        seconds = parsers.time(arg)
        m.append(
            SubSection(
                arg, KeyValueItem('seconds', seconds),
                KeyValueItem('formatted', str(timedelta(seconds=seconds)))))
    return MDTeXDocument(m)
示例#3
0
async def lock(client: Client, db: Database, chat: Chat, event: Command,
               msg: Message, args) -> KanTeXDocument:
    """Set a chat to read only.

    Arguments:
        `duration`: How long the chat should be locked
        `-self`: Use to make other Kantek instances ignore your command

    Examples:
        {cmd} 2h
        {cmd} 1d
        {cmd}
    """
    participant = (await
                   client(GetParticipantRequest(chat,
                                                msg.from_id))).participant
    permitted = False
    if isinstance(participant, ChannelParticipantCreator):
        permitted = True
    elif isinstance(participant, ChannelParticipantAdmin):
        rights = participant.admin_rights
        permitted = rights.ban_users
    if not permitted:
        return KanTeXDocument('Insufficient permission.')

    duration = None
    if args:
        try:
            duration = parsers.time(args[0])
        except MissingExpression as err:
            return KanTeXDocument(Italic(err))

    if duration and duration < 10:
        return KanTeXDocument('Duration too short.')

    permissions = chat.default_banned_rights.to_dict()
    del permissions['_']
    del permissions['until_date']
    del permissions['view_messages']
    await db.chats.lock(event.chat_id,
                        {k: v
                         for k, v in permissions.items() if not v})
    try:
        await client(
            EditChatDefaultBannedRightsRequest(chat,
                                               banned_rights=ChatBannedRights(
                                                   until_date=None,
                                                   view_messages=None,
                                                   send_messages=True,
                                                   send_media=True,
                                                   send_stickers=True,
                                                   send_gifs=True,
                                                   send_games=True,
                                                   send_inline=True,
                                                   send_polls=True,
                                                   change_info=True,
                                                   invite_users=True,
                                                   pin_messages=True)))
        if duration:
            config = Config()
            await client.send_message(chat,
                                      f'{config.prefix}unlock',
                                      schedule=msg.date +
                                      timedelta(seconds=duration))
        return KanTeXDocument('Chat locked.')
    except ChatNotModifiedError:
        return KanTeXDocument('Chat already locked.')
示例#4
0
async def schedule(client: Client, chat: Channel, msg: Message, kwargs: Dict,
                   event: Command) -> KanTeXDocument:
    """Schedule commands from a file or a message

    One command per line. Must be in reply to either a message or a file.

    Arguments:
        `-overwrite`: Overwrite all currently scheduled commands
        `-dynamic`: Determine the offset between messages dynamically depending on the messages word count
        `offset`: Offset as duration expression, see `{prefix}help parsers time`

    Examples:
        {cmd} -overwrite
        {cmd} -overwrite -dynamic
        {cmd} -overwrite offset: 30m
    """
    offset = kwargs.get('offset', '1h')
    offset = parsers.time(offset)
    dynamic = kwargs.get('dynamic', False)
    if kwargs.get('overwrite'):
        scheduled = await client(GetScheduledHistoryRequest(chat, 0))
        scheduled_ids = [smsg.id for smsg in scheduled.messages]
        await client(DeleteScheduledMessagesRequest(chat, scheduled_ids))

    if msg.is_reply:
        reply_msg: Message = await msg.get_reply_message()
        if isinstance(reply_msg.media, MessageMediaDocument):
            commands = (await
                        reply_msg.download_media(bytes)).decode().split('\n')
        else:
            commands = reply_msg.text.split('\n')
        current = datetime.now()
        next_time = current.astimezone(timezone.utc)
        next_time += timedelta(seconds=15)
        from_time = next_time
        for cmd in commands:
            if cmd:
                if dynamic:
                    offset = (len(cmd.split())**0.7) * 60
                try:
                    await client.send_message(chat, cmd, schedule=next_time)
                except FloodWaitError as err:
                    await msg.edit(
                        f'FloodWait. Sleeping for {err.seconds} seconds.')
                    await asyncio.sleep(err.seconds)

                next_time += timedelta(seconds=offset)
                await asyncio.sleep(0.5)
        await event.delete()
        return KanTeXDocument(
            Section(
                'Scheduled Messages',
                KeyValueItem(
                    Bold('From'),
                    from_time.astimezone(
                        current.tzinfo).strftime('%Y-%m-%d %H:%M:%S')),
                KeyValueItem(
                    Bold('To'),
                    next_time.astimezone(
                        current.tzinfo).strftime('%Y-%m-%d %H:%M:%S')),
                KeyValueItem(Bold('Count'), Code(len(commands)))))