示例#1
0
文件: pprint.py 项目: foxkit-us/PyIRC
 def topic_details(self, _, line):
     """Show the details of a topic."""
     channel = line.params[1]
     setter = self.nick_colour(Hostmask.parse(line.params[2]).nick)
     set_on = str(datetime.utcfromtimestamp(int(line.params[3])))
     self._printf("*** Topic of {} set by {} on {}.".format(channel, setter,
                                                            set_on))
示例#2
0
 def topic_details(self, _, line):
     """Show the details of a topic."""
     channel = line.params[1]
     setter = self.nick_colour(Hostmask.parse(line.params[2]).nick)
     set_on = str(datetime.utcfromtimestamp(int(line.params[3])))
     self._printf("*** Topic of {} set by {} on {}.".format(
         channel, setter, set_on))
示例#3
0
    def topic_who_time(self, _, line):
        """Update the channel's topic metadata."""
        channel = self.get_channel(line.params[1])
        if channel is None:
            _logger.debug("Topic time for unknown channel: %s", line.params[1])
            return

        channel.topicwho = Hostmask.parse(line.params[2])
        channel.topictime = int(line.params[3])
示例#4
0
    def topic_who_time(self, _, line):
        """Update the channel's topic metadata."""
        channel = self.get_channel(line.params[1])
        if channel is None:
            _logger.debug("Topic time for unknown channel: %s",
                          line.params[1])
            return

        channel.topicwho = Hostmask.parse(line.params[2])
        channel.topictime = int(line.params[3])
示例#5
0
    def kick(self, _, line):
        """Fire a (scope, user_kick) event for users being kicked."""
        params = line.params

        channel = params[0]
        target = Hostmask(nick=params[1])
        reason = params[2]

        scope = Scope(target, channel, True, reason=reason,
                      cause=line.hostmask)
        self.call_event("scope", "user_kick", scope)
示例#6
0
    def prefix(self, _, setter, target, mode):
        # Parse into hostmask in case of usernames-in-host
        channel = self.get_channel(target)
        if channel is None:
            _logger.warning("Got a PREFIX event for an unknown channel: %s",
                            target)
            return

        hostmask = Hostmask.parse(mode.param)
        if mode.adding:
            channel.users[hostmask.nick].add(mode.mode)
        else:
            channel.users[hostmask.nick].discard(mode.mode)
示例#7
0
    def prefix(self, _, setter, target, mode):
        # Parse into hostmask in case of usernames-in-host
        channel = self.get_channel(target)
        if channel is None:
            _logger.warning("Got a PREFIX event for an unknown channel: %s",
                            target)
            return

        hostmask = Hostmask.parse(mode.param)
        if mode.adding:
            channel.users[hostmask.nick].add(mode.mode)
        else:
            channel.users[hostmask.nick].discard(mode.mode)
示例#8
0
    def monitor_offline(self, _, line):
        """Remove users who go offline on MONITOR."""
        if not self._usable:
            return

        monitor = [Hostmask.parse(h) for h in line.params[-1].split(",")]
        if not monitor:
            return

        user_track = self.base.user_track
        for user in monitor:
            if user_track.get_user(user.nick):
                user_track.remove_user(user.nick)
示例#9
0
    def monitor_online(self, _, line):
        """Add users who come online on MONITOR."""
        if not self._usable:
            return

        monitor = [Hostmask.parse(h) for h in line.params[-1].split(",")]
        if not monitor:
            return

        user_track = self.base.user_track
        for user in monitor:
            user_track.add_user(user.nick,
                                username=user.username,
                                host=user.host)
示例#10
0
    def test_channel_topic_user(self):
        """Ensure topic set by user is handled correctly."""
        name = '#Sporks'
        topic = "#Sporks - we'll bring yo dick"
        setter = Hostmask(nick='lstarnes',
                          username='******',
                          host='interlinked/netadmin/automaton/lstarnes')
        set_on = int(time())  # 1437288043

        irc = self.connection
        irc.inject_line(join_line(irc, name))
        irc.inject_line(
            Line(hostmask=setter, command='TOPIC', params=(name, topic)))

        self.assertTopicEqual(topic, setter, set_on)
示例#11
0
    def parse_stats_opers(self, _, line):
        """Evaluate a stats line for an oper."""
        if line.params[1] != 'p':
            return

        match = _charybdis_oper_re.match(line.params[-1])
        if not match:
            return

        nick = match.group("nick")
        user = match.group("user")
        host = match.group("host")
        hostmask = Hostmask(nick=nick, user=user, host=host)

        entry = OperEntry(None, None, hostmask, None)
        return self.call_event("stats", "oper", entry)
