コード例 #1
0
ファイル: __init__.py プロジェクト: miniCruzer/mammon
def m_privmsg_client(info):
    ctx = get_context()
    if ctx.conf.name == info["target"].servername:
        msg = RFC1459Message.from_data(
            "PRIVMSG", source=info["source"].hostmask, params=[info["target_name"], info["message"]]
        )
        info["target"].dump_message(msg)
コード例 #2
0
ファイル: away.py プロジェクト: miniCruzer/mammon
def m_away_notify(info):
    cli = info['source']
    params = cli.metadata.get('away', None)
    if params:
        params = [params]
    msg = RFC1459Message.from_data('AWAY', source=cli.hostmask, params=params)
    cli.sendto_common_peers(msg, exclude=[cli], cap='away-notify')
コード例 #3
0
    def recv(self, number_of_bytes=4096):
        """Receive bytes from the IRC server."""
        try:
            new_data = self.sock.recv(number_of_bytes).decode(
                'utf-8', 'replace')
        except socket.timeout as ex:
            error = ex.args[0]

            if error == 'timed out':
                return []
            else:
                raise ex

        self._new_data += new_data
        raw_messages = []
        message_buffer = ''

        for char in self._new_data:
            if char in ('\r', '\n'):
                if len(message_buffer):
                    print(' ->', message_buffer)
                    raw_messages.append(message_buffer)
                    message_buffer = ''
                continue

            message_buffer += char

        # convert to actual rfc1459 messages
        messages = []

        for msg in raw_messages:
            messages.append(RFC1459Message.from_message(msg))

        return messages
コード例 #4
0
ファイル: users.py プロジェクト: linostar/vagrirc
    def recv(self, number_of_bytes=4096):
        """Receive bytes from the IRC server."""
        try:
            new_data = self.sock.recv(number_of_bytes).decode('utf-8', 'replace')
        except socket.timeout as ex:
            error = ex.args[0]

            if error == 'timed out':
                return []
            else:
                raise ex

        self._new_data += new_data
        raw_messages = []
        message_buffer = ''

        for char in self._new_data:
            if char in ('\r', '\n'):
                if len(message_buffer):
                    print(' ->', message_buffer)
                    raw_messages.append(message_buffer)
                    message_buffer = ''
                continue

            message_buffer += char

        # convert to actual rfc1459 messages
        messages = []

        for msg in raw_messages:
            messages.append(RFC1459Message.from_message(msg))

        return messages
コード例 #5
0
def m_privmsg_channel(info):
    msg = RFC1459Message.from_data(
        'PRIVMSG',
        source=info['source'],
        params=[info['target_name'], info['message']])
    # XXX - when we have s2s, make sure we only dump messages to local clients here or in dump_message
    info['target'].dump_message(msg, exclusion_list=[info['source']])
コード例 #6
0
def m_PING(cli, ev_msg):
    reply = ev_msg['params'][0] if ev_msg['params'] else cli.ctx.conf.name
    msg = RFC1459Message.from_data('PONG',
                                   source=cli.ctx.conf.name,
                                   params=[reply])
    cli.dump_message(msg)
    cli.update_pings()
コード例 #7
0
def m_away_notify(info):
    cli = info['source']
    params = cli.metadata.get('away', None)
    if params:
        params = [params]
    msg = RFC1459Message.from_data('AWAY', source=cli, params=params)
    cli.sendto_common_peers(msg, exclude=[cli], cap='away-notify')
コード例 #8
0
def m_privmsg_client(info):
    ctx = get_context()
    if ctx.conf.name == info['target'].servername:
        msg = RFC1459Message.from_data(
            'PRIVMSG',
            source=info['source'],
            params=[info['target_name'], info['message']])
        info['target'].dump_message(msg)
