示例#1
0
    def generic_update(self, bot, source, message, field, api_fn):
        if not message:
            bot.say(f"You must specify a {field} to update to!")
            return

        try:
            api_fn(self.bot.streamer_user_id,
                   message,
                   authorization=bot.bot_token_manager)
        except HTTPError as e:
            if e.response.status_code == 401:
                bot.say(
                    f"Error (bot operator): The bot needs to be re-authenticated to be able to update the {field}."
                )
                return
            elif e.response.status_code == 403:
                bot.say(
                    f"Error: The bot is not a channel editor and was not able to update the {field}."
                )
                return
            else:
                raise e

        log_msg = f'{source} updated the {field} to "{message}"'
        bot.say(log_msg)
        AdminLogManager.add_entry(f"{field.capitalize()} set", source, log_msg)
示例#2
0
    def playsound_create(playsound_name: str, **options) -> ResponseReturnValue:
        # Create playsound
        playsound_name = PlaysoundModule.massage_name(playsound_name)

        if not PlaysoundModule.validate_name(playsound_name):
            return (
                {
                    "error": "Invalid Playsound name. The playsound name may only contain lowercase latin letters, 0-9, -, or _. No spaces :rage:"
                },
                400,
            )

        try:
            json_data = request.get_json()
            if not json_data:
                return {"error": "Missing json body"}, 400
            data = CreatePlaysoundSchema().load(json_data)
        except ValidationError as err:
            return {"error": f"Did not match schema: {json.dumps(err.messages)}"}, 400

        with DBManager.create_session_scope() as db_session:
            count = db_session.query(Playsound).filter(Playsound.name == playsound_name).count()
            if count >= 1:
                return "Playsound already exists", 400

            # the rest of the parameters are initialized with defaults
            playsound = Playsound(name=playsound_name, link=data.link)
            db_session.add(playsound)
            log_msg = f"The {playsound_name} playsound has been added"
            AdminLogManager.add_entry("Playsound added", options["user"], log_msg)

            return "OK", 200
示例#3
0
    def permaban_command(bot, source, message, **rest) -> bool:
        if not message:
            return False

        username = message.split(" ")[0]
        with DBManager.create_session_scope() as db_session:
            user = User.find_by_user_input(db_session, username)
            if not user:
                bot.whisper(source, "No user with that name found.")
                return False

            if user.banned:
                bot.whisper(source, "User is already permabanned.")
                return False

            user.banned = True
            bot.ban(
                user,
                reason=
                f"User has been added to the {bot.bot_user.login} banlist. Contact a moderator level 1000 or higher for unban.",
            )
            log_msg = f"{user} has been permabanned"
            bot.whisper(source, log_msg)

            AdminLogManager.add_entry("Permaban added", source, log_msg)

        return True
示例#4
0
    def unpermaban_command(self, bot, source, message, **rest):
        if not message:
            return

        username = message.split(" ")[0]
        with DBManager.create_session_scope() as db_session:
            user = User.find_by_user_input(db_session, username)
            if not user:
                bot.whisper(source, "No user with that name found.")
                return False

            if user.banned is False:
                bot.whisper(source, "User is not permabanned.")
                return False

            user.banned = False
            log_msg = f"{user} is no longer permabanned"
            bot.whisper(source, log_msg)

            AdminLogManager.add_entry("Permaban remove", source, log_msg)

            if self.settings["unban_from_chat"] is True:
                bot.unban(user)

                if self.settings["enable_send_timeout"] is True:
                    bot.timeout(
                        user,
                        1,
                        self.settings["timeout_reason"].format(source=source),
                        once=True)
示例#5
0
    def level(self, **options):
        message = options['message']
        bot = options['bot']
        source = options['source']

        if message:
            msg_args = message.split(' ')
            if len(msg_args) > 1:
                username = msg_args[0].lower()
                new_level = int(msg_args[1])
                if new_level >= source.level:
                    bot.whisper(source.username, 'You cannot promote someone to the same or higher level as you ({0}).'.format(source.level))
                    return False

                # We create the user if the user didn't already exist in the database.
                with bot.users.get_user_context(username) as user:
                    old_level = user.level
                    user.level = new_level

                    log_msg = '{}\'s user level changed from {} to {}'.format(
                            user.username_raw,
                            old_level,
                            new_level)

                    bot.whisper(source.username, log_msg)

                    AdminLogManager.add_entry('Userlevel edited', source, log_msg)

                    return True

        bot.whisper(source.username, 'Usage: !level USERNAME NEW_LEVEL')
        return False
示例#6
0
    def remove_alias(bot, source, message, event, args):
        """Dispatch method for removing aliases from a command.
        Usage: !remove alias EXISTING_ALIAS_1 EXISTING_ALIAS_2"""
        if message:
            aliases = re.split(r"\|| ", message.lower())
            log.info(aliases)
            if len(aliases) < 1:
                bot.whisper(source.username,
                            "Usage: !remove alias EXISTINGALIAS")
                return False

            num_removed = 0
            commands_not_found = []
            for alias in aliases:
                if alias not in bot.commands:
                    commands_not_found.append(alias)
                    continue

                command = bot.commands[alias]

                # error out on commands that are not from the DB, e.g. module commands like !8ball that cannot have
                # aliases registered. (command.command and command.data are None on those commands)
                if command.data is None or command.command is None:
                    bot.whisper(
                        source.username,
                        "That command cannot have aliases removed from.")
                    return False

                current_aliases = command.command.split("|")
                current_aliases.remove(alias)

                if len(current_aliases) == 0:
                    bot.whisper(
                        source.username,
                        "{0} is the only remaining alias for this command and can't be removed."
                        .format(alias),
                    )
                    continue

                new_aliases = "|".join(current_aliases)
                bot.commands.edit_command(command, command=new_aliases)

                num_removed += 1
                del bot.commands[alias]
                log_msg = "The alias {0} has been removed from {1}".format(
                    alias,
                    new_aliases.split("|")[0])
                AdminLogManager.add_entry("Alias removed", source, log_msg)

            whisper_str = ""
            if num_removed > 0:
                whisper_str = "Successfully removed {0} aliases.".format(
                    num_removed)
            if len(commands_not_found) > 0:
                whisper_str += " Aliases {0} not found".format(
                    ", ".join(commands_not_found))
            if len(whisper_str) > 0:
                bot.whisper(source.username, whisper_str)
        else:
            bot.whisper(source.username, "Usage: !remove alias EXISTINGALIAS")
