Kellobotti

This commit is contained in:
Juhani Krekelä 2020-04-24 03:26:16 +03:00
parent 635cab7440
commit beafa34b54
3 changed files with 82 additions and 11 deletions

View File

@ -1,14 +1,13 @@
o3-base
=======
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.
Posts a Unicode clock emoji corresponding to the current time twice an hour.
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`.
Copy `bot.conf.example` to `bot.conf` and run `python3 ircbot.py` to bring
up the bot.
Edit `bot.conf` to configure the bot.
License
-------

View File

@ -1,7 +1,7 @@
[server]
host = irc.freenode.net
port = 6667
nick = o3-base
username = o3-base
realname = IRC bot based on o3-base
nick = kellobotti
username = kellobotti
realname = Tick tock
channels = ##ingsoc

View File

@ -1,3 +1,74 @@
import datetime
import select
import threading
import channel
commchan = None
commchan_lock = threading.Lock()
class Clock(threading.Thread):
def __init__(self, irc, commchan):
self.irc = irc
self.commchan = commchan
threading.Thread.__init__(self)
def send_time(self, hour, half_past):
# Convert to 12h clock
hour = hour % 12
# Deal with the fact that unicode has 1…12
if hour == 0: hour = 12
clockface = chr(0x1F550 - 1 + hour + (12 if half_past else 0))
for chan in self.irc.get_channels():
self.irc.bot_response(chan, clockface)
def run(self):
poll = select.poll()
poll.register(self.commchan, select.POLLIN)
last_hour = None
last_half_past = None
quit = False
while not quit:
now = datetime.datetime.now()
half_past = now.minute >= 30
if last_hour != now.hour or last_half_past != half_past:
self.send_time(now.hour, half_past)
last_hour = now.hour
last_half_past = half_past
# Set poll timeout to when we next need to wake up
timeout = ((30 - now.minute % 30) * 60 - now.second) * 1000 - now.microsecond // 1000
for fd, event in poll.poll(timeout):
if fd == self.commchan.fileno():
comm = self.commchan.recv()
if comm == 'quit':
quit = True
self.commchan.close()
def stop_clock():
global commchan, commchan_lock
with commchan_lock:
if commchan is None:
return
else:
commchan.send('quit')
commchan = None
def start_clock(irc):
global commchan, commchan_lock
with commchan_lock:
if commchan is not None:
return
else:
commchan = channel.Channel()
Clock(irc, commchan).start()
# initialize(*, config)
# Called to initialize the IRC bot
# Runs before even logger is brought up, and blocks further bringup until it's done
@ -11,14 +82,15 @@ def initialize(*, config):
# Blocks the bot until it's done, including PING/PONG handling
# irc is the IRC API object
def on_connect(*, irc):
...
stop_clock()
start_clock(irc)
# on_quit(*, irc)
# Called just before IRC bot sends QUIT
# Blocks the bot until it's done, including PING/PONG handling
# irc is the IRC API object
def on_quit(*, irc):
...
stop_clock()
# handle_message(*, prefix, message, nick, channel, irc)
# Called for PRIVMSGs.