コード例 #9
0
 def dump_verb(self, verb, params, source=None, unprefixed=False):
     """Dump a verb to a connected client."""
     # unprefixed is kind of a hack, but some clients fall over when
     #   prefixes are presented with messages like PING
     if source is None and not unprefixed:
         source = self.ctx.conf.name
     msg = RFC1459Message.from_data(verb, source=source, params=params)
     self.dump_message(msg)
コード例 #10
0
    def flush_legacy_mode_change(self, cli, before, after, before_users,
                                 after_users):
        out = str()
        args = []
        mod = 0

        for i in channel_property_items.keys():
            if before.get(i, False) and not after.get(i, False):
                if mod == 1:
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in before.get(i, []):
                            if j not in after.get(i):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if before.get(i, False) != True:
                        args.append(before.get(i))
                else:
                    mod = 1
                    out += '-'
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in before.get(i, []):
                            if j not in after.get(i):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if before.get(i, False) != True:
                        args.append(before.get(i))
            elif not before.get(i, False) and after.get(i, False):
                if mod == 2:
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in after.get(i):
                            if j not in before.get(i, []):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if after.get(i, False) != True:
                        args.append(after.get(i))
                else:
                    mod = 2
                    out += '+'
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in after.get(i):
                            if j not in before.get(i, []):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if after.get(i, False) != True:
                        args.append(after.get(i))
        if len(out) > 0:
            msg = RFC1459Message.from_data('MODE',
                                           source=cli,
                                           params=[self.name, out] + args)
            self.dump_message(msg)
コード例 #11
0
ファイル: client.py プロジェクト: miniCruzer/mammon
    def quit(self, message):
        eventmgr_core.dispatch('client quit', {
            'client': self,
            'message': message,
        })

        m = RFC1459Message.from_data('QUIT', source=self.hostmask, params=[message])
        self.sendto_common_peers(m)
        self.exit()
コード例 #12
0
ファイル: channel.py プロジェクト: miniCruzer/mammon
def m_join_channel(info):
    ch = info['channel']
    cli = info['client']
    message = info['message']

    ctx = get_context()

    ch.dump_message(RFC1459Message.from_data('PART', source=cli.hostmask, params=[ch.name, message]))
    ch.part(cli)
コード例 #13
0
 def dump_numeric(self, numeric, params, add_target=True):
     """Dump a numeric to a connected client.
     This includes the `target` field that numerics have for routing.  You do *not* need to include it."""
     if add_target:
         params = [self.nickname] + params
     msg = RFC1459Message.from_data(numeric,
                                    source=self.ctx.conf.name,
                                    params=params)
     self.dump_message(msg)
コード例 #14
0
    def quit(self, message):
        eventmgr_core.dispatch('client quit', {
            'client': self,
            'message': message,
        })

        m = RFC1459Message.from_data('QUIT', source=self, params=[message])
        self.sendto_common_peers(m)
        self.exit()
コード例 #15
0
ファイル: __init__.py プロジェクト: miniCruzer/mammon
def m_NOTICE(cli, ev_msg):
    targetlist = ev_msg["params"][0].split(",")
    message = ev_msg["params"][1]

    for target in targetlist:
        if target[0] != "#":
            cli_tg = cli.ctx.clients.get(target, None)
            if not cli_tg:
                continue
            msg = RFC1459Message.from_data("NOTICE", source=cli.hostmask, params=[cli_tg.nickname, message])
            cli_tg.dump_message(msg)
            continue

        ch = cli.ctx.chmgr.get(target)
        if not ch or not ch.can_send(cli):
            continue

        msg = RFC1459Message.from_data("NOTICE", source=cli.hostmask, params=[ch.name, message])
        ch.dump_message(msg, exclusion_list=[cli])
コード例 #16
0
ファイル: client.py プロジェクト: miniCruzer/mammon
    def kill(self, source, reason):
        eventmgr_core.dispatch('client killed', {
            'source': source,
            'client': self,
            'reason': reason,
        })

        m = RFC1459Message.from_data('KILL', source=source.hostmask, params=[self.nickname, reason])
        self.dump_message(m)
        self.quit('Killed ({source} ({reason}))'.format(source=source.nickname, reason=reason))
