示例#1
0
async def demote(event: NewMessage.Event) -> None:
    """Demote a user in a group or channel."""
    if not event.is_private and not await get_rights(event, ban_users=True):
        await event.answer("`You do not have rights to remove admins in here!`"
                           )
        return
    elif event.is_private:
        await event.answer("`You can't demote users in private chats.`")
        return

    user, reason, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.answer(f"`Demote machine broke!\n{user}`")
            return
    else:
        await event.answer("`At least specifiy a user, maybe?`")
        return

    entity = await event.get_chat()
    try:
        await client.edit_admin(entity=entity, user=user, is_admin=False)
        text = "`Successfully demoted `{}` (``{}``)!`"
        if reason:
            text += f"\n`Reason:` `{reason}`"
        e1 = await get_chat_link(user)
        e2 = await get_chat_link(entity, event.id)
        log_msg = f"Successfully demoted {e1} in {e2}"
        if reason:
            log_msg += f"\nReason: {reason}"

        await event.answer(text.format(e1, user.id), log=("demote", log_msg))
    except Exception as e:
        await event.answer(f"`{e}`")
        LOGGER.exception(e)
示例#2
0
async def unban(event):
    if ((event.is_channel or event.is_group)
            and not (event.chat.creator or event.chat.admin_rights.ban_users)):
        await event.edit("`You do not have rights to un-ban users in here!`")
        return

    user, reason, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`Un-ban machine broke!\n{user}`")
            return

    try:
        await client.edit_permissions(entity=await event.get_input_chat(),
                                      user=user,
                                      view_messages=True,
                                      send_messages=True,
                                      send_media=True,
                                      send_stickers=True,
                                      send_gifs=True,
                                      send_games=True,
                                      send_inline=True,
                                      send_polls=True)
        text = "`Successfully un-banned ``{}`` (``{}``)!`"
        if reason:
            text += f"\n`Reason:` `{reason}`"
        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit(f"`{e}`")
        LOGGER.exception(e)
示例#3
0
async def update_requirements():
    reqs = os.path.join(basedir, "requirements.txt")
    try:
        await create_subprocess_shell(' '.join(sys.executable, "-m", "pip",
                                               "install", "-r", str(reqs)))
    except Exception as e:
        LOGGER.exception(e)
示例#4
0
async def ban(event):
    if ((event.is_channel or event.is_group)
            and not (event.chat.creator or event.chat.admin_rights.ban_users)):
        await event.edit("`You do not have rights to ban users in here!`")
        return

    user, reason, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`Ban machine broke!\n{user}`")
            return

    try:
        await client.edit_permissions(entity=await event.get_input_chat(),
                                      user=user,
                                      view_messages=False)
        text = "`Successfully banned ``{}`` (``{}``)!`"
        if reason:
            text += f"\n`Reason:` `{reason}`"
        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit("`An exception occured trying to ban. "
                         " Make sure you have the correct rights! "
                         "Check the logs for more information.`")
        LOGGER.exception(e)
示例#5
0
async def promote(event):
    if ((event.is_channel or event.is_group) and
            not (event.chat.creator or event.chat.admin_rights.add_admins)):
        await event.edit("`You do not have rights to add admins in here!`")
        return

    user, extra, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`Promote machine broke!\n{user}`")
            return

    try:
        await client.edit_admin(
            entity=await event.get_input_chat(),
            post_messages=True if event.is_channel else False,
            edit_messages=True if event.is_channel else False,
            user=user,
            is_admin=True,
            title=extra)
        text = "`Successfully promoted ``{}`` (``{}``)!`"
        if extra:
            text += f"\n`Title:` `{extra}`"
        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit("`An exception occured trying to promote. "
                         " Make sure you have the correct rights! "
                         "Check the logs for more information.`")
        LOGGER.exception(e)
示例#6
0
async def bio_filter(event: ChatAction.Event) -> None:
    """Filter incoming messages for blacklisting."""
    text = None
    broadcast = getattr(event.chat, 'broadcast', False)

    if not redis or event.is_private or broadcast:
        return

    if event.user_added or event.user_joined:
        try:
            sender = await event.get_input_user()
            chat = await event.get_chat()
            sender_id = await client.get_peer_id(sender)
            chat_id = await client.get_peer_id(chat)
            localbl = localBlacklists.get(chat_id, False)
        except (ValueError, TypeError):
            return
        if chat_id in whitelistedChats or sender_id in whitelistedUsers:
            return
        if await is_admin(chat_id, sender_id):
            return

        user = await client(functions.users.GetFullUserRequest(id=sender))
        if GlobalBlacklist.bio:
            for value in GlobalBlacklist.bio:
                bio = await escape_string(value)
                if re.search(bio, user.about, flags=re.I):
                    text = ("**Banned due to globally blacklisted bio match: "
                            f"{value}**")
        elif localbl and getattr(localbl, 'bio', False):
            for value in localBlacklists[chat_id].bio:
                bio = await escape_string(value)
                if re.search(bio, user.about, flags=re.I):
                    text = f"**Banned due to blacklisted bio match: {value}**"

        if text:
            ban_right = getattr(chat.admin_rights, 'ban_users', False)
            if ban_right or chat.creator:
                pass
            else:
                return
            try:
                await client.edit_permissions(entity=chat,
                                              user=sender_id,
                                              view_messages=False)
                await event.reply(text)
                if client.logger:
                    logger_group = client.config['userbot'].getint(
                        'logger_group_id', 'me')
                    log_text = ("**USERBOT LOG** #blacklist\n"
                                f'Banned {sender_id} from {chat_id}.\n{text}.')
                    await client.send_message(logger_group, log_text)
            except Exception as e:
                await event.reply(f"**Couldn't ban user due to {e}**")
                LOGGER.exception(e)