示例#7
0
    def level(self, **options):
        message = options['message']
        bot = options['bot']
        source = options['source']

        if message:
            msg_args = message.split(' ')
            if len(msg_args) > 1:
                username = msg_args[0].lower()
                new_level = int(msg_args[1])
                if new_level >= source.level:
                    bot.whisper(
                        source.username,
                        'You cannot promote someone to the same or higher level as you ({0}).'
                        .format(source.level))
                    return False

                # We create the user if the user didn't already exist in the database.
                with bot.users.get_user_context(username) as user:
                    old_level = user.level
                    user.level = new_level

                    log_msg = '{}\'s user level changed from {} to {}'.format(
                        user.username_raw, old_level, new_level)

                    bot.whisper(source.username, log_msg)

                    AdminLogManager.add_entry('Userlevel edited', source,
                                              log_msg)

                    return True

        bot.whisper(source.username, 'Usage: !level USERNAME NEW_LEVEL')
        return False
示例#8
0
    def put(self, playsound_name, **options):
        playsound_name = PlaysoundModule.massage_name(playsound_name)

        if not PlaysoundModule.validate_name(playsound_name):
            return (
                {
                    "error": "Invalid Playsound name. The playsound name may only contain lowercase latin letters, 0-9, -, or _. No spaces :rage:"
                },
                400,
            )

        post_parser = RequestParser()
        post_parser.add_argument("link", required=True)
        args = post_parser.parse_args()

        try:
            link = args["link"]
        except (ValueError, KeyError):
            return {"error": "Invalid `link` parameter."}, 400

        with DBManager.create_session_scope() as db_session:
            count = db_session.query(Playsound).filter(Playsound.name == playsound_name).count()
            if count >= 1:
                return "Playsound already exists", 400

            # the rest of the parameters are initialized with defaults
            playsound = Playsound(name=playsound_name, link=link)
            db_session.add(playsound)
            log_msg = f"The {playsound_name} playsound has been added"
            AdminLogManager.add_entry("Playsound added", options["user"], log_msg)

            return "OK", 200
示例#9
0
    def set_title(bot, source, message, event, args):
        # XXX: This should be a module
        if message:
            bot.twitchapi.set_title(bot.streamer, message)
            log_msg = '{0} updated the title to "{1}"'.format(source.username_raw, message)
            bot.say(log_msg)

            AdminLogManager.add_entry('Title set', source, log_msg)
示例#10
0
    def set_title(bot, source, message, event, args):
        # XXX: This should be a module
        if message:
            bot.twitchapi.set_title(bot.streamer, message)
            log_msg = '{0} updated the title to "{1}"'.format(source.username_raw, message)
            bot.say(log_msg)

            AdminLogManager.add_entry('Title set', source, log_msg)
示例#11
0
    def add_command(bot, source, message, event, args):
        """Dispatch method for creating commands.
        Usage: !add command ALIAS [options] RESPONSE
        See pajbot/managers/command.py parse_command_arguments for available options
        """

        if not message:
            return False

        # Make sure we got both an alias and a response
        message_parts = message.split()
        if len(message_parts) < 2:
            bot.send_message_to_user(
                source,
                "Usage: !add command ALIAS [options] RESPONSE",
                event,
                method="whisper")
            return False

        options, response = bot.commands.parse_command_arguments(
            message_parts[1:])

        if options is False:
            bot.send_message_to_user(source,
                                     "Invalid command",
                                     event,
                                     method="whisper")
            return False

        options["added_by"] = source.id

        alias_str = message_parts[0].replace("!", "").lower()
        action_type: str = options.get("action_type", "say")
        if response.startswith("/me") or response.startswith(".me"):
            action_type = "me"
            response = " ".join(response.split(" ")[1:])
        action = {"type": action_type, "message": response}

        command, new_command, alias_matched = bot.commands.create_command(
            alias_str, action=action, **options)
        if new_command is True:
            bot.send_message_to_user(source,
                                     f"Added your command (ID: {command.id})",
                                     event,
                                     method="whisper")

            log_msg = f"The !{command.command.split('|')[0]} command has been created"
            AdminLogManager.add_entry("Command created", source, log_msg)
            return True

        # At least one alias is already in use, notify the user to use !edit command instead
        bot.send_message_to_user(
            source,
            f"The alias {alias_matched} is already in use. To edit that command, use !edit command instead of !add command.",
            event,
            method="whisper",
        )
        return False
示例#12
0
    def add_command(bot, source, message, event, args):
        """Dispatch method for creating commands.
        Usage: !add command ALIAS [options] RESPONSE
        Multiple options available:
        --whisper/--no-whisper
        --reply/--no-reply
        --modonly/--no-modonly
        --cd CD
        --usercd USERCD
        --level LEVEL
        --cost COST
        """

        if message:
            # Make sure we got both an alias and a response
            message_parts = message.split()
            if len(message_parts) < 2:
                bot.whisper(source.username, 'Usage: !add command ALIAS [options] RESPONSE')
                return False

            options, response = bot.commands.parse_command_arguments(message_parts[1:])

            options['added_by'] = source.id

            if options is False:
                bot.whisper(source.username, 'Invalid command')
                return False

            alias_str = message_parts[0].replace('!', '').lower()
            type = 'say'
            if options['whisper'] is True:
                type = 'whisper'
            elif options['reply'] is True:
                type = 'reply'
            elif response.startswith('/me') or response.startswith('.me'):
                type = 'me'
                response = ' '.join(response.split(' ')[1:])
            elif options['whisper'] is False or options['reply'] is False:
                type = 'say'
            action = {
                'type': type,
                'message': response,
            }

            command, new_command, alias_matched = bot.commands.create_command(alias_str, action=action, **options)
            if new_command is True:
                bot.whisper(source.username, 'Added your command (ID: {command.id})'.format(command=command))

                log_msg = 'The !{} command has been created'.format(command.command.split('|')[0])
                AdminLogManager.add_entry('Command created',
                        source,
                        log_msg)
                return True

            # At least one alias is already in use, notify the user to use !edit command instead
            bot.whisper(source.username, 'The alias {} is already in use. To edit that command, use !edit command instead of !add command.'.format(alias_matched))
            return False
