コード例 #1
0
ファイル: pybot.py プロジェクト: xgabst/pybot
 def on_whoisuser(self, connection, raw_msg):
     """ called by super() when WHOIS response arrives """
     self._call_plugins_methods('whoisuser',
                                raw_msg=raw_msg,
                                nick=irc_nickname(raw_msg.arguments[0]),
                                user=irc_nickname(raw_msg.arguments[1]),
                                host=irc_nickname(raw_msg.arguments[2]))
コード例 #2
0
ファイル: pybot.py プロジェクト: xgabst/pybot
 def on_nick(self, connection, raw_msg):
     """ called by super() when somebody changes nickname """
     self._call_plugins_methods('nick',
                                raw_msg=raw_msg,
                                source=raw_msg.source,
                                old_nickname=irc_nickname(
                                    raw_msg.source.nick),
                                new_nickname=irc_nickname(raw_msg.target))
コード例 #3
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
    def get_ops(self) -> list:
        with self._db_mutex:
            self._db_cursor.execute(
                f"SELECT nickname FROM '{self._db_ops_tablename}'")
            result = self._db_cursor.fetchall()

        return [irc_nickname(n[0]) for n in result] + [self.config['superop']]
コード例 #4
0
        def command_impl(self, sender_nick, **kwargs):
            sender_nick = irc_nickname(sender_nick)

            if hasattr(command_impl, '__superadmin'
                       ) and sender_nick != self.bot.config['superop']:
                self.logger.info(
                    f'{sender_nick} is not superop, skipping command')
                self.bot.say(f"{sender_nick}: you're not bot owner, sorry!")
                return

            if hasattr(command_impl,
                       '__admin') and not self.bot.is_user_op(sender_nick):
                self.logger.info(f'{sender_nick} is not op, skipping command')
                self.bot.say(f"{sender_nick}: you're not bot operator, sorry!")
                return

            if hasattr(command_impl, '__channel_op'
                       ) and not self.bot.get_channel().is_oper(sender_nick):
                self.logger.info(
                    f'{sender_nick} is not channel operator, skipping command')
                self.bot.say(
                    f"{sender_nick}: you're not channel operator, sorry!")
                return

            try:
                function(self, sender_nick=sender_nick, **kwargs)
            except Exception as e:
                self.logger.error(
                    f'exception caught calling {function.__qualname__}: {type(e).__name__}: {e}'
                )
                self.bot.say('internal error, sorry :(')
                if self.bot.is_debug_mode_enabled(): raise
コード例 #5
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
    def get_ignored_users(self) -> list:
        with self._db_mutex:
            self._db_cursor.execute(
                f"SELECT nickname FROM '{self._db_ignored_users_tablename}'")
            result = self._db_cursor.fetchall()

        return [irc_nickname(n[0]) for n in result]
コード例 #6
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
 def on_mode(self, _, raw_msg):
     """ called by super() when someone's mode changed """
     self._call_plugins_methods('mode',
                                raw_msg=raw_msg,
                                source=raw_msg.source,
                                who=irc_nickname(raw_msg.arguments[1]),
                                mode_change=raw_msg.arguments[0])
コード例 #7
0
ファイル: pybot.py プロジェクト: xgabst/pybot
    def on_nicknameinuse(self, connection, raw_msg):
        """ called by super() when given nickname is reserved """
        nickname = irc_nickname(self.config['nickname'][self._nickname_id])
        self._nickname_id += 1

        if self._nickname_id >= len(self.config['nickname']):
            self.logger.critical(
                f'nickname {nickname} is busy, no more nicknames to use')
            sys.exit(2)

        new_nickname = irc_nickname(self.config['nickname'][self._nickname_id])
        self.logger.warning(
            f'nickname {nickname} is busy, using {new_nickname}')
        self._call_plugins_methods('nicknameinuse',
                                   raw_msg=raw_msg,
                                   busy_nickname=nickname)
        self.connection.nick(new_nickname)
        self._login()
コード例 #8
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
    def add_op(self, nickname):
        if self.is_user_ignored(nickname): self.unignore_user(nickname)
        if irc_nickname(nickname) == self.config['superop']: return

        with self._db_mutex:
            self._db_cursor.execute(
                f"INSERT OR REPLACE INTO '{self._db_ops_tablename}' VALUES (?)",
                (nickname, ))
            self._db_connection.commit()