示例#7
0
async def tban(event: NewMessage.Event) -> None:
    """Temporary ban a user in a group or channel."""
    if not event.is_private and not await get_rights(event, ban_users=True):
        await event.answer("`You do not have rights to t-ban users in here!`")
        return
    elif event.is_private:
        await event.answer("`You can't t-ban users in private chats.`")
        return

    user, extra, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.answer(f"`T-ban machine broke!\n{user}`")
            return
    else:
        await event.answer("`At least specifiy a user, maybe?`")
        return

    entity = await event.get_chat()
    try:
        time = None
        reason = None
        seconds = None
        text = "`Successfully t-banned `{}` (``{}``)!`"
        e1 = await get_chat_link(user)
        e2 = await get_chat_link(entity, event.id)
        log_msg = f"Successfully t-banned {e1} in {e2}"
        if extra:
            reason, seconds = await split_extra_string(extra)
            if reason:
                text += f"\n`Reason:` `{reason}`"
                log_msg += f"\nReason: {reason}"
            if seconds:
                time = timedelta(seconds=seconds)
                text += f"\n`Time:` `{await _humanfriendly_seconds(seconds)}`"
                log_msg += f"Time: {await _humanfriendly_seconds(seconds)}"

        if not seconds:
            await event.answer("`Provide the total time limit for t-ban!`")
            return

        await client.edit_permissions(
            entity=entity,
            user=user,
            until_date=time,
            view_messages=False
        )

        await event.answer(
            text.format(e1, user.id),
            log=("tban", log_msg)
        )
    except Exception as e:
        await event.answer(f"`{e}`")
        LOGGER.exception(e)
示例#8
0
async def update_requirements():
    try:
        process = await asyncio.create_subprocess_shell(
            f'{sys.executable} -m pip install --user -r requirements.txt',
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)
        await process.communicate()
        return process.returncode
    except Exception as e:
        LOGGER.exception(e)
        return await client.get_traceback(e)
示例#9
0
async def update_requirements():
    reqs = str(requirements_path)
    try:
        process = await asyncio.create_subprocess_shell(
            ' '.join([sys.executable, "-m", "pip", "install", "-r", reqs]),
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)
        await process.communicate()
        return process.returncode
    except Exception as e:
        LOGGER.exception(e)
        return repr(e)
示例#10
0
async def update_requirements():
    args = ['-m', 'pip', 'install', '--user', '-r', 'requirements.txt']
    try:
        process = await asyncio.create_subprocess_exec(
            sys.executable.replace(' ', '\\ '),
            *args,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)
        await process.communicate()
        return process.returncode
    except Exception as e:
        LOGGER.exception(e)
        return await client.get_traceback(e)
示例#11
0
async def update_requirements():
    reqs = ' '.join(
        [sys.executable, "-m", "pip", "install", "-r", 'requirements.txt'])
    try:
        process = await asyncio.create_subprocess_shell(
            reqs,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)
        await process.communicate()
        return process.returncode
    except Exception as e:
        LOGGER.exception(e)
        return await client.get_traceback(e)
示例#12
0
async def update_requirements():
    args = ["-m", "pip", "install", "--user", "-r", "requirements.txt"]
    try:
        process = await asyncio.create_subprocess_exec(
            sys.executable.replace(" ", "\\ "),
            *args,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )
        await process.communicate()
        return process.returncode
    except Exception as e:
        LOGGER.exception(e)
        return await client.get_traceback(e)
示例#13
0
async def unban(event: NewMessage.Event) -> None:
    """Un-ban a user in a group or channel."""
    if not event.is_private and not await get_rights(event, ban_users=True):
        await event.answer("`You do not have rights to un-ban users in here!`")
        return
    elif event.is_private:
        await event.answer("`You can't un-ban users in private chats.`")
        return

    user, reason, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.answer(f"`Un-ban machine broke!\n{user}`")
            return
    else:
        await event.answer("`At least specifiy a user, maybe?`")
        return

    entity = await event.get_chat()
    try:
        await client.edit_permissions(
            entity=entity,
            user=user,
            view_messages=True,
            send_messages=True,
            send_media=True,
            send_stickers=True,
            send_gifs=True,
            send_games=True,
            send_inline=True,
            send_polls=True
        )
        text = "`Successfully un-banned `{}` (``{}``)!`"
        if reason:
            text += f"\n`Reason:` `{reason}`"
        e1 = await get_chat_link(user)
        e2 = await get_chat_link(entity, event.id)
        log_msg = f"Successfully unbanned {e1} in {e2}"
        if reason:
            log_msg += f"\nReason: {reason}"

        await event.answer(
            text.format(e1, user.id),
            log=("unban", log_msg)
        )
    except Exception as e:
        await event.answer(f"`{e}`")
        LOGGER.exception(e)
