Пример #1
0
    def dispatch(self, origin, text, args):
        bytes = text
        event = args[0]
        args = args[1:]

        for priority in ('high', 'medium', 'low'):
            items = self.commands[priority].items()
            for regexp, funcs in items:
                for func in funcs:
                    if event != func.event:
                        continue

                    match = regexp.match(text)
                    if match:
                        if self.limit(origin, func):
                            continue

                        willie = self.WillieWrapper(self, origin)
                        trigger = self.Trigger(text, origin, bytes, match,
                                               event, args, self)

                        nick = (trigger.nick).lower()

                        ## blocking ability
                        bad_nicks = self.config.core.get_list('nick_blocks')
                        bad_masks = self.config.core.get_list('host_blocks')

                        if len(bad_masks) > 0:
                            for hostmask in bad_masks:
                                hostmask = hostmask.replace("\n", "")
                                if len(hostmask) < 1:
                                    continue
                                re_temp = re.compile(hostmask)
                                host = origin.host
                                host = host.lower()
                                if re_temp.findall(host) or hostmask in host:
                                    return
                        if len(bad_nicks) > 0:
                            for nick in bad_nicks:
                                nick = nick.replace("\n", "")
                                if len(nick) < 1:
                                    continue
                                re_temp = re.compile(nick)
                                #RFC-lowercasing the regex is impractical. So
                                #we'll just specify to use RFC-lowercase in the
                                #regex, which means we'll have to be in RFC-
                                #lowercase here.
                                if (re_temp.findall(trigger.nick.lower())
                                        or Nick(nick).lower()
                                        in trigger.nick.lower()):
                                    return

                        if func.thread:
                            targs = (func, origin, willie, trigger)
                            t = threading.Thread(target=self.call, args=targs)
                            t.start()
                        else:
                            self.call(func, origin, willie, trigger)
Пример #2
0
 def _nick_blocked(self, nick):
     bad_nicks = self.config.core.get_list('nick_blocks')
     for bad_nick in bad_nicks:
         bad_nick = bad_nick.strip()
         if not bad_nick:
             continue
         if (re.match(bad_nick + '$', nick, re.IGNORECASE)
                 or Nick(bad_nick) == nick):
             return True
     return False