コード例 #17
0
ファイル: channel.py プロジェクト: miniCruzer/mammon
    def flush_legacy_mode_change(self, cli, before, after, before_users, after_users):
        out = str()
        args = []
        mod = 0

        for i in channel_property_items.keys():
            if before.get(i, False) and not after.get(i, False):
                if mod == 1:
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in before.get(i, []):
                            if j not in after.get(i):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if before.get(i, False) != True:
                        args.append(before.get(i))
                else:
                    mod = 1
                    out += '-'
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in before.get(i, []):
                            if j not in after.get(i):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if before.get(i, False) != True:
                        args.append(before.get(i))
            elif not before.get(i, False) and after.get(i, False):
                if mod == 2:
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in after.get(i):
                            if j not in before.get(i, []):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if after.get(i, False) != True:
                        args.append(after.get(i))
                else:
                    mod = 2
                    out += '+'
                    if i == 'ban' or i == 'quiet' or i == 'invite-exemption' or i == 'exemption':
                        for j in after.get(i):
                            if j not in before.get(i, []):
                                out += channel_property_items[i]
                                args.append(j)
                        continue
                    out += channel_property_items[i]
                    if after.get(i, False) != True:
                        args.append(after.get(i))
        if len(out) > 0:
            msg = RFC1459Message.from_data('MODE', source=cli.hostmask, params=[self.name, out] + args)
            self.dump_message(msg)
コード例 #18
0
def m_part_channel(info):
    ch = info['channel']
    cli = info['client']
    message = info['message']

    ctx = get_context()

    ch.dump_message(
        RFC1459Message.from_data('PART', source=cli, params=[ch.name,
                                                             message]))
    ch.part(cli)
コード例 #19
0
    def kill(self, source, reason):
        eventmgr_core.dispatch('client killed', {
            'source': source,
            'client': self,
            'reason': reason,
        })

        m = RFC1459Message.from_data('KILL',
                                     source=source,
                                     params=[self.nickname, reason])
        self.dump_message(m)
        self.quit('Killed ({source} ({reason}))'.format(source=source.nickname,
                                                        reason=reason))
コード例 #20
0
def m_TOPIC(cli, ev_msg):
    chanlist = ev_msg['params'][0].split(',')

    for chan in chanlist:
        if not validate_chan(chan):
            cli.dump_numeric('479', [chan, 'Illegal channel name'])
            return

        ch = cli.ctx.chmgr.get(chan, create=False)
        if not ch:
            cli.dump_numeric('403', [chan, 'No such channel'])
            continue

        if not ch.has_member(cli):
            cli.dump_numeric('442', [ch.name, "You're not on that channel"])
            continue

        # handle inquiry
        if len(ev_msg['params']) == 1:
            if ch.topic:
                cli.dump_numeric('332', [ch.name, ch.topic])
                cli.dump_numeric('333',
                                 [ch.name, ch.topic_setter, ch.topic_ts])
                continue

            cli.dump_numeric('331', [ch.name, 'No topic is set'])
            continue

        # XXX - if not ch.get_member(cli).props.get('topic-change', False) and
        if not ch.props.get('op-topic'):
            cli.dump_numeric('482',
                             [ch.name, 'You\'re not a channel operator'])
            continue

        topic = ev_msg['params'][1]

        # restrict length if we have it defined
        topiclen = cli.ctx.conf.limits.get('topic', None)
        if topiclen and len(ev_msg['params'][1]) > topiclen:
            topic = topic[:topiclen]

        # handle setting
        ch.topic = topic
        ch.topic_setter = cli.hostmask
        ch.topic_ts = cli.ctx.current_ts

        # distribute new topic to peers
        ch.dump_message(
            RFC1459Message.from_data('TOPIC',
                                     source=cli,
                                     params=[ch.name, ch.topic]))
