Beispiel #1
0
async def update(client: Client, event: Command, tags: Tags) -> None:
    """Run git pull and exit.

    This command assumes the bot is running under a process manager that automatically restarts it.

    Tags:
        update: Set to `silent` to silence any messages

    Examples:
        {cmd}
    """
    silent = tags.get('update', False)
    if not silent:
        progess_message = await client.respond(event, MDTeXDocument(
            Section('Updating',
                    f'Running {Code("git pull")}')))
    else:
        await event.delete()
    subprocess.call(['git', 'pull', '-q'])
    new_commit = helpers.get_commit()
    if not silent:
        await progess_message.delete()
        await client.respond(
            event,
            MDTeXDocument(
                Section('Updated Kantek',
                        KeyValueItem('New commit', Link(new_commit, helpers.link_commit(new_commit))),
                        Italic('Restarting bot'))))
    await client.disconnect()
Beispiel #2
0
async def fwgban(client: Client, db: Database, tags: Tags, chat: Channel,
                 msg: Message, args: List, kwargs: Dict,
                 event: Command) -> Optional[KanTeXDocument]:
    """Globally ban a user.

    This will not actively ban them from any chats except the one command was issued in as reply. GBanned users will be automatically banned on join or when writing a message by the Grenzschutz module.
    When banning by reply the message content will be automatically sent to the SpamWatch API if enabled.

    Arguments:

        `reason`: Ban reason, defaults to `spam[gban]`


    Tags:
        gban:
            verbose: Send a message when a user was banned by id


    Examples (as replies):
        {cmd} "some reason here"
        {cmd}
    """
    _gban = tags.get('gban')
    if event.is_private:
        admin = False
    else:
        admin = bool(chat.creator or chat.admin_rights)
    only_joinspam = kwargs.get('only_joinspam', False) or kwargs.get(
        'oj', False)

    verbose = False
    if _gban == 'verbose' or event.is_private:
        verbose = True

    if msg.is_reply:
        bancmd = tags.get('gbancmd')
        reply_msg: Message = await msg.get_reply_message()
        forward: Forward = reply_msg.forward
        if forward.sender_id is None:
            raise Error('User has forward privacy enabled or is a Channel')

        uid = forward.sender_id
        if args:
            ban_reason = ' '.join(args)
        else:
            ban_reason = DEFAULT_REASON
            try:
                participant = await client(
                    GetParticipantRequest(event.chat_id, reply_msg.from_id))
                if not isinstance(participant.participant,
                                  ChannelParticipantCreator):
                    join_date = participant.participant.date

                    if (reply_msg.date -
                            datetime.timedelta(hours=1)) < join_date:
                        ban_reason = 'joinspam'
                    elif only_joinspam:
                        return
            except (UserNotParticipantError, TypeError):
                pass
        banned_uids: Dict = {}
        message = await helpers.textify_message(reply_msg)
        banned, reason = await client.gban(uid, ban_reason, message)
        banned_uids[reason] = banned_uids.get(reason, []) + [str(uid)]
        if verbose:
            sections = []
            if not banned:
                sections.append(KeyValueItem(Bold('Error'), reason))
                await client.respond(msg,
                                     KanTeXDocument(*sections),
                                     reply=True)
                return

            if banned_uids:
                bans = _build_message(banned_uids, message)
                sections.append(Section(f'GBanned User', *bans))

            await client.respond(msg, KanTeXDocument(*sections), reply=True)
            return

    else:
        pass
Beispiel #3
0
async def update(client: Client, event: Command, tags: Tags) -> None:
    """Run git pull and exit.

    This command assumes the bot is running under a process manager that automatically restarts it.

    Tags:
        update: Set to `silent` to silence any messages

    Examples:
        {cmd}
    """
    silent = tags.get('update', False)
    old_commit = helpers.get_commit()
    # region git pull
    if not silent:
        progess_message = await client.respond(
            event,
            KanTeXDocument(Section('Updating', f'Running {Code("git pull")}')))
    else:
        await event.delete()

    proc = subprocess.call(['git', 'pull', '-q'])
    if proc != 0:
        msg = KanTeXDocument(
            Section('Error', f'{Code("git")} returned non-zero exit code.',
                    'Please update manually'))
        if not silent:
            await progess_message.edit(str(msg))
        else:
            await client.respond(event, msg)
        return
    # endregion

    new_commit = helpers.get_commit()
    if old_commit == new_commit:
        await client.respond(
            event,
            KanTeXDocument(
                Section('No Update Available', Italic('Doing nothing'))))
        return

    # region pip install
    proc = subprocess.call(['pip', 'install', '-r', 'requirements.txt'])
    if proc != 0:
        msg = KanTeXDocument(
            Section('Error', f'{Code("pip")} returned non-zero exit code.',
                    'Please update manually'))
        if not silent:
            await progess_message.edit(str(msg))
        else:
            await client.respond(event, msg)
        return
    # endregion

    # region migrant
    '''
    if not silent:
        await progess_message.edit(str(KanTeXDocument(
            Section('Updating',
                    f'Running {Code("migrant apply --all")}'))))
    proc = subprocess.run(['migrant', 'apply', '--all'], stderr=subprocess.PIPE)
    if proc.returncode != 0:
        if b'MigrationComplete' not in proc.stderr:
            msg = KanTeXDocument(
                Section('Error',
                        f'{Code("migrant")} returned non-zero exit code.',
                        'Please update manually'))
            if not silent:
                await progess_message.edit(str(msg))
            else:
                await client.respond(event, msg)
            return
    # endregion
    '''

    if not silent:
        await progess_message.delete()
        await client.respond(
            event,
            KanTeXDocument(
                Section(
                    'Updated Kantek',
                    KeyValueItem(
                        'New commit',
                        Link(new_commit, helpers.link_commit(new_commit))),
                    Italic('Restarting bot'))))
    await client.disconnect()