示例#14
0
async def ban_user(event: NewMessage.Event or ChatAction.Event,
                   text: str,
                   bl_type: str = None,
                   match: Union[str, int] = None,
                   globally: bool = False) -> bool:
    if isinstance(event, NewMessage.Event):
        sender = await event.get_input_sender()
    else:
        sender = await event.get_input_user()
    temp_banlist.append(sender)
    chat = await event.get_chat()
    ban_right = getattr(chat.admin_rights, 'ban_users', False)
    delete_messages = getattr(chat.admin_rights, 'delete_messages', False)
    if not (ban_right or chat.creator):
        return False
    user_href = "[{0}](tg://user?id={0})".format(sender.user_id)
    try:
        await client.edit_permissions(entity=chat.id,
                                      user=sender,
                                      view_messages=False)
        if delete_messages:
            await event.delete()
        text = text.format(user_href, ' globally ' if globally else ' ')
        await event.respond(text)
        if client.logger:
            logger_group = client.config['userbot'].getint(
                'logger_group_id', 'me')
            if chat.username:
                chat_href = (f"[{chat.title}]"
                             f"(tg://resolve?domain={chat.username})")
            else:
                chat_href = f"[{chat.title}] `{chat.id}`"
            log_text = ("**USERBOT LOG** #blacklist\n"
                        f"Banned {user_href} from {chat_href}.\n")
            if bl_type and match:
                log_text += f"Blacklist type: `{bl_type}`.\nMatch: `{match}`"
            await client.send_message(logger_group, log_text)
        if bl_type and match and sender.user_id not in blacklistedUsers:
            blacklistedUsers.update({sender.user_id: (bl_type, match)})
            redis.set('blacklist:users', dill.dumps(blacklistedUsers))
        return True
    except Exception as e:
        exc = await client.get_traceback(e)
        await event.respond(f"**Couldn't ban user. Exception:\n**```{exc}```")
        LOGGER.exception(e)
        return False
    finally:
        temp_banlist.remove(sender)
示例#15
0
async def ban_user(event: NewMessage.Event, text: str) -> bool:
    chat = await event.get_chat()
    ban_right = getattr(chat.admin_rights, 'ban_user', False)
    if not (chat.creator or ban_right):
        return False
    try:
        await client.edit_permissions(entity=event.chat_id,
                                      user=event.from_id,
                                      view_messages=False)
        await event.answer(
            text,
            log=('blacklist',
                 f'Banned {event.from_id} from {event.chat_id}.\n{text}.'))
        return True
    except Exception as e:
        await event.answer(f"**Couldn't ban user due to {e}**", reply=True)
        LOGGER.exception(e)
        return False
示例#16
0
async def sed(e):
    sed_result = separate_sed(e.text)
    L = await e.get_reply_message()
    if sed_result:
        if L:
            to_fix = L.text
        else:
            await e.edit(
                "`Master, I don't have brains. Well you too don't I guess.`"
            )
            return

        repl, repl_with, flags = sed_result

        if not repl:
            await e.edit(
                "`Master, I don't have brains. Well you too don't I guess.`"
            )
            return

        try:
            check = re.match(repl, to_fix, flags=re.IGNORECASE)
            if check and check.group(0).lower() == to_fix.lower():
                await e.edit(
                    "`Boi!, that's a reply. Don't use sed`"
                )
                return

            if "i" in flags and "g" in flags:
                text = re.sub(repl, repl_with, to_fix, flags=re.I).strip()
            elif "i" in flags:
                text = re.sub(repl, repl_with, to_fix, count=1, flags=re.I).strip()
            elif "g" in flags:
                text = re.sub(repl, repl_with, to_fix).strip()
            else:
                text = re.sub(repl, repl_with, to_fix, count=1).strip()
        except sre_constants.error:
            LOGGER.warning(e.text)
            LOGGER.exception("SRE constant error")
            await e.edit("B O I! [Learn Regex](https://regexone.com)")
            return
        if text:
            await e.edit("Did you mean? \n\n`" + text + "`")
示例#17
0
async def promote(event: NewMessage.Event) -> None:
    """Promote a user in a group or channel."""
    if not event.is_private and not await get_rights(event, add_admins=True):
        await event.answer("`You do not have rights to add admins in here!`")
        return
    elif event.is_private:
        await event.answer("`You can't promote users in private chats.`")
        return

    user, extra, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.answer(f"`Promote machine broke!\n{user}`")
            return
    else:
        await event.answer("`At least specifiy a user, maybe?`")
        return

    entity = await event.get_chat()
    try:
        await client.edit_admin(
            entity=entity,
            user=user,
            is_admin=True,
            title=extra
        )
        text = "`Successfully promoted `{}` (``{}``)!`"
        if extra:
            text += f"\n`Title:` `{extra}`"
        e1 = await get_chat_link(user)
        e2 = await get_chat_link(entity, event.id)
        log_msg = f"Successfully promoted {e1} in {e2}"
        if extra:
            log_msg += f"\nTitle: {extra}"

        await event.answer(
            text.format(e1, user.id),
            log=("promote", log_msg)
        )
    except Exception as e:
        await event.answer(f"`{e}`")
        LOGGER.exception(e)
示例#18
0
async def tmute(event):
    if ((event.is_channel or event.is_group)
            and not (event.chat.creator or event.chat.ban_users)):
        await event.edit("`You do not have rights to mute users in here!`")
        return

    user, extra, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`T-mute machine broke!\n{user}`")
            return

    try:
        time = None
        reason = None
        seconds = None
        text = "`Successfully t-muted ``{}`` (``{}``)!`"
        if extra:
            reason, seconds = await split_extra_string(extra)
            if reason:
                text += f"\n`Reason:` `{reason}`"
            if seconds:
                time = timedelta(seconds=seconds)
                text += f"\n`Time:` `{time}`"

        if not seconds:
            await event.edit("`Provide the total time limit for t-mute!`")
            return

        await client.edit_permissions(entity=await event.get_input_chat(),
                                      user=user,
                                      until_date=time,
                                      send_messages=False)

        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit("`An exception occured trying to t-mute. "
                         " Make sure you have the correct rights! "
                         "Check the logs for more information.`")
        LOGGER.exception(e)