Пример #3
0
    def __init__(self, config):
        if config.ca_certs is not None:
            ca_certs = config.ca_certs
        else:
            ca_certs = '/etc/pki/tls/cert.pem'

        if config.log_raw is None:
            #Default is to log raw data, can be disabled in config
            config.log_raw = True
        asynchat.async_chat.__init__(self)
        self.set_terminator('\n')
        self.buffer = ''

        self.nick = Nick(config.nick)
        """Willie's current ``Nick``. Changing this while Willie is running is
        untested."""
        self.user = config.user
        """Willie's user/ident."""
        self.name = config.name
        """Willie's "real name", as used for whois."""

        self.channels = []
        """The list of channels Willie is currently in."""

        self.stack = []
        self.ca_certs = ca_certs
        self.hasquit = False

        self.sending = threading.RLock()
        self.writing_lock = threading.Lock()
        self.raw = None

        #Right now, only accounting for two op levels.
        #This might be expanded later.
        #These lists are filled in startup.py, as of right now.
        self.ops = dict()
        """
        A dictionary mapping channels to a ``Nick`` list of their operators.
        """
        self.halfplus = dict()
        """
        A dictionary mapping channels to a ``Nick`` list of their half-ops and
        ops.
        """
        self.voices = dict()
        """
        A dictionary mapping channels to a ``Nick`` list of their voices,
        half-ops and ops.
        """

        #We need this to prevent error loops in handle_error
        self.error_count = 0

        self.connection_registered = False
        """ Set to True when a server has accepted the client connection and
Пример #4
0
    def __init__(self, bot, source, args, tags):
        self.hostmask = source
        self.tags = tags

        #Split out the nick, user, and host from hostmask per the regex above.
        match = Origin.source.match(source or '')
        self.nick, self.user, self.host = match.groups()
        self.nick = Nick(self.nick)

        # If we have more than one argument, the second one is the sender
        if len(args) > 1:
            target = Nick(args[1])
        else:
            target = None

        # Unless we're messaging the bot directly, in which case that second
        # arg will be our bot's name.
        if target and target.lower() == bot.nick.lower():
            target = self.nick
        self.sender = target
Пример #5
0
    def __init__(self, bot, source, args):
        self.hostmask = source

        match = Origin.source.match(source or '')
        self.nick, self.user, self.host = match.groups()
        self.nick = Nick(self.nick)

        if len(args) > 1:
            target = args[1]
        else:
            target = None
        if target and target.lower() == bot.nick.lower():
            target = self.nick
        self.sender = target
Пример #6
0
    def __init__(self, bot, source, args):
        self.hostmask = source

        #Split out the nick, user, and host from hostmask per the regex above.
        match = Origin.source.match(source or '')
        self.nick, self.user, self.host = match.groups()
        self.nick = Nick(self.nick)

        # If we have more than one argument, the second one is the sender
        if len(args) > 1:
            target = args[1]
        else:
            target = None

        # Unless we're messaging the bot directly, in which case that second
        # arg will be our bot's name.
        if target and target.lower() == bot.nick.lower():
            target = self.nick
        self.sender = target
Пример #7
0
    def __init__(self):
        asynchat.async_chat.__init__(self)
        self.set_terminator('\n')
        self.error_count = 0
        self.last_error_timestamp = datetime.now()
        self.buffer = ''

        self.nick = Nick(settings.BOT_NICK)
        self.ident = settings.BOT_IDENT
        self.name = settings.BOT_NAME
        self.log = logger()

        self.stack = []
        self.channels = []
        self.ca_certs = '/etc/pki/tls/cert.pem'
        self.has_quit = False

        self.sending = threading.RLock()
        self.writing_lock = threading.Lock()

        self.last_ping_time = None
        self.raw = None
        self.ssl = None
Пример #8
0
 def del_voice(self, channel, name):
     self.voices[channel].discard(Nick(name))
Пример #9
0
 def del_halfop(self, channel, name):
     self.halfplus[channel].discard(Nick(name))
Пример #10
0
 def del_op(self, channel, name):
     self.ops[channel].discard(Nick(name))
Пример #11
0
 def add_voice(self, channel, name):
     if isinstance(name, Nick):
         self.voices[channel].add(name)
     else:
         self.voices[channel].add(Nick(name))
Пример #12
0
 def add_halfop(self, channel, name):
     if isinstance(name, Nick):
         self.halfplus[channel].add(name)
     else:
         self.halfplus[channel].add(Nick(name))
Пример #13
0
 def add_op(self, channel, name):
     if isinstance(name, Nick):
         self.ops[channel].add(name)
     else:
         self.ops[channel].add(Nick(name))
Пример #14
0
        def __new__(cls, text, origin, bytes, match, event, args, self):
            s = unicode.__new__(cls, text)
            s.raw = origin.raw
            s.sender = origin.sender
            """
            The channel (or nick, in a private message) from which the
            message was sent.
            """
            s.hostmask = origin.hostmask
            """
            Hostmask of the person who sent the message in the form
            <nick>!<user>@<host>
            """
            s.user = origin.user
            """Local username of the person who sent the message"""
            s.nick = origin.nick
            """The ``Nick`` of the person who sent the message."""
            s.event = event
            """
            The IRC event (e.g. ``PRIVMSG`` or ``MODE``) which triggered the
            message."""
            s.bytes = bytes
            """
            The text which triggered the message. Equivalent to
            ``Trigger.group(0)``.
            """
            s.match = match
            """
            The regular expression ``MatchObject_`` for the triggering line.
            .. _MatchObject: http://docs.python.org/library/re.html#match-objects
            """
            s.group = match.group
            """The ``group`` function of the ``match`` attribute.

            See Python ``re_`` documentation for details."""
            s.groups = match.groups
            """The ``groups`` function of the ``match`` attribute.

            See Python ``re_`` documentation for details."""
            s.args = args
            """
            A tuple containing each of the arguments to an event. These are the
            strings passed between the event name and the colon. For example,
            setting ``mode -m`` on the channel ``#example``, args would be
            ``('#example', '-m')``
            """
            if len(self.config.core.get_list('admins')) > 0:
                s.admin = (origin.nick in [
                    Nick(n) for n in self.config.core.get_list('admins')
                ])
            else:
                s.admin = False
            """
            True if the nick which triggered the command is in Willie's admin
            list as defined in the config file.
            """

            # Support specifying admins by hostnames
            if not s.admin and len(self.config.core.get_list('admins')) > 0:
                for each_admin in self.config.core.get_list('admins'):
                    re_admin = re.compile(each_admin)
                    if re_admin.findall(origin.host):
                        s.admin = True
                    elif '@' in each_admin:
                        temp = each_admin.split('@')
                        re_host = re.compile(temp[1])
                        if re_host.findall(origin.host):
                            s.admin = True

            if not self.config.core.owner:
                s.owner = False
            elif '@' in self.config.core.owner:
                s.owner = origin.nick + '@' + \
                    origin.host == self.config.core.owner
            else:
                s.owner = (origin.nick == Nick(self.config.core.owner))

            # Bot owner inherits all the admin rights, therefore is considered
            # admin
            s.admin = s.admin or s.owner

            s.host = origin.host
            if s.sender is not s.nick:  # no ops in PM
                s.ops = self.ops.get(s.sender, [])
                """
                List of channel operators in the channel the message was
                recived in
                """
                s.halfplus = self.halfplus.get(s.sender, [])
                """
                List of channel half-operators in the channel the message was
                recived in
                """
                s.isop = (s.nick in s.ops or s.nick in s.halfplus)
                """True if the user is half-op or an op"""
                s.voices = self.voices.get(s.sender, [])
                """
                List of channel operators in the channel the message was
                recived in
                """
                s.isvoice = (s.nick in s.ops or s.nick in s.halfplus
                             or s.nick in s.voices)
                """True if the user is voiced, has op, or has half-op"""
            else:
                s.isop = False
                s.isvoice = False
                s.ops = []
                s.halfplus = []
                s.voices = []
            return s