diff --git a/bot.py b/bot.py index c1df71f..7589fc7 100644 --- a/bot.py +++ b/bot.py @@ -6,9 +6,6 @@ from threading import Thread import ConfigParser # Some basic variables used to configure the bot. -server = "irc.freenode.net" -channel = "#openhatch" # Please use #openhatch-bots rather than #openhatch for testing -botnick = "WelcomeBot" channel_greeters = ['shauna', 'paulproteus', 'marktraceur'] hello_list = [r'hello', r'hi', r'hey', r'yo', r'sup'] help_list = [r'help', r'info', r'faq', r'explain yourself'] @@ -21,7 +18,8 @@ help_list = [r'help', r'info', r'faq', r'explain yourself'] # Defines a bot class Bot(object): - def __init__(self, nick_source='nicks.csv', wait_time=60): + def __init__(self, botnick, nick_source='nicks.csv', wait_time=60): + self.botnick = botnick self.nick_source = nick_source self.wait_time = wait_time self.known_nicks = [] @@ -31,8 +29,8 @@ class Bot(object): row = clean_nick(row[0]) # Sends nicks to remove unnecessary decorators. Hacked to deal with list-of-string format. :( self.known_nicks.append([row]) self.newcomers = [] - self.hello_regex = re.compile(get_regex(hello_list), re.I) # Regexed version of hello list - self.help_regex = re.compile(get_regex(help_list), re.I) # Regexed version of help list + self.hello_regex = re.compile(get_regex(hello_list, self.botnick), re.I) # Regexed version of hello list + self.help_regex = re.compile(get_regex(help_list, self.botnick), re.I) # Regexed version of help list # Adds the current newcomer's nick to nicks.csv and known_nicks. def add_known_nick(self,new_known_nick): @@ -59,7 +57,7 @@ class NewComer(object): ### Startup Functions ### ######################### -# Parse configuration file and load settings +# Parse configuration file and return settings dictionary def parsesettings(): parser = ConfigParser.ConfigParser() parser.read("settings.ini") @@ -68,26 +66,16 @@ def parsesettings(): for option in parser.options(section): settings[option] = parser.get(section, option) - # Needs to be a cleaner way to do this - global channel - global botnick - global server - global channel_greeter - global hello_list - global help_lis - - channel = settings["channel"] - botnick = settings["botnick"] - server = settings["server"] + return settings # Creates a socket that will be used to send and receive messages, # then connects the socket to an IRC server and joins the channel. -def irc_start(): # pragma: no cover (this excludes this function from testing) +def irc_start(server): # pragma: no cover (this excludes this function from testing) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock.connect((server, 6667)) # Here we connect to server using port 6667. return ircsock -def join_irc(ircsock): +def join_irc(ircsock, botnick, channel): ircsock.send("USER {0} {0} {0} :This is http://openhatch.org/'s greeter bot" ".\n".format(botnick)) # bot authentication ircsock.send("NICK {}\n".format(botnick)) # Assign the nick to the bot. @@ -102,7 +90,7 @@ def msg_handler(ircsock): # pragma: no cover (this excludes this function from return new_msg # Called by bot on startup. Builds a regex that matches one of the options + (space) botnick. -def get_regex(options): +def get_regex(options, botnick): pattern = "(" for s in options: pattern += s @@ -117,7 +105,7 @@ def get_regex(options): ######################### # Welcomes the "person" passed to it. -def welcome_nick(newcomer, ircsock): +def welcome_nick(newcomer, ircsock, channel): ircsock.send("PRIVMSG {0} :Welcome {1}! The channel is pretty quiet " "right now, so I thought I'd say hello, and ping some people " "(like {2}) that you're here. If no one responds for a " @@ -127,10 +115,10 @@ def welcome_nick(newcomer, ircsock): "\n".format(channel, newcomer, greeter_string("and", channel_greeters))) # Checks and manages the status of newcomers. -def process_newcomers(bot, newcomerlist, ircsock, welcome=1): +def process_newcomers(bot, newcomerlist, ircsock, welcome=1, channel): for person in newcomerlist: if welcome == 1: - welcome_nick(person.nick, ircsock) + welcome_nick(person.nick, ircsock, channel) bot.add_known_nick(person.nick) bot.newcomers.remove(person) @@ -154,11 +142,11 @@ def clean_nick(actor): return actor # Parses messages and responds to them appropriately. -def message_response(bot, ircmsg, actor, ircsock): +def message_response(bot, ircmsg, actor, ircsock, channel): # if someone other than a newcomer speaks into the channel if ircmsg.find("PRIVMSG " + channel) != -1 and actor not in [i.nick for i in bot.newcomers]: - process_newcomers(bot,bot.newcomers, ircsock, welcome=0) # Process/check newcomers without welcoming them + process_newcomers(bot,bot.newcomers, ircsock, welcome=0, channel) # Process/check newcomers without welcoming them # if someone (other than the bot) joins the channel if ircmsg.find("JOIN " + channel) != -1 and actor != botnick: @@ -178,15 +166,15 @@ def message_response(bot, ircmsg, actor, ircsock): bot.newcomers.remove(i) # remove them from the list # If someone talks to (or refers to) the bot. - if botnick.lower() and "PRIVMSG".lower() in ircmsg.lower(): + if bot.botnick.lower() and "PRIVMSG".lower() in ircmsg.lower(): if bot.hello_regex.search(ircmsg): - bot_hello(random.choice(hello_list), actor, ircsock) + bot_hello(random.choice(hello_list), actor, ircsock, channel) if bot.help_regex.search(ircmsg): - bot_help(ircsock) + bot_help(ircsock, channel) # If someone tries to change the wait time... - if ircmsg.find(botnick + " --wait-time ") != -1: - bot.wait_time = wait_time_change(actor, ircmsg, ircsock) # call this to check and change it + if ircmsg.find(bot.botnick + " --wait-time ") != -1: + bot.wait_time = wait_time_change(actor, ircmsg, ircsock, channel) # call this to check and change it # If the server pings us then we've got to respond! if ircmsg.find("PING :") != -1: @@ -198,11 +186,11 @@ def message_response(bot, ircmsg, actor, ircsock): ############################################################# # Responds to a user that inputs "Hello Mybot". -def bot_hello(greeting, actor, ircsock): +def bot_hello(greeting, actor, ircsock, channel): ircsock.send("PRIVMSG {0} :{1} {2}\n".format(channel, greeting, actor)) # Explains what the bot is when queried. -def bot_help(ircsock): +def bot_help(ircsock, channel): ircsock.send("PRIVMSG {} :I'm a bot! I'm from here . You can change my behavior by " "submitting a pull request or by talking to shauna" @@ -223,7 +211,7 @@ def greeter_string(conjunction, greeters): return greeterstring # Changes the wait time from the channel. -def wait_time_change(actor, ircmsg, ircsock): +def wait_time_change(actor, ircmsg, ircsock, channel): for admin in channel_greeters: if actor == admin: finder = re.search(r'\d\d*', re.search(r'--wait-time \d\d*', ircmsg) @@ -245,10 +233,10 @@ def pong(ircsock): ########################## def main(): - parsesettings() - ircsock = irc_start() - join_irc(ircsock) - WelcomeBot = Bot() + settings = parsesettings() + ircsock = irc_start(settings["server"]) + join_irc(ircsock, settings["botnick"], settings["channel"]) + WelcomeBot = Bot(settings["botnick"]) while 1: # Loop forever ready_to_read, b, c = select.select([ircsock],[],[], 1) # b&c are ignored here process_newcomers(WelcomeBot, [i for i in WelcomeBot.newcomers if i.around_for() > WelcomeBot.wait_time],ircsock) @@ -256,7 +244,7 @@ def main(): ircmsg = msg_handler(ircsock) # gets message from ircsock ircmsg, actor = parse_messages(ircmsg) # parses it or returns None if ircmsg is not None: # If we were able to parse it - message_response(WelcomeBot, ircmsg, actor, ircsock) # Respond to the parsed message + message_response(WelcomeBot, ircmsg, actor, ircsock, settings["channel"]) # Respond to the parsed message if __name__ == "__main__": # This line tells the interpreter to only execute main() if the program is being run, not imported. sys.exit(main())