Exemplo n.º 1
0
    def quote(self, *msg, force=None, tags=None):
        if not isinstance(tags, dict):
            if msg and isinstance(msg[0], dict):
                tags, *msg = msg
            else:
                tags = {}

        if not self.connected:
            if self._sendq is None:
                self._sendq = []
            self.debug('>Q>', msg)
            self._sendq.append((tags, *msg))
            return

        # Parse the message using miniirc's built-in parser to reduce redundancy
        msg = ' '.join(msg)
        self.debug('>>>', msg)
        cmd, hostmask, _, args = miniirc.ircv3_message_parser(msg)
        cmd = cmd.upper()
        del _

        if _outgoing_cmds.get(cmd):
            self._run(_outgoing_cmds[cmd](self, self._client, tags, cmd, args))
        else:
            self.debug('Unknown command run:', cmd)
Exemplo n.º 2
0
    def json_parser(self, msg: str):
        # Use the standard parser if required
        if msg.startswith('@') or msg.startswith('CAP'):
            return miniirc.ircv3_message_parser(msg)

        # Parse the message
        tags: dict = {}
        try:
            msg = json.loads(msg)
        except json.JSONDecodeError:
            self.debug('Error decoding JSON.')
            return

        if not isinstance(msg, list) or len(msg) == 0:
            self.debug('Decoded JSON is not a list (or an empty list).')
            return

        # Get the tags
        if isinstance(msg[0], dict):
            tags = msg.pop(0)

            # Sanity check
            for k, v in tags.items():
                if not isinstance(v, (str, bool)):
                    self.debug('Invalid IRCv3 tags.')
                    tags = {}
                    break

        # Make sure the message is not too short
        if len(msg) < 2:
            self.debug('Message too short.')
            return

        # Get the hostmask
        if isinstance(msg[0], str) and '!' in msg:
            h = msg[0].split('!', 1)
            if len(h) < 2:
                h.append(h[0])
            i = h[1].split('@', 1)
            if len(i) < 2:
                i.append(i[0])
            hostmask = (h[0], i[0], i[1])
        elif isinstance(msg[0], (tuple, list)) and len(msg[0]) == 3:
            hostmask = tuple(msg[0])
        else:
            hostmask = (msg[1], msg[1], msg[1])

        # Get the args
        cmd  = msg[1]
        args = msg[2:]
        if args:
            args[-1] = ':' + args[-1]

        # Return the parsed data
        return cmd, hostmask, tags, args
Exemplo n.º 3
0
 def _tags_to_dict(
         tag_list: Union[str, list[str]],
         separator: Optional[str] = ';') -> dict[str, Union[str, bool]]:
     if not separator:
         assert isinstance(tag_list, list)
         tag_list = ';'.join(map(lambda i: i.replace(';', '\\:'), tag_list))
     elif separator != ';':
         assert isinstance(tag_list, str)
         tag_list = tag_list.replace(';', '\\:').replace(separator, ';')
     cmd, hostmask, tags, args = miniirc.ircv3_message_parser(
         '@{} '.format(tag_list))
     return tags
Exemplo n.º 4
0
def ircv3_message_parser(
    msg: Union[str, bytes, bytearray],
    *,
    colon: bool = True
) -> tuple[str, Hostmask, dict[str, Union[str, bool]], list[str]]:
    """
    The same as miniirc.ircv3_message_parser, but also accepts bytes and
    bytearrays. The colon keyword argument works in the same way as the colon
    keyword argument on miniirc.Handler.

    Returns a 4-tuple: (command, hostmask, tags, args)
    """
    if isinstance(msg, (bytes, bytearray)):
        msg = msg.decode('utf-8', 'replace')

    if colon:
        return miniirc.ircv3_message_parser(msg)  # type: ignore

    command, hostmask, tags, args = miniirc.ircv3_message_parser(msg)
    if args and args[-1].startswith(':'):
        args[-1] = args[-1][1:]
    return command, hostmask, tags, args  # type: ignore
Exemplo n.º 5
0
    def _irc_quote_hack(self, *msg, force: Optional[bool] = None,
            tags: Optional[dict[str, Union[str, bool]]] = None) -> None:
        irc = self._irc
        if cap_name not in irc.active_caps:
            del irc.quote
            return irc.quote(*msg, force=force, tags=tags)
        cmd, hostmask, _, args_ = miniirc.ircv3_message_parser(' '.join(msg))
        args: list = args_

        if args and args[-1].startswith(':'):
            args[-1] = args[-1][1:]
        args.insert(0, cmd)
        if isinstance(tags, dict):
            args.insert(0, tags)

        rawmsg = json.dumps(args, separators=(',', ':'))
        utils.get_raw_socket(irc).sendall(rawmsg.encode('utf-8') + b'\r\n')