<commit_before>"""
twitterbot

  A twitter IRC bot. Twitterbot connected to an IRC server and idles in
  a channel, polling a twitter account and broadcasting all updates to
  friends.
  
USAGE

  twitterbot [config_file]

CONFIG_FILE

  The config file is an ini-style file that must contain the following:
  
[irc]
server: <irc_server>
port: <irc_port>
nick: <irc_nickname>
channel: <irc_channel_to_join>

[twitter]
email: <twitter_account_email>
password: <twitter_account_password>

  If no config file is given "twitterbot.ini" will be used by default.

"""

# TODO add delimiter if first word isn't "is" or "was"

BOT_VERSION = "TwitterBot 0.2.1 (mike.verdone.ca/twitter)"

IRC_BOLD = chr(0x02)
IRC_ITALIC = chr(0x16)
IRC_UNDERLINE = chr(0x1f)
IRC_REGULAR = chr(0x0f)

import sys
import time
from dateutil.parser import parse
from ConfigParser import ConfigParser
from heapq import heappop, heappush
import traceback

from api import Twitter, TwitterError
from util import htmlentitydecode

try:
    import irclib
except:
    raise ImportError(
        "This module requires python irclib available from "
        + "http://python-irclib.sourceforge.net/")

def debug(msg):
    # uncomment this for debug text stuff
    # print >> sys.stderr, msg
    pass

class SchedTask(object):
    def __init__(self, task, delta):
        self.task = task
        self.delta = delta
        self.next = time.time()

    def __repr__(self):
        return "<SchedTask %s next:%i delta:%i>" %(
            self.task.__name__, self.next, self.delta)
    
    def __cmp__(self, other):
        return cmp(self.next, other.next)
    
    def __call__(self):
        return self.task()

class Scheduler(object):
    def __init__(self, tasks):
        self.task_heap = []
        for task in tasks:
            heappush(self.task_heap, task)
    
    def next_task(self):
        now = time.time()
        task = heappop(self.task_heap)
        wait = task.next - now
        if (wait > 0):
            time.sleep(wait)
        task()
        task.next = now + task.delta
        heappush(self.task_heap, task)
        debug("tasks: " + str(self.task_heap))
        
    def run_forever(self):
        try:
            while True:
                self.next_task()
        except KeyboardInterrupt:
            pass
            
class TwitterBot(object):
    def __init__(self, configFilename):
        self.configFilename = configFilename
        self.config = load_config(self.configFilename)
        self.irc = irclib.IRC()
        self.irc.add_global_handler('privmsg', self.handle_privmsg)
        self.irc.add_global_handler('ctcp', self.handle_ctcp)
        self.ircServer = self.irc.server()
        self.twitter = Twitter(
            self.config.get('twitter', 'email'),
            self.config.get('twitter', 'password'))
        self.sched = Scheduler(
            (SchedTask(self.process_events, 1),
             SchedTask(self.check_statuses, 120)))
        self.lastUpdate = time.gmtime()

    def check_statuses(self):
        debug("In check_statuses")
        try:
            updates = self.twitter.statuses.friends_timeline()
        except Exception, e:
            print >> sys.stderr, "Exception while querying twitter:"
            traceback.print_exc(file=sys.stderr)
            return
        
        for update in updates:
            crt = parse(update['created_at']).utctimetuple()
            if (crt > self.lastUpdate):
                text = (htmlentitydecode(
                    update['text'].replace('\n', ' '))
                    .encode('utf-8', 'replace'))
                self.privmsg_channel(
                    "=^_^= %s%s%s %s" %(
                        IRC_BOLD, update['user']['screen_name'],
                        IRC_BOLD, text))
                self.lastUpdate = crt
            else:
                break

    def process_events(self):<commit_msg>Fix bug where max only one tweet is announced every 2 mins<commit_after>"""
twitterbot

  A twitter IRC bot. Twitterbot connected to an IRC server and idles in
  a channel, polling a twitter account and broadcasting all updates to
  friends.
  
USAGE

  twitterbot [config_file]

CONFIG_FILE

  The config file is an ini-style file that must contain the following:
  
[irc]
server: <irc_server>
port: <irc_port>
nick: <irc_nickname>
channel: <irc_channel_to_join>

[twitter]
email: <twitter_account_email>
password: <twitter_account_password>

  If no config file is given "twitterbot.ini" will be used by default.

"""