コード例 #9
0
ファイル: pybot.py プロジェクト: xgabst/pybot
    def on_pubmsg(self, connection, raw_msg):
        """ called by super() when msg received """
        full_msg = raw_msg.arguments[0].strip()
        sender_nick = irc_nickname(raw_msg.source.nick)

        if self.is_user_ignored(sender_nick):
            self.logger.debug(f'user {sender_nick} is ignored, skipping msg')
            return

        self._call_plugins_methods('pubmsg',
                                   raw_msg=raw_msg,
                                   source=raw_msg.source,
                                   msg=full_msg)

        raw_cmd = msg_parser.trim_msg(self.config['command_prefix'], full_msg)
        if not raw_cmd:
            raw_cmd = msg_parser.trim_msg(self.get_nickname() + ':', full_msg)
        if not raw_cmd:
            raw_cmd = msg_parser.trim_msg(self.get_nickname() + ',', full_msg)

        args_list = raw_cmd.split()
        cmd = args_list[0].strip() if len(args_list) > 0 else ''
        args_list = args_list[1:]
        assert raw_cmd.startswith(cmd)
        raw_cmd = raw_cmd[len(cmd):].strip()

        if cmd in self.commands:
            func = self.commands[cmd]
            self.logger.debug(
                f'calling command  {func.__qualname__}(sender_nick={sender_nick}, args={args_list}, msg=\'{raw_cmd}\', raw_msg=...)...'
            )
            func(sender_nick=sender_nick,
                 args=args_list,
                 msg=raw_cmd,
                 raw_msg=raw_msg)
        elif self.config['try_autocorrect'] and cmd:
            possible_cmd = self._get_best_command_match(cmd, sender_nick)
            if possible_cmd:
                self.say(
                    f"no such command: {cmd}, did you mean '{possible_cmd}'?")
            else:
                self.say(f'no such command: {cmd}')

        for reg in self.msg_regexes:
            regex_search_result = reg.findall(full_msg)
            if regex_search_result:
                for func in self.msg_regexes[reg]:
                    self.logger.debug(
                        f'calling message regex handler  {func.__qualname__}(sender_nick={sender_nick}, msg=\'{full_msg}\', reg_res={regex_search_result}, raw_msg=...)...'
                    )
                    func(sender_nick=sender_nick,
                         msg=full_msg,
                         reg_res=regex_search_result,
                         raw_msg=raw_msg)
コード例 #10
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
    def rm_op(self, nickname):
        """
        throws RuntimeError when nickname is superop
        """
        if irc_nickname(nickname) == self.config['superop']:
            raise RuntimeError('cannot remove superop')

        with self._db_mutex:
            self._db_cursor.execute(
                f"DELETE FROM '{self._db_ops_tablename}' WHERE nickname = ? COLLATE NOCASE",
                (nickname, ))
            self._db_connection.commit()
コード例 #11
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
    def on_namreply(self, _, raw_msg):
        """ called by super() when NAMES response arrives """
        nickname_prefixes = '~&@%+'
        nicks = raw_msg.arguments[2].split()
        for i in range(0, len(nicks)):
            for prefix in nickname_prefixes:
                if nicks[i].startswith(prefix): nicks[i] = nicks[i][1:].strip()

            nicks[i] = irc_nickname(nicks[i])

        self._call_plugins_methods('namreply',
                                   raw_msg=raw_msg,
                                   nicknames=nicks)
コード例 #12
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
 def _can_user_call_command(self, nickname, command_name):
     nickname = irc_nickname(nickname)
     func = self.get_commands()[command_name]
     if hasattr(func, '__admin') and not self.is_user_op(nickname):
         return False
     if hasattr(func,
                '__superadmin') and nickname != self.config['superop']:
         return False
     if hasattr(
             func,
             '__channel_op') and not self.get_channel().is_oper(nickname):
         return False
     return True
コード例 #13
0
ファイル: pybot.py プロジェクト: xgabst/pybot
    def on_privmsg(self, connection, raw_msg):
        """ called by super() when private msg received """
        full_msg = raw_msg.arguments[0]
        sender_nick = irc_nickname(raw_msg.source.nick)
        logging.info(f'[PRIVATE MSG] {sender_nick}: {full_msg}')

        if self.is_user_ignored(sender_nick):
            self.logger.debug(f'user {sender_nick} is ignored, skipping msg')
            return

        self._call_plugins_methods('privmsg',
                                   raw_msg=raw_msg,
                                   source=raw_msg.source,
                                   msg=full_msg)
コード例 #14
0
ファイル: plugin.py プロジェクト: xgabst/pybot
 def admin_impl(self, sender_nick, **kwargs):
     sender_nick = irc_nickname(sender_nick)
     if sender_nick in self.bot.config['ops']:
         function(self, sender_nick=sender_nick, **kwargs)
     else:
         self.logger.info(f'{sender_nick} is not op, skipping command')
コード例 #15
0
ファイル: pybot.py プロジェクト: xgabst/pybot
 def get_nickname(self):
     return irc_nickname(self.connection.get_nickname())
