From 002f1eecf89a8a2c9f90a66d6950ab4e9a89bf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Wed, 3 Jan 2018 18:08:24 +0200 Subject: [PATCH] Read config from a configuration file --- .gitignore | 1 + README.md | 6 ++++++ bot.conf.example | 7 +++++++ botcmd.py | 7 +++++-- ircbot.py | 31 ++++++++++++++++++++++++------- 5 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 bot.conf.example diff --git a/.gitignore b/.gitignore index 15c993e..5b91b8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ *.pyc *.swp +bot.conf diff --git a/README.md b/README.md index 7871387..b83dcc5 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ This project seeks to replace o2-base as an easy python base to build IRC bots on. It is not related to the failed oonbotti3 project, but is rather based on the IRC bot framework of HynneFlip. +Setup +===== +Copy `bot.conf.example` to `bot.conf` and run `python3 ircbot.py` to bring up +the bot skeleton, which can be used as a very quick and dirty IRC client. User +code goes in `botcmd.py`. + License ------- Everything in this repo is under UNLICENSE / CC0. diff --git a/bot.conf.example b/bot.conf.example new file mode 100644 index 0000000..accc678 --- /dev/null +++ b/bot.conf.example @@ -0,0 +1,7 @@ +[server] +host = irc.freenode.net +port = 6667 +nick = o3-base +username = o3-base +realname = IRC bot based on o3-base +channels = ##ingsoc diff --git a/botcmd.py b/botcmd.py index aadc318..ce409f2 100644 --- a/botcmd.py +++ b/botcmd.py @@ -1,12 +1,14 @@ -# initialize() +# initialize(*, config) # Called to initialize the IRC bot # Runs before even logger is brought up, and blocks further bringup until it's done -def initialize(): +# config is a configpatser.ConfigParser object containig contents of bot.conf +def initialize(*, config): ... # on_connect(*, irc) # Called after IRC bot has connected and sent the USER/NICk commands but not yet attempted anything else # Blocks the bot until it's done, including PING/PONG handling +# irc is the IRC API object def on_connect(*, irc): ... @@ -26,6 +28,7 @@ def handle_message(*, prefix, message, nick, channel, irc): # prefix is the prefix at the start of the message, without the leading ':' # command is the command or number code # arguments is rest of the arguments of the command, represented as a list. ':'-arguments are handled automatically +# irc is the IRC API object # All strings are bytestrings or bytearrays def handle_nonmessage(*, prefix, command, arguments, irc): ... diff --git a/ircbot.py b/ircbot.py index ed2f7cf..bfbeae2 100644 --- a/ircbot.py +++ b/ircbot.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import configparser import select import socket import threading @@ -12,7 +13,7 @@ import botcmd import cron import line_handling -Server = namedtuple('Server', ['host', 'port', 'nick', 'realname', 'channels']) +Server = namedtuple('Server', ['host', 'port', 'nick', 'username', 'realname', 'channels']) class LoggerThread(threading.Thread): def __init__(self, logging_channel, dead_notify_channel): @@ -284,7 +285,7 @@ class ServerThread(threading.Thread): try: # Run initialization - self.send_line_raw(b'USER HynneFlip a a :' + self.server.realname.encode('utf-8')) + self.send_line_raw(b'USER %s a a :%s' % (self.server.username.encode('utf-8'), self.server.realname.encode('utf-8'))) # Set up nick self.api.nick(self.server.nick.encode('utf-8')) @@ -304,7 +305,7 @@ class ServerThread(threading.Thread): if not reconnecting: # Tell the server we're quiting - self.send_line_raw(b'QUIT :HynneFlip exiting normally') + self.send_line_raw(b'QUIT :%s exiting normally' % self.server.username.encode('utf-8')) self.server_socket.close() break @@ -341,11 +342,27 @@ def spawn_loggerthread(): LoggerThread(logging_channel, dead_notify_channel).start() return logging_channel, dead_notify_channel -if __name__ == '__main__': - # TODO: read from a configuration file - server = Server(host = 'irc.freenode.net', port = 6667, nick = 'o3-base', realname = 'IRC bot based on o3-base', channels = ['##ingsoc']) +# read_config() → config, server +# Reads the configuration file and returns the configuration object as well as a server object for spawn_serverthread +def read_config(): + config = configparser.ConfigParser() + config.read('bot.conf') - botcmd.initialize() + host = config['server']['host'] + port = int(config['server']['port']) + nick = config['server']['nick'] + username = config['server']['username'] + realname = config['server']['realname'] + channels = config['server']['channels'].split() + + server = Server(host = host, port = port, nick = nick, username = username, realname = realname, channels = channels) + + return config, server + +if __name__ == '__main__': + config, server = read_config() + + botcmd.initialize(config = config) cron_control_channel = cron.start() logging_channel, dead_notify_channel = spawn_loggerthread()