# TODO add delimiter if first word isn't "is" or "was"

BOT_VERSION = "TwitterBot 0.2.1 (mike.verdone.ca/twitter)"

IRC_BOLD = chr(0x02)
IRC_ITALIC = chr(0x16)
IRC_UNDERLINE = chr(0x1f)
IRC_REGULAR = chr(0x0f)

import sys
import time
from dateutil.parser import parse
from ConfigParser import ConfigParser
from heapq import heappop, heappush
import traceback

from api import Twitter, TwitterError
from util import htmlentitydecode

try:
    import irclib
except:
    raise ImportError(
        "This module requires python irclib available from "
        + "http://python-irclib.sourceforge.net/")

def debug(msg):
    # uncomment this for debug text stuff
    # print >> sys.stderr, msg
    pass

class SchedTask(object):
    def __init__(self, task, delta):
        self.task = task
        self.delta = delta
        self.next = time.time()

    def __repr__(self):
        return "<SchedTask %s next:%i delta:%i>" %(
            self.task.__name__, self.next, self.delta)
    
    def __cmp__(self, other):
        return cmp(self.next, other.next)
    
    def __call__(self):
        return self.task()

class Scheduler(object):
    def __init__(self, tasks):
        self.task_heap = []
        for task in tasks:
            heappush(self.task_heap, task)
    
    def next_task(self):
        now = time.time()
        task = heappop(self.task_heap)
        wait = task.next - now
        if (wait > 0):
            time.sleep(wait)
        task()
        task.next = now + task.delta
        heappush(self.task_heap, task)
        debug("tasks: " + str(self.task_heap))
        
    def run_forever(self):
        try:
            while True:
                self.next_task()
        except KeyboardInterrupt:
            pass
            
class TwitterBot(object):
    def __init__(self, configFilename):
        self.configFilename = configFilename
        self.config = load_config(self.configFilename)
        self.irc = irclib.IRC()
        self.irc.add_global_handler('privmsg', self.handle_privmsg)
        self.irc.add_global_handler('ctcp', self.handle_ctcp)
        self.ircServer = self.irc.server()
        self.twitter = Twitter(
            self.config.get('twitter', 'email'),
            self.config.get('twitter', 'password'))
        self.sched = Scheduler(
            (SchedTask(self.process_events, 1),
             SchedTask(self.check_statuses, 120)))
        self.lastUpdate = time.gmtime()

    def check_statuses(self):
        debug("In check_statuses")
        try:
            updates = self.twitter.statuses.friends_timeline()
        except Exception, e:
            print >> sys.stderr, "Exception while querying twitter:"
            traceback.print_exc(file=sys.stderr)
            return
        
        nextLastUpdate = self.lastUpdate
        for update in updates:
            crt = parse(update['created_at']).utctimetuple()
            if (crt > self.lastUpdate):
                text = (htmlentitydecode(
                    update['text'].replace('\n', ' '))
                    .encode('utf-8', 'replace'))
                self.privmsg_channel(
                    "=^_^= %s%s%s %s" %(
                        IRC_BOLD, update['user']['screen_name'],
                        IRC_BOLD, text))
                nextLastUpdate = crt
            else:
                break
        self.lastUpdate = nextLastUpdate
        
    def process_events(self):
{'fraction_non_alphanumeric': 0.1024766237048269, 'fraction_numerical': 0.004927975739196361, 'mean_word_length': 2.226661231145536, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4356642', 'n_tokens_mistral': 2463, 'n_tokens_neox': 2356, 'n_words': 604}