root/imbot/MessageQueue.py

Revision 118, 5.6 kB (checked in by pantley2, 3 years ago)

IMBOT: still trying to prevent it from repeating itself

Line 
1 import re, threading
2 from time import time, sleep
3 from random import choice
4
5 from Log import Log
6 from Commands import Commands
7 from Cleaner import Cleaner
8
9 class MessageQueue:
10         def __init__(self, brain):
11                 '''Initialize incoming/outgoing queues'''
12                 self.log = Log()
13                 self.brain = brain
14                 self.commands = Commands(self.brain)
15                 self.incoming = []
16                 self.outgoing = []
17                 self.last_save = time() + 60
18                
19                 self.smiley_codes = {
20                         r':-)': "01smile",
21                         r':-(': "02smile",
22                         r';-)': "03smile",
23                         r':-P': "04smile",
24                         r':-O': "05smile",
25                         r':-*': "06smile",
26                         r'>:o': "07smile",
27                         r'8-)': "08smile",
28                         r':-$': "09smile",
29                         r':-!': "10smile",
30                         r':-[': "11smile",
31                         r'O:-\)': "12smile",
32                         r':-\\': "13smile",
33                         r":'(": "14smile",
34                         r':-X': "15smile",
35                         r':-D': "16smile"
36                 }
37        
38         def compute_delay(self, message, time_elapsed=0):
39                 '''
40                 Returns the number of seconds to wait before sending 'message' based on the message's contents
41                 and how much time it took to generate the response (time_elapsed)
42                 '''
43                 delay = 0.1 * (len(message) + choice(range(0, int(len(message)/3) + 1)))
44                
45                 if time_elapsed > delay:
46                         self.log.add('sending "%s" immediately' % message)
47                         delay = 0
48                 else:
49                         delay = delay - time_elapsed
50                         self.log.add('sending "%s" in %s seconds' % (message, delay))
51                
52                 return 0#delay
53        
54         def add_incoming(self, sender, message):
55                 '''Append ['sender', 'message'] to the incoming queue'''
56                 self.incoming.append([time(), sender, message])
57        
58         def add_outgoing(self, recipient, message, time_elapsed=0, away=False):
59                 '''Append [time_to_send, 'recipient', 'message'] to the outgoing queue'''
60                 self.outgoing.append([time() + self.compute_delay(message, time_elapsed), recipient, message, away])
61        
62         def log_message(self, their_name, sender, message):
63                 ''' Print a message to the screen and append it to their_name.txt '''
64                 # append this message to a log file
65                 filename = 'Logs/%s.txt' % self.brain.cleaner.simplify(their_name)
66                 fileHandle = open(filename, 'a')
67                 fileHandle.write('%s: %s\n' % (sender, message))
68                 fileHandle.close()
69                
70                 # online
71                 if self.brain.online:
72                         # someone >> message (outgoing)
73                         if sender == self.brain.screenname:
74                                 print '\t%s >> %s' % (their_name, message)
75                        
76                         # someone: message (incoming)
77                         else:
78                                 print '%s: %s' % (their_name, message)
79                
80                 # outgoing offline console messages
81                 elif sender == self.brain.screenname:
82                         print '%s: %s' % (sender, message)
83        
84         def process_incoming(self):
85                 '''
86                 If we received a message with a command in it, run the command.
87                 Otherwise, parse the message and generate a response to it.
88                 '''
89                 if len(self.incoming):
90                         # print/log the message
91                         (time_received, sender, message) = self.incoming.pop(0)
92                         self.log_message(sender, sender, message)
93                        
94                         # run a command or parse their message and think of a response
95                         if not self.commands.run(sender, message):
96                                 # store the symbols that make up smileys as "words"
97                                 message = self.smiley_to_code(message)
98                                
99                                 # gibberish detector
100                                 if Cleaner.contains_gibberish(message):
101                                         print "Not saving message: gibberish detected!"
102                                         their_message = choice(['eh?', 'haha', 'lol?', "i really have on idea what you're trying to say", "uh...", "what?", "i'm so confused",
103                                                 "lol", "ok", "okay", "that's nice", "right", "you make no sense"])
104                                
105                                 # really long message detector
106                                 elif len(message) > 150:
107                                         print "Not saving message: %d is too many characters" % len(message)
108                                         their_message = choice(['no need to write a book on the subject!', "that's ridiculously long", "i'm not going to read all of that",
109                                         "can you recap that in a few words?", 'thats... really long', 'whoa big message', 'are you writing me a novel?'])
110                                
111                                 # useless characters detector
112                                 elif Cleaner.contains_mostly_symbols(message):
113                                         print "Not saving message: sentence contains more symbols than letters"
114                                         their_message = choice(['what?', 'um, okay', "i'm so confused", 'huh?', 'what are you trying to say?', 'that makes no sense',
115                                         'are you speaking in code?', 'sorry, I only understand English', "i'm just going to ignore that nonsense"])
116                                
117                                 # normal looking sentence
118                                 else:
119                                         their_message = self.brain.parse_incoming_message(sender, message)
120                                 threading.Thread(target=self.brain.generate_reply, kwargs={'recipient': sender, 'sentence': their_message}).start()
121        
122         def process_outgoing(self):
123                 '''
124                 If an outgoing message is ready to send,
125                 return [time_to_send, recipient, message, away],
126                 otherwise return None
127                 '''
128                 if len(self.outgoing) and time() > self.outgoing[0][0]:
129                         # print/log the message
130                         info = self.outgoing.pop(0)
131                         (time_sent, recipient, message, away) = info
132                        
133                         # restore smiley codes to their original form :-)
134                         message = self.code_to_smiley(message)
135                        
136                         self.log_message(recipient, self.brain.screenname, message)
137                        
138                         # return the message in case it needs to be sent to someone online
139                         return info
140                 return None
141        
142         def process(self):
143                 '''
144                 Processes incoming messages. Then if an outgoing message is ready to send,
145                 return [time_to_send, recipient, message, away], otherwise return None
146                 '''
147                 # save our brain graphs to disk every once in awhile
148                 if time() > self.last_save:
149                         self.brain.save()
150                         self.last_save = time() + 60 * choice(range(1, 5))
151                
152                 self.process_incoming()
153                 return self.process_outgoing()
154        
155         def smiley_to_code(self, text):
156                 ''' Converts smileys :-) to codes 01SMILE '''
157                 for smiley, code in self.smiley_codes.items():
158                         text = re.sub(re.escape(smiley), code, text)
159                 return text
160        
161         def code_to_smiley(self, text):
162                 ''' Converts codes 01SMILE to smileys :-) '''
163                 for smiley, code in self.smiley_codes.items():
164                         text = re.sub(re.escape(code), smiley, text)
165                 return text
166        
167        
168        
Note: See TracBrowser for help on using the browser.