diff --git a/Module.py b/Module.py index 16070d8..e2bccff 100644 --- a/Module.py +++ b/Module.py @@ -32,11 +32,6 @@ class Module(object): def priority(self): return 50 - def timer_interval(self): - """Run a timer-based event every N seconds (0 to disable).""" - - return 0 - def __init__(self, irc, config, server): """Construct a feature module. Inheritors can do special things here, but should be sure to call Module.__init__. @@ -62,10 +57,6 @@ class Module(object): # set up database for this module self.db_init() - # register the timer, if the implementing module has one - if self.timer_interval() > 0: - Timer(self.timer_interval(), self.timer_bootstrap, ()).start() - # print what was loaded, for debugging print("loaded " + self.__class__.__name__) @@ -242,26 +233,6 @@ class Module(object): print("looks like someone forgot to implement do!") - def timer_bootstrap(self): - """Run a thread that does something periodically. - - This only has real functionality if timer_interval() is - defined to return non-zero. - """ - - # don't actually do stuff if, since the last timer registration, - # the interval was set to 0 - if self.timer_interval() > 0 and self.is_shutdown == False: - self.timer_do() - - if self.timer_interval() > 0 and self.is_shutdown == False: - Timer(self.timer_interval(), self.timer_bootstrap, ()).start() - - def timer_do(self): - """If we're invoking the timer, do something (that you should implement).""" - - print("looks like someone forgot to implement timer_do!") - def help_description(self): """Return a quick list of commands or other summary, should be less than two lines. If you want the module hidden from "!help", diff --git a/modules/Markov.py b/modules/Markov.py index 7187b35..a0fa7c1 100644 --- a/modules/Markov.py +++ b/modules/Markov.py @@ -23,6 +23,8 @@ import random import re import sqlite3 import sys +import thread +import time from dateutil.parser import * from dateutil.relativedelta import * @@ -42,10 +44,6 @@ class Markov(Module): http://code.activestate.com/recipes/194364-the-markov-chain-algorithm/ """ - def timer_interval(self): - """Do various conversation scoring and infinite reply checks.""" - return 30 - def __init__(self, irc, config, server): """Create the Markov chainer, and learn text from a file if available.""" @@ -69,6 +67,9 @@ class Markov(Module): Module.__init__(self, irc, config, server) + self.next_shut_up_check = 0 + thread.start_new_thread(self.thread_do, ()) + def db_init(self): """Create the markov chain table.""" @@ -280,30 +281,34 @@ class Markov(Module): self.lines_seen.append(('.self.said.', datetime.now())) return self._generate_line(target, min_size=min_size, max_size=max_size) - def timer_do(self): + def thread_do(self): """Do various things.""" - self._do_shut_up_checks() + while not self.is_shutdown: + self._do_shut_up_checks() + time.sleep(1) def _do_shut_up_checks(self): """Check to see if we've been talking too much, and shut up if so.""" - self.shut_up = False + if self.next_shut_up_check < time.time(): + self.shut_up = False + self.next_shut_up_check = time.time() + 30 - last_30_sec_lines = [] + last_30_sec_lines = [] - for (nick,then) in self.lines_seen: - rdelta = relativedelta(datetime.now(), then) - if rdelta.years == 0 and rdelta.months == 0 and rdelta.days == 0 and rdelta.hours == 0 and rdelta.minutes == 0 and rdelta.seconds <= 29: - last_30_sec_lines.append((nick,then)) + for (nick,then) in self.lines_seen: + rdelta = relativedelta(datetime.now(), then) + if rdelta.years == 0 and rdelta.months == 0 and rdelta.days == 0 and rdelta.hours == 0 and rdelta.minutes == 0 and rdelta.seconds <= 29: + last_30_sec_lines.append((nick,then)) - if len(last_30_sec_lines) >= 15: - lines_i_said = len(filter(lambda (a,b): a == '.self.said.', last_30_sec_lines)) - if lines_i_said >= 8: - self.shut_up = True - targets = self._get_chatter_targets() - for t in targets: - self.sendmsg(self.connection, t, 'shutting up for 30 seconds due to last 30 seconds of activity') + if len(last_30_sec_lines) >= 15: + lines_i_said = len(filter(lambda (a,b): a == '.self.said.', last_30_sec_lines)) + if lines_i_said >= 8: + self.shut_up = True + targets = self._get_chatter_targets() + for t in targets: + self.sendmsg(self.connection, t, 'shutting up for 30 seconds due to last 30 seconds of activity') def _learn_line(self, line, target): """Create Markov chains from the provided line.""" diff --git a/modules/Twitter.py b/modules/Twitter.py index 38c204f..d80c1d5 100644 --- a/modules/Twitter.py +++ b/modules/Twitter.py @@ -20,7 +20,8 @@ from ConfigParser import NoSectionError, NoOptionError import oauth2 as oauth import re import sqlite3 -from threading import Timer +import thread +import time import urlparse from extlib import irclib @@ -32,11 +33,6 @@ class Twitter(Module): """Access Twitter via the bot as an authenticated client.""" - def timer_interval(self): - """Check for twitter updates every 300 seconds.""" - - return 300 - def __init__(self, irc, config, server): """Prepare for oauth stuff (but don't execute it yet).""" @@ -72,6 +68,9 @@ class Twitter(Module): self.twit = twitter.Api() self.authed = False + self.next_timeline_check = 0 + thread.start_new_thread(self.thread_do, ()) + def db_init(self): """Set up the settings table.""" @@ -239,39 +238,45 @@ class Twitter(Module): return 'The bot is now logged in.' - def timer_do(self): + def thread_do(self): """Check the timeline.""" - self._check_self_timeline() + + while not self.is_shutdown: + self._check_self_timeline() + time.sleep(1) def _check_self_timeline(self): """Check my timeline, and if there are entries, print them to the channel.""" - if self.authed: - # get the id of the last check we made - since_id = self._get_last_since_id() - output_channel = self._get_output_channel() + if self.next_timeline_check < time.time(): + self.next_timeline_check = time.time() + 300 - if since_id is not None and output_channel != '': - tweets = self.twit.GetFriendsTimeline(since_id=since_id) - tweets.reverse() - for tweet in tweets: - tweet_text = self._return_tweet_or_retweet_text(tweet=tweet, print_source=True) - self.sendmsg(self.connection, output_channel.encode('utf-8', 'ignore'), tweet_text) + if self.authed: + # get the id of the last check we made + since_id = self._get_last_since_id() + output_channel = self._get_output_channel() - # friends timeline printed, find the latest id - new_since_id = self._get_latest_tweet_id(tweets, since_id) + if since_id is not None and output_channel != '': + tweets = self.twit.GetFriendsTimeline(since_id=since_id) + tweets.reverse() + for tweet in tweets: + tweet_text = self._return_tweet_or_retweet_text(tweet=tweet, print_source=True) + self.sendmsg(self.connection, output_channel.encode('utf-8', 'ignore'), tweet_text) - tweets = self.twit.GetMentions(since_id=since_id) - tweets.reverse() - for tweet in tweets: - tweet_text = self._return_tweet_or_retweet_text(tweet=tweet, print_source=True) - self.sendmsg(self.connection, output_channel.encode('utf-8', 'ignore'), tweet_text) + # friends timeline printed, find the latest id + new_since_id = self._get_latest_tweet_id(tweets, since_id) - # mentions printed, find the latest id - new_since_id = self._get_latest_tweet_id(tweets, new_since_id) + tweets = self.twit.GetMentions(since_id=since_id) + tweets.reverse() + for tweet in tweets: + tweet_text = self._return_tweet_or_retweet_text(tweet=tweet, print_source=True) + self.sendmsg(self.connection, output_channel.encode('utf-8', 'ignore'), tweet_text) - # set since_id - self._set_last_since_id(new_since_id) + # mentions printed, find the latest id + new_since_id = self._get_latest_tweet_id(tweets, new_since_id) + + # set since_id + self._set_last_since_id(new_since_id) def _return_tweet_or_retweet_text(self, tweet, print_source=False): """