示例#19
0
async def kick(event):
    if ((event.is_channel or event.is_group)
            and not (event.chat.creator or event.chat.admin_rights.ban_users)):
        await event.edit("`You do not have rights to kick users in here!`")
        return

    user, reason, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`Kick machine broke!\n{user}`")
            return

    try:
        await client.kick_participant(entity=await event.get_input_chat(),
                                      user=user)
        text = "`Successfully kicked ``{}`` (``{}``)!`"
        if reason:
            text += f"\n`Reason:` `{reason}`"
        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit(f"`{e}`")
        LOGGER.exception(e)
示例#20
0
async def mute(event):
    if ((event.is_channel or event.is_group)
            and not (event.chat.creator or event.chat.ban_users)):
        await event.edit("`You do not have rights to mute users in here!`")
        return

    user, reason, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`Mute machine broke!\n{user}`")
            return

    try:
        await client.edit_permissions(entity=await event.get_input_chat(),
                                      user=user,
                                      send_messages=False)
        text = "`Successfully muted ``{}`` (``{}``)!`"
        if reason:
            text += f"\n`Reason:` `{reason}`"
        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit(f"`{e}`")
        LOGGER.exception(e)
示例#21
0
async def ban_user(event: NewMessage.Event or ChatAction.Event,
                   text: str,
                   bl_type: str = None,
                   match: Union[str, int] = None) -> bool:
    if isinstance(event, NewMessage.Event):
        sender = await event.get_input_sender()
    else:
        sender = await event.get_input_user()
    temp_banlist.append(sender)
    chat = await event.get_chat()
    ban_right = getattr(chat.admin_rights, 'ban_users', False)
    delete_messages = getattr(chat.admin_rights, 'delete_messages', False)
    if not (ban_right or chat.creator):
        return False
    try:
        await client.edit_permissions(entity=chat.id,
                                      user=sender,
                                      view_messages=False)
        if delete_messages:
            await event.delete()
        await event.respond(text)
        if client.logger:
            logger_group = client.config['userbot'].getint(
                'logger_group_id', 'me')
            log_text = ("**USERBOT LOG** #blacklist\n"
                        f"Banned {sender.user_id} from {chat.id}.\n{text}.")
            await client.send_message(logger_group, log_text)
        if bl_type and match:
            blacklistedUsers.update({sender.user_id: (bl_type, match)})
            redis.set('blacklist:users', dill.dumps(blacklistedUsers))
        return True
    except Exception as e:
        await event.respond(f"**Couldn't ban user due to {e}**")
        LOGGER.exception(e)
        return False
    finally:
        temp_banlist.remove(sender)
示例#22
0
async def promote(event):
    if ((event.is_channel or event.is_group) and
            not (event.chat.creator or event.chat.admin_rights.add_admins)):
        await event.edit("`You do not have rights to add admins in here!`")
        return

    user, extra, exception = await get_entity_from_msg(event)
    if user:
        if exception:
            await event.edit(f"`Promote machine broke!\n{user}`")
            return

    try:
        await client.edit_admin(entity=await event.get_input_chat(),
                                user=user,
                                is_admin=True,
                                title=extra)
        text = "`Successfully promoted ``{}`` (``{}``)!`"
        if extra:
            text += f"\n`Title:` `{extra}`"
        await event.edit(text.format(get_display_name(user), user.id))
    except Exception as e:
        await event.edit(f"`{e}`")
        LOGGER.exception(e)