示例#13
0
    def add_command(bot, source, message, event, args):
        """Dispatch method for creating commands.
        Usage: !add command ALIAS [options] RESPONSE
        Multiple options available:
        --whisper/--no-whisper
        --reply/--no-reply
        --modonly/--no-modonly
        --cd CD
        --usercd USERCD
        --level LEVEL
        --cost COST
        """

        if message:
            # Make sure we got both an alias and a response
            message_parts = message.split()
            if len(message_parts) < 2:
                bot.whisper(source.username, 'Usage: !add command ALIAS [options] RESPONSE')
                return False

            options, response = bot.commands.parse_command_arguments(message_parts[1:])

            options['added_by'] = source.id

            if options is False:
                bot.whisper(source.username, 'Invalid command')
                return False

            alias_str = message_parts[0].replace('!', '').lower()
            type = 'say'
            if options['whisper'] is True:
                type = 'whisper'
            elif options['reply'] is True:
                type = 'reply'
            elif response.startswith('/me') or response.startswith('.me'):
                type = 'me'
                response = ' '.join(response.split(' ')[1:])
            elif options['whisper'] is False or options['reply'] is False:
                type = 'say'
            action = {
                'type': type,
                'message': response,
            }

            command, new_command, alias_matched = bot.commands.create_command(alias_str, action=action, **options)
            if new_command is True:
                bot.whisper(source.username, 'Added your command (ID: {command.id})'.format(command=command))

                log_msg = 'The !{} command has been created'.format(command.command.split('|')[0])
                AdminLogManager.add_entry('Command created',
                        source,
                        log_msg)
                return True

            # At least one alias is already in use, notify the user to use !edit command instead
            bot.whisper(source.username, 'The alias {} is already in use. To edit that command, use !edit command instead of !add command.'.format(alias_matched))
            return False
示例#14
0
    def add_alias(bot, source, message, event, args):
        """Dispatch method for adding aliases to already-existing commands.
        Usage: !add alias EXISTING_ALIAS NEW_ALIAS_1 NEW_ALIAS_2 ...
        """

        if message:
            message = message.replace("!", "").lower()
            # Make sure we got both an existing alias and at least one new alias
            message_parts = message.split()
            if len(message_parts) < 2:
                bot.whisper(source.username,
                            "Usage: !add alias existingalias newalias")
                return False

            existing_alias = message_parts[0]
            new_aliases = re.split(r"\|| ", " ".join(message_parts[1:]))
            added_aliases = []
            already_used_aliases = []

            if existing_alias not in bot.commands:
                bot.whisper(
                    source.username,
                    'No command called "{0}" found'.format(existing_alias))
                return False

            command = bot.commands[existing_alias]

            for alias in set(new_aliases):
                if alias in bot.commands:
                    already_used_aliases.append(alias)
                else:
                    added_aliases.append(alias)
                    bot.commands[alias] = command

            if len(added_aliases) > 0:
                new_aliases = "{}|{}".format(command.command,
                                             "|".join(added_aliases))
                bot.commands.edit_command(command, command=new_aliases)

                bot.whisper(
                    source.username,
                    "Successfully added the aliases {0} to {1}".format(
                        ", ".join(added_aliases), existing_alias),
                )
                log_msg = "The aliases {0} has been added to {1}".format(
                    ", ".join(added_aliases), existing_alias)
                AdminLogManager.add_entry("Alias added", source, log_msg)
            if len(already_used_aliases) > 0:
                bot.whisper(
                    source.username,
                    "The following aliases were already in use: {0}".format(
                        ", ".join(already_used_aliases)),
                )
        else:
            bot.whisper(source.username,
                        "Usage: !add alias existingalias newalias")
示例#15
0
    def add_alias(bot, source, message, event, args):
        """Dispatch method for adding aliases to already-existing commands.
        Usage: !add alias EXISTING_ALIAS NEW_ALIAS_1 NEW_ALIAS_2 ...
        """

        if message:
            message = message.replace("!", "").lower()
            # Make sure we got both an existing alias and at least one new alias
            message_parts = message.split()
            if len(message_parts) < 2:
                bot.whisper(source, "Usage: !add alias existingalias newalias")
                return False

            existing_alias = message_parts[0]
            new_aliases = re.split(r"\|| ", " ".join(message_parts[1:]))
            added_aliases = []
            already_used_aliases = []

            if existing_alias not in bot.commands:
                bot.whisper(source,
                            f'No command called "{existing_alias}" found')
                return False

            command = bot.commands[existing_alias]

            # error out on commands that are not from the DB, e.g. module commands like !8ball that cannot have
            # aliases registered. (command.command and command.data are None on those commands)
            if command.data is None or command.command is None:
                bot.whisper(source,
                            "That command cannot have aliases added to.")
                return False

            for alias in set(new_aliases):
                if alias in bot.commands:
                    already_used_aliases.append(alias)
                else:
                    added_aliases.append(alias)
                    bot.commands[alias] = command

            if len(added_aliases) > 0:
                new_aliases = f"{command.command}|{'|'.join(added_aliases)}"
                bot.commands.edit_command(command, command=new_aliases)

                bot.whisper(
                    source,
                    f"Successfully added the aliases {', '.join(added_aliases)} to {existing_alias}"
                )
                log_msg = f"The aliases {', '.join(added_aliases)} has been added to {existing_alias}"
                AdminLogManager.add_entry("Alias added", source, log_msg)
            if len(already_used_aliases) > 0:
                bot.whisper(
                    source,
                    f"The following aliases were already in use: {', '.join(already_used_aliases)}"
                )
        else:
            bot.whisper(source, "Usage: !add alias existingalias newalias")
