-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmucbot.py
153 lines (123 loc) · 5.16 KB
/
mucbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
## Copyright (C) 2011 Matthias Matousek <[email protected]>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2, or (at your option)
## any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
import xmpp, time, re, logging
from threading import Thread
from random import randint
class Mucbot(Thread):
def __init__(self, jid, pwd, room, botname='', roompwd='', greeting=[],
quotes=[], minwait=-1, maxwait=-1, reactions={}, delay=3,
rcv_handler=[]):
'''initalize bot and let it join the room'''
Thread.__init__(self)
if botname == '':
botname = jid.getNode()
# the jid of the bot
self.jid = jid
# the room to join
self.room = room
# the nick to appear with
self.botname = botname
# the password for the room
self.roompwd = roompwd
# quotes to tell periodical
self.quotes = quotes
# minimum and maximum time to wait before quoting something
self.minwait = minwait
self.maxwait = maxwait
# a dictionary containing reactions. the keys have to be
# regular expressions pattern as strings and the value a list of
# reactions from which one will be picked randomly. it's sufficient to
# consider the lower case since every message body will be made lower
# case before parsingiit.
self.reactions = reactions
# seconds to wait before replying
self.delay = delay
# a list of handlers that will be executed when a message is received
self.rcv_handler = rcv_handler
# a list of possible greetings when the bot enters a room
self.greeting = greeting
# compile the patterns
for key in self.reactions.keys():
self.reactions[re.compile(key)] = self.reactions.pop(key)
self.client = xmpp.Client(jid.getDomain(), debug=[])
self.client.connect()
self.client.RegisterHandler('message', self.msg_rcv)
self.client.RegisterHandler('presence', self.pres_rcv)
self.client.auth(jid.getNode(), pwd, resource=jid.getResource())
self.join_room()
def join_room(self):
p = xmpp.Presence(to='%s/%s' % (self.room, self.botname))
p.setTag('x', namespace=xmpp.NS_MUC).setTagData('password', self.roompwd)
p.getTag('x').addChild('history', {'maxchars':'0', 'maxstanzas':'0'})
self.client.send(p)
self.jointime = time.time()
logging.info('%s joined %s' % (self.botname, self.room))
def msg_rcv(self, sess, msg):
'''will be executed when a message arrives'''
logging.debug('received message')
# ignore messages that come from this bot
sender = str(msg.getFrom())
if len(sender.split('/')) > 1:
sender = sender.split('/')[1]
if sender.lower().find(self.botname) >= 0:
return
# first execute all given handlers
for handler in self.rcv_handler:
handler(self, msg.getFrom(), msg.getBody())
self.react(msg.getBody())
def react(self, msg):
'''react to a message by searching for all patterns and replying with
the matching answer'''
logging.debug(msg)
msg = msg.lower()
time.sleep(self.delay)
for pattern in self.reactions.keys():
if pattern.search(msg):
self.say(self.reactions[pattern][randint(0,len(self.reactions[pattern])-1)])
return
def pres_rcv(self, sess, pres):
# ignore messages that come from this bot
sender = str(pres.getFrom())
if len(sender.split('/')) > 1:
sender = sender.split('/')[1]
if sender.lower().find(self.botname) >= 0:
return
def say(self, msg):
'''send the given message to the room'''
m = xmpp.Message(to=self.room, body=msg, typ='groupchat')
self.client.send(m)
def getClient(self):
return self.client
def processing(self):
while True:
self.client.Process(1)
def run(self):
processor = Thread()
processor.run = self.processing
processor.start()
time.sleep(self.delay)
if len(self.greeting) > 0:
self.say(self.greeting[randint(0, len(self.greeting)-1)])
if self.minwait==-1 or self.maxwait==-1:
return
while True:
r = randint(self.minwait, self.maxwait)
logging.info('waiting %d seconds before next quote' % r)
time.sleep(r)
self.say(self.quotes[randint(0,len(self.quotes)-1)])
if __name__ == '__main__':
jid = xmpp.JID('[email protected]')
pwd = 'mypassword'
room = '[email protected]'
examplebot = Mucbot(jid, pwd, room)
examplebot.say("hello world")
time.sleep(1)