示例#23
0
async def updater(event: NewMessage.Event) -> None:
    """Pull newest changes from the official repo and update the script/app."""
    arg = event.matches[0].group(1)
    await event.answer("`Checking for updates!`")
    try:
        repo = git.Repo(basedir)
        fetched_items = repo.remotes.origin.fetch()
    except git.exc.NoSuchPathError as path:
        await event.answer(f"`Couldn't find {path}!`")
        repo.__del__()
        return
    except git.exc.GitCommandError as command:
        await event.answer(
            f"`An error occured trying to get the Git Repo.`\n`{command}`")
        repo.__del__()
        return
    except git.exc.InvalidGitRepositoryError:
        repo = git.Repo.init(basedir)
        origin = repo.create_remote('origin', main_repo)
        if not origin.exists():
            await event.answer(
                "`The main repository does not exist. Remote is invalid!`")
            repo.__del__()
            return
        fetched_items = origin.fetch()
        repo.create_head('master', origin.refs.master).set_tracking_branch(
            origin.refs.master).checkout()
    fetched_commits = repo.iter_commits(f"HEAD..{fetched_items[0].ref.name}")
    untracked_files = repo.untracked_files
    old_commit = repo.head.commit
    for diff_added in old_commit.diff('FETCH_HEAD').iter_change_type('M'):
        if "requirements.txt" in diff_added.b_path:
            await event.answer("`Updating the pip requirements!`")
            updated = await update_requirements()
            if updated == 0:
                await event.answer("`Successfully updated the requirements.`")
            else:
                if isinstance(updated, int):
                    await event.answer(
                        "`Failed trying to install requirements."
                        " Install them manually and run the command again.`")
                else:
                    await event.answer(f'```{updated}```')
                return
            break

    if arg == "add":
        repo.index.add(untracked_files, force=True)
        repo.index.commit("[PaperplaneRemix] Updater: Untracked files")
    elif arg == "reset":
        repo.head.reset('--hard')

    try:
        repo.remotes.origin.pull()
    except git.exc.GitCommandError as command:
        text = ("`An error occured trying to Git pull:`\n`{0}`\n\n"
                "`You may use` **{1}update reset** `or` **{1}update add** "
                "`to reset your repo or add and commit your changes as well.`")
        prefix = client.prefix if client.prefix is not None else '.'
        await event.answer(text.format(command, prefix))
        repo.__del__()
        return

    new_commit = repo.head.commit
    if old_commit == new_commit:
        await event.answer("`Already up-to-date!`")
        repo.__del__()
        return

    remote_url = repo.remote().url.replace(".git", '/')
    if remote_url[-1] != '/':
        remote_url = remote_url + '/'

    now = datetime.datetime.now(datetime.timezone.utc)
    def_changelog = changelog = "**PaperplaneRemix changelog:**"
    for commit in fetched_commits:
        changelog += summary.format(rev=repo.git.rev_parse(commit.hexsha,
                                                           short=7),
                                    summary=commit.summary,
                                    url=remote_url,
                                    sha=commit.hexsha)
        ago = (now - commit.committed_datetime).total_seconds()
        elspased = (await _humanfriendly_seconds(ago)).split(',')[0]
        committers_link = author_link.format(author=commit.committer,
                                             url=remote_url)
        authors_link = author_link.format(author=commit.author, url=remote_url)
        if commit.author == commit.committer:
            committed = commited.format(committer=committers_link,
                                        elapsed=elspased)
        else:
            committed = authored.format(author=authors_link,
                                        committer=committers_link,
                                        elapsed=elspased)
        changelog += f"{committed:>{len(committed) + 8}}"
    if changelog == def_changelog:
        changelog = "`No changelog for you! IDK what happened.`"

    toast = await event.answer(
        "`Successfully pulled the new commits. Updating the bot!`",
        log=("update", changelog.strip()))
    if not client.logger:
        await event.answer(changelog.strip(),
                           reply_to=toast.id,
                           link_preview=False)

    os.environ['userbot_update'] = "True"
    heroku_api_key = client.config['api_keys'].get('api_key_heroku', False)
    if os.getenv("DYNO", False) and heroku_api_key:
        heroku_conn = heroku3.from_key(heroku_api_key)
        app = None
        for heroku_app in heroku_conn.apps():
            if "api_key_heroku" in heroku_app.config():
                app = heroku_app
                break
        if app is None:
            await event.answer(
                "`You seem to be running on Heroku "
                "with an invalid environment. Couldn't update the app.`\n"
                "`The changes will be reverted upon dyno restart.`")
            await asyncio.sleep(2)
            repo.__del__()
            await restart(event)
        else:
            for build in app.builds():
                if build.status == "pending":
                    await event.answer(
                        "`There seems to be an ongoing build in your app.`"
                        " `Try again after it's finished.`")
                    return
            # Don't update the telethon environment varaibles
            userbot_config = client.config['userbot']
            app.config().update(dict(userbot_config))
            app.config().update({
                "userbot_restarted": f"{event.chat_id}/{event.message.id}",
                "userbot_update": "True"
            })
            if event.client.disabled_commands:
                disabled_list = ", ".join(client.disabled_commands.keys())
                app.config().update(
                    {"userbot_disabled_commands": disabled_list})

            url = f"https://*****:*****@git.heroku.com/{app.name}.git"
            if "heroku" in repo.remotes:
                repo.remotes['heroku'].set_url(url)
            else:
                repo.create_remote('heroku', url)
            if repo.untracked_files:
                repo.index.add(untracked_files, force=True)
                repo.index.commit("[PaperplaneRemix] Updater: Untracked files")
            app.enable_feature('runtime-dyno-metadata')
            await event.answer(
                "`Pushing all the changes to Heroku. Might take a while.`")
            remote = repo.remotes['heroku']
            try:
                remote.push(refspec=f'{repo.active_branch.name}:master',
                            force=True)
                await event.answer("`There was nothing to push to Heroku?`")
            except git.exc.GitCommandError as command:
                await event.answer(
                    "`An error occured trying to pull and push to Heorku`"
                    f"\n`{command}`")
                LOGGER.exception(command)
            repo.__del__()
    else:
        repo.__del__()
        await restart(event)
示例#24
0
async def update(event):
    arg = event.matches[0].group(1)
    main_repo = "https://github.com/kandnub/TG-UserBot.git"
    try:
        repo = git.Repo(basedir)
    except git.exc.NoSuchPathError as path:
        await event.edit(f"`Couldn't find {path}!`")
        return
    except git.exc.GitCommandError as command:
        await event.edit(
            f"`An error occured trying to get the Git Repo.`\n`{command}`")
        return
    except git.exc.InvalidGitRepositoryError:
        repo = git.Repo.init(basedir)
        origin = repo.create_remote('origin', main_repo)
        if not origin.exists():
            await event.edit(
                "`The main repository does not exist. Remote is invalid!`")
            return
        origin.fetch()
        repo.create_head('master', origin.refs.master).set_tracking_branch(
            origin.refs.master).checkout()

    await event.edit("`Checking for updates!`")
    untracked_files = repo.untracked_files
    old_commit = repo.head.commit
    if arg == "add":
        repo.index.add(untracked_files, force=True)
        repo.index.commit("[TG-UserBot] Updater: Untracked files")
    elif arg == "reset":
        repo.head.reset('--hard')
    try:
        pull = repo.remotes.origin.pull()
    except git.exc.GitCommandError as command:
        text = ("`An error occured trying to Git pull:`\n`{0}`\n\n"
                "`You may use` **{1}update reset** `or` **{1}update add** "
                "`to reset your repo or add and commit your changes as well.`")
        prefix = client.prefix if client.prefix is not None else '.'
        await event.edit(text.format(command, prefix))
        return
    new_commit = repo.head.commit
    if old_commit == new_commit:
        await event.edit("`Already up-to-date!`")
        return

    heroku_api_key = client.config['userbot'].get('api_key_heroku', False)
    if os.getenv("DYNO", False) and heroku_api_key:
        heroku_conn = heroku3.from_key(heroku_api_key)
        heroku_app = None
        for app in heroku_conn.apps():
            if app.name == os.getenv('HEROKU_APP_NAME', ''):
                heroku_app = app
                break
        if heroku_app is None:
            await event.edit(
                "`You seem to be running on Heroku "
                "with an invalid environment. Couldn't update the app.`\n"
                "`The changes will be reverted upon dyno restart.`")
            await sleep(2)
            await updated_pip_modules(event, pull, repo, new_commit)
            await restart(event)
        else:
            # Don't update the telethon environment varaibles
            userbot_config = client.config['userbot']
            app.config().update(dict(userbot_config))
            app.config().update(
                {'userbot_restarted': f"{event.chat_id}/{event.message.id}"})
            url = f"https://*****:*****@git.heroku.com/{app.name}.git"
            if "heroku" in repo.remotes:
                repo.remotes['heroku'].set_url(url)
            else:
                repo.create_remote('heroku', url)
            if repo.untracked_files:
                repo.index.add(untracked_files, force=True)
                repo.index.commit("[TG-UserBot] Updater: Untracked files")
            app.enable_feature('runtime-dyno-metadata')
            await event.edit("`Pushing all the changes to the Heroku.`")
            remote = repo.remotes['heroku']
            try:
                remote.push(refspec=f'{str(repo.active_branch)}:master',
                            force=True)
                await event.edit("`There was nothing to push to Heroku?`")
            except git.exc.GitCommandError as command:
                await event.edit(
                    "`An error occured trying to pull and push to Heorku`"
                    f"\n`{command}`")
                LOGGER.exception(command)
    else:
        await updated_pip_modules(event, pull, repo, new_commit)
        await restart(event)