示例#12
0
    def prefix(self, event):
        # Parse into hostmask in case of usernames-in-host
        hostmask = Hostmask.parse(event.param)

        assert hostmask

        user = self.get_user(hostmask.nick)
        if not user:
            # Add the user
            user = self.add_user(hostmask.nick, user=hostmask.username,
                                 host=hostmask.host)

        channel = user.channels[event.target]
        if event.adding:
            channel.add(event.mode)
        else:
            channel.discard(event.mode)
示例#13
0
    def test_channel_topic_server_server(self):
        """Ensure topic sent from and set by server is handled correctly."""
        name = '#help'
        topic = 'Official help channel | To register a nick : /msg NickServ '\
                'help register | To group a nick, /msg nickserv help group | '\
                'Lost password? /msg nickserv SENDPASS <accountname> | State '\
                'your question and people will answer eventually (It might '\
                'take 10 or so minutes)'
        setter = 'chrysalis.server'
        set_on = 1395559296

        irc = self.connection
        irc.inject_line(join_line(irc, name))
        irc.inject_line(rpl_topic_line(irc, name, topic))
        irc.inject_line(rpl_topiwhotime_line(irc, name, setter, set_on))

        self.assertTopicEqual(topic, Hostmask(host=setter), set_on)
示例#14
0
def userhost_parse(mask):
    """Parse a USERHOST reply.

    :returns:
        An object with the following attributes set:

        :hostmask:
            :py:class:`~PyIRC.line.Hostmask` of the user. This may be a cloak.

        :operator:
            Whether or not the user is an operator. False does not mean they
            are not an operator, as operators may be hidden on the server.

        :away:
            Whether or not the user is away.

    """
    if not mask:
        raise ValueError("Need a mask to parse")

    ret = SimpleNamespace(hostmask=None, operator=None, away=None)

    nick, sep, userhost = mask.partition('=')
    if not sep:
        return ret

    if nick.endswith('*'):
        nick = nick[:-1]
        ret.operator = True

    if userhost.startswith(('+', '-')):
        away, userhost = userhost[0], userhost[:1]
        ret.away = (away == '+')

    # user@host
    username, sep, host = userhost.partition('@')
    if not sep:
        host = username
        username = None

    ret.hostmask = Hostmask(nick=nick, username=username, host=host)

    return ret
示例#15
0
    def test_channel_topic_server_user(self):
        """Ensure topic sent from server, set by user, is handled correctly."""

        name = '#gentoo-python'
        topic = 'Set e.g. PYTHON_TARGETS="python2_7 python3_2 python3_3 '\
                'python3_4" in /etc/make.conf if you want to install Python '\
                'modules for multiple Python versions. | '\
                'http://www.gentoo.org/proj/en/Python/#doc_chap5'
        setter = Hostmask(nick='xiaomiao',
                          username='******',
                          host='gentoo/developer/bonsaikitten')
        set_on = 1404711155

        irc = self.connection
        irc.inject_line(join_line(irc, name))
        irc.inject_line(rpl_topic_line(irc, name, topic))
        irc.inject_line(rpl_topiwhotime_line(irc, name, setter, set_on))

        self.assertTopicEqual(topic, setter, set_on)
示例#16
0
    def prefix(self, _, setter, target, mode):
        """Update the channel mode of a user."""
        # pylint: disable=unused-argument
        # Parse into hostmask in case of usernames-in-host
        hostmask = Hostmask.parse(mode.param)

        assert hostmask

        user = self.get_user(hostmask.nick)
        if user is None:
            # This can happen from override or ChanServ guard off
            user = self.add_user(hostmask.nick, username=hostmask.username,
                                 host=hostmask.host)
            self.timeout_user(hostmask.nick)

        channel = user.channels[target]
        if mode.adding:
            channel.add(mode.mode)
        else:
            channel.discard(mode.mode)
示例#17
0
    def names(self, _, line):
        """Handle bursting of new users from NAMES."""
        params = line.params

        channel = params[2]

        isupport = self.base.isupport
        prefix = prefix_parse(isupport.get("PREFIX"))

        for hostmask in params[3].split(' '):
            if not hostmask:
                continue

            modes, hostmask = status_prefix_parse(hostmask, prefix)
            hostmask = Hostmask.parse(hostmask)

            modes = [(m, hostmask, True, None) for m in modes]

            scope = Scope(
                hostmask, channel, False, cause=line.hostmask, modes=modes)
            self.call_event("scope", "user_burst", scope)
示例#18
0
    def parse_stats_opers(self, _, line):
        """Evaluate a stats line for an oper."""
        if line.params[1] != 'p':
            return

        match = _hybrid_oper_re(line.params[-1])
        if not match:
            return

        flag = match.group("flag")
        privs = match.group("privs")

        nick = match.group("nick")
        user = match.group("user")
        host = match.group("host")
        hostmask = Hostmask(nick=nick, user=user, host=host)

        idle = int(match.group("idle"))

        entry = OperEntry(flag, privs, hostmask, idle)
        return self.call_event("stats", "oper", entry)