示例#16
0
    def edit_playsound_command(self, bot, source, message, **rest):
        """Method for editing playsounds.
        Usage: !edit playsound PLAYSOUNDNAME [LINK] [options]
        Multiple options available:
        --volume VOLUME
        --cooldown COOLDOWN
        --enabled/--disabled
        """

        options, name, link = self.parse_playsound_arguments(message)

        if options is False or name is False or link is False:
            bot.whisper(
                source,
                "Invalid usage. Correct syntax: !edit playsound <name> [link] "
                +
                "[--volume 0-100] [--cooldown 60/none] [--enabled/--disabled]",
            )
            return

        with DBManager.create_session_scope() as session:
            playsound = session.query(Playsound).filter(
                Playsound.name == name).one_or_none()
            if playsound is None:
                bot.whisper(
                    source,
                    "No playsound with that name exists. You can create playsounds with "
                    "!add playsound <name> <link> [options].",
                )
                return

            old_link = playsound.link

            if not self.update_link(bot, source, playsound, link):
                return

            if not self.update_volume(bot, source, playsound, options):
                return

            if not self.update_cooldown(bot, source, playsound, options):
                return

            if not self.update_enabled(bot, source, playsound, options):
                return

            if link in message:
                log_msg = f"The {name} playsound has been updated from {old_link} to {link}"
            else:
                log_msg = f"The {name} playsound has been updated"

            session.add(playsound)
            bot.whisper(source, "Successfully edited your playsound.")
            AdminLogManager.add_entry("Playsound edited", source, log_msg)
示例#17
0
    def playsound_delete(playsound_name: str, **options) -> ResponseReturnValue:
        with DBManager.create_session_scope() as db_session:
            playsound = db_session.query(Playsound).filter(Playsound.name == playsound_name).one_or_none()

            if playsound is None:
                return "Playsound does not exist", 404

            log_msg = f"The {playsound.name} playsound has been removed"
            AdminLogManager.add_entry("Playsound removed", options["user"], log_msg)
            db_session.delete(playsound)

            return "OK", 200
示例#18
0
 def twitter_unfollow(bot, source, message, event, args):
     if message:
         username = message.split(" ")[0].strip().lower()
         if bot.twitter_manager.unfollow_user(username):
             log_msg = f"No longer following {username}"
             bot.whisper(source, log_msg)
             AdminLogManager.add_entry("Twitter user unfollowed", source, log_msg)
         else:
             bot.whisper(
                 source,
                 f"An error occured while attempting to unfollow {username}, perhaps we are not following this person?",
             )
示例#19
0
    def remove_command(bot, source, message, event, args):
        if message:
            id = None
            command = None
            try:
                id = int(message)
            except Exception:
                pass

            if id is None:
                potential_cmd = ''.join(
                    message.split(' ')[:1]).lower().replace('!', '')
                if potential_cmd in bot.commands:
                    command = bot.commands[potential_cmd]
                    log.info('got command: {0}'.format(command))
            else:
                for key, check_command in bot.commands.items():
                    if check_command.id == id:
                        command = check_command
                        break

            if command is None:
                bot.whisper(source.username,
                            'No command with the given parameters found')
                return False

            if command.id == -1:
                bot.whisper(
                    source.username,
                    'That command is an internal command, it cannot be removed.'
                )
                return False

            if source.level < 2000:
                if command.action is not None and not command.action.type == 'message':
                    bot.whisper(
                        source.username,
                        'That command is not a normal command, it cannot be removed by you.'
                    )
                    return False

            bot.whisper(
                source.username,
                'Successfully removed command with id {0}'.format(command.id))
            log_msg = 'The !{} command has been removed'.format(
                command.command.split('|')[0])
            AdminLogManager.add_entry('Command removed', source, log_msg)
            bot.commands.remove_command(command)
        else:
            bot.whisper(source.username,
                        'Usage: !remove command (COMMAND_ID|COMMAND_ALIAS)')
示例#20
0
    def remove_alias(bot, source, message, event, args):
        """Dispatch method for removing aliases from a command.
        Usage: !remove alias EXISTING_ALIAS_1 EXISTING_ALIAS_2"""
        if message:
            aliases = re.split('\|| ', message.lower())
            log.info(aliases)
            if len(aliases) < 1:
                bot.whisper(source.username,
                            'Usage: !remove alias EXISTINGALIAS')
                return False

            num_removed = 0
            commands_not_found = []
            for alias in aliases:
                if alias not in bot.commands:
                    commands_not_found.append(alias)
                    continue

                command = bot.commands[alias]

                current_aliases = command.command.split('|')
                current_aliases.remove(alias)

                if len(current_aliases) == 0:
                    bot.whisper(
                        source.username,
                        "{0} is the only remaining alias for this command and can't be removed."
                        .format(alias))
                    continue

                new_aliases = '|'.join(current_aliases)
                bot.commands.edit_command(command, command=new_aliases)

                num_removed += 1
                del bot.commands[alias]
                log_msg = 'The alias {0} has been removed from {1}'.format(
                    alias,
                    new_aliases.split('|')[0])
                AdminLogManager.add_entry('Alias removed', source, log_msg)

            whisper_str = ''
            if num_removed > 0:
                whisper_str = 'Successfully removed {0} aliases.'.format(
                    num_removed)
            if len(commands_not_found) > 0:
                whisper_str += ' Aliases {0} not found'.format(
                    ', '.join(commands_not_found))
            if len(whisper_str) > 0:
                bot.whisper(source.username, whisper_str)
        else:
            bot.whisper(source.username, 'Usage: !remove alias EXISTINGALIAS')
示例#21
0
    def remove_command(bot, source, message, event, args):
        if message:
            id = None
            command = None
            try:
                id = int(message)
            except Exception:
                pass

            if id is None:
                potential_cmd = "".join(
                    message.split(" ")[:1]).lower().replace("!", "")
                if potential_cmd in bot.commands:
                    command = bot.commands[potential_cmd]
            else:
                for key, check_command in bot.commands.items():
                    if check_command.id == id:
                        command = check_command
                        break

            if command is None:
                bot.whisper(source.username,
                            "No command with the given parameters found")
                return False

            if command.id == -1:
                bot.whisper(
                    source.username,
                    "That command is an internal command, it cannot be removed."
                )
                return False

            if source.level < 2000:
                if command.action is not None and not command.action.type == "message":
                    bot.whisper(
                        source.username,
                        "That command is not a normal command, it cannot be removed by you."
                    )
                    return False

            bot.whisper(
                source.username,
                "Successfully removed command with id {0}".format(command.id))
            log_msg = "The !{} command has been removed".format(
                command.command.split("|")[0])
            AdminLogManager.add_entry("Command removed", source, log_msg)
            bot.commands.remove_command(command)
        else:
            bot.whisper(source.username,
                        "Usage: !remove command (COMMAND_ID|COMMAND_ALIAS)")
