Mercurial > xib
comparison participant.py @ 0:4c842d23d4ce
Initial commit, version 0.1
Signed-off-by: Charly COSTE <changaco@changaco.net>
author | Charly COSTE <changaco@changaco.net> |
---|---|
date | Sun, 16 Aug 2009 01:47:03 +0200 |
parents | |
children | 3f651f4fdb4f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c842d23d4ce |
---|---|
1 #!/usr/bin/env python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # This program is free software: you can redistribute it and/or modify | |
5 # it under the terms of the GNU General Public License as published by | |
6 # the Free Software Foundation, either version 3 of the License, or | |
7 # (at your option) any later version. | |
8 # | |
9 # This program is distributed in the hope that it will be useful, | |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 # GNU General Public License for more details. | |
13 # | |
14 # You should have received a copy of the GNU General Public License | |
15 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | |
17 | |
18 import muc | |
19 xmpp = muc.xmpp | |
20 del muc | |
21 import irclib | |
22 from encoding import * | |
23 from threading import Thread | |
24 from time import sleep | |
25 | |
26 | |
27 class participant: | |
28 def __init__(self, owner_bridge, protocol, nickname): | |
29 self.bridge = owner_bridge | |
30 self.protocol = protocol | |
31 self.nickname = nickname | |
32 self.irc_connection = None | |
33 self.xmpp_c = None | |
34 if protocol == 'xmpp': | |
35 self.createDuplicateOnIRC() | |
36 elif protocol == 'irc': | |
37 self.createDuplicateOnXMPP() | |
38 else: | |
39 raise Exception('Internal Error: bad protocol') | |
40 quit(1) | |
41 | |
42 | |
43 def createDuplicateOnXMPP(self): | |
44 if self.xmpp_c != None or self.irc_connection != None or self.protocol == 'both' or self.bridge.mode == 'minimal': | |
45 return | |
46 self.xmpp_c = xmpp.client.Client(self.bridge.bot.jid.getDomain(), debug=[]) | |
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) | |
56 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 sleep(1) # try to prevent "reconnecting too fast" shit | |
63 self.irc_connection = self.bridge.bot.irc.server() | |
64 self.irc_connection.bridge = self.bridge | |
65 self.irc_connection.nick_callback = self._irc_nick_callback | |
66 self.irc_connection.connect(self.bridge.irc_server, self.bridge.irc_port, self.nickname) | |
67 | |
68 | |
69 def _irc_nick_callback(self, error): | |
70 if error == None: | |
71 self.irc_connection.join(self.bridge.irc_room) | |
72 self.irc_connection.nick_callback = None | |
73 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on IRC side of bridge "'+str(self.bridge)+'"', debug=True) | |
74 elif self.protocol != 'both': | |
75 if error == 'nicknameinuse': | |
76 self.bridge.bot.error('===> Debug: "'+self.nickname+'" is already used in the IRC chan of bridge "'+str(self.bridge)+'"', debug=True) | |
77 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms, please avoid that if possible') | |
78 self.protocol = 'both' | |
79 self.irc_connection.close() | |
80 self.irc_connection = None | |
81 elif error == 'erroneusnickname': | |
82 self.bridge.bot.error('===> Debug: "'+self.nickname+'" got "erroneusnickname" on bridge "'+str(self.bridge)+'"', debug=True) | |
83 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') | |
84 self.irc_connection.close() | |
85 self.irc_connection = None | |
86 | |
87 | |
88 def _xmpp_join_callback(self, errors): | |
89 if len(errors) == 0: | |
90 self.bridge.bot.error('===> Debug: "'+self.nickname+'" duplicate succesfully created on XMPP side of bridge "'+str(self.bridge)+'"', debug=True) | |
91 elif self.protocol != 'both': | |
92 for error in errors: | |
93 try: | |
94 raise error | |
95 except xmpp.muc.NicknameConflict: | |
96 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) | |
97 self.bridge.say('[Warning] The nickname "'+self.nickname+'" is used on both rooms or reserved on the XMPP server, please avoid that if possible') | |
98 self.protocol = 'both' | |
99 self.xmpp_c = None | |
100 | |
101 | |
102 def _xmpp_loop(self): | |
103 while True: | |
104 if self.xmpp_c != None: | |
105 self.xmpp_c.Process(5) | |
106 else: | |
107 sleep(5) | |
108 | |
109 | |
110 def changeNickname(self, newnick, on_protocol): | |
111 if self.protocol == 'xmpp': | |
112 if on_protocol == 'xmpp': | |
113 raise Exception('Internal Error: wanted to change nickname on bad protocol') | |
114 if self.irc_connection: | |
115 self.irc_connection.nick(newnick) | |
116 self.nickname = newnick | |
117 elif self.protocol == 'irc': | |
118 if on_protocol == 'irc': | |
119 raise Exception('Internal Error: wanted to change nickname on bad protocol') | |
120 if self.muc: | |
121 self.muc.change_nick(newnick, callback=self._xmpp_join_callback) | |
122 self.nickname = newnick | |
123 elif self.protocol == 'both': | |
124 if on_protocol == 'irc': | |
125 self.protocol = 'xmpp' | |
126 self.createDuplicateOnIRC() | |
127 elif on_protocol == 'xmpp': | |
128 self.protocol = 'irc' | |
129 self.createDuplicateOnXMPP() | |
130 | |
131 | |
132 def sayOnIRC(self, message): | |
133 try: | |
134 if self.protocol == 'irc': | |
135 raise Exception('Internal Error: "'+self.nickname+'" comes from IRC') | |
136 elif self.protocol == 'both' or self.irc_connection == None: | |
137 self.bridge.irc_connection.privmsg(self.bridge.irc_room, '<'+self.nickname+'> '+message) | |
138 else: | |
139 self.irc_connection.privmsg(self.bridge.irc_room, message) | |
140 except EncodingException: | |
141 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') | |
142 | |
143 | |
144 def sayOnIRCTo(self, to, message): | |
145 if self.protocol == 'irc': | |
146 raise Exception('Internal Error: "'+self.nickname+'" comes from IRC') | |
147 elif self.irc_connection == None: | |
148 if self.bridge.mode != 'normal': | |
149 self.bridge.getParticipant(to).sayOnXMPPTo(self.nickname, 'Sorry but cross-protocol private messages are disabled in limited mode.') | |
150 else: | |
151 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.') | |
152 else: | |
153 try: | |
154 self.irc_connection.privmsg(to, message) | |
155 except EncodingException: | |
156 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') | |
157 | |
158 | |
159 def sayOnXMPP(self, message): | |
160 if self.protocol == 'xmpp': | |
161 raise Exception('Internal Error: "'+self.nickname+'" comes from XMPP') | |
162 elif self.protocol == 'both' or self.xmpp_c == None: | |
163 self.bridge.xmpp_room.say('<'+self.nickname+'> '+auto_decode(message)) | |
164 else: | |
165 try: | |
166 self.muc.say(auto_decode(message)) | |
167 except EncodingException: | |
168 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') | |
169 | |
170 | |
171 def sayOnXMPPTo(self, to, message): | |
172 if self.protocol == 'xmpp': | |
173 raise Exception('Internal Error: "'+self.nickname+'" comes from XMPP') | |
174 else: | |
175 try: | |
176 self.muc.sayTo(to, auto_decode(message)) | |
177 except EncodingException: | |
178 self.bridge.say('[Warning] "'+self.nickname+'" is sending messages using an unknown encoding') | |
179 | |
180 | |
181 def leave(self, message): | |
182 if message == None: | |
183 message = '' | |
184 try: | |
185 self.muc.leave(message) | |
186 except AttributeError: | |
187 pass | |
188 try: | |
189 self.irc_connection.disconnect(message) | |
190 except AttributeError: | |
191 pass | |
192 self.nickname = None | |
193 | |
194 | |
195 def __del__(self): | |
196 if self.nickname != None: | |
197 self.leave('') |