示例#25
0
        async def wrapper(check):
            if check.edit_date and check.is_channel and not check.is_group:
                # Messages sent in channels can be edited by other users.
                # Ignore edits that take place in channels.
                return
            if group_only and not check.is_group:
                await check.respond("`Are you sure this is a group?`")
                return
            if check.via_bot_id and not insecure and check.out:
                # Ignore outgoing messages via inline bots for security reasons
                return
            if pattern.startswith(
                    "^.") and not check.message.message.startswith("."):
                return

            try:
                await func(check)
            #
            # HACK HACK HACK
            # Raise StopPropagation to Raise StopPropagation
            # This needed for AFK to working properly
            # TODO
            # Rewrite events to not passing all exceptions
            #
            except events.StopPropagation:
                raise events.StopPropagation
            # This is a gay exception and must be passed out. So that it doesnt spam chats
            except KeyboardInterrupt:
                pass
            except BaseException as e:
                LOGGER.exception(e)  # Log the error in console
                # Check if we have to disable error logging message.
                if not disable_errors:
                    date = strftime("%Y-%m-%d %H:%M:%S", gmtime())

                    text = "**Sorry, I encountered a error!**\n"
                    link = "[https://t.me/tgpaperplane](Userbot Support Chat)"
                    text += "If you wanna you can report it"
                    text += f"- just forward this message to {link}.\n"
                    text += "I won't log anything except the fact of error and date\n"

                    ftext = "\nDisclaimer:\nThis file uploaded ONLY here, "
                    ftext += "we logged only fact of error and date, "
                    ftext += "we respect your privacy, "
                    ftext += "you may not report this error if you've "
                    ftext += "any confidential data here, no one will see your data "
                    ftext += "if you choose not to do so.\n\n"
                    ftext += "--------BEGIN USERBOT TRACEBACK LOG--------"
                    ftext += "\nDate: " + date
                    ftext += "\nGroup ID: " + str(check.chat_id)
                    ftext += "\nSender ID: " + str(check.sender_id)
                    ftext += "\n\nEvent Trigger:\n"
                    ftext += str(check.text)
                    ftext += "\n\nTraceback info:\n"
                    ftext += str(format_exc())
                    ftext += "\n\nError text:\n"
                    ftext += str(sys.exc_info()[1])
                    ftext += "\n\n--------END USERBOT TRACEBACK LOG--------"

                    #command = "git log --pretty=format:\"%an: %s\" -5"

                    #ftext += "\n\n\nLast 5 commits:\n"

                    #process = await asyncsubshell(command,
                    #                              stdout=asyncsub.PIPE,
                    #                              stderr=asyncsub.PIPE)
                    #stdout, stderr = await process.communicate()
                    #result = str(stdout.decode().strip()) \
                    #    + str(stderr.decode().strip())

                    #ftext += result

                    file = open("error.log", "w+")
                    file.write(ftext)
                    file.close()

                    remove("error.log")
            else:
                pass
