From dcf694d5d01f400524b33a87753fb25d0bb83ab8 Mon Sep 17 00:00:00 2001 From: ngharo Date: Thu, 14 Sep 2017 15:42:02 -0500 Subject: Working cut for bots that connect to Freenode --- bot.py | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 41 ++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 bot.py create mode 100644 main.py 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() -- cgit v1.2.3