Mercurial > xib
annotate bridge.py @ 195:e4ceefab8ba5
fixed Bot.restart_bridges_delayed(), don't send the message to admins more than once
Signed-off-by: Charly COSTE <changaco@changaco.net>
author | Charly COSTE <changaco@changaco.net> |
---|---|
date | Sun, 21 Feb 2010 16:19:25 +0100 |
parents | c2a8586e64b5 |
children | 4a379eb359dd |
rev | line source |
---|---|
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
2 # -*- coding: utf-8 -*- |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
3 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
4 # This program is free software: you can redistribute it and/or modify |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
5 # it under the terms of the GNU General Public License as published by |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
6 # the Free Software Foundation, either version 3 of the License, or |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
7 # (at your option) any later version. |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
8 # |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
9 # This program is distributed in the hope that it will be useful, |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
12 # GNU General Public License for more details. |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
13 # |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
14 # You should have received a copy of the GNU General Public License |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
15 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
16 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
17 |
124 | 18 import re |
19 import threading | |
20 import traceback | |
21 | |
22 from irclib import ServerConnection | |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
23 import muc |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
24 xmpp = muc.xmpp |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
25 del muc |
124 | 26 |
27 from participant import Participant | |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
28 import say_levels |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
29 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
30 |
124 | 31 class Bridge: |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
32 |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
33 modes = ['bypass', 'normal', 'limited', 'minimal'] |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
34 |
124 | 35 class NoSuchParticipantException(Exception): pass |
36 | |
37 | |
174
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
38 def __init__(self, owner_bot, xmpp_room_jid, irc_room, irc_server, mode, say_level, irc_port=6667, irc_connection_interval=None, irc_charsets=None): |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
39 """Create a new bridge.""" |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
40 self.bot = owner_bot |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
41 self.irc_server = irc_server |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
42 self.irc_port = irc_port |
45
41394ddb3aff
Lower before comparing strings.
Charly COSTE <changaco@changaco.net>
parents:
40
diff
changeset
|
43 self.irc_room = irc_room.lower() |
150
e0eea72ea493
new bridge attribute "irc_connection_interval" (in seconds)
Charly COSTE <changaco@changaco.net>
parents:
139
diff
changeset
|
44 self.irc_connection_interval = irc_connection_interval |
172
64a0e9636ae6
removed encoding.py, charsets handling is now in irclib and custom charsets can be set per server in the configuration file
Charly COSTE <changaco@changaco.net>
parents:
169
diff
changeset
|
45 self.irc_charsets = irc_charsets |
187 | 46 self.irc_op = False |
103 | 47 self.xmpp_room_jid = xmpp_room_jid |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
48 self.say_level = say_level |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
49 self.participants = [] |
195
e4ceefab8ba5
fixed Bot.restart_bridges_delayed(), don't send the message to admins more than once
Charly COSTE <changaco@changaco.net>
parents:
193
diff
changeset
|
50 self.reconnecting = False |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
51 if mode not in self.__class__.modes: |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
52 raise Exception('[Error] "'+mode+'" is not a correct value for a bridge\'s "mode" attribute') |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
53 self.mode = mode |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
54 |
40
faa468731d8a
Tried to get thread safety and handle disconnections in muc.py
Charly COSTE <changaco@changaco.net>
parents:
38
diff
changeset
|
55 self.lock = threading.RLock() |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
56 |
103 | 57 self.init2() |
58 | |
59 | |
60 def init2(self): | |
195
e4ceefab8ba5
fixed Bot.restart_bridges_delayed(), don't send the message to admins more than once
Charly COSTE <changaco@changaco.net>
parents:
193
diff
changeset
|
61 self.reconnecting = False |
e4ceefab8ba5
fixed Bot.restart_bridges_delayed(), don't send the message to admins more than once
Charly COSTE <changaco@changaco.net>
parents:
193
diff
changeset
|
62 |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
63 # Join XMPP room |
174
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
64 self.xmpp_room = xmpp.muc(self.xmpp_room_jid) |
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
65 self.xmpp_room.join(self.bot.xmpp_c, self.bot.nickname, callback=self._xmpp_join_callback) |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
66 |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
67 # Join IRC room |
174
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
68 self.irc_connection = self.bot.irc.open_connection(self.irc_server, self.irc_port, self.bot.nickname, delay=self.irc_connection_interval) |
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
69 self.irc_connection.connect(nick_callback=self._irc_nick_callback, charsets=self.irc_charsets) |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
70 |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
71 self.bot.error(say_levels.notice, 'bridge "'+str(self)+'" is running in '+self.mode+' mode and a say_level of "'+str(self.say_level)+'"') |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
72 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
73 |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
74 def _join_irc_failed(self, reason): |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
75 self.bot.error(say_levels.error, 'failed to connect to the IRC chan of bridge '+str(self)+'\nreason: '+reason, send_to_admins=True) |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
76 self.stop(message='Failed to connect to the IRC chan, stopping bridge', log=False) |
179
f6c6708c6c0e
handle IRC events cannotsendtochan and notonchannel, send unhandled events to bot admins
Charly COSTE <changaco@changaco.net>
parents:
176
diff
changeset
|
77 |
f6c6708c6c0e
handle IRC events cannotsendtochan and notonchannel, send unhandled events to bot admins
Charly COSTE <changaco@changaco.net>
parents:
176
diff
changeset
|
78 |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
79 def _irc_nick_callback(self, error, arguments=[]): |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
80 if error == None: |
85
dfa030c141f1
Fixed callbacks in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
84
diff
changeset
|
81 if self.mode == None: |
dfa030c141f1
Fixed callbacks in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
84
diff
changeset
|
82 return |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
83 self.irc_connection.join(self.irc_room) |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
84 self.bot.error(3, 'successfully connected on IRC side of bridge "'+str(self)+'"', debug=True) |
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
85 self.say(say_levels.notice, 'bridge "'+str(self)+'" is running in '+self.mode+' mode', on_xmpp=False) |
174
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
86 if self.mode not in ['normal', 'bypass']: |
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
87 self.show_participants_list_on(protocols=['irc']) |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
88 else: |
85
dfa030c141f1
Fixed callbacks in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
84
diff
changeset
|
89 self.mode = None |
192
12fa9bb73b1d
check connection in Bridge.say(), use Bridge.say() in Participant.sayOn{IRC,XMPP}()
Charly COSTE <changaco@changaco.net>
parents:
191
diff
changeset
|
90 self.say(say_levels.error, 'failed to connect to the IRC chan, leaving ...', on_irc=False) |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
91 if error in ['nicknameinuse', 'nickcollision']: |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
92 reason = '"'+self.bot.nickname+'" is already used or reserved on the IRC server' |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
93 elif error == 'erroneusnickname': |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
94 reason = '"'+self.bot.nickname+'" got "erroneusnickname"' |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
95 elif error == 'nicknametoolong': |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
96 reason = '"'+self.bot.nickname+'" got "nicknametoolong", limit seems to be '+str(arguments[0]) |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
97 else: |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
98 reason = error |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
99 self._join_irc_failed(reason) |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
100 |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
101 |
135
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
102 def _RemoteServerNotFound_handler(self): |
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
103 server = xmpp.protocol.JID(self.xmpp_room_jid).getDomain() |
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
104 bridges = self.bot.findBridges([server]) |
190
6db99e458168
fixed calls to Bot.restart_bridges_delayed(), arguments changed in f52cb2f6e273328e73d75ab4ecf214c8dc9dfe1b
Charly COSTE <changaco@changaco.net>
parents:
189
diff
changeset
|
105 error = [say_levels.warning, 'The MUC server '+server+' seems to be down, the bot will try to recreate all bridges related to this server in 5 minutes'] |
6db99e458168
fixed calls to Bot.restart_bridges_delayed(), arguments changed in f52cb2f6e273328e73d75ab4ecf214c8dc9dfe1b
Charly COSTE <changaco@changaco.net>
parents:
189
diff
changeset
|
106 self.bot.restart_bridges_delayed(bridges, 300, error) |
135
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
107 |
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
108 |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
109 def _xmpp_join_callback(self, errors): |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
110 """Called by muc._xmpp_presence_handler""" |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
111 if len(errors) == 0: |
113
6daf0854aa9f
added "--show-say-level" and "--show-participants" options to the "bridges" command, renamed {irc,xmpp}_participants commands
Charly COSTE <changaco@changaco.net>
parents:
112
diff
changeset
|
112 if hasattr(self, 'reconnecting'): |
111
59401ac0f47a
handle XMPP remote-server-not-found
Charly COSTE <changaco@changaco.net>
parents:
109
diff
changeset
|
113 del self.reconnecting |
85
dfa030c141f1
Fixed callbacks in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
84
diff
changeset
|
114 if self.mode == None: |
dfa030c141f1
Fixed callbacks in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
84
diff
changeset
|
115 return |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
116 self.bot.error(3, 'succesfully connected on XMPP side of bridge "'+str(self)+'"', debug=True) |
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
117 self.say(say_levels.notice, 'bridge "'+str(self)+'" is running in '+self.mode+' mode', on_irc=False) |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
118 else: |
85
dfa030c141f1
Fixed callbacks in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
84
diff
changeset
|
119 self.mode = None |
192
12fa9bb73b1d
check connection in Bridge.say(), use Bridge.say() in Participant.sayOn{IRC,XMPP}()
Charly COSTE <changaco@changaco.net>
parents:
191
diff
changeset
|
120 self.say(say_levels.error, 'failed to connect to the XMPP room, leaving ...', on_xmpp=False) |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
121 for error in errors: |
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
122 try: |
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
123 raise error |
135
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
124 except xmpp.muc.RemoteServerNotFound: |
922858915907
handle xmpp.muc.RemoteServerNotFound
Charly COSTE <changaco@changaco.net>
parents:
132
diff
changeset
|
125 self._RemoteServerNotFound_handler() |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
126 except: |
176
bca516d04bdb
attach traceback to error message when joining IRC or XMPP fails
Charly COSTE <changaco@changaco.net>
parents:
175
diff
changeset
|
127 trace = traceback.format_exc() |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
128 self.bot.error(say_levels.error, 'failed to connect to the XMPP room of bridge "'+str(self)+'", stopping bridge\n'+trace, send_to_admins=True) |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
129 self.stop(message='Failed to connect to the XMPP room, stopping bridge') |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
130 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
131 |
115
0ae0f8836a7a
split long messages when sending on IRC
Charly COSTE <changaco@changaco.net>
parents:
114
diff
changeset
|
132 def addParticipant(self, from_protocol, nickname, real_jid=None, irc_id=None): |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
133 """Add a participant to the bridge.""" |
175
8378da7844f2
minor fix in Bridge.addParticipant(), don't rely on Bridge.irc_connection or Bridge.xmpp_room when not necessary
Charly COSTE <changaco@changaco.net>
parents:
174
diff
changeset
|
134 if (from_protocol == 'irc' and nickname == self.bot.nickname) or (from_protocol == 'xmpp' and nickname == self.bot.nickname): |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
135 self.bot.error(3, 'not adding self ('+self.bot.nickname+') to bridge "'+str(self)+'"', debug=True) |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
136 return |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
137 try: |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
138 p = self.getParticipant(nickname) |
72
6c4b841144f6
Better handling of participants
Charly COSTE <changaco@changaco.net>
parents:
64
diff
changeset
|
139 if p.protocol != from_protocol: |
120
de00bbe026a7
bugfix related to the bypass mode
Charly COSTE <changaco@changaco.net>
parents:
118
diff
changeset
|
140 if from_protocol == 'irc' and isinstance(p.irc_connection, ServerConnection) and p.irc_connection.really_connected == True and p.irc_connection.real_nickname == nickname or from_protocol == 'xmpp' and isinstance(p.xmpp_c, xmpp.client.Client) and isinstance(p.muc, xmpp.muc) and p.xmpp_c.nickname == nickname: |
115
0ae0f8836a7a
split long messages when sending on IRC
Charly COSTE <changaco@changaco.net>
parents:
114
diff
changeset
|
141 if irc_id: |
0ae0f8836a7a
split long messages when sending on IRC
Charly COSTE <changaco@changaco.net>
parents:
114
diff
changeset
|
142 p.irc_connection.irc_id = irc_id |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
143 return p |
123
75a03f10a863
Code refactoring (new method participant.set_both_sides())
Charly COSTE <changaco@changaco.net>
parents:
122
diff
changeset
|
144 p.set_both_sides() |
109 | 145 return p |
124 | 146 except self.NoSuchParticipantException: |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
147 pass |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
148 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
149 if nickname == 'ChanServ' and from_protocol == 'irc': |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
150 return |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
151 |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
152 self.bot.error(3, 'adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
153 try: |
124 | 154 p = Participant(self, from_protocol, nickname, real_jid=real_jid) |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
155 except: |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
156 self.bot.error(3, 'unknown error while adding participant "'+nickname+'" from "'+from_protocol+'" to bridge "'+str(self)+'"', debug=True) |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
157 traceback.print_exc() |
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
158 return |
191
ac89a4a72a62
removed buggy exception catch in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
190
diff
changeset
|
159 self.lock.acquire() |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
160 self.participants.append(p) |
97
c71861491968
bridge.addParticipant improvements
Charly COSTE <changaco@changaco.net>
parents:
86
diff
changeset
|
161 self.lock.release() |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
162 if self.mode not in ['normal', 'bypass']: |
102
b3eba9489329
In minimal mode, display the participants' list on XMPP when someone joins on IRC
Charly COSTE <changaco@changaco.net>
parents:
101
diff
changeset
|
163 if from_protocol == 'xmpp': |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
164 self.show_participants_list_on(protocols=['irc']) |
102
b3eba9489329
In minimal mode, display the participants' list on XMPP when someone joins on IRC
Charly COSTE <changaco@changaco.net>
parents:
101
diff
changeset
|
165 elif self.mode == 'minimal' and from_protocol == 'irc': |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
166 self.show_participants_list_on(protocols=['xmpp']) |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
167 return p |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
168 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
169 |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
170 def createDuplicatesOn(self, protocols): |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
171 for p in self.participants: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
172 if p.protocol == 'xmpp' and 'irc' in protocols: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
173 p.createDuplicateOnIRC() |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
174 elif p.protocol == 'irc' and 'xmpp' in protocols: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
175 p.createDuplicateOnXMPP() |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
176 |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
177 |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
178 def changeMode(self, new_mode): |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
179 if new_mode == self.mode: |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
180 return 'Mode is already equal to '+self.mode |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
181 |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
182 old_mode = self.mode |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
183 self.mode = new_mode |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
184 |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
185 unhandled = False |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
186 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
187 if new_mode in ['normal', 'bypass']: |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
188 |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
189 if old_mode == 'limited': |
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
190 # From limited to {normal,bypass} |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
191 self.createDuplicatesOn(['irc']) |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
192 |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
193 elif old_mode in ['minimal', 'normal']: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
194 # From {minimal,normal} to {normal,bypass} |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
195 self.createDuplicatesOn(['irc', 'xmpp']) |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
196 |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
197 elif old_mode == 'bypass': |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
198 # From bypass to normal |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
199 pass # Handled below |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
200 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
201 else: |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
202 # Unhandled mode changing |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
203 unhandled = True |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
204 |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
205 elif new_mode == 'limited': |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
206 |
139
38eb220142a1
fixed minimal→*limited mode changing
Charly COSTE <changaco@changaco.net>
parents:
137
diff
changeset
|
207 if old_mode == 'minimal': |
38eb220142a1
fixed minimal→*limited mode changing
Charly COSTE <changaco@changaco.net>
parents:
137
diff
changeset
|
208 self.createDuplicatesOn(['xmpp']) |
38eb220142a1
fixed minimal→*limited mode changing
Charly COSTE <changaco@changaco.net>
parents:
137
diff
changeset
|
209 |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
210 i = 0 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
211 for p in self.participants: |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
212 if p.protocol == 'xmpp': |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
213 i += 1 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
214 p._close_irc_connection('Bridge is switching to limited mode') |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
215 |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
216 self.show_participants_list_on(protocols=['irc']) |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
217 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
218 elif new_mode == 'minimal': |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
219 for p in self.participants: |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
220 p.leave('Bridge is switching to minimal mode') |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
221 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
222 else: |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
223 # Unhandled mode changing |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
224 unhandled = True |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
225 |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
226 if unhandled: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
227 self.mode = old_mode |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
228 return 'Error: unhandled mode changing from '+self.mode+' to '+new_mode |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
229 |
132
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
230 if old_mode == 'bypass': |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
231 # From bypass to * |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
232 for p in self.participants: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
233 if p.nickname != p.duplicate_nickname: |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
234 p.leave('Bridge is switching to '+new_mode+' mode') |
6a6885dbed25
handle more mode changing cases (added bridge.createDuplicatesOn())
Charly COSTE <changaco@changaco.net>
parents:
131
diff
changeset
|
235 |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
236 self.say(say_levels.notice, 'Bridge is switching from '+old_mode+' to '+new_mode+' mode.', log=True) |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
237 |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
238 |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
239 def getParticipant(self, nickname): |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
240 """Returns a participant object if there is a participant using nickname in the bridge. Raises a NoSuchParticipantException otherwise.""" |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
241 self.lock.acquire() |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
242 for p in self.participants: |
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
243 if nickname in [p.nickname, p.duplicate_nickname]: |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
244 self.lock.release() |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
245 return p |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
246 self.lock.release() |
124 | 247 raise self.NoSuchParticipantException('there is no participant using the nickname "'+nickname+'" in this bridge') |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
248 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
249 |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
250 def get_participants_nicknames_list(self, protocols=['irc', 'xmpp']): |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
251 """Returns a list of the nicknames of the bridge's participants that are connected on the XMPP side.""" |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
252 self.lock.acquire() |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
253 participants_nicknames = [] |
11
79b0a7f48a3e
Introduced the command mechanism and fixed a bug
Charly COSTE <changaco@changaco.net>
parents:
10
diff
changeset
|
254 for p in self.participants: |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
255 if p.protocol in protocols: |
18
3cdf7bb580da
Fixed bot.respond(), boosted XMPP thread to lower latency, fixed mode notice.
Charly COSTE <changaco@changaco.net>
parents:
17
diff
changeset
|
256 participants_nicknames.append('"'+p.nickname+'"') |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
257 self.lock.release() |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
258 return participants_nicknames |
11
79b0a7f48a3e
Introduced the command mechanism and fixed a bug
Charly COSTE <changaco@changaco.net>
parents:
10
diff
changeset
|
259 |
79b0a7f48a3e
Introduced the command mechanism and fixed a bug
Charly COSTE <changaco@changaco.net>
parents:
10
diff
changeset
|
260 |
62
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
261 def hasParticipant(self, nickname): |
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
262 try: |
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
263 self.getParticipant(nickname) |
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
264 return True |
124 | 265 except self.NoSuchParticipantException: |
62
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
266 return False |
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
267 |
61491895c607
Added bridge.hasParticipant() and fixed participant.changeNickname()
Charly COSTE <changaco@changaco.net>
parents:
60
diff
changeset
|
268 |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
269 def removeParticipant(self, left_protocol, nickname, leave_message): |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
270 """Remove the participant using nickname from the bridge. Raises a NoSuchParticipantException if nickname is not used in the bridge.""" |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
271 |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
272 was_on_both = None |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
273 p = self.getParticipant(nickname) |
189
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
274 |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
275 if p.left: |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
276 self.lock.acquire() |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
277 self.participants.remove(p) |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
278 del p |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
279 self.lock.release() |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
280 return |
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
281 |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
282 if p.protocol == 'xmpp': |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
283 if p.irc_connection == 'both': |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
284 was_on_both = True |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
285 if left_protocol == 'xmpp': |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
286 p.protocol = 'irc' |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
287 p.createDuplicateOnXMPP() |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
288 elif left_protocol == 'irc': |
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
289 p.createDuplicateOnIRC() |
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
290 else: |
100
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
291 if left_protocol == 'xmpp': |
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
292 was_on_both = False |
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
293 elif left_protocol == 'irc': |
189
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
294 # got disconnected somehow |
131
46af7f2744a9
added irclib.ServerConnection.left_channels
Charly COSTE <changaco@changaco.net>
parents:
125
diff
changeset
|
295 if isinstance(p.irc_connection, ServerConnection): |
100
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
296 p.irc_connection.join(self.irc_room) |
131
46af7f2744a9
added irclib.ServerConnection.left_channels
Charly COSTE <changaco@changaco.net>
parents:
125
diff
changeset
|
297 else: |
46af7f2744a9
added irclib.ServerConnection.left_channels
Charly COSTE <changaco@changaco.net>
parents:
125
diff
changeset
|
298 c = self.bot.irc.get_connection(self.irc_server, self.irc_port, p.duplicate_nickname) |
46af7f2744a9
added irclib.ServerConnection.left_channels
Charly COSTE <changaco@changaco.net>
parents:
125
diff
changeset
|
299 if not (c and self.irc_room in c.left_channels): |
46af7f2744a9
added irclib.ServerConnection.left_channels
Charly COSTE <changaco@changaco.net>
parents:
125
diff
changeset
|
300 p._close_irc_connection(leave_message) |
46af7f2744a9
added irclib.ServerConnection.left_channels
Charly COSTE <changaco@changaco.net>
parents:
125
diff
changeset
|
301 p.createDuplicateOnIRC() |
100
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
302 return |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
303 |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
304 elif p.protocol == 'irc': |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
305 if p.xmpp_c == 'both': |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
306 was_on_both = True |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
307 if left_protocol == 'irc': |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
308 p.protocol = 'xmpp' |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
309 p.createDuplicateOnIRC() |
84
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
310 elif left_protocol == 'xmpp': |
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
311 p.createDuplicateOnXMPP() |
844ccdcf66be
Fixed callbacks, addParticipant, removeParticipant and __del__ in bridge.py
Charly COSTE <changaco@changaco.net>
parents:
72
diff
changeset
|
312 else: |
100
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
313 if left_protocol == 'irc': |
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
314 was_on_both = False |
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
315 elif left_protocol == 'xmpp': |
189
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
316 # got disconnected somehow |
100
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
317 if isinstance(p.xmpp_c, xmpp.client.Client): |
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
318 self.bot.reopen_xmpp_connection(p.xmpp_c) |
6289ac5a2db7
Reconnect when a connection is closed
Charly COSTE <changaco@changaco.net>
parents:
97
diff
changeset
|
319 return |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
320 |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
321 else: |
19
c1b84196c100
Changed format of non-debug error messages, fixed IRC namreply handling, prevented crash when receiving bad XMPP stanza.
Charly COSTE <changaco@changaco.net>
parents:
18
diff
changeset
|
322 raise Exception('[Internal Error] bad protocol') |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
323 |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
324 if was_on_both == True: |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
325 self.bot.error(3, '"'+nickname+'" was on both sides of bridge "'+str(self)+'" but left '+left_protocol, debug=True) |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
326 |
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
327 elif was_on_both == False: |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
328 self.bot.error(3, 'removing participant "'+nickname+'" from bridge "'+str(self)+'"', debug=True) |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
329 p.leave(leave_message) |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
330 if left_protocol == 'xmpp': |
118
b29fd5696a78
new mode bypass and new method bridge.changeMode
Charly COSTE <changaco@changaco.net>
parents:
115
diff
changeset
|
331 if self.mode not in ['normal', 'bypass']: |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
332 self.show_participants_list_on(protocols=['irc']) |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
333 elif left_protocol == 'irc': |
24
4e1f27ea527b
First hack at locks for thread safety. Some other minor changes.
Charly COSTE <changaco@changaco.net>
parents:
22
diff
changeset
|
334 if self.mode == 'minimal': |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
335 self.show_participants_list_on(protocols=['xmpp']) |
189
e04410e7e527
split the leaving process in two, first call to Bridge.removeParticipant() calls Participant.leave(), second call (when the bot receives the part or quit event) removes it from Bridge.participants
Charly COSTE <changaco@changaco.net>
parents:
187
diff
changeset
|
336 |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
337 else: |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
338 self.bot.error(1, 'Bad decision tree, p.protocol='+p.protocol+' left_protocol='+left_protocol+'\np.xmpp_c='+str(p.xmpp_c)+'\np.irc_connection='+str(p.irc_connection), debug=True) |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
339 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
340 |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
341 def restart(self, log=True): |
103 | 342 """Restart the bridge""" |
343 | |
344 # Stop the bridge | |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
345 self.stop(message='Restarting bridge', log=log) |
103 | 346 |
347 # Recreate the bridge | |
348 self.init2() | |
349 | |
350 | |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
351 def say(self, importance, message, on_irc=True, on_xmpp=True, log=False, send_to_admins=False): |
17
32a35f7eff70
Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots.
Charly COSTE <changaco@changaco.net>
parents:
15
diff
changeset
|
352 """Make the bot say something.""" |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
353 if log or send_to_admins: |
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
354 self.bot.error(importance, message+' ('+str(self)+')', send_to_admins=send_to_admins) |
182
60ee2b914616
minor fix in bridge.py, importance was printed twice
Charly COSTE <changaco@changaco.net>
parents:
180
diff
changeset
|
355 message = self.bot.format_message(importance, message) |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
356 if importance < self.say_level: |
21
801160b4136f
Introduced a bridge's "say" attribute to offer more flexibility in what the bot says.
Charly COSTE <changaco@changaco.net>
parents:
19
diff
changeset
|
357 return |
192
12fa9bb73b1d
check connection in Bridge.say(), use Bridge.say() in Participant.sayOn{IRC,XMPP}()
Charly COSTE <changaco@changaco.net>
parents:
191
diff
changeset
|
358 if on_xmpp and isinstance(self.xmpp_room, xmpp.muc) and self.xmpp_room.connected: |
11
79b0a7f48a3e
Introduced the command mechanism and fixed a bug
Charly COSTE <changaco@changaco.net>
parents:
10
diff
changeset
|
359 self.xmpp_room.say(message) |
192
12fa9bb73b1d
check connection in Bridge.say(), use Bridge.say() in Participant.sayOn{IRC,XMPP}()
Charly COSTE <changaco@changaco.net>
parents:
191
diff
changeset
|
360 if on_irc and isinstance(self.irc_connection, ServerConnection) and self.irc_connection.really_connected: |
56 | 361 self.irc_connection.privmsg(self.irc_room, message) |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
362 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
363 |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
364 def show_participants_list_on(self, protocols=[]): |
174
c158ad24ef3c
moved irc connection interval handling to irclib
Charly COSTE <changaco@changaco.net>
parents:
172
diff
changeset
|
365 if 'irc' in protocols and self.irc_connection.really_connected: |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
366 xmpp_participants_nicknames = self.get_participants_nicknames_list(protocols=['xmpp']) |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
367 self.say(say_levels.info, 'Participants on XMPP: '+' '.join(xmpp_participants_nicknames), on_xmpp=False) |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
368 if 'xmpp' in protocols: |
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
369 irc_participants_nicknames = self.get_participants_nicknames_list(protocols=['irc']) |
180
102f895347ff
added a required "importance" argument to Bot.error()
Charly COSTE <changaco@changaco.net>
parents:
179
diff
changeset
|
370 self.say(say_levels.info, 'Participants on IRC: '+' '.join(irc_participants_nicknames), on_irc=False) |
152
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
371 |
17305e57f71d
removed automatic switching to limited mode (created Bridge.show_participants_list_on())
Charly COSTE <changaco@changaco.net>
parents:
150
diff
changeset
|
372 |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
373 def stop(self, message='Stopping bridge', log=True): |
103 | 374 """Stop the bridge""" |
375 | |
376 # Close IRC connection if not used by an other bridge, just leave the room otherwise | |
109 | 377 if isinstance(self.irc_connection, ServerConnection): |
378 self.irc_connection.used_by -= 1 | |
379 if self.irc_connection.used_by < 1: | |
380 self.irc_connection.close(message) | |
381 else: | |
382 self.irc_connection.part(self.irc_room, message=message) | |
383 self.irc_connection = None | |
103 | 384 |
385 # Leave the MUC | |
109 | 386 if isinstance(self.xmpp_room, xmpp.muc): |
387 self.xmpp_room.leave(message=message) | |
388 self.xmpp_room.__del__() | |
389 self.xmpp_room = None | |
103 | 390 |
391 # Delete participants objects | |
392 for p in self.participants: | |
393 p.leave(message) | |
394 self.participants = [] | |
193
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
395 |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
396 if log: |
c2a8586e64b5
handle IRC inviteonlychan event, improved error messages
Charly COSTE <changaco@changaco.net>
parents:
192
diff
changeset
|
397 self.bot.error(-1, message+' '+str(self), send_to_admins=True) |
103 | 398 |
399 | |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
400 def __str__(self): |
103 | 401 return self.irc_room+'@'+self.irc_server+' <-> '+self.xmpp_room_jid |
0
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
402 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
403 |
4c842d23d4ce
Initial commit, version 0.1
Charly COSTE <changaco@changaco.net>
parents:
diff
changeset
|
404 def __del__(self): |
103 | 405 self.stop(message='Removing bridge') |