aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bot.py95
-rw-r--r--main.py41
2 files changed, 136 insertions, 0 deletions
diff --git a/bot.py b/bot.py
new file mode 100644
index 0000000..3a5e664
--- /dev/null
+++ b/bot.py
@@ -0,0 +1,95 @@
+import time
+import threading
+import irctk
+import random
+
+class Bot(threading.Thread):
+ host = 'tolkien.freenode.net'
+ port = 6697
+ ssl = True
+ password = None
+
+ def __init__(self, channel, threads, queue, name, rate, per):
+ threading.Thread.__init__(self)
+ self.threads = threads
+ self.queue = queue
+ self.name = name
+ self.channel = channel
+ # following for rate limiting:
+ self.rate = rate
+ self.per = per
+ self.last_check = time.time()
+ self.allowance = rate
+
+ self.log('starting up')
+ self.ready = False
+
+ self.client = irctk.Client(nickname=name, ident=name, realname=name, password=Bot.password)
+ self.client.delegate = self
+ self.client.connect(Bot.host, Bot.port, use_tls=Bot.ssl)
+
+ def irc_raw(self, client, line):
+ try:
+ self.log('IRC: ' + line)
+ except:
+ self.log('failed to log')
+ #pass
+
+ def log(self, line):
+ print "{} [{}] {}".format(time.strftime('%H:%M'), self.name, line)
+
+ def irc_registered(self, client):
+ self.log('joining ' + self.channel)
+ channel = client.add_channel(self.channel)
+ channel.join()
+
+ def irc_channel_join(self, client, nick, channel):
+ if str(nick) == str(client.get_nickname()):
+ self.log('im ready :)')
+ self.ready = True
+
+ def can_send(self):
+ current = time.time()
+ time_passed = current - self.last_check;
+ self.last_check = current
+ self.allowance += time_passed * (self.rate / self.per)
+
+ if self.allowance > self.rate:
+ self.allowance = self.rate
+
+ if self.allowance > 1.0:
+ self.allowance -= 1.0
+ return True
+
+ return False
+
+ def run(self):
+ self.log('run() called')
+
+ while True:
+ waiting = True
+ while waiting:
+ for thread in self.threads:
+ if not thread.ready:
+ waiting = True
+ break
+ else:
+ waiting = False
+
+ time.sleep(random.random())
+
+ # start flushing the queue
+ while self.can_send():
+ try:
+ line = self.queue.popleft()
+ self.client.send_line(
+ 'PRIVMSG ' + self.channel + ' :' + line
+ )
+ time.sleep(0.25)
+ except IndexError:
+ # end of queue
+ self.log('done working')
+ self.client.quit('bye bye')
+ return
+
+ time.sleep(0.1)
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..2b8a902
--- /dev/null
+++ b/main.py
@@ -0,0 +1,41 @@
+import sys
+import math
+import collections
+import zokket
+from bot import Bot
+
+botname_prefix = 'audzx'
+queue = collections.deque()
+rate = 5.0 # messages
+per = 8.0 # seconds
+max_workers = 6
+channel = '#test123aszz'
+
+if len(sys.argv) == 2:
+ channel = sys.argv[1]
+
+if channel[0] != '#':
+ channel = '#' + channel
+
+linecount = 0
+for line in sys.stdin:
+ queue.append(line.strip())
+ linecount += 1
+
+workers = int(math.ceil(linecount / rate))
+if workers > max_workers:
+ workers = max_workers
+
+if workers == 0:
+ sys.exit(1)
+
+print 'starting {} worker threads'.format(workers)
+threads = []
+for i in range(workers):
+ botname = botname_prefix + chr(97 + i)
+ threads.append(Bot(channel, threads, queue, botname, rate, per))
+
+for bot in threads:
+ bot.start()
+
+zokket.DefaultRunloop.run()