<s> import os <EOL> import pickle <EOL> import random <EOL> import re <EOL> import sys <EOL> from irc import IRCBot , IRCConnection <EOL> class MarkovBot ( IRCBot ) : <EOL> """<STR_LIT>""" <EOL> messages_to_generate = <NUM_LIT:5> <EOL> chattiness = <NUM_LIT> <EOL> max_words = <NUM_LIT:15> <EOL> chain_length = <NUM_LIT:2> <EOL> stop_word = '<STR_LIT:\n>' <EOL> filename = '<STR_LIT>' <EOL> last = None <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( MarkovBot , self ) . __init__ ( * args , ** kwargs ) <EOL> self . load_data ( ) <EOL> def load_data ( self ) : <EOL> if os . path . exists ( self . filename ) : <EOL> fh = open ( self . filename , '<STR_LIT:rb>' ) <EOL> self . word_table = pickle . loads ( fh . read ( ) ) <EOL> fh . close ( ) <EOL> else : <EOL> self . word_table = { } <EOL> def save_data ( self ) : <EOL> fh = open ( self . filename , '<STR_LIT:w>' ) <EOL> fh . write ( pickle . dumps ( self . word_table ) ) <EOL> fh . close ( ) <EOL> def split_message ( self , message ) : <EOL> words = message . split ( ) <EOL> if len ( words ) > self . chain_length : <EOL> words . extend ( [ self . stop_word ] * self . chain_length ) <EOL> for i in range ( len ( words ) - self . chain_length ) : <EOL> yield ( words [ i : i + self . chain_length + <NUM_LIT:1> ] ) <EOL> def generate_message ( self , person , size = <NUM_LIT:15> , seed_key = None ) : <EOL> person_words = len ( self . word_table . get ( person , { } ) ) <EOL> if person_words < size : <EOL> return <EOL> if not seed_key : <EOL> seed_key = random . choice ( self . word_table [ person ] . keys ( ) ) <EOL> message = [ ] <EOL> for i in xrange ( self . messages_to_generate ) : <EOL> words = seed_key <EOL> gen_words = [ ] <EOL> for i in xrange ( size ) : <EOL> if words [ <NUM_LIT:0> ] == self . stop_word : <EOL> break <EOL> gen_words . append ( words [ <NUM_LIT:0> ] ) <EOL> try : <EOL> words = words [ <NUM_LIT:1> : ] + ( random . choice ( self . word_table [ person ] [ words ] ) , ) <EOL> except KeyError : <EOL> break <EOL> if len ( gen_words ) > len ( message ) : <EOL> message = list ( gen_words ) <EOL> return '<STR_LIT:U+0020>' . join ( message ) <EOL> def imitate ( self , sender , message , channel ) : <EOL> person = message . replace ( '<STR_LIT>' , '<STR_LIT>' ) . strip ( ) [ : <NUM_LIT:10> ] <EOL> if person != self . conn . nick : <EOL> return self . generate_message ( person ) <EOL> def cite ( self , sender , message , channel ) : <EOL> if self . last : <EOL> return self . last <EOL> def sanitize_message ( self , message ) : <EOL> """<STR_LIT>""" <EOL> return re . sub ( '<STR_LIT>' , '<STR_LIT>' , message . lower ( ) ) <EOL> def log ( self , sender , message , channel ) : <EOL> sender = sender [ : <NUM_LIT:10> ] <EOL> self . word_table . setdefault ( sender , { } ) <EOL> if message . startswith ( '<STR_LIT:/>' ) : <EOL> return <EOL> try : <EOL> say_something = self . is_ping ( message ) or sender != self . conn . nick and random . random ( ) < self . chattiness <EOL> except AttributeError : <EOL> say_something = False <EOL> messages = [ ] <EOL> seed_key = None <EOL> if self . is_ping ( message ) : <EOL> message = self . fix_ping ( message ) <EOL> for words in self . split_message ( self . sanitize_message ( message ) ) : <EOL> key = tuple ( words [ : - <NUM_LIT:1> ] ) <EOL> if key in self . word_table : <EOL> self . word_table [ sender ] [ key ] . append ( words [ - <NUM_LIT:1> ] ) <EOL> else : <EOL> self . word_table [ sender ] [ key ] = [ words [ - <NUM_LIT:1> ] ] <EOL> if self . stop_word not in key and say_something : <EOL> for person in self . word_table : <EOL> if person == sender : <EOL> continue <EOL> if key in self . word_table [ person ] : <EOL> generated = self . generate_message ( person , seed_key = key ) <EOL> if generated : <EOL> messages . append ( ( person , generated ) ) <EOL> if len ( messages ) : <EOL> self . last , message = random . choice ( messages ) <EOL> return message <EOL> def load_log_file ( self , filename ) : <EOL> fh = open ( filename , '<STR_LIT:r>' ) <EOL> logline_re = re . compile ( '<STR_LIT>' ) <EOL> for line in fh . readlines ( ) : <EOL> match = logline_re . search ( line ) <EOL> if match : <EOL> sender , message = match . groups ( ) <EOL> self . log ( sender , message , '<STR_LIT>' , False , None ) <EOL> def load_text_file ( self , filename , sender ) : <EOL> fh = open ( filename , '<STR_LIT:r>' ) <EOL> for line in fh . readlines ( ) : <EOL> self . log ( sender , line , '<STR_LIT>' , False , None ) <EOL> def command_patterns ( self ) : <EOL> return ( <EOL> self . ping ( '<STR_LIT>' , self . imitate ) , <EOL> self . ping ( '<STR_LIT>' , self . cite ) , <EOL> ( '<STR_LIT>' , self . log ) , <EOL> ) <EOL> host = '<STR_LIT>' <EOL> port = <NUM_LIT> <EOL> nick = '<STR_LIT>' <EOL> conn = IRCConnection ( host , port , nick ) <EOL> markov_bot = MarkovBot ( conn ) <EOL> if len ( sys . argv ) > <NUM_LIT:1> and sys . argv [ <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> if len ( sys . argv ) == <NUM_LIT:3> : <EOL> markov_bot . load_log_file ( sys . argv [ <NUM_LIT:2> ] ) <EOL> elif len ( sys . argv ) : <EOL> markov_bot . load_text_file ( sys . argv [ <NUM_LIT:2> ] , sys . argv [ <NUM_LIT:3> ] ) <EOL> else : <EOL> conn . connect ( ) <EOL> conn . join ( '<STR_LIT>' ) <EOL> try : <EOL> conn . enter_event_loop ( ) <EOL> except : <EOL> pass <EOL> markov_bot . save_data ( ) </s>