示例#22
0
    def update_game(self, bot: Bot, source, message, **rest) -> Any:
        auth_error = "Error: The streamer must grant permissions to update the game. The streamer needs to be re-authenticated to fix this problem."

        if ("user:edit:broadcast"
                not in bot.streamer_access_token_manager.token.scope
                and "channel:manage:broadcast"
                not in bot.streamer_access_token_manager.token.scope):
            bot.say(auth_error)
            return

        game_name = message

        if not game_name:
            bot.say("You must specify a game to update to!")
            return

        # Resolve game name to game ID
        game = bot.twitch_helix_api.get_game_by_game_name(game_name)
        if not game:
            bot.say(f"Unable to find a game with the name '{game_name}'")
            return

        try:
            bot.twitch_helix_api.modify_channel_information(
                bot.streamer.id,
                {"game_id": game.id},
                authorization=bot.streamer_access_token_manager,
            )
        except HTTPError as e:
            if e.response.status_code == 401:
                log.error(
                    f"Failed to update game to '{game_name}' - auth error")
                bot.say(auth_error)
                bot.streamer_access_token_manager.invalidate_token()
            elif e.response.status_code == 500:
                log.error(
                    f"Failed to update game to '{game_name}' - internal server error"
                )
                bot.say(f"{source}, Failed to update game! Please try again.")
            else:
                log.exception(
                    f"Unhandled HTTPError when updating to {game_name}")
            return

        log_msg = f'{source} updated the game to "{game_name}"'
        bot.say(log_msg)
        AdminLogManager.add_entry("Game set", source, log_msg)
示例#23
0
    def update_title(self, bot: Bot, source, message, **rest) -> Any:
        auth_error = "Error: The streamer must grant permissions to update the title. The streamer needs to be re-authenticated to fix this problem."

        if ("user:edit:broadcast"
                not in bot.streamer_access_token_manager.token.scope
                and "channel:manage:broadcast"
                not in bot.streamer_access_token_manager.token.scope):
            bot.say(auth_error)
            return

        title = message

        if not title:
            bot.say("You must specify a title to update to!")
            return

        try:
            bot.twitch_helix_api.modify_channel_information(
                bot.streamer.id,
                {"title": title},
                authorization=bot.streamer_access_token_manager,
            )
        except HTTPError as e:
            if e.response.status_code == 401:
                log.error(f"Failed to update title to '{title}' - auth error")
                bot.say(auth_error)
                bot.streamer_access_token_manager.invalidate_token()
            elif e.response.status_code == 400:
                log.error(f"Title '{title}' contains banned words")
                bot.say(
                    f"{source}, Title contained banned words. Please remove the banned words and try again."
                )
            elif e.response.status_code == 500:
                log.error(
                    f"Failed to update title to '{title}' - internal server error"
                )
                bot.say(
                    f"{source}, Failed to update the title! Please try again.")
            else:
                log.exception(f"Unhandled HTTPError when updating to {title}")
            return

        log_msg = f'{source} updated the title to "{title}"'
        bot.say(log_msg)
        AdminLogManager.add_entry("Title set", source, log_msg)
示例#24
0
    def remove_alias(bot, source, message, event, args):
        """Dispatch method for removing aliases from a command.
        Usage: !remove alias EXISTING_ALIAS_1 EXISTING_ALIAS_2"""
        if message:
            aliases = re.split('\|| ', message.lower())
            log.info(aliases)
            if len(aliases) < 1:
                bot.whisper(source.username, 'Usage: !remove alias EXISTINGALIAS')
                return False

            num_removed = 0
            commands_not_found = []
            for alias in aliases:
                if alias not in bot.commands:
                    commands_not_found.append(alias)
                    continue

                command = bot.commands[alias]

                current_aliases = command.command.split('|')
                current_aliases.remove(alias)

                if len(current_aliases) == 0:
                    bot.whisper(source.username, "{0} is the only remaining alias for this command and can't be removed.".format(alias))
                    continue

                new_aliases = '|'.join(current_aliases)
                bot.commands.edit_command(command, command=new_aliases)

                num_removed += 1
                del bot.commands[alias]
                log_msg = 'The alias {0} has been removed from {1}'.format(alias, new_aliases.split('|')[0])
                AdminLogManager.add_entry('Alias removed',
                        source,
                        log_msg)

            whisper_str = ''
            if num_removed > 0:
                whisper_str = 'Successfully removed {0} aliases.'.format(num_removed)
            if len(commands_not_found) > 0:
                whisper_str += ' Aliases {0} not found'.format(', '.join(commands_not_found))
            if len(whisper_str) > 0:
                bot.whisper(source.username, whisper_str)
        else:
            bot.whisper(source.username, 'Usage: !remove alias EXISTINGALIAS')
示例#25
0
    def permaban_command(self, **options):
        message = options['message']
        bot = options['bot']
        source = options['source']

        if message:
            username = message.split(' ')[0].strip().lower()
            with bot.users.get_user_context(username) as user:
                if user.banned:
                    bot.whisper(source.username, 'User is already permabanned.')
                    return False

                user.banned = True
                message = message.lower()
                log_msg = '{} has been permabanned'.format(user.username_raw)
                bot.whisper(source.username, log_msg)

                AdminLogManager.add_entry('Permaban added', source, log_msg)
示例#26
0
    def permaban_command(**options):
        message = options["message"]
        bot = options["bot"]
        source = options["source"]

        if message:
            username = message.split(" ")[0].strip().lower()
            with bot.users.get_user_context(username) as user:
                if user.banned:
                    bot.whisper(source.username, "User is already permabanned.")
                    return False

                user.banned = True
                message = message.lower()
                log_msg = "{} has been permabanned".format(user.username_raw)
                bot.whisper(source.username, log_msg)

                AdminLogManager.add_entry("Permaban added", source, log_msg)
示例#27
0
    def get(self, command_id, **options):
        with DBManager.create_session_scope() as db_session:
            command = db_session.query(Command).filter_by(id=command_id).one_or_none()
            if command is None:
                return {'error': 'Invalid command ID'}, 404
            if command.level > options['user'].level:
                return {'error': 'Unauthorized'}, 403
            log_msg = 'The !{} command has been removed'.format(command.command.split('|')[0])
            AdminLogManager.add_entry('Command removed',
                    options['user'],
                    log_msg)
            db_session.delete(command.data)
            db_session.delete(command)

        if SocketClientManager.send('command.remove', {'command_id': command_id}) is True:
            return {'success': 'good job'}, 200
        else:
            return {'error': 'could not push update'}, 500