コード例 #21
0
def m_NOTICE(cli, ev_msg):
    targetlist = ev_msg['params'][0].split(',')
    message = ev_msg['params'][1]

    for target in targetlist:
        if target[0] != '#':
            cli_tg = cli.ctx.clients.get(target, None)
            if not cli_tg:
                continue
            msg = RFC1459Message.from_data('NOTICE',
                                           source=cli,
                                           params=[cli_tg.nickname, message])
            cli_tg.dump_message(msg)
            continue

        ch = cli.ctx.chmgr.get(target)
        if not ch or not ch.can_send(cli):
            continue

        msg = RFC1459Message.from_data('NOTICE',
                                       source=cli,
                                       params=[ch.name, message])
        ch.dump_message(msg, exclusion_list=[cli])
コード例 #22
0
def m_join_channel(info):
    ch = info['channel']
    cli = info['client']
    ctx = get_context()

    ch.join(cli)
    ch.dump_message(RFC1459Message.from_data('JOIN',
                                             source=cli,
                                             params=[ch.name]),
                    exclude_cap='extended-join')
    ch.dump_message(RFC1459Message.from_data(
        'JOIN',
        source=cli,
        params=[
            ch.name, '*' if cli.account is None else cli.account, cli.realname
        ]),
                    cap='extended-join')

    if cli.servername != ctx.conf.name:
        return

    cli.handle_side_effect('TOPIC', params=[ch.name])
    cli.handle_side_effect('NAMES', params=[ch.name])
コード例 #23
0
ファイル: channel.py プロジェクト: miniCruzer/mammon
def m_join_channel(info):
    ch = info['channel']
    cli = info['client']
    ctx = get_context()

    ch.join(cli)
    ch.dump_message(RFC1459Message.from_data('JOIN', source=cli.hostmask, params=[ch.name]))

    if cli.servername != ctx.conf.name:
        return

    if ch.topic:
        cli.handle_side_effect('TOPIC', params=[ch.name])

    cli.handle_side_effect('NAMES', params=[ch.name])
コード例 #24
0
ファイル: channel.py プロジェクト: miniCruzer/mammon
def m_TOPIC(cli, ev_msg):
    chanlist = ev_msg['params'][0].split(',')

    for chan in chanlist:
        if not validate_chan(chan):
            cli.dump_numeric('479', [chan, 'Illegal channel name'])
            return

        ch = cli.ctx.chmgr.get(chan, create=False)
        if not ch:
            cli.dump_numeric('403', [chan, 'No such channel'])
            continue

        if not ch.has_member(cli):
            cli.dump_numeric('442', [ch.name, "You're not on that channel"])
            continue

        # XXX - if not ch.get_member(cli).props.get('topic-change', False) and
        if not ch.props.get('op-topic'):
            cli.dump_numeric('482', [ch.name, 'You\'re not a channel operator'])
            continue

        # handle inquiry
        if len(ev_msg['params']) == 1:
            if ch.topic:
                cli.dump_numeric('332', [ch.name, ch.topic])
                cli.dump_numeric('333', [ch.name, ch.topic_setter, ch.topic_ts])
                continue

            cli.dump_numeric('331', [ch.name, 'No topic is set'])
            continue

        topic = ev_msg['params'][1]

        # restrict length if we have it defined
        topiclen = cli.ctx.conf.limits.get('topic', None)
        if topiclen and len(ev_msg['params'][1]) > topiclen:
            topic = topic[:topiclen]

        # handle setting
        ch.topic = topic
        ch.topic_setter = cli.hostmask
        ch.topic_ts = cli.ctx.current_ts

        # distribute new topic to peers
        ch.dump_message(RFC1459Message.from_data('TOPIC', source=cli.hostmask, params=[ch.name, ch.topic]))
