def lineReceived(self, line): line = irc_decode(irc.lowDequote(line)) try: prefix, command, params = irc.parsemsg(line) self.handleCommand(command, prefix, params) except irc.IRCBadMessage: # emit and ignore traceback.print_exc() return if self.__botIsEnable: database.client.write(self.__nickname, command + " " + (' '.join(params))) if command == "001": self.__nickname = params[0] if self.__perform is not None: for x in self.__perform: self.write(x) self.__perform = None elif command == "NICK": nick = prefix.split("!", 1)[0] if nick == self.__nickname: self.__nickname = params[0]
def lineReceived(self, line): """Called for every line received from the server.""" # The IRC spec does not specify a message encoding, meaning that some # messages may fail to decode into a UTF-8 string. While we must be # aware of the issue and choose to replace "invalid" characters (which # are technically valid per the IRC RFC, hence us warning about this # behavior), we must also ensure that the Twisted IRCClient's # implementation of lineReceived does not receive these characters, as # it will not replace them. try: line = line.decode('utf-8') except UnicodeDecodeError: self.logger.warning( "Stripping non-UTF-8 data from received line: {}".format(line)) line = line.decode('utf-8', 'replace') # Log raw output self.irc_logger.info(line) # Log if the command received is in the error range _, command, _ = irc.parsemsg(line) if command.isnumeric() and 400 <= int(command) <= 599: self.logger.warning( "Received an error from the server: {}".format(line)) self.event_manager.fire("irc.raw", command, line) # Send IRCClient the version of the line that has had non-UTF-8 # characters replaced. # # Bug: https://twistedmatrix.com/trac/ticket/9443 super().lineReceived(line.encode('utf-8'))
def parse(self, connection, outgoing, raw, **kwargs): """Parse a raw IRC message string and return a corresponding `.Message` object. Any keyword arguments override field values returned by the parser.""" try: prefix, command, params = parsemsg(raw) except IndexError: parsed_kwargs = {'action': 'unknown'} else: parsed_kwargs = {'actor': Hostmask.from_string(prefix)} if command in self.functions: try: parsed_kwargs['action'] = command.lower() parsed_kwargs.update( self.functions[command](command, params)) except IndexError: del parsed_kwargs['action'] if 'action' not in parsed_kwargs: parsed_kwargs['action'] = 'unknown' parsed_kwargs['subaction'] = command splits = 2 if raw.startswith(':') else 1 params = raw.split(None, splits) if len(params) > splits: parsed_kwargs['content'] = params[splits] else: parsed_kwargs['content'] = '' parsed_kwargs.update(kwargs) return Message(connection, outgoing, raw=raw, **parsed_kwargs)
def lineReceived(self, line): line = irc_decode(irc.lowDequote(line)) try: prefix, command, params = irc.parsemsg(line) self.handleCommand(command, prefix, params) except irc.IRCBadMessage: # emit and ignore traceback.print_exc() return if self.__botIsEnable: database.client.write( self.__nickname, command + " "+(' '.join(params)) ) if command == "001": self.__nickname = params[0] if self.__perform is not None: for x in self.__perform: self.write(x) self.__perform = None elif command == "NICK": nick = prefix.split("!", 1)[0] if nick == self.__nickname: self.__nickname = params[0]
def response(self): """ Grabs our responses and then clears the transport """ response = self.ircUser.transport.value() self.ircUser.transport.clear() if bytes != str and isinstance(response, bytes): response = response.decode("utf-8") response = response.splitlines() return [irc.parsemsg(r) for r in response]
def lineReceived(self, line): irc.IRCClient.lineReceived(self, line) print line prefix, command, params = irc.parsemsg(line) if command == "ERROR": if params and params[0].find("too fast") != -1: print "Client trying to reconnect too fast."
def lineReceived(self, line): line = irc.lowDequote(line).decode(self.config['charset'], 'replace') try: prefix, command, params = irc.parsemsg(line) if command in irc.numeric_to_symbolic: parsedcmd = irc.numeric_to_symbolic[command] else: parsedcmd = command self.handleCommand(parsedcmd, prefix, params) if self._registered: self.event_raw(command, prefix, params) except irc.IRCBadMessage: self.badMessage(line, *sys.exc_info())
def lineReceived(self, line): """ Override IRCClient.lineReceived() to properly decode bytes to unicode and ignore errors. """ if isinstance(line, bytes): line = line.decode("utf-8", errors="ignore") line = lowDequote(line) try: prefix, command, params = parsemsg(line) if command in numeric_to_symbolic: command = numeric_to_symbolic[command] self.handleCommand(command, prefix, params) except IRCBadMessage: self.badMessage(line, *sys.exc_info())
def lineReceived(self, line): # use instead of query line = irc.lowDequote(line) try: prefix, command, params = irc.parsemsg(line) if irc.numeric_to_symbolic.has_key(command): command = irc.numeric_to_symbolic[command] self.handleCommand(command, prefix, params) except irc.IRCBadMessage: self.badMessage(line, *sys.exc_info()) try: if command == "RPL_NAMREPLY": names = params[3].split() for name in names: if name.startswith("@"): self.ops.append(name[1:]) except: self.logger.error(traceback.format_exc())
def lineReceived(self, line): line_str = line.decode('utf-8') # self.log.debug(line_str) if line_str.startswith('@'): tags = line_str[1:].split(':')[0].split(' ')[0].split(';') tags = dict(t.split('=') for t in tags) line_str = ':' + line_str.split(' :', 1)[1] # noinspection PyTypeChecker prefix, cmd, args = irc.parsemsg(line_str) if cmd == "PRIVMSG": self.privmsg(prefix, args[0], args[1], tags) elif cmd == "WHISPER": self.privmsg(prefix, args[0], args[1], tags) elif cmd == "USERSTATE": self.log.info('USERSTATE: %s' % str(tags)) elif cmd == "ROOMSTATE": self.log.info('ROOMSTATE: %s' % str(tags)) elif cmd == "USERNOTICE": if len(args) == 2: self.log.info( 'User %s has resubscribed to the channel!: %s' % (tags['login'], args[1])) else: self.log.info('User %s has resubscribed to the channel!' % tags['login']) elif cmd == "HOSTTARGET": if args[1].split(' ')[0] == "-": self.log.info('Exited host mode in %s.' % args[0]) else: self.log.info('%s now hosting %s with %s viewers.' % (args[0], args[1], args[2])) elif cmd == "CLEARCHAT": if len(args) == 1: self.log.info('Chat has been cleared in %s!' % args[0]) elif len(args) == 2: self.log.info('User %s has been banned from the chat.' % args[1]) elif cmd == "RECONNECT": # TODO: Implement logic to reconnect and rejoin eventually self.log.warning( 'Received reconnect notice from the Twitch server!') elif cmd == "NOTICE": # TODO: Finish implementing this for logging purposes pass else: irc.IRCClient.lineReceived(self, line)
def lineReceived(self, line): global total_channels, joined_channels, number_of_total_channels, total_channels_flag if bytes != str and isinstance(line, bytes): # decode bytes from transport to unicode #line = line.decode('utf-8', 'backslashreplace') line = line.decode('utf-8', 'ignore') line = irc.lowDequote(line) try: prefix, command, params = irc.parsemsg(line) all_params = ''.join([p for p in params]).lower() # too many channels # if '405' in command: # if 'You have joined too many channels' in params[2]: # print('Total channels before restrict: ' + str(joined_channels)) ### skip not interesting messages # to_skip = set(['372', '332', '353', '322', 'PRIVMSG', 'QUIT']) # to_skip = set(['353', '322', 'PRIVMSG']) to_skip = set(['']) if (command not in to_skip) or (FULL_LOG == 1): print('prefix: {}, command: {}, params: {}'.format(prefix, command, params)) ### SASL auth if requiered if 'CAP' in command: print('CAP') if 'ack' in all_params: self.sendLine('AUTHENTICATE PLAIN') print('AUTHENTICATE PLAIN') if 'ls' in all_params: print('ls') if 'sasl' in all_params: print('sasl') self.sendLine('CAP REQ :sasl') print('CAP REQ :sasl') if 'AUTHENTICATE' in command: if '+' in params[0]: self.auth_with_SASL() if '903' in command: self.identified = True return ### ERROR if 'error' in command.lower(): if 'too fast' in params[0]: self.logger.log('[{}: An error occured: {}]'.format( self.nickname, params[0] )) time.sleep(10) if '4' in str(command)[0]: self.logger.log('[{}: An error occured: {}]'.format( self.nickname, ' '.join([s for s in params]) )) ### 353: users in channel # if '353' in command: # if self.nickname in params[3]: # self.joined(params[2]) # return ### 433: Nickname is already in use if '433' in command: self.setNick(get_random_nick()) ### irc.cyberarmy.net need to pause 60 sec to request /LIST if 'you cannot list within the first' in ''.join([p for p in params]).lower(): time.sleep(60) self.sendLine('LIST') ### total joined channels if '319' in command: joined_channels += params[2] if '318' in command: self.logger.log('[{}: joined channels at this time: {} of all {}]'.format( self.nickname, len(joined_channels.split(' '))-1, number_of_total_channels )) ### signed on server signed_commands = ['903', '376', '422'] if command in signed_commands: if not self.bot_signed: self.signedOn() return #### total channels on server if '322' in command: # params[1] - channel name, params[2] - number of users # print(command) try: if int(params[-2]) >= MINIMUM_USERS: if MAXIMUM_USERS: if int(params[-2]) <= MAXIMUM_USERS: total_channels.append(params[1]) else: total_channels.append(params[1]) except: print ('Channel %s have unformatted number of users' % params[1]) # if 'End of /LIST' in params: if '323' in command: # total_channels = self.channels.copy() number_of_total_channels = len(total_channels) total_channels_flag = True self.logger.log('[Summary channels to join: {}]'.format(len(total_channels))) if command in irc.numeric_to_symbolic: command = irc.numeric_to_symbolic[command] else: self.handleCommand(command, prefix, params) ### Identifiend identified_list = ['You are now logged', 'You are now identified', 'There are already', 'No such nick'] if (len(params) > 0) and (self.nickname == params[0]): for i in identified_list: if i.lower() in all_params: ### Server may have limit for nick identified in one account ### and we need to try to get all others channels without make identified self.identified = True ### joining channels if self.write_time and len(self.channels) > 0: delta = datetime.now() - self.write_time if int(delta.total_seconds()) > 5: self.join_channels() except irc.IRCBadMessage: print(line) self.badMessage(line, *sys.exc_info())
def lineReceived(self, line): line = irc_decode(irc.lowDequote(line)) try: prefix, command, params = irc.parsemsg(line) self.handleCommand(command, prefix, params) except irc.IRCBadMessage: # emit and ignore traceback.print_exc() return if command == "CAP": if (self.registered): return # We're performing CAP negotiation. # We're receiving the list. Wait until its complete, then request what # we want. if (params[1] == "LS"): if (self.saslauth): return if (params[2] == "*"): self.cap.extend(params[3].split(" ")) else: self.cap.extend(params[2].split(" ")) reqlist = [] if ("multi-prefix" in self.cap): reqlist.append("multi-prefix") if ("sasl" in self.cap): if (self.authUser and self.authSecret): self.saslauth = True reqlist.append("sasl") if (reqlist): self.write("CAP REQ :" + ' '.join(reqlist)) self.cap = reqlist else: self.write("CAP END") # We're receiving acknowledgement of requested features. Handle it. # Once all acknowledgements are received, end CAP is SASL is not # underway. if "ACK" in params: if "sasl" in params[-1].split(" "): if (self.authUser and self.authSecret): self.write("AUTHENTICATE " + config.atheme["sasl_type"]) self.saslauth = True if (not self.saslauth): self.write("CAP END") # We're receiving negative acknowledgement; a feature upgrade was denied. # Once all acknowledgements are received, end CAP is SASL is not # underway. if (params[1] == "NACK"): for item in params[2].split(" "): self.cap.remove(item) if (not self.saslauth): self.write("CAP END") # Handle SASL authentication requests. if (command == "AUTHENTICATE"): if (not self.saslauth): return # We're performing SASL auth. Send them our authcookie. authtext = base64.b64encode('\0'.join( [self.authUser, self.authUser, self.authSecret])) while (len(authtext) >= 400): self.write("AUTHENTICATE " + authtext[0:400]) authtext = authtext[400:] if (len(authtext) != 0): self.write("AUTHENTICATE " + authtext) else: self.write("AUTHENTICATE +") # Handle SASL result messages. # End CAP after one of these, unless an acknowledgement message is still # waiting. if (command in ["903", "904", "905", "906", "907"]): if (self.saslauth): self.saslauth = False if (not self.saslauth): self.write("CAP END") if command == "001": self.registered = True self.__nickname = params[0] if self.__perform is not None: for x in self.__perform: self.write(x) self.__perform = None elif command == "NICK": nick = prefix.split("!", 1)[0] if nick == self.__nickname: self.__nickname = params[0]
def init_linestr(self, linestr): self.linestr = linestr # parse the line into a normalized form self.prefix, self.cmd, self.args = irc.parsemsg(linestr) if self.prefix == '': self.prefix = None self.cmd = self.cmd.upper()
def lineReceived(self, line): line = irc_decode(irc.lowDequote(line)) try: prefix, command, params = irc.parsemsg(line) self.handleCommand(command, prefix, params) except irc.IRCBadMessage: # emit and ignore traceback.print_exc() return if command == "CAP": if (self.registered): return # We're performing CAP negotiation. # We're receiving the list. Wait until its complete, then request what # we want. if (params[1] == "LS"): if (self.saslauth): return if (params[2] == "*"): self.cap.extend(params[3].split(" ")) else: self.cap.extend(params[2].split(" ")) reqlist = [] if ("multi-prefix" in self.cap): reqlist.append("multi-prefix") if ("sasl" in self.cap): if (self.authUser and self.authSecret): self.saslauth = True reqlist.append("sasl") if (reqlist): self.write("CAP REQ :" + ' '.join(reqlist)) self.cap = reqlist else: self.write("CAP END") # We're receiving acknowledgement of requested features. Handle it. # Once all acknowledgements are received, end CAP is SASL is not # underway. if "ACK" in params: if "sasl" in params[-1].split(" "): if (self.authUser and self.authSecret): self.write("AUTHENTICATE "+config.atheme["sasl_type"]) self.saslauth = True if (not self.saslauth): self.write("CAP END") # We're receiving negative acknowledgement; a feature upgrade was denied. # Once all acknowledgements are received, end CAP is SASL is not # underway. if (params[1] == "NAK"): for item in params[2].split(" "): self.cap.remove(item) if (not self.saslauth): self.write("CAP END") # Handle SASL authentication requests. if (command == "AUTHENTICATE"): if (not self.saslauth): return # We're performing SASL auth. Send them our authcookie. authtext = base64.b64encode('\0'.join([self.authUser, self.authUser, self.authSecret])) while (len(authtext) >= 400): self.write("AUTHENTICATE " + authtext[0:400]) authtext = authtext[400:] if (len(authtext) != 0): self.write("AUTHENTICATE " + authtext) else: self.write("AUTHENTICATE +") # Handle SASL result messages. # End CAP after one of these, unless an acknowledgement message is still # waiting. if (command in ["903", "904", "905","906","907"]): if (self.saslauth): self.saslauth = False if (not self.saslauth): self.write("CAP END") if command == "001": f = self.factory.ircinit self.write("NS IDENTIFY %s %s" % (f["nick"], f["pass"])) self.registered = True self.__nickname = params[0] if self.__perform is not None: for x in self.__perform: self.write(x) self.__perform = None elif command == "NICK": nick = prefix.split("!", 1)[0] if nick == self.__nickname: self.__nickname = params[0]