comparison participant.py @ 17:32a35f7eff70

Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots. Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Thu, 20 Aug 2009 01:00:54 +0200
parents 79b0a7f48a3e
children c1b84196c100
comparison
equal deleted inserted replaced
16:0c4a7452d66c 17:32a35f7eff70
29 self.bridge = owner_bridge 29 self.bridge = owner_bridge
30 self.protocol = protocol 30 self.protocol = protocol
31 self.nickname = nickname 31 self.nickname = nickname
32 self.irc_connection = None 32 self.irc_connection = None
33 self.xmpp_c = None 33 self.xmpp_c = None
34 self.muc = None
34 if protocol == 'xmpp': 35 if protocol == 'xmpp':
35 self.createDuplicateOnIRC() 36 self.createDuplicateOnIRC()
36 elif protocol == 'irc': 37 elif protocol == 'irc':
37 self.createDuplicateOnXMPP() 38 self.createDuplicateOnXMPP()
38 else: 39 else:
39 raise Exception('Internal Error: bad protocol') 40 raise Exception('Internal Error: bad protocol')
40 quit(1)
41 41
42 42
43 def createDuplicateOnXMPP(self): 43 def createDuplicateOnXMPP(self):
44 if self.xmpp_c != None or self.irc_connection != None or self.protocol == 'both' or self.bridge.mode == 'minimal': 44 if self.xmpp_c != None or self.irc_connection != None or self.bridge.mode == 'minimal':
45 return 45 return
46 self.xmpp_c = xmpp.client.Client(self.bridge.bot.jid.getDomain(), debug=[]) 46 self.xmpp_c = self.bridge.bot.get_xmpp_connection(self.nickname)
47 self.xmpp_c.connect()
48 self.xmpp_c.auth(self.bridge.bot.jid.getNode(), self.bridge.bot.password, resource=self.nickname)
49 self.xmpp_c.RegisterHandler('presence', self.bridge.bot._xmpp_presence_handler)
50 self.xmpp_c.RegisterHandler('iq', self.bridge.bot._xmpp_iq_handler)
51 self.xmpp_c.RegisterHandler('message', self.bridge.bot._xmpp_message_handler)
52 self.xmpp_thread = Thread(target=self._xmpp_loop)
53 self.xmpp_thread.start()
54 self.xmpp_c.sendInitPresence()
55 self.muc = xmpp.muc(self.bridge.xmpp_room.room_jid) 47 self.muc = xmpp.muc(self.bridge.xmpp_room.room_jid)
56 self.muc.join(self.xmpp_c, self.nickname, status='From IRC', callback=self._xmpp_join_callback) 48 self.muc.join(self.xmpp_c, self.nickname, status='From IRC', callback=self._xmpp_join_callback)
57
58
59 def createDuplicateOnIRC(self):
60 if self.irc_connection != None or self.xmpp_c != None or self.protocol == 'both' or self.bridge.mode != 'normal':
61 return
62 if ' ' in self.nickname:
63 self.bridge.bot.error('===> Debug: "'+self.nickname+'" contains a white space character, duplicate cannot be created on the IRC chan of bridge "'+str(self.bridge)+'"', debug=True)
64 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains a white space character, duplicate cannot be created on IRC, please avoid that if possible')
65 return
66 sleep(1) # try to prevent "reconnecting too fast" shit
67 self.irc_connection = self.bridge.bot.irc.server()
68 self.irc_connection.bridge = self.bridge
69 self.irc_connection.nick_callback = self._irc_nick_callback
70 self.irc_connection.connect(self.bridge.irc_server, self.bridge.irc_port, self.nickname)
71
72
73 def _irc_nick_callback(self, error):
74 if error == None:
75 self.irc_connection.join(self.bridge.irc_room)
76 self.irc_connection.nick_callback = None
77 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"', debug=True)
78 elif self.protocol != 'both':
79 if error == 'nicknameinuse':
80 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the IRC chan of bridge "'+str(self.bridge)+'"', debug=True)
81 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the IRC server, please avoid that if possible')
82 self.protocol = 'both'
83 self.irc_connection.closing = True
84 self.irc_connection.disconnect()
85 self.irc_connection = None
86 elif error == 'erroneusnickname':
87 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True)
88 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains non-ASCII characters and cannot be used in the IRC channel, please avoid that if possible')
89 self.irc_connection.closing = True
90 self.irc_connection.disconnect()
91 self.irc_connection = None
92 49
93 50
94 def _xmpp_join_callback(self, errors): 51 def _xmpp_join_callback(self, errors):
95 if len(errors) == 0: 52 if len(errors) == 0:
96 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on XMPP side of bridge "'+str(self.bridge)+'"', debug=True) 53 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on XMPP side of bridge "'+str(self.bridge)+'"', debug=True)
97 elif self.protocol != 'both': 54 else:
98 for error in errors: 55 for error in errors:
99 try: 56 try:
100 raise error 57 raise error
101 except xmpp.muc.NicknameConflict: 58 except xmpp.muc.NicknameConflict:
102 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the XMPP MUC or reserved on the XMPP server of bridge "'+str(self.bridge)+'"', debug=True) 59 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the XMPP MUC or reserved on the XMPP server of bridge "'+str(self.bridge)+'"', debug=True)
103 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible') 60 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible')
104 self.protocol = 'both' 61 self.bridge.bot.close_xmpp_connection(self.nickname)
105 self.xmpp_c = None 62 self.xmpp_c = None
106 63
107 64
108 def _xmpp_loop(self): 65 def createDuplicateOnIRC(self):
109 while True: 66 if self.irc_connection != None or self.xmpp_c != None or self.bridge.mode != 'normal':
110 if self.xmpp_c != None: 67 return
111 self.xmpp_c.Process(5) 68 sleep(1) # try to prevent "reconnecting too fast" shit
112 else: 69 self.irc_connection = self.bridge.bot.irc.server(self.bridge.irc_server, self.bridge.irc_port, self.nickname)
113 sleep(5) 70 self.irc_connection.connect(nick_callback=self._irc_nick_callback)
71 self.irc_connection.join(self.bridge.irc_room)
72
73
74 def _irc_nick_callback(self, error, arguments=[]):
75 if error == None:
76 self.irc_connection.join(self.bridge.irc_room)
77 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"', debug=True)
78 else:
79 if error == 'nicknameinuse':
80 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the IRC chan of bridge "'+str(self.bridge)+'"', debug=True)
81 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the IRC server, please avoid that if possible')
82 self.irc_connection.close('')
83 self.irc_connection = None
84 elif error == 'erroneusnickname':
85 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True)
86 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains unauthorized characters and cannot be used in the IRC channel, please avoid that if possible')
87 self.irc_connection.close('')
88 self.irc_connection = None
89 elif error == 'nicknametoolong':
90 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "nicknametoolong" on bridge "'+str(self.bridge)+'"', debug=True)
91 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is too long (limit seems to be '+str(arguments[0])+') and cannot be used in the IRC channel, please avoid that if possible')
92 self.irc_connection.close('')
93 self.irc_connection = None
114 94
115 95
116 def changeNickname(self, newnick, on_protocol): 96 def changeNickname(self, newnick, on_protocol):
117 if self.protocol == 'xmpp': 97 if self.protocol == 'xmpp':
118 if on_protocol == 'xmpp': 98 if on_protocol == 'xmpp':
119 raise Exception('Internal Error: wanted to change nickname on bad protocol') 99 self.bridge.removeParticipant('irc', self.nickname, '')
120 self.nickname = newnick 100 self.bridge.addParticipant('irc', newnick)
121 if ' ' in self.nickname: 101
122 self.bridge.bot.error('===> Debug: "'+self.nickname+'" contains a white space character, duplicate cannot be created on the IRC chan of bridge "'+str(self.bridge)+'"', debug=True) 102 else:
123 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains a white space character, duplicate cannot be created on IRC, please avoid that if possible') 103 self.nickname = newnick
124 if self.irc_connection != None: 104 if self.irc_connection != None:
125 self.irc_connection.closing = True 105 self.irc_connection.nick(newnick, callback=self._irc_nick_callback)
126 self.irc_connection.disconnect() 106 else:
127 self.irc_connection = None 107 self.createDuplicateOnIRC()
128 return 108
129 if self.irc_connection != None:
130 self.irc_connection.nick(newnick)
131 else:
132 self.createDuplicateOnIRC()
133 elif self.protocol == 'irc': 109 elif self.protocol == 'irc':
134 if on_protocol == 'irc':
135 raise Exception('Internal Error: wanted to change nickname on bad protocol')
136 self.nickname = newnick
137 if self.muc:
138 self.muc.change_nick(newnick, callback=self._xmpp_join_callback)
139 else:
140 self.createDuplicateOnXMPP()
141 elif self.protocol == 'both':
142 if on_protocol == 'irc': 110 if on_protocol == 'irc':
143 self.bridge.removeParticipant('xmpp', self.nickname, '') 111 self.bridge.removeParticipant('xmpp', self.nickname, '')
144 self.bridge.addParticipant('xmpp', newnick) 112 self.bridge.addParticipant('xmpp', newnick)
145 elif on_protocol == 'xmpp': 113
146 self.bridge.removeParticipant('irc', self.nickname, '') 114 else:
147 self.bridge.addParticipant('irc', newnick) 115 self.nickname = newnick
116 if self.muc != None:
117 self.muc.change_nick(newnick, status='From IRC', callback=self._xmpp_join_callback)
118 else:
119 self.createDuplicateOnXMPP()
148 120
149 121
150 def sayOnIRC(self, message): 122 def sayOnIRC(self, message):
123 if self.protocol == 'irc':
124 raise Exception('Internal Error: "'+self.nickname+'" comes from IRC')
125
151 try: 126 try:
152 if self.protocol == 'irc': 127 if self.irc_connection == None:
153 raise Exception('Internal Error: "'+self.nickname+'" comes from IRC')
154 elif self.protocol == 'both' or self.irc_connection == None:
155 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message) 128 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message)
156 else: 129 else:
157 self.irc_connection.privmsg(self.bridge.irc_room, message) 130 self.irc_connection.privmsg(self.bridge.irc_room, message)
158 except EncodingException: 131 except EncodingException:
159 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') 132 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding')
160 133
161 134
162 def sayOnIRCTo(self, to, message): 135 def sayOnIRCTo(self, to, message):
163 if self.protocol == 'irc': 136 if self.protocol == 'irc':
164 raise Exception('Internal Error: "'+self.nickname+'" comes from IRC') 137 raise Exception('Internal Error: "'+self.nickname+'" comes from IRC')
165 elif self.irc_connection == None: 138
139 if self.irc_connection == None:
166 if self.bridge.mode != 'normal': 140 if self.bridge.mode != 'normal':
167 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in limited mode.') 141 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in limited mode.')
168 else: 142 else:
169 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but you cannot send cross-protocol private messages because I don\'t have an IRC duplicate with your nickname.') 143 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but you cannot send cross-protocol private messages because I don\'t have an IRC duplicate with your nickname.')
170 else: 144 else:
175 149
176 150
177 def sayOnXMPP(self, message): 151 def sayOnXMPP(self, message):
178 if self.protocol == 'xmpp': 152 if self.protocol == 'xmpp':
179 raise Exception('Internal Error: "'+self.nickname+'" comes from XMPP') 153 raise Exception('Internal Error: "'+self.nickname+'" comes from XMPP')
180 elif self.protocol == 'both' or self.xmpp_c == None: 154
181 self.bridge.xmpp_room.say('<'+self.nickname+'> '+auto_decode(message)) 155 try:
182 else: 156 if self.xmpp_c == None:
183 try: 157 self.bridge.xmpp_room.say('<'+self.nickname+'> '+auto_decode(message))
158 else:
184 self.muc.say(auto_decode(message)) 159 self.muc.say(auto_decode(message))
185 except EncodingException: 160 except EncodingException:
186 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') 161 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding')
187 162
188 163
189 def sayOnXMPPTo(self, to, message): 164 def sayOnXMPPTo(self, to, message):
190 if self.protocol == 'xmpp': 165 if self.protocol == 'xmpp':
191 raise Exception('Internal Error: "'+self.nickname+'" comes from XMPP') 166 raise Exception('Internal Error: "'+self.nickname+'" comes from XMPP')
192 else: 167
193 try: 168 try:
194 self.muc.sayTo(to, auto_decode(message)) 169 self.muc.sayTo(to, auto_decode(message))
195 except EncodingException: 170 except EncodingException:
196 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') 171 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding')
197 172
198 173
199 def leave(self, message): 174 def leave(self, message):
200 if message == None: 175 if message == None:
201 message = '' 176 message = ''
202 if self.xmpp_c != None: 177 if self.xmpp_c != None:
203 self.muc.leave(message) 178 self.muc.leave(message)
179 self.bridge.bot.close_xmpp_connection(self.nickname)
204 if self.irc_connection != None: 180 if self.irc_connection != None:
205 self.irc_connection.closing = True 181 self.irc_connection.used_by -= 1
206 self.irc_connection.disconnect(message) 182 if self.irc_connection.used_by < 1:
183 self.irc_connection.close(message)
207 self.irc_connection = None 184 self.irc_connection = None
208 self.nickname = None 185 self.nickname = None
209 186
210 187
211 def __del__(self): 188 def __del__(self):