def test_splitDelimiters(self): """ Test that split() skips any delimiter (space or newline) that it finds at the very beginning of the string segment it is operating on. Nothing should be added to the output list because of it. """ r = irc.split("xx yyz", 2) self.assertEquals(['xx', 'yy', 'z'], r) r = irc.split("xx\nyyz", 2) self.assertEquals(['xx', 'yy', 'z'], r)
def msg(self, user, message, length=None): if not user.startswith('#'): fmt = 'PRIVMSG #jtv :/w %s ' % user else: fmt = 'PRIVMSG %s :' % (user, ) if length is None: length = self._safeMaximumLineLength(fmt) # Account for the line terminator. minimum_length = len(fmt) + 2 if length <= minimum_length: raise ValueError("Maximum length must exceed %d for message " "to %s" % (minimum_length, user)) for line in irc.split(message, length - minimum_length): self.sendLine(fmt + line)
def notice(self, user, message, length=None): if not message or not user: return fmt = 'NOTICE %s :' % (user,) if length is None: length = self._safeMaximumLineLength(fmt) # Account for the line terminator. minimumLength = len(fmt) + 2 if length <= minimumLength: raise ValueError("Maximum length must exceed %d for message " "to %s" % (minimumLength, user)) for line in irc.split(message, length - minimumLength): self.sendLine(fmt + line)
def testSplitSanity(self): # Whiteboxing self.assertRaises(ValueError, irc.split, 'foo', -1) self.assertRaises(ValueError, irc.split, 'foo', 0) self.assertEquals([], irc.split('', 1)) self.assertEquals([], irc.split(''))
def dispatch(self, msg, source, user=None, direct=False): if not isinstance(msg, list): msg = [msg] channels = dict() if direct and user: # Direct reply log.noise('Dispatching msg from {!r} directly to user: {!r}'.format(source, user)) channels[user] = msg else: try: route = self.routes[self.relays.get(source) or source] except KeyError: log.noise('No routes to dispatch message to, dropping: {!r}'.format(msg)) return # Pull msg through all the pipelines and build dst channels / msgs buffer for dst, pipe in route: msg_copy = list(msg) for name in pipe: relay = self.relays[name] results = yield defer.DeferredList(list( defer.maybeDeferred(relay.dispatch, part) for part in msg_copy )) msg_copy = set() for chk, result in results: if not chk: log.error( 'Detected pipeline failure (src: {}, dst: {}, pipe: {}, relay: {}, msg: {}): {}'\ .format(source, dst, pipe, name, msg_copy, result) ) elif isinstance(result, list): msg_copy.update(result) else: msg_copy.add(result) msg_copy = msg_copy.difference({None}) if not msg_copy: break else: if dst in self.relays: extra_kwz = dict() if isinstance(dst, types.StringTypes): dst = self.relays[dst] if user and 'source' in inspect.getargspec(dst.dispatch).args: extra_kwz['source'] = user log.noise('Delivering msgs to dst relay: {}, extra_kwz: {}'.format(dst, extra_kwz)) yield defer.DeferredList(list( defer.maybeDeferred(dst.dispatch, msg_copy, **extra_kwz) for msg_copy in msg_copy )) else: channels.setdefault(self.channels[dst].name, set()).update(msg_copy) # Check whether anything can be delivered to channels at all if not self.proto: log.warn( 'Failed to deliver message(s)' ' ({!r}) to the following channels: {}'.format(msg, channels) ) defer.returnValue(None) # Encode and deliver for channel, msg in channels.viewitems(): for msg in msg: if not isinstance(msg, types.StringTypes): log.warn('Dropping non-string message: {!r}'.format(msg)) continue if isinstance(msg, unicode): try: msg = msg.encode(self.irc_enc) except UnicodeEncodeError as err: log.warn('Failed to encode ({}) unicode msg ({!r}): {}'.format(self.irc_enc, msg, err)) msg = msg.encode(self.irc_enc, 'replace') max_len = min( self.max_line_length, self.proto._safeMaximumLineLength('PRIVMSG {} :'.format(channel)) - 2 ) first_line = True for line in irc.split(msg, length=max_len): if not first_line: line = ' {}'.format(line) if not self.dry_run: self.proto.msg(channel, line) else: log.info('IRC line (channel: {}): {}'.format(channel, line)) first_line = False