示例#28
0
    def add_alias(bot, source, message, event, args):
        """Dispatch method for adding aliases to already-existing commands.
        Usage: !add alias EXISTING_ALIAS NEW_ALIAS_1 NEW_ALIAS_2 ...
        """

        if message:
            message = message.replace('!', '').lower()
            # Make sure we got both an existing alias and at least one new alias
            message_parts = message.split()
            if len(message_parts) < 2:
                bot.whisper(source.username, 'Usage: !add alias existingalias newalias')
                return False

            existing_alias = message_parts[0]
            new_aliases = re.split('\|| ', ' '.join(message_parts[1:]))
            added_aliases = []
            already_used_aliases = []

            if existing_alias not in bot.commands:
                bot.whisper(source.username, 'No command called "{0}" found'.format(existing_alias))
                return False

            command = bot.commands[existing_alias]

            for alias in set(new_aliases):
                if alias in bot.commands:
                    already_used_aliases.append(alias)
                else:
                    added_aliases.append(alias)
                    bot.commands[alias] = command

            if len(added_aliases) > 0:
                new_aliases = '{}|{}'.format(command.command, '|'.join(added_aliases))
                bot.commands.edit_command(command, command=new_aliases)

                bot.whisper(source.username, 'Successfully added the aliases {0} to {1}'.format(', '.join(added_aliases), existing_alias))
                log_msg = 'The aliases {0} has been added to {1}'.format(', '.join(added_aliases), existing_alias)
                AdminLogManager.add_entry('Alias added',
                        source,
                        log_msg)
            if len(already_used_aliases) > 0:
                bot.whisper(source.username, 'The following aliases were already in use: {0}'.format(', '.join(already_used_aliases)))
        else:
            bot.whisper(source.username, 'Usage: !add alias existingalias newalias')
示例#29
0
    def level(bot, source, message, **rest):
        if not message:
            bot.whisper(source, "Usage: !level USERNAME NEW_LEVEL")
            return False

        msg_args = message.split(" ")
        if len(msg_args) < 2:
            return False

        username = msg_args[0].lower()
        new_level = int(msg_args[1])
        if new_level >= source.level:
            bot.whisper(
                source,
                f"You cannot promote someone to the same or higher level as you ({source.level})."
            )
            return False

        # We create the user if the user didn't already exist in the database.
        with DBManager.create_session_scope() as db_session:
            user = User.find_or_create_from_user_input(db_session,
                                                       bot.twitch_helix_api,
                                                       username)
            if user is None:
                bot.whisper(
                    source,
                    f'A user with the name "{username}" could not be found.')
                return False

            if user.level >= source.level:
                bot.whisper(
                    source,
                    f"You cannot change the level of someone who is the same or higher level than you. You are level {source.level}, and {username} is level {user.level}",
                )
                return False

            old_level = user.level
            user.level = new_level

            log_msg = f"{user}'s user level changed from {old_level} to {new_level}"

            bot.whisper(source, log_msg)

            AdminLogManager.add_entry("Userlevel edited", source, log_msg)
示例#30
0
文件: commands.py 项目: zneix/pajbot
    def post(self, command_id, **options):
        with DBManager.create_session_scope() as db_session:
            command = db_session.query(Command).filter_by(
                id=command_id).one_or_none()
            if command is None:
                return {"error": "Invalid command ID"}, 404
            if command.level > options["user"].level:
                return {"error": "Unauthorized"}, 403
            log_msg = f"The !{command.command.split('|')[0]} command has been removed"
            AdminLogManager.add_entry("Command removed", options["user"],
                                      log_msg)
            db_session.delete(command.data)
            db_session.delete(command)

        if SocketClientManager.send("command.remove",
                                    {"command_id": command_id}) is True:
            return {"success": "good job"}, 200
        else:
            return {"error": "could not push update"}, 500
示例#31
0
    def level(**options):
        message = options["message"]
        bot = options["bot"]
        source = options["source"]

        if message:
            msg_args = message.split(" ")
            if len(msg_args) > 1:
                username = msg_args[0].lower()
                new_level = int(msg_args[1])
                if new_level >= source.level:
                    bot.whisper(
                        source.username,
                        "You cannot promote someone to the same or higher level as you ({0})."
                        .format(source.level),
                    )
                    return False

                # We create the user if the user didn't already exist in the database.
                with bot.users.get_user_context(username) as user:
                    if user.level >= source.level:
                        bot.whisper(
                            source.username,
                            "You cannot change the level of someone who is the same or higher level than you. You are level {}, and {} is level {}"
                            .format(source.level, username, user.level),
                        )
                        return False

                    old_level = user.level
                    user.level = new_level

                    log_msg = "{}'s user level changed from {} to {}".format(
                        user.username_raw, old_level, new_level)

                    bot.whisper(source.username, log_msg)

                    AdminLogManager.add_entry("Userlevel edited", source,
                                              log_msg)

                    return True

        bot.whisper(source.username, "Usage: !level USERNAME NEW_LEVEL")
        return False
示例#32
0
    def permaban_command(self, **options):
        message = options['message']
        bot = options['bot']
        source = options['source']

        if message:
            username = message.split(' ')[0].strip().lower()
            with bot.users.get_user_context(username) as user:
                if user.banned:
                    bot.whisper(source.username,
                                'User is already permabanned.')
                    return False

                user.banned = True
                message = message.lower()
                log_msg = '{} has been permabanned'.format(user.username_raw)
                bot.whisper(source.username, log_msg)

                AdminLogManager.add_entry('Permaban added', source, log_msg)
示例#33
0
文件: permaban.py 项目: radnov/pajbot
    def permaban_command(bot, source, message, **rest):
        if not message:
            return

        username = message.split(" ")[0]
        with DBManager.create_session_scope() as db_session:
            user = User.find_by_user_input(db_session, username)
            if not user:
                bot.whisper(source, "No user with that name found.")
                return False

            if user.banned:
                bot.whisper(source, "User is already permabanned.")
                return False

            user.banned = True
            log_msg = f"{user} has been permabanned"
            bot.whisper(source, log_msg)

            AdminLogManager.add_entry("Permaban added", source, log_msg)