示例#19
0
    def handle_list(self, caller, line):
        modechar = self.mode_chars[caller.eventpair[1]]
        params = line.params

        try:
            target = params[1]
            mask = params[2]
            if len(params) > 3:
                setter = Hostmask.parse(params[3])
                if len(params) > 4:
                    timestamp = int(params[4])
            else:
                setter = line.hostmask
                timestamp = None
        except Exception as e:
            _logger.warning("Bogus list mode received: %s (exception: %s)",
                            modechar, e)
            return

        mode = Mode(modechar, mask, True, timestamp)
        self.call_event("modes", "mode_list", setter, target, mode)
示例#20
0
    def handle_list(self, event, mode):
        line = event.line
        params = line.params

        try:
            target = params[1]
            mask = params[2]
            if len(params) > 3:
                setter = Hostmask.parse(params[3])
                if len(params) > 4:
                    timestamp = int(params[4])
            else:
                setter = line.hostmask
                timestamp = None
        except Exception as e:
            logger.warning("Bogus list mode received: %s (exception: %s)",
                           mode, e)
            return

        self.call_event("modes", "mode_list", line, setter, target, True,
                        mode, mask, timestamp)
示例#21
0
def banmask_parse(string, supported_extban):
    """Normalise a ban mask into either an extban or nick!user@host set"""
    ret = SimpleNamespace()
    ret.nick = ret.user = ret.host = None

    extban = extban_parse(string, supported_extban)
    if extban:
        # Unpack
        ret.extban, ret.extban_target = extban
        return ret

    ret.extban = ret.extban_target = None

    try:
        hostmask = Hostmask.parse(string)
    except Exception:
        return ret

    if not hostmask:
        return ret

    ret.nick, ret.user, ret.host = hostmask.nick, hostmask.user, hostmask.host
    return ret
示例#22
0
    def _parse_ban_lines(line):
        """Parse a foo:line in Hybrid-derived servers, excluding RESV and
        X:lines."""
        params = line.params

        match = _stats_ban_re.match(params[-1])
        assert match, "Bug in the stats matching regex!"

        t = match.group("type")
        if t == "K" or t == "G":
            # Don't use Hostmask, because this is for matching purposes.
            mask = (params[3], params[4], params[2])
        elif t == "D":
            mask = params[2]
        else:
            _logger.warning("Unknown bantype, just guessing!")
            mask = params[:-1]

        duration = int(match.group("duration")) * 60

        year = int(match.group("year"))
        month = int(match.group("month"))
        day = int(match.group("day"))
        hour = int(match.group("hour"))
        minute = int(match.group("minute"))
        if all(x is not None for x in (year, month, day)):
            setdate = datetime(year, month, day, hour, minute)
        else:
            setdate = None

        reason = match.group("reason")
        oreason = match.group("oreason")
        settermask = Hostmask.parse(match.group("settermask"))
        setter = match.group("setter")

        return BanEntry(mask, settermask, setter, setdate, duration, reason,
                        oreason)
示例#23
0
    def _parse_ban_lines(line):
        """Parse a foo:line in Hybrid-derived servers, excluding RESV and
        X:lines."""
        params = line.params

        match = _stats_ban_re.match(params[-1])
        assert match, "Bug in the stats matching regex!"

        t = match.group("type")
        if t == "K" or t == "G":
            # Don't use Hostmask, because this is for matching purposes.
            mask = (params[3], params[4], params[2])
        elif t == "D":
            mask = params[2]
        else:
            _logger.warning("Unknown bantype, just guessing!")
            mask = params[:-1]

        duration = int(match.group("duration")) * 60

        year = int(match.group("year"))
        month = int(match.group("month"))
        day = int(match.group("day"))
        hour = int(match.group("hour"))
        minute = int(match.group("minute"))
        if all(x is not None for x in (year, month, day)):
            setdate = datetime(year, month, day, hour, minute)
        else:
            setdate = None

        reason = match.group("reason")
        oreason = match.group("oreason")
        settermask = Hostmask.parse(match.group("settermask"))
        setter = match.group("setter")

        return BanEntry(mask, settermask, setter, setdate, duration, reason,
                        oreason)
示例#24
0
def banmask_parse(string, supported_extban):
    """Normalise a ban mask into either an extban or nick!user@host set."""
    ret = SimpleNamespace()
    ret.nick = ret.user = ret.host = None

    extban = extban_parse(string, supported_extban)
    if extban:
        # Unpack
        ret.extban, ret.extban_target = extban
        return ret

    ret.extban = ret.extban_target = None

    try:
        hostmask = Hostmask.parse(string)
    except ValueError:
        return ret

    if not hostmask:
        return ret

    ret.nick, ret.user, ret.host = (hostmask.nick, hostmask.username,
                                    hostmask.host)
    return ret
示例#25
0
def conn_mask(connection):
    return Hostmask(nick=connection.nick,
                    username=connection.username,
                    host='test-connection.local')