示例#26
0
async def updater(event: NewMessage.Event) -> None:
    """
    Pull newest changes from the official repo and update the script/app.


    `{prefix}update` or `{prefix}update reset` or `{prefix}update add`
        Reset will reset the repository and add will commit your changes.
    """
    arg = event.matches[0].group(1)
    await event.answer("`Checking for updates!`")
    try:
        repo = git.Repo(basedir)
        fetched_items = repo.remotes.origin.fetch()
    except git.exc.NoSuchPathError as path:
        await event.answer(f"`Couldn't find {path}!`")
        repo.__del__()
        return
    except git.exc.GitCommandError as command:
        await event.answer(
            f"`An error occured trying to get the Git Repo.`\n`{command}`")
        repo.__del__()
        return
    except git.exc.InvalidGitRepositoryError:
        repo = git.Repo.init(basedir)
        origin = repo.create_remote("origin", main_repo)
        if not origin.exists():
            await event.answer(
                "`The main repository does not exist. Remote is invalid!`")
            repo.__del__()
            return
        fetched_items = origin.fetch()
        repo.create_head("master", origin.refs.master).set_tracking_branch(
            origin.refs.master).checkout(force=True)
    fetched_commits = repo.iter_commits(f"HEAD..{fetched_items[0].ref.name}")
    untracked_files = repo.untracked_files
    old_commit = repo.head.commit
    for diff_added in old_commit.diff("FETCH_HEAD").iter_change_type("M"):
        if "requirements.txt" in diff_added.b_path:
            await event.answer("`Updating the pip requirements!`")
            updated = await update_requirements()
            if updated == 0:
                await event.answer("`Successfully updated the requirements.`")
            else:
                if isinstance(updated, int):
                    await event.answer(
                        "`Failed trying to install requirements."
                        " Install them manually and run the command again.`")
                else:
                    await event.answer(f"```{updated}```")
                return
            break

    if arg == "add":
        repo.index.add(untracked_files, force=True)
        repo.index.commit("[PaperplaneRemix] Updater: Untracked files")
    elif arg == "reset":
        repo.head.reset("--hard")

    try:
        config = repo.config_reader()
        try:
            if config.get_value("user", "name") and config.get_value(
                    "user", "email"):
                pass
        except (NoSectionError, NoOptionError):
            LOGGER.warning(
                "No 'git' credentials found, falling back to generic data for the git pull."
            )
            repo.config_writer().set_value(
                "user", "name", "PaperplaneRemix Updater").release()
            repo.config_writer().set_value("user", "email", "<>").release()
        repo.remotes.origin.pull()
    except git.exc.GitCommandError as command:
        text = ("`An error occured trying to Git pull:`\n`{0}`\n\n"
                "`You may use` **{1}update reset** `or` **{1}update add** "
                "`to reset your repo or add and commit your changes as well.`")
        prefix = client.prefix if client.prefix is not None else "."
        await event.answer(text.format(command, prefix))
        repo.__del__()
        return

    new_commit = repo.head.commit
    if old_commit == new_commit:
        await event.answer("`Already up-to-date!`")
        repo.__del__()
        return

    remote_url = repo.remote().url.replace(".git", "/")
    if remote_url[-1] != "/":
        remote_url = remote_url + "/"

    now = datetime.datetime.now(datetime.timezone.utc)
    def_changelog = changelog = "**PaperplaneRemix changelog:**"
    for commit in reversed(list(fetched_commits)):
        changelog += summary.format(
            rev=repo.git.rev_parse(commit.hexsha, short=7),
            summary=commit.summary,
            url=remote_url,
            sha=commit.hexsha,
        )
        ago = (now - commit.committed_datetime).total_seconds()
        elspased = (await _humanfriendly_seconds(ago)).split(",")[0]
        committers_link = author_link.format(author=commit.committer,
                                             url=remote_url)
        authors_link = author_link.format(author=commit.author, url=remote_url)
        if commit.author == commit.committer:
            committed = commited.format(committer=committers_link,
                                        elapsed=elspased)
        else:
            committed = authored.format(author=authors_link,
                                        committer=committers_link,
                                        elapsed=elspased)
        changelog += f"{committed:>{len(committed) + 8}}"
    if changelog == def_changelog:
        changelog = "`No changelog for you! IDK what happened.`"

    toast = await event.answer(
        "`Successfully pulled the new commits. Updating the userbot!`",
        log=("update", changelog.strip()),
    )
    if not client.logger:
        await event.answer(changelog.strip(),
                           reply_to=toast.id,
                           link_preview=False)

    os.environ["userbot_update"] = "True"
    heroku_api_key = client.config["api_keys"].get("api_key_heroku", False)
    if os.getenv("DYNO", False) and heroku_api_key:
        heroku_conn = heroku3.from_key(heroku_api_key)
        app = None
        for heroku_app in heroku_conn.apps():
            if "api_key_heroku" in heroku_app.config():
                app = heroku_app
                break
        if app is None:
            await event.answer(
                "`You seem to be running on Heroku "
                "with an invalid environment. Couldn't update the app.`\n"
                "`The changes will be reverted upon dyno restart.`")
            repo.__del__()
            await restart(event)
        else:
            for build in app.builds():
                if build.status == "pending":
                    await event.answer(
                        "`There seems to be an ongoing build in your app.`"
                        " `Try again after it's finished.`")
                    return

            # Don't update the telethon environment varaibles
            userbot_config = dict(client.config["userbot"])
            app.config().update(userbot_config)

            # "Dirty Fix" for Heroku Dynos to update proper environment
            # variables for external plugin flags.
            heroku_ext_flags = {
                x[12:]: os.getenv(x, None)
                for x in list(os.environ) if x.startswith("ext_userbot_")
            }
            for flag in userbot_config:
                if flag in heroku_ext_flags:
                    app.config().update(
                        {f"ext_userbot_{flag}": userbot_config[flag]})
                    app.config().update({flag: None})

            app.config().update({
                "userbot_restarted": f"{event.chat_id}/{event.message.id}",
                "userbot_update": "True",
            })
            if event.client.disabled_commands:
                disabled_list = ", ".join(client.disabled_commands.keys())
                app.config().update(
                    {"userbot_disabled_commands": disabled_list})

            url = f"https://*****:*****@git.heroku.com/{app.name}.git"
            if "heroku" in repo.remotes:
                repo.remotes["heroku"].set_url(url)
            else:
                repo.create_remote("heroku", url)
            if repo.untracked_files:
                repo.index.add(untracked_files, force=True)
                repo.index.commit("[PaperplaneRemix] Updater: Untracked files")
            app.enable_feature("runtime-dyno-metadata")
            await event.answer(
                f"`Pushing all the changes to Heroku. This might take a while.`"
            )
            remote = repo.remotes["heroku"]
            try:
                remote.push(refspec=f"{repo.active_branch.name}:master",
                            force=True)
                await event.answer("`There was nothing to push to Heroku?`")
            except git.exc.GitCommandError as command:
                await event.answer(
                    "`An error occured trying to pull and push to Heorku`"
                    f"\n`{command}`")
                LOGGER.exception(command)
            repo.__del__()
    else:
        repo.__del__()
        await restart(event)