示例#34
0
    def remove_command(bot, source, message, event, args):
        if message:
            id = None
            command = None
            try:
                id = int(message)
            except Exception:
                pass

            if id is None:
                potential_cmd = ''.join(message.split(' ')[:1]).lower().replace('!', '')
                if potential_cmd in bot.commands:
                    command = bot.commands[potential_cmd]
                    log.info('got command: {0}'.format(command))
            else:
                for key, check_command in bot.commands.items():
                    if check_command.id == id:
                        command = check_command
                        break

            if command is None:
                bot.whisper(source.username, 'No command with the given parameters found')
                return False

            if command.id == -1:
                bot.whisper(source.username, 'That command is an internal command, it cannot be removed.')
                return False

            if source.level < 2000:
                if command.action is not None and not command.action.type == 'message':
                    bot.whisper(source.username, 'That command is not a normal command, it cannot be removed by you.')
                    return False

            bot.whisper(source.username, 'Successfully removed command with id {0}'.format(command.id))
            log_msg = 'The !{} command has been removed'.format(command.command.split('|')[0])
            AdminLogManager.add_entry('Command removed',
                    source,
                    log_msg)
            bot.commands.remove_command(command)
        else:
            bot.whisper(source.username, 'Usage: !remove command (COMMAND_ID|COMMAND_ALIAS)')
示例#35
0
    def generic_update(self, bot: Bot, source, message: str, field: str,
                       extra_args: Dict[str, str]) -> None:
        if not message:
            bot.say(f"You must specify a {field} to update to!")
            return

        if ("user:edit:broadcast"
                not in bot.streamer_access_token_manager.token.scope
                or not self.bot.twitch_helix_api.modify_channel_information(
                    self.bot.streamer_user_id,
                    authorization=bot.streamer_access_token_manager,
                    **extra_args,
                )):
            bot.say(
                "Error: The streamer grants permission to update the game. The streamer needs to be re-authenticated to fix this problem."
            )
            return

        log_msg = f'{source} updated the {field} to "{message}"'
        bot.say(log_msg)
        AdminLogManager.add_entry(f"{field.capitalize()} set", source, log_msg)
示例#36
0
    def generic_update(self, bot, source, message, field, api_fn):
        if not message:
            bot.say(f"You must specify a {field} to update to!")
            return

        if "channel_editor" in bot.streamer_access_token_manager.token.scope:
            api_fn(self.bot.streamer_user_id, message, authorization=bot.streamer_access_token_manager)
        else:
            try:
                api_fn(self.bot.streamer_user_id, message, authorization=bot.bot_token_manager)
            except HTTPError as e:
                if e.response.status_code == 401:
                    bot.say(
                        f"Error: Neither the streamer nor the bot token grants permission to update the {field}. The streamer needs to be re-authenticated to fix this problem."
                    )
                    return
                else:
                    raise e

        log_msg = f'{source} updated the {field} to "{message}"'
        bot.say(log_msg)
        AdminLogManager.add_entry(f"{field.capitalize()} set", source, log_msg)
示例#37
0
    def unpermaban_command(**options):
        message = options["message"]
        bot = options["bot"]
        source = options["source"]

        if message:
            username = message.split(" ")[0].strip().lower()
            with bot.users.find_context(username) as user:
                if not user:
                    bot.whisper(source.username, "No user with that name found.")
                    return False

                if user.banned is False:
                    bot.whisper(source.username, "User is not permabanned.")
                    return False

                user.banned = False
                message = message.lower()
                log_msg = "{} is no longer permabanned".format(user.username_raw)
                bot.whisper(source.username, log_msg)

                AdminLogManager.add_entry("Permaban remove", source, log_msg)
示例#38
0
    def unpermaban_command(self, **options):
        message = options['message']
        bot = options['bot']
        source = options['source']

        if message:
            username = message.split(' ')[0].strip().lower()
            with bot.users.find_context(username) as user:
                if not user:
                    bot.whisper(source.username, 'No user with that name found.')
                    return False

                if user.banned is False:
                    bot.whisper(source.username, 'User is not permabanned.')
                    return False

                user.banned = False
                message = message.lower()
                log_msg = '{} is no longer permabanned'.format(user.username_raw)
                bot.whisper(source.username, log_msg)

                AdminLogManager.add_entry('Permaban remove', source, log_msg)
示例#39
0
    def edit_command(bot, source, message, event, args):
        """Dispatch method for editing commands.
        Usage: !edit command ALIAS [options] RESPONSE
        Multiple options available:
        --whisper/--no-whisper
        --reply/--no-reply
        --modonly/--no-modonly
        --cd CD
        --usercd USERCD
        --level LEVEL
        --cost COST
        """

        if message:
            # Make sure we got both an alias and a response
            message_parts = message.split()
            if len(message_parts) < 2:
                bot.whisper(source.username, 'Usage: !add command ALIAS [options] RESPONSE')
                return False

            options, response = bot.commands.parse_command_arguments(message_parts[1:])

            options['edited_by'] = source.id

            if options is False:
                bot.whisper(source.username, 'Invalid command')
                return False

            alias = message_parts[0].replace('!', '').lower()
            type = 'say'
            if options['whisper'] is True:
                type = 'whisper'
            elif options['reply'] is True:
                type = 'reply'
            elif response.startswith('/me') or response.startswith('.me'):
                type = 'me'
                response = ' '.join(response.split(' ')[1:])
            elif options['whisper'] is False or options['reply'] is False:
                type = 'say'
            action = {
                'type': type,
                'message': response,
            }

            command = bot.commands.get(alias, None)

            if command is None:
                bot.whisper(source.username, 'No command found with the alias {}. Did you mean to create the command? If so, use !add command instead.'.format(alias))
                return False

            old_message = ''
            new_message = ''

            if len(action['message']) > 0:
                options['action'] = action
                old_message = command.action.response
                new_message = action['message']
            elif not type == command.action.subtype:
                options['action'] = {
                    'type': type,
                    'message': command.action.response,
                }
            bot.commands.edit_command(command, **options)
            bot.whisper(source.username, 'Updated the command (ID: {command.id})'.format(command=command))

            if len(new_message) > 0:
                log_msg = 'The !{} command has been updated from "{}" to "{}"'.format(
                        command.command.split('|')[0],
                        old_message,
                        new_message)
            else:
                log_msg = 'The !{} command has been updated'.format(command.command.split('|')[0])

            AdminLogManager.add_entry('Command edited',
                    source,
                    log_msg,
                    data={
                        'old_message': old_message,
                        'new_message': new_message,
                        })