Beispiel #4
0
async def gban(client: Client, db: Database, tags: Tags, chat: Channel,
               msg: Message, args: List, kwargs: Dict, event: Command) -> None:
    """Globally ban a user.

    This will not actively ban them from any chats except the one command was issued in as reply. GBanned users will be automatically banned on join or when writing a message by the Grenzschutz module.
    When banning by reply the message content will be automatically sent to the SpamWatch API if enabled.

    Arguments:
        `ids`: List of user ids to be gbanned
        `reason`: Ban reason, defaults to `spam[gban]`
        `msg`: String of the message the user sent. Only useful with the SpamWatch API
        `link`: Link to the users message. Only useful with the SpamWatch API
        `sa`: Key for a Strafanzeige entry, simply copy paste this from {prefix}user

    Tags:
        gban:
            verbose: Send a message when a user was banned by id
        gbancmd:
            *: Send `{{bancmd}} {{ban_reason}}` in reply to the message

    Examples:
        {cmd} 777000
        {cmd} 777000 "some reason here"
        {cmd} 777000 msg: "the message for the api"
        {cmd} 777000 link: https://t.me/c/1129887931/26708
        {cmd} sa: xcQq9aMm77U2aA
        {cmd}
    """
    _gban = tags.get('gban')
    if event.is_private:
        admin = False
    else:
        admin = bool(chat.creator or chat.admin_rights)
    only_joinspam = kwargs.get('only_joinspam', False) or kwargs.get(
        'oj', False)
    sa_key = kwargs.get('sa')
    anzeige = None
    if sa_key:
        anzeige = await db.strafanzeigen.get(sa_key)

    if anzeige:
        _kw, _args = parsers.arguments(anzeige)
        kwargs.update(_kw)
        args.extend(_args)

    verbose = False
    if _gban == 'verbose' or event.is_private:
        verbose = True
    await msg.delete()
    if msg.is_reply:
        bancmd = tags.get('gbancmd')
        reply_msg: Message = await msg.get_reply_message()
        uid = reply_msg.from_id
        if args:
            ban_reason = args[0]
        else:
            ban_reason = DEFAULT_REASON
            try:
                participant = await client(
                    GetParticipantRequest(event.chat_id, reply_msg.from_id))
                join_date = participant.participant.date

                if (reply_msg.date - datetime.timedelta(hours=1)) < join_date:
                    ban_reason = 'joinspam'
                elif only_joinspam:
                    return
            except UserNotParticipantError:
                pass

        message = await helpers.textify_message(reply_msg)
        await client.gban(uid, ban_reason, message)
        peer_channel: InputPeerChannel = await event.get_input_chat()
        if not client.config.debug_mode:
            await client(
                ReportRequest(peer_channel, [reply_msg.id],
                              InputReportReasonSpam()))
        if bancmd == 'manual' or bancmd is None:
            if admin:
                await client.ban(chat, uid)

        elif bancmd is not None:
            await reply_msg.reply(f'{bancmd} {ban_reason}')
            await asyncio.sleep(0.5)

        if not client.config.debug_mode and admin:
            await reply_msg.delete()

    else:
        uids = []
        ban_reason = []
        for arg in args:
            if isinstance(arg, int):
                uids.append(arg)
            else:
                ban_reason.append(arg)
        if ban_reason:
            ban_reason = ' '.join(ban_reason)
        else:
            ban_reason = kwargs.get('reason', DEFAULT_REASON)

        message = kwargs.get('msg')
        if not message:
            link = kwargs.get('link')
            if link:
                try:
                    linked_msg: Message = await helpers.get_linked_message(
                        client, link)
                    message = await helpers.textify_message(linked_msg)
                except Exception:  # pylint: disable = W0703
                    message = link

        skipped_uids = {}
        banned_uids = {}
        progress_message: Optional[Message]
        if verbose and len(uids) > 10:
            progress_message: Message = await client.send_message(
                chat, f"Processing {len(uids)} User IDs")
        else:
            progress_message = None
        while uids:
            uid_batch = uids[:CHUNK_SIZE]
            for uid in uid_batch:
                banned, reason = await client.gban(uid, ban_reason, message)
                if not banned:
                    skipped_uids[reason] = skipped_uids.get(reason,
                                                            []) + [str(uid)]
                # sleep to avoid flooding the bots too much
                else:
                    banned_uids[reason] = banned_uids.get(reason,
                                                          []) + [str(uid)]
                await asyncio.sleep(0.5)
            uids = uids[CHUNK_SIZE:]
            if uids:
                if progress_message:
                    await progress_message.edit(
                        f"Sleeping for 10 seconds after banning {len(uid_batch)} Users. {len(uids)} Users left."
                    )
                await asyncio.sleep(10)

        if progress_message:
            await progress_message.delete()

        if verbose:
            sections = []
            if banned_uids:
                bans = _build_message(banned_uids, message)
                sections.append(
                    Section(
                        f'GBanned User{"s" if len(banned_uids) > 1 else ""}',
                        *bans))
            if skipped_uids:
                bans = _build_message(skipped_uids)
                sections.append(Section('Skipped GBan', *bans))

            await client.respond(event, MDTeXDocument(*sections))