Mercurial > xib
comparison participant.py @ 118:b29fd5696a78
new mode bypass and new method bridge.changeMode
Signed-off-by: Charly COSTE <changaco@changaco.net>
author | Charly COSTE <changaco@changaco.net> |
---|---|
date | Sat, 28 Nov 2009 23:47:11 +0100 |
parents | d062efcfbe9d |
children | 75a03f10a863 |
comparison
equal
deleted
inserted
replaced
117:d062efcfbe9d | 118:b29fd5696a78 |
---|---|
20 del muc | 20 del muc |
21 from irclib import ServerNotConnectedError, ServerConnection | 21 from irclib import ServerNotConnectedError, ServerConnection |
22 from encoding import * | 22 from encoding import * |
23 from threading import Thread | 23 from threading import Thread |
24 from time import sleep | 24 from time import sleep |
25 import re | |
25 | 26 |
26 | 27 |
27 class participant: | 28 class participant: |
28 def __init__(self, owner_bridge, protocol, nickname, real_jid=None): | 29 def __init__(self, owner_bridge, protocol, nickname, real_jid=None): |
29 self.bot_admin = False | 30 self.bot_admin = False |
30 self.real_jid = real_jid | 31 self.real_jid = real_jid |
31 self.bridge = owner_bridge | 32 self.bridge = owner_bridge |
32 self.protocol = protocol | 33 self.protocol = protocol |
33 self.nickname = nickname | 34 self.nickname = nickname |
35 self.duplicate_nickname = self.nickname | |
34 self.irc_connection = None | 36 self.irc_connection = None |
35 self.xmpp_c = None | 37 self.xmpp_c = None |
36 self.muc = None | 38 self.muc = None |
37 if protocol == 'xmpp': | 39 if protocol == 'xmpp' and self.bridge.mode in ['normal', 'bypass']: |
38 self.createDuplicateOnIRC() | 40 self.createDuplicateOnIRC() |
39 elif protocol == 'irc': | 41 elif protocol == 'irc' and self.bridge.mode != 'minimal': |
40 self.createDuplicateOnXMPP() | 42 self.createDuplicateOnXMPP() |
41 else: | 43 |
42 raise Exception('[Internal Error] bad protocol') | 44 |
45 def _get_new_duplicate_nickname(self): | |
46 new_duplicate_nickname = self.duplicate_nickname | |
47 for i in xrange(5): | |
48 new_duplicate_nickname = new_duplicate_nickname+'_' | |
49 if not self.bridge.hasParticipant(new_duplicate_nickname): | |
50 return new_duplicate_nickname | |
51 return None | |
43 | 52 |
44 | 53 |
45 def createDuplicateOnXMPP(self): | 54 def createDuplicateOnXMPP(self): |
46 if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection) or self.bridge.mode == 'minimal' or self.nickname == 'ChanServ': | 55 if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection): |
47 return | 56 return |
48 self.xmpp_c = self.bridge.bot.get_xmpp_connection(self.nickname) | 57 self.xmpp_c = self.bridge.bot.get_xmpp_connection(self.duplicate_nickname) |
49 self.muc = xmpp.muc(self.bridge.xmpp_room_jid) | 58 self.muc = xmpp.muc(self.bridge.xmpp_room_jid) |
50 self.muc.join(self.xmpp_c, self.nickname, status='From IRC', callback=self._xmpp_join_callback) | 59 self.join_muc() |
60 | |
61 | |
62 def join_muc(self): | |
63 self.muc.join(self.xmpp_c, self.duplicate_nickname, status='From IRC', callback=self._xmpp_join_callback) | |
51 | 64 |
52 | 65 |
53 def _xmpp_join_callback(self, errors): | 66 def _xmpp_join_callback(self, errors): |
54 if len(errors) == 0: | 67 if len(errors) == 0: |
55 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on XMPP side of bridge "'+str(self.bridge)+'"', debug=True) | 68 m = '===> Debug: "'+self.nickname+'" duplicate succesfully created on XMPP side of bridge "'+str(self.bridge)+'"' |
69 if self.nickname != self.duplicate_nickname: | |
70 m += ' using nickname "'+self.duplicate_nickname+'"' | |
71 self.bridge.say('[Info] "'+self.nickname+'" will appear as "'+self.duplicate_nickname+'" on XMPP because its real nickname is reserved or contains unauthorized characters') | |
72 self.bridge.bot.error(m, debug=True) | |
56 elif self.xmpp_c != 'both': | 73 elif self.xmpp_c != 'both': |
57 for error in errors: | 74 for error in errors: |
58 try: | 75 try: |
59 raise error | 76 raise error |
60 except xmpp.muc.NicknameConflict: | 77 except xmpp.muc.NicknameConflict as e: |
61 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) | 78 if xmpp.protocol.JID(e.args[0]).getResource() != self.duplicate_nickname: |
62 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible') | 79 return |
63 if self.muc.connected == True: | 80 |
64 self.muc.leave('Changed nickname to "'+self.nickname+'"') | 81 if self.bridge.mode == 'bypass': |
82 new_duplicate_nickname = self._get_new_duplicate_nickname() | |
83 if new_duplicate_nickname != None: | |
84 self.bridge.bot.error('===> Debug: "'+self.duplicate_nickname+'" is already used in the XMPP MUC or reserved on the XMPP server of bridge "'+str(self.bridge)+'", trying "'+new_duplicate_nickname+'"', debug=True) | |
85 if self.duplicate_nickname == self.nickname: | |
86 self.bridge.say('[Info] The nickname "'+self.duplicate_nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible') | |
87 self.duplicate_nickname = new_duplicate_nickname | |
88 if isinstance(self.xmpp_c, xmpp.client.Client): | |
89 self.bridge.bot.close_xmpp_connection(self.nickname) | |
90 self.xmpp_c = None | |
91 self.createDuplicateOnXMPP() | |
92 return | |
93 | |
94 else: | |
95 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) | |
96 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible') | |
97 if self.muc.connected == True: | |
98 self.muc.leave('Changed nickname to "'+self.nickname+'"') | |
65 except xmpp.muc.RoomIsFull: | 99 except xmpp.muc.RoomIsFull: |
66 self.bridge.bot.error('[Warning] XMPP MUC of bridge "'+str(self.bridge)+'" is full', send_to_admins=True) | 100 self.bridge.bot.error('[Warning] XMPP MUC of bridge "'+str(self.bridge)+'" is full', send_to_admins=True) |
67 self.bridge.say('[Warning] XMPP room is full') | 101 self.bridge.say('[Warning] XMPP room is full') |
68 | 102 |
69 if isinstance(self.xmpp_c, xmpp.client.Client): | 103 if isinstance(self.xmpp_c, xmpp.client.Client): |
70 self.bridge.bot.close_xmpp_connection(self.nickname) | 104 self.bridge.bot.close_xmpp_connection(self.nickname) |
71 self.xmpp_c = None | 105 self.xmpp_c = None |
72 | 106 |
73 | 107 |
74 def createDuplicateOnIRC(self): | 108 def createDuplicateOnIRC(self): |
75 if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection) or self.bridge.mode != 'normal': | 109 if isinstance(self.xmpp_c, xmpp.client.Client) or isinstance(self.irc_connection, ServerConnection): |
76 return | 110 return |
77 sleep(1) # try to prevent "reconnecting too fast" shit | 111 sleep(1) # try to prevent "reconnecting too fast" shit |
78 self.irc_connection = self.bridge.bot.irc.server(self.bridge.irc_server, self.bridge.irc_port, self.nickname) | 112 self.irc_connection = self.bridge.bot.irc.server(self.bridge.irc_server, self.bridge.irc_port, self.duplicate_nickname) |
79 self.irc_connection.connect(nick_callback=self._irc_nick_callback) | 113 self.irc_connection.connect(nick_callback=self._irc_nick_callback) |
80 | 114 |
81 | 115 |
82 def _irc_nick_callback(self, error, arguments=[]): | 116 def _irc_nick_callback(self, error, arguments=[]): |
83 if error == None: | 117 if error == None: |
84 self.irc_connection.join(self.bridge.irc_room) | 118 self.irc_connection.join(self.bridge.irc_room) |
85 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"', debug=True) | 119 m = '===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"' |
120 if self.nickname != self.duplicate_nickname: | |
121 m += ' using nickname "'+self.duplicate_nickname+'"' | |
122 self.bridge.say('[Info] "'+self.nickname+'" will appear as "'+self.duplicate_nickname+'" on IRC because its real nickname is reserved or contains unauthorized characters') | |
123 self.bridge.bot.error(m, debug=True) | |
124 | |
86 elif self.irc_connection != 'both': | 125 elif self.irc_connection != 'both': |
87 if error == 'nicknameinuse': | 126 |
88 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is used or reserved on the IRC server of bridge "'+str(self.bridge)+'"', debug=True) | 127 if error in ['nicknameinuse', 'nickcollision']: |
89 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used or reserved on the IRC server, please avoid that if possible') | 128 if arguments[0].arguments()[0] != self.duplicate_nickname: |
90 elif error == 'nickcollision': | 129 return |
91 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is used or reserved on the IRC server of bridge "'+str(self.bridge)+'"', debug=True) | 130 |
92 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used or reserved on the IRC server, please avoid that if possible') | 131 if self.bridge.mode == 'bypass': |
132 new_duplicate_nickname = self._get_new_duplicate_nickname() | |
133 if new_duplicate_nickname != None: | |
134 self.bridge.bot.error('===> Debug: "'+self.duplicate_nickname+'" is already used or reserved on the IRC server of bridge "'+str(self.bridge)+'", trying "'+new_duplicate_nickname+'"', debug=True) | |
135 if self.duplicate_nickname == self.nickname: | |
136 self.bridge.say('[Info] The nickname "'+self.duplicate_nickname+'" is used or reserved on the IRC server, please avoid that if possible') | |
137 self.duplicate_nickname = new_duplicate_nickname | |
138 if isinstance(self.irc_connection, ServerConnection): | |
139 self.irc_connection.close('') | |
140 self.irc_connection = error | |
141 self.createDuplicateOnIRC() | |
142 return | |
143 | |
144 else: | |
145 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is used or reserved on the IRC server of bridge "'+str(self.bridge)+'"', debug=True) | |
146 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used or reserved on the IRC server, please avoid that if possible') | |
147 | |
93 elif error == 'erroneusnickname': | 148 elif error == 'erroneusnickname': |
94 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True) | 149 if self.bridge.mode == 'bypass': |
95 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains unauthorized characters and cannot be used in the IRC channel, please avoid that if possible') | 150 self.duplicate_nickname = re.sub('[^a-zA-Z]', '', self.nickname) |
151 if isinstance(self.irc_connection, ServerConnection): | |
152 self.irc_connection.close('') | |
153 self.irc_connection = error | |
154 self.createDuplicateOnIRC() | |
155 return | |
156 else: | |
157 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True) | |
158 self.bridge.say('[Warning] The nickname "'+self.nickname+'" contains unauthorized characters and cannot be used in the IRC channel, please avoid that if possible') | |
159 | |
96 elif error == 'nicknametoolong': | 160 elif error == 'nicknametoolong': |
97 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "nicknametoolong" on bridge "'+str(self.bridge)+'"', debug=True) | 161 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "nicknametoolong" on bridge "'+str(self.bridge)+'"', debug=True) |
98 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') | 162 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') |
163 | |
99 else: | 164 else: |
100 self.bridge.bot.error('===> Debug: unknown error while adding "'+self.nickname+'" to IRC side of bridge "'+str(self.bridge)+'"', debug=True) | 165 self.bridge.bot.error('===> Debug: unknown error while adding "'+self.nickname+'" to IRC side of bridge "'+str(self.bridge)+'"', debug=True) |
101 self.bridge.say('[Warning] unknown error while adding "'+self.nickname+'" to IRC side of bridge') | 166 self.bridge.say('[Warning] unknown error while adding "'+self.nickname+'" to IRC side of bridge') |
102 | 167 |
103 if isinstance(self.irc_connection, ServerConnection): | 168 if isinstance(self.irc_connection, ServerConnection): |
115 self._close_irc_connection('unwanted nick change') | 180 self._close_irc_connection('unwanted nick change') |
116 self.irc_connection = 'unwanted nick change' | 181 self.irc_connection = 'unwanted nick change' |
117 | 182 |
118 else: | 183 else: |
119 self.nickname = newnick | 184 self.nickname = newnick |
185 self.duplicate_nickname = newnick | |
120 if isinstance(self.irc_connection, ServerConnection): | 186 if isinstance(self.irc_connection, ServerConnection): |
121 if self.irc_connection.used_by == 1: | 187 if self.irc_connection.used_by == 1: |
122 self.irc_connection.nick(newnick, callback=self._irc_nick_callback) | 188 self.irc_connection.nick(newnick, callback=self._irc_nick_callback) |
123 else: | 189 else: |
124 self._close_irc_connection('Changed nickname') | 190 self._close_irc_connection('Changed nickname') |
133 self._close_xmpp_connection('unwanted nick change') | 199 self._close_xmpp_connection('unwanted nick change') |
134 self.xmpp_c = 'unwanted nick change' | 200 self.xmpp_c = 'unwanted nick change' |
135 | 201 |
136 else: | 202 else: |
137 self.nickname = newnick | 203 self.nickname = newnick |
204 self.duplicate_nickname = newnick | |
138 if isinstance(self.xmpp_c, xmpp.client.Client): | 205 if isinstance(self.xmpp_c, xmpp.client.Client): |
139 for b in self.bridge.bot.bridges: | 206 for b in self.bridge.bot.bridges: |
140 if b.hasParticipant(oldnick) and b.irc_server != self.bridge.irc_server: | 207 if b.hasParticipant(oldnick) and b.irc_server != self.bridge.irc_server: |
141 self.muc.leave(message='Changed nickname to "'+self.nickname+'"') | 208 self.muc.leave(message='Changed nickname to "'+self.nickname+'"') |
142 self.xmpp_c = None | 209 self.xmpp_c = None |
225 def leave(self, message): | 292 def leave(self, message): |
226 if message == None: | 293 if message == None: |
227 message = '' | 294 message = '' |
228 self._close_xmpp_connection(message) | 295 self._close_xmpp_connection(message) |
229 self._close_irc_connection(message) | 296 self._close_irc_connection(message) |
230 self.nickname = None | |
231 | 297 |
232 | 298 |
233 def _close_xmpp_connection(self, message): | 299 def _close_xmpp_connection(self, message): |
234 if isinstance(self.xmpp_c, xmpp.client.Client): | 300 if isinstance(self.xmpp_c, xmpp.client.Client): |
235 self.muc.leave(auto_decode(message)) | 301 self.muc.leave(auto_decode(message)) |
254 r += '\nself.muc.connected='+str(self.muc.connected) | 320 r += '\nself.muc.connected='+str(self.muc.connected) |
255 return r | 321 return r |
256 | 322 |
257 | 323 |
258 def __del__(self): | 324 def __del__(self): |
259 if self.nickname != None: | 325 self.leave('') |
260 self.leave('') |