コード例 #16
0
ファイル: pybot.py プロジェクト: xgabst/pybot
 def is_user_ignored(self, nickname):
     nickname = irc_nickname(nickname)
     return ('ignored_users' in self.config
             and nickname in self.config['ignored_users']) and (
                 nickname not in self.config['ops'])
コード例 #17
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
    def on_pubmsg(self, _, raw_msg):
        """ called by super() when msg received """
        full_msg = raw_msg.arguments[0].strip()
        sender_nick = irc_nickname(raw_msg.source.nick)

        self._call_plugins_methods('pubmsg',
                                   raw_msg=raw_msg,
                                   source=raw_msg.source,
                                   msg=full_msg)

        if self.is_user_ignored(sender_nick):
            self._logger.debug(f'user {sender_nick} is ignored, skipping msg')
            return

        args = msg_parser.trim_msg(self.get_command_prefix(), full_msg)
        if not args:
            args = msg_parser.trim_msg(self.get_nickname() + ':', full_msg)
        if not args:
            args = msg_parser.trim_msg(self.get_nickname() + ',', full_msg)

        # fix should not affect msg regexps
        reg_raw_msg = raw_msg
        reg_full_msg = full_msg
        if args and args.split()[0].strip() == 'fix':
            fixed_command = self._get_fixed_command()
            if 'builtins' not in self.get_plugins_names(
            ) or 'fix' not in self.get_plugin_commands('builtins'):
                pass
            elif not self._can_user_call_command(sender_nick, 'fix'):
                pass
            elif not fixed_command:
                self.say('no fix available')
                args = ''  # to disable further cmd executing
            else:
                self._logger.info(
                    f'fixing command for {sender_nick}: {fixed_command}')
                args = fixed_command
                self.register_fixed_command(None)
                raw_msg = None
                full_msg = None
        else:
            if self.config['use_fix_tip']:
                with self._fixed_command_lock:
                    fixed_command = self._get_fixed_command()
                    if not self._use_fix_tip_given and fixed_command and self.get_command_prefix(
                    ) + fixed_command.strip() == full_msg.strip():
                        self._use_fix_tip_given = True
                        use_fix_responses = [
                            '%s: why u no %s?', 'hey, %s, use %s!',
                            '%s: use %s to fix your previous command',
                            "%s: you're making %s feature sad"
                        ]
                        self.say(
                            random.choice(use_fix_responses) %
                            (sender_nick, f'{self.get_command_prefix()}fix'))

        args_list = args.split()
        cmd = args_list[0].strip() if args_list else ''
        args_list = args_list[1:]
        assert args.startswith(cmd)
        args = args[len(cmd):].strip()

        # !set entry some msg
        # cmd       == "set"
        # full_msg  == "!set entry some msg"
        # args      == "entry some msg"
        # args_list == ["some", "msg"]
        # raw_msg   == IRC Event class

        if cmd in self.get_commands():
            func = self.get_commands()[cmd]
            self._logger.debug(
                f'calling command  {func.__qualname__}(sender_nick={sender_nick}, args={args_list}, msg=\'{args}\', raw_msg=...)...'
            )
            func(sender_nick=sender_nick,
                 args=args_list,
                 msg=args,
                 raw_msg=raw_msg)
        elif self.config['try_autocorrect'] and cmd and len(
                cmd) > 0 and cmd[0].isalpha():
            possible_cmd = self._get_best_command_match(cmd, sender_nick)
            if possible_cmd:
                self.say(
                    f"no such command: {cmd}, did you mean '{possible_cmd}'?")
                if possible_cmd != 'fix':
                    self.register_fixed_command(f'{possible_cmd} {args}')
            else:
                self.say(f'no such command: {cmd}')

        with self._plugins_lock:
            for reg in self._msg_regexps:
                regex_search_result = reg.findall(reg_full_msg)
                if regex_search_result:
                    for func in self._msg_regexps[reg]:
                        self._logger.debug(
                            f'calling message regex handler  {func.__qualname__}(sender_nick={sender_nick}, msg=\'{reg_full_msg}\', reg_res={regex_search_result}, raw_msg=...)...'
                        )
                        func(sender_nick=sender_nick,
                             msg=reg_full_msg,
                             reg_res=regex_search_result,
                             raw_msg=reg_raw_msg)
コード例 #18
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
 def is_user_op(self, nickname):
     return irc_nickname(nickname) in self.get_ops()
コード例 #19
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
 def is_user_ignored(self, nickname):
     return irc_nickname(nickname) in self.get_ignored_users(
     ) and not self.is_user_op(nickname)
コード例 #20
0
ファイル: pybot.py プロジェクト: hbdgr/pybot
 def get_usernames_on_channel(self) -> list:
     """
     :return: names of users in channel
     """
     return [irc_nickname(x) for x in list(self.get_channel().users())]