示例#40
0
    def commands_create(**options):
        session.pop('command_created_id', None)
        session.pop('command_edited_id', None)
        if request.method == 'POST':
            if 'aliases' not in request.form:
                abort(403)
            alias_str = request.form.get('aliases', '').replace('!', '').lower()
            delay_all = request.form.get('cd', Command.DEFAULT_CD_ALL)
            delay_user = request.form.get('usercd', Command.DEFAULT_CD_USER)
            level = request.form.get('level', Command.DEFAULT_LEVEL)
            cost = request.form.get('cost', 0)

            try:
                delay_all = int(delay_all)
                delay_user = int(delay_user)
                level = int(level)
                cost = int(cost)
            except ValueError:
                abort(403)

            if len(alias_str) == 0:
                abort(403)
            if delay_all < 0 or delay_all > 9999:
                abort(403)
            if delay_user < 0 or delay_user > 9999:
                abort(403)
            if level < 0 or level > 2000:
                abort(403)
            if cost < 0 or cost > 9999999:
                abort(403)

            user = options.get('user', None)

            if user is None:
                abort(403)

            options = {
                'delay_all': delay_all,
                'delay_user': delay_user,
                'level': level,
                'cost': cost,
                'added_by': user.id,
            }

            valid_action_types = ['say', 'me', 'whisper', 'reply']
            action_type = request.form.get('reply', 'say').lower()
            if action_type not in valid_action_types:
                abort(403)

            response = request.form.get('response', '')
            if len(response) == 0:
                abort(403)

            action = {
                'type': action_type,
                'message': response
            }
            options['action'] = action

            command_manager = (
                pajbot.managers.command.CommandManager(
                    socket_manager=None,
                    module_manager=ModuleManager(None).load(),
                    bot=None).load(enabled=None))

            command_aliases = []

            for alias, command in command_manager.items():
                command_aliases.append(alias)
                if command.command and len(command.command) > 0:
                    command_aliases.extend(command.command.split('|'))

            command_aliases = set(command_aliases)

            alias_str = alias_str.replace(' ', '').replace('!', '').lower()
            alias_list = alias_str.split('|')

            alias_list = [alias for alias in alias_list if len(alias) > 0]

            if len(alias_list) == 0:
                return render_template('admin/create_command_fail.html')

            for alias in alias_list:
                if alias in command_aliases:
                    return render_template('admin/create_command_fail.html')

            alias_str = '|'.join(alias_list)

            command = Command(command=alias_str, **options)
            command.data = CommandData(command.id, **options)
            log_msg = 'The !{} command has been created'.format(command.command.split('|')[0])
            AdminLogManager.add_entry('Command created',
                    user,
                    log_msg)
            with DBManager.create_session_scope(expire_on_commit=False) as db_session:
                db_session.add(command)
                db_session.add(command.data)
                db_session.commit()
                db_session.expunge(command)
                db_session.expunge(command.data)

            SocketClientManager.send('command.update', {'command_id': command.id})
            session['command_created_id'] = command.id
            return redirect('/admin/commands/', 303)
        else:
            return render_template('admin/create_command.html')
示例#41
0
文件: commands.py 项目: jardg/pajbot
    def post(self, command_id, **extra_args):
        args = pajbot.utils.remove_none_values(self.post_parser.parse_args())
        if len(args) == 0:
            return {
                    'error': 'Missing parameter to edit.'
                    }, 400

        valid_names = [
                'enabled',
                'level',
                'delay_all',
                'delay_user',
                'cost',
                'can_execute_with_whisper',
                'sub_only'
                ]

        valid_action_names = [
                'type',
                'message'
                ]

        with DBManager.create_session_scope() as db_session:
            command = db_session.query(Command).options(joinedload(Command.data).joinedload(CommandData.user)).filter_by(id=command_id).one_or_none()
            if command is None:
                return {'error': 'Invalid command ID'}, 404

            if command.level > extra_args['user'].level:
                return {'error': 'Unauthorized'}, 403
            parsed_action = json.loads(command.action_json)
            options = {
                'edited_by': extra_args['user'].id,
            }

            for key in args:
                if key.startswith('data_'):
                    name = key[5:]
                    value = args[key]

                    if name.startswith('action_'):
                        name = name[7:]
                        if name in valid_action_names and name in parsed_action and command.action.type == 'message':
                            value_type = type(parsed_action[name])
                            if value_type is bool:
                                parsed_value = True if value == '1' else False
                            elif value_type is int:
                                try:
                                    parsed_value = int(value)
                                except ValueError:
                                    continue
                            else:
                                parsed_value = value
                            parsed_action[name] = parsed_value
                        command.action_json = json.dumps(parsed_action)
                    else:
                        if name in valid_names:
                            value_type = type(getattr(command, name))
                            if value_type is bool:
                                parsed_value = True if value == '1' else False
                            elif value_type is int:
                                try:
                                    parsed_value = int(value)
                                except ValueError:
                                    continue
                            else:
                                parsed_value = value
                            options[name] = parsed_value

            aj = json.loads(command.action_json)
            old_message = ''
            new_message = ''
            try:
                old_message = command.action.response
                new_message = aj['message']
            except:
                pass

            command.set(**options)
            command.data.set(**options)

            if len(old_message) > 0 and old_message != new_message:
                log_msg = 'The !{} command has been updated from "{}" to "{}"'.format(
                        command.command.split('|')[0],
                        old_message,
                        new_message)
            else:
                log_msg = 'The !{} command has been updated'.format(command.command.split('|')[0])

            AdminLogManager.add_entry('Command edited',
                    extra_args['user'],
                    log_msg,
                    data={
                        'old_message': old_message,
                        'new_message': new_message,
                        })

        if SocketClientManager.send('command.update', {'command_id': command_id}) is True:
            return {'success': 'good job'}, 200
        else:
            return {'error': 'could not push update'}, 500