示例#27
0
async def ban_user(
    event: NewMessage.Event or ChatAction.Event,
    bl_type: str = None,
    match: Union[str, int] = None,
    index: int = None,
    globally: bool = False,
) -> bool:
    if isinstance(event, NewMessage.Event):
        sender = await event.get_input_sender()
    else:
        sender = await event.get_input_user()
    temp_banlist.append(sender)
    chat = await event.get_chat()
    ban_right = getattr(chat.admin_rights, "ban_users", False)
    delete_messages = getattr(chat.admin_rights, "delete_messages", False)
    exc_logger = client.logger if client.logger else "self"

    if not (ban_right or chat.creator):
        return False
    user_href = "[{0}](tg://user?id={0})".format(sender.user_id)

    try:
        await client.edit_permissions(entity=chat.id,
                                      user=sender,
                                      view_messages=False)
        if bl_type and match and sender.user_id not in blacklistedUsers:
            blacklistedUsers.update({sender.user_id: (bl_type, match)})
            redis.set("blacklist:users", dill.dumps(blacklistedUsers))
    except Exception as e:
        exc = await client.get_traceback(e)
        await client.send_message(exc_logger, exc)
        LOGGER.exception(e)
        return False
    try:
        if delete_messages:
            await event.delete()
    except Exception:
        pass
    try:
        key = "g" + bl_type if globally else bl_type
        text, var = full_key_strings.get(key)
        formats = {
            "match": match,
            "type": bl_type,
            "index": index,
            "chat": chat.id,
            "user": sender.user_id,
            "user_link": user_href,
        }
        await client.resanswer(
            await event.get_input_chat(),
            text,
            plugin="blacklist",
            name=var,
            formats=formats,
            reply_to=event,
        )
        if client.logger:
            logger_group = client.config["userbot"].getint(
                "logger_group_id", "me")
            if chat.username:
                chat_href = f"[{chat.title}]" f"(tg://resolve?domain={chat.username})"
            else:
                chat_href = f"[{chat.title}] `{chat.id}`"
            log_text = ("**USERBOT LOG** #blacklist\n"
                        f"Banned {user_href} from {chat_href}.\n")
            if bl_type and match:
                log_text += f"Blacklist type: `{bl_type}`.\nMatch: `{match}`"
            await client.send_message(logger_group, log_text)
        return True
    except Exception as e:
        exc = await client.get_traceback(e)
        await client.send_message(exc_logger, exc)
        LOGGER.exception(e)
        return False
    finally:
        temp_banlist.remove(sender)
示例#28
0
async def ban_user(event: NewMessage.Event or ChatAction.Event,
                   bl_type: str = None,
                   match: Union[str, int] = None,
                   index: int = None,
                   globally: bool = False) -> bool:
    if isinstance(event, NewMessage.Event):
        sender = await event.get_input_sender()
    else:
        sender = await event.get_input_user()
    temp_banlist.append(sender)
    chat = await event.get_chat()
    ban_right = getattr(chat.admin_rights, 'ban_users', False)
    delete_messages = getattr(chat.admin_rights, 'delete_messages', False)
    if not (ban_right or chat.creator):
        return False
    user_href = "[{0}](tg://user?id={0})".format(sender.user_id)
    try:
        await client.edit_permissions(entity=chat.id,
                                      user=sender,
                                      view_messages=False)
    except Exception as e:
        exc = await client.get_traceback(e)
        await event.respond(f"**Couldn't ban user. Exception:\n**```{exc}```")
        LOGGER.exception(e)
        return False
    try:
        if delete_messages:
            await event.delete()
    except Exception:
        pass
    try:
        key = 'g' + bl_type if globally else bl_type
        text, var = full_key_strings.get(key)
        formats = {
            'match': match,
            'type': bl_type,
            'index': index,
            'chat': chat.id,
            'user': sender.user_id,
            'user_link': user_href
        }
        await client.resanswer(event,
                               text,
                               plugin='blacklist',
                               name=var,
                               formats=formats,
                               chat_override=True,
                               reply_to=event)
        if client.logger:
            logger_group = client.config['userbot'].getint(
                'logger_group_id', 'me')
            if chat.username:
                chat_href = (f"[{chat.title}]"
                             f"(tg://resolve?domain={chat.username})")
            else:
                chat_href = f"[{chat.title}] `{chat.id}`"
            log_text = ("**USERBOT LOG** #blacklist\n"
                        f"Banned {user_href} from {chat_href}.\n")
            if bl_type and match:
                log_text += f"Blacklist type: `{bl_type}`.\nMatch: `{match}`"
            await client.send_message(logger_group, log_text)
        if bl_type and match and sender.user_id not in blacklistedUsers:
            blacklistedUsers.update({sender.user_id: (bl_type, match)})
            redis.set('blacklist:users', dill.dumps(blacklistedUsers))
        return True
    except Exception as e:
        exc = await client.get_traceback(e)
        await event.respond(
            f"**Something went wrong. Exception:\n**```{exc}```")
        LOGGER.exception(e)
        return False
    finally:
        temp_banlist.remove(sender)