コード例 #25
0
ファイル: client.py プロジェクト: miniCruzer/mammon
    def message_received(self, data):
        data = data.decode('UTF-8', 'replace').strip('\r\n')

        linelen = self.ctx.conf.limits.get('line', None)
        if linelen and len(data) > linelen:
            data = data[:linelen]

        m = RFC1459Message.from_message(data)
        m.client = self

        # logging.debug('client {0} --> {1}'.format(repr(self.__dict__), repr(m.serialize())))
        if len(self.recvq) > self.ctx.conf.recvq_len:
            self.quit('Excess flood')
            return

        self.recvq.append(m)

        # XXX - drain_queue should be called on all objects at once to enforce recvq limits
        self.drain_queue()
コード例 #26
0
ファイル: __init__.py プロジェクト: miniCruzer/mammon
def m_NICK(cli, ev_msg):
    new_nickname = ev_msg["params"][0]
    nicklen = cli.ctx.conf.limits.get("nick", None)
    if nicklen and len(new_nickname) > nicklen:
        new_nickname = new_nickname[:nicklen]
    if not validate_nick(new_nickname):
        cli.dump_numeric("432", [new_nickname, "Erroneous nickname"])
        return
    if new_nickname in cli.ctx.clients:
        cli.dump_numeric("433", [new_nickname, "Nickname already in use"])
        return
    msg = RFC1459Message.from_data("NICK", source=cli.hostmask, params=[new_nickname])
    if cli.registered:
        if cli.nickname in cli.ctx.clients:
            cli.ctx.clients.pop(cli.nickname)
        cli.ctx.clients[new_nickname] = cli
        cli.sendto_common_peers(msg)
    cli.nickname = new_nickname
    cli.release_registration_lock("NICK")
コード例 #27
0
    def message_received(self, data):
        data = data.decode('UTF-8', 'replace').strip('\r\n')

        linelen = self.ctx.conf.limits.get('line', None)
        if linelen and len(data) > linelen:
            data = data[:linelen]

        m = RFC1459Message.from_message(data)
        m.client = self

        # logging.debug('client {0} --> {1}'.format(repr(self.__dict__), repr(m.serialize())))
        if len(self.recvq) > self.ctx.conf.recvq_len:
            self.quit('Excess flood')
            return

        self.recvq.append(m)

        # XXX - drain_queue should be called on all objects at once to enforce recvq limits
        self.drain_queue()
コード例 #28
0
def m_NICK(cli, ev_msg):
    new_nickname = ev_msg['params'][0]
    nicklen = cli.ctx.conf.limits.get('nick', None)
    if nicklen and len(new_nickname) > nicklen:
        new_nickname = new_nickname[:nicklen]
    if not validate_nick(new_nickname):
        cli.dump_numeric('432', [new_nickname, 'Erroneous nickname'])
        return
    with cli.ctx.prereg_nicks_lock:
        if new_nickname in cli.ctx.clients or new_nickname in cli.ctx.prereg_nicks:
            cli.dump_numeric('433', [new_nickname, 'Nickname already in use'])
            return
        cli.ctx.prereg_nicks.append(new_nickname)
    msg = RFC1459Message.from_data('NICK', source=cli, params=[new_nickname])
    if cli.registered:
        if cli.nickname in cli.ctx.clients:
            cli.ctx.clients.pop(cli.nickname)
        cli.ctx.clients[new_nickname] = cli
        cli.sendto_common_peers(msg)
    cli.nickname = new_nickname
    cli.release_registration_lock('NICK')
コード例 #29
0
ファイル: client.py プロジェクト: miniCruzer/mammon
    def flush_legacy_mode_change(self, before, after):
        out = str()
        mod = 0

        for i in user_property_items.keys():
            if before.get(i, False) and not after.get(i, False):
                if mod == 1:
                    out += user_property_items[i]
                else:
                    mod = 1
                    out += '-'
                    out += user_property_items[i]
            elif not before.get(i, False) and after.get(i, False):
                if mod == 2:
                    out += user_property_items[i]
                else:
                    mod = 2
                    out += '+'
                    out += user_property_items[i]

        msg = RFC1459Message.from_data('MODE', source=self.hostmask, params=[self.nickname, out])
        self.dump_message(msg)
コード例 #30
0
    def flush_legacy_mode_change(self, before, after):
        out = str()
        mod = 0

        for i in user_property_items.keys():
            if before.get(i, False) and not after.get(i, False):
                if mod == 1:
                    out += user_property_items[i]
                else:
                    mod = 1
                    out += '-'
                    out += user_property_items[i]
            elif not before.get(i, False) and after.get(i, False):
                if mod == 2:
                    out += user_property_items[i]
                else:
                    mod = 2
                    out += '+'
                    out += user_property_items[i]

        msg = RFC1459Message.from_data('MODE',
                                       source=self,
                                       params=[self.nickname, out])
        self.dump_message(msg)
コード例 #31
0
 def send_message(self, verb, **kwargs):
     """Send the given message to the IRC server."""
     msg = RFC1459Message.from_data(verb, **kwargs)
     self.send(msg)
コード例 #32
0
ファイル: __init__.py プロジェクト: miniCruzer/mammon
def m_privmsg_channel(info):
    msg = RFC1459Message.from_data(
        "PRIVMSG", source=info["source"].hostmask, params=[info["target_name"], info["message"]]
    )
    # XXX - when we have s2s, make sure we only dump messages to local clients here or in dump_message
    info["target"].dump_message(msg, exclusion_list=[info["source"]])
コード例 #33
0
ファイル: client.py プロジェクト: miniCruzer/mammon
 def handle_side_effect(self, msg, params=[]):
     m = RFC1459Message.from_data(msg, source=self.hostmask, params=params)
     m.client = self
     self.eventmgr.dispatch(*m.to_event())
コード例 #34
0
 def handle_side_effect(self, msg, params=[]):
     m = RFC1459Message.from_data(msg, source=self, params=params)
     m.client = self
     self.eventmgr.dispatch(*m.to_event())
コード例 #35
0
ファイル: example.py プロジェクト: DanielOaks/ircreactor
 def data_received(self, data):
     m = RFC1459Message.from_message(data.decode('UTF-8', 'replace').strip('\r\n'))
     m.client = self
     em.dispatch(*m.to_event())
     self.transport.write(bytes(m.to_message() + '\r\n', 'UTF-8'))
コード例 #36
0
ファイル: client.py プロジェクト: miniCruzer/mammon
 def dump_numeric(self, numeric, params):
     """Dump a numeric to a connected client.
     This includes the `target` field that numerics have for routing.  You do *not* need to include it."""
     msg = RFC1459Message.from_data(numeric, source=self.ctx.conf.name, params=[self.nickname] + params)
     self.dump_message(msg)
コード例 #37
0
ファイル: client.py プロジェクト: miniCruzer/mammon
 def dump_verb(self, verb, params):
     """Dump a verb to a connected client."""
     msg = RFC1459Message.from_data(verb, source=self.ctx.conf.name, params=params)
     self.dump_message(msg)
コード例 #38
0
ファイル: users.py プロジェクト: linostar/vagrirc
 def send_message(self, verb, **kwargs):
     """Send the given message to the IRC server."""
     msg = RFC1459Message.from_data(verb, **kwargs)
     self.send(msg)
コード例 #39
0
ファイル: __init__.py プロジェクト: miniCruzer/mammon
def m_PING(cli, ev_msg):
    reply = ev_msg["params"][0] if ev_msg["params"] else cli.ctx.conf.name
    msg = RFC1459Message.from_data("PONG", source=cli.ctx.conf.name, params=[reply])
    cli.dump_message(msg)