Index: trunk/extensions/XMLRC/bridge/udp2xmpp.py |
— | — | @@ -492,12 +492,29 @@ |
493 | 493 | self.description = description |
494 | 494 | |
495 | 495 | if on_timeout: |
| 496 | + if type(on_timeout) == unicode or type(on_timeout) == str: |
| 497 | + msg = on_timeout |
| 498 | + |
| 499 | + on_timeout = lambda cb: self.connection.warn(msg), |
| 500 | + |
496 | 501 | self.on_timeout = on_timeout |
497 | 502 | |
498 | 503 | if on_error: |
| 504 | + if type(on_error) == unicode or type(on_error) == str: |
| 505 | + msg = on_error |
| 506 | + if msg.find("%") < 0: |
| 507 | + msg += " (%s)" |
| 508 | + |
| 509 | + on_error = lambda cb, stanza: self.connection.warn(msg % stanza.getError()), |
| 510 | + |
499 | 511 | self.on_error = on_error |
500 | 512 | |
501 | 513 | if on_match: |
| 514 | + if type(on_match) == unicode or type(on_match) == str: |
| 515 | + msg = on_match |
| 516 | + |
| 517 | + on_match = lambda cb, stanza: self.connection.info(msg), |
| 518 | + |
502 | 519 | self.on_match = on_match |
503 | 520 | |
504 | 521 | if match_condition: |
— | — | @@ -730,7 +747,7 @@ |
731 | 748 | self.process_presence_muc_user( conn, x ) |
732 | 749 | |
733 | 750 | def process_presence_muc_user(self, conn, x): |
734 | | - self.info( 'muc presence: %s' % x.__str__() ) #FIXME: better info! |
| 751 | + self.debug( 'muc presence: %s' % x.__str__() ) #FIXME: better info! |
735 | 752 | |
736 | 753 | def guess_local_resource(self): |
737 | 754 | resource = "%s-%d" % ( socket.gethostname(), os.getpid() ) |
— | — | @@ -772,7 +789,7 @@ |
773 | 790 | self.jabber.RegisterHandler( 'iq', self.process_other_stanza ) |
774 | 791 | |
775 | 792 | self.jid = jid; |
776 | | - self.info( 'connected as %s' % ( jid ) ) |
| 793 | + self.info( 'connected as %s to %s' % ( jid, host ) ) |
777 | 794 | |
778 | 795 | self.ping() |
779 | 796 | self.on_connect() |
— | — | @@ -863,15 +880,22 @@ |
864 | 881 | if stanza.getAttr("type") == "get" and stanza.getAttr("id") is None: |
865 | 882 | stanza.setAttr( "id", self.make_id("iq") ) |
866 | 883 | |
867 | | - if callable(callback): |
| 884 | + if not callback and 'on_match' in args: |
| 885 | + callback = args['on_match'] |
| 886 | + del args['on_match'] |
| 887 | + |
| 888 | + if callback and callable(callback): |
868 | 889 | # if callback is a plain callable, wrap in a XmppCallback |
869 | 890 | callback = XmppCallback(stanza, on_match = callback, **args) |
870 | 891 | elif callback: |
871 | 892 | # otherwise auto-match stanza |
872 | 893 | callback.configure_for_response(stanza) |
| 894 | + elif args: |
| 895 | + raise Exception("no callback, but callback arguments: %s" % repr(args)) |
873 | 896 | |
874 | 897 | self.jabber.send(stanza) |
875 | 898 | self.trace('>> stanza sent: %s' % stanza.__str__() ) |
| 899 | + self.trace('...callback: %s' % repr(callback) ) |
876 | 900 | |
877 | 901 | if callback: |
878 | 902 | self.add_callback(callback) # NOTE: can't miss anything, this is single threaded! |
— | — | @@ -905,7 +929,7 @@ |
906 | 930 | ping = xmpp.Iq( typ='get', to= self.jid.getDomain(), frm= self.jid ) |
907 | 931 | ping.addChild( name= "ping", namespace = "urn:xmpp:ping" ) |
908 | 932 | |
909 | | - self.send( ping, lambda cb, stanza: self.info('response received to ping!') ) |
| 933 | + self.send( ping, lambda cb, stanza: self.debug('response received to ping!'), description= "expect pong" ) |
910 | 934 | self.debug('ping sent: %s' % ping.__str__() ) |
911 | 935 | |
912 | 936 | def reconnect_backoff( self ): |
— | — | @@ -1126,38 +1150,73 @@ |
1127 | 1151 | self.message_type = 'groupchat' |
1128 | 1152 | |
1129 | 1153 | self.room_identity = None |
| 1154 | + self.presence = None |
1130 | 1155 | self.status = None |
| 1156 | + self.is_new_room = None |
| 1157 | + self.presence_type = None |
1131 | 1158 | |
1132 | | - def join_protocol(self, connection): |
| 1159 | + def part_protocol(self, connection ): |
1133 | 1160 | # use our own desired nickname as resource part of the group's JID |
1134 | 1161 | jid = self.jid.getStripped() + "/" + self.nick; |
1135 | 1162 | |
1136 | 1163 | #create presence stanza |
| 1164 | + part = xmpp.Presence( to= jid, typ = "unavailable" ) |
| 1165 | + |
| 1166 | + send = self.connection.future_send( part, |
| 1167 | + match_condition = lambda cb, stanza: self.is_my_presence(stanza), |
| 1168 | + on_match = lambda cb, stanza: None, #already handled by permanent handler for set_my_presence |
| 1169 | + on_error = "FAILED TO LEAVE ROOM %s! " % jid, |
| 1170 | + on_timeout = "TIMEOUT WHILE LEAVING ROOM %s! " % jid, |
| 1171 | + description = "final presence for %s (part)" % jid, |
| 1172 | + ) |
| 1173 | + self.connection.info( 'leaving room %s' % self.jid.getStripped() ) |
| 1174 | + yield send |
| 1175 | + |
| 1176 | + def join_protocol(self, connection, create = True, register = True ): |
| 1177 | + # use our own desired nickname as resource part of the group's JID |
| 1178 | + jid = self.jid.getStripped() + "/" + self.nick; |
| 1179 | + |
| 1180 | + #create presence stanza |
1137 | 1181 | join = xmpp.Presence( to= jid ) |
1138 | 1182 | join.addChild( name = 'x', namespace = 'http://jabber.org/protocol/muc' ) #announce full MUC support |
1139 | 1183 | |
1140 | | - send = self.connection.future_send( join, lambda cb, stanza: self.room_joined(stanza), |
| 1184 | + send = self.connection.future_send( join, |
1141 | 1185 | match_condition = lambda cb, stanza: self.is_my_presence(stanza), |
1142 | | - on_error = lambda cb, stanza: self.connection.warn("FAILED TO JOIN ROOM %s! %s " % (jid, stanza.getError())), |
1143 | | - on_timeout = lambda cb: self.connection.warn("FAILED TO JOIN ROOM %s!" % jid) |
| 1186 | + on_match = lambda cb, stanza: self.set_my_presence(stanza, callback = cb), |
| 1187 | + on_error = "PRESENCE ERROR %s! " % jid, |
| 1188 | + permanent = True, |
| 1189 | + description = "room presence for %s" % jid |
1144 | 1190 | ) |
1145 | | - self.connection.info( 'joining room %s' % self.jid.getStripped() ) |
| 1191 | + self.connection.debug( 'joining room %s' % self.jid.getStripped() ) |
1146 | 1192 | yield send |
1147 | 1193 | |
| 1194 | + #create disco query |
1148 | 1195 | disco = xmpp.Iq( to= self.jid, typ="get" ) |
1149 | 1196 | disco.addChild( name="query", namespace = "http://jabber.org/protocol/disco#info" ) |
1150 | 1197 | |
1151 | | - send = self.connection.future_send( disco, lambda cb, stanza: self.set_room_info(stanza), |
1152 | | - on_error = lambda cb, stanza: self.connection.warn("FAILED TO GET ROOM IDENTITY %s! %s " % (jid, stanza.getError())), |
1153 | | - on_timeout = lambda cb: self.connection.warn("FAILED TO GET ROOM IDENTITY %s!" % jid), |
| 1198 | + send = self.connection.future_send( disco, |
| 1199 | + on_match = lambda cb, stanza: self.set_room_info(stanza), |
| 1200 | + on_error = "FAILED TO GET ROOM IDENTITY FOR %s! " % jid, |
| 1201 | + on_timeout = "TIMEOUT WHILE GETTING ROOM IDENTITY FOR %s!" % jid, |
| 1202 | + description = "room info for %s" % jid |
1154 | 1203 | ) |
1155 | 1204 | yield send |
1156 | 1205 | |
1157 | | - |
| 1206 | + if not self.is_new_room: |
| 1207 | + return |
| 1208 | + elif not create and not register: |
| 1209 | + self.connection.warn("ROMM %s DID NOT EXIST! creation/registeration is not enabled." % jid) |
| 1210 | + self.part() |
| 1211 | + return |
1158 | 1212 | |
| 1213 | + #TODO: configure/register! |
| 1214 | + |
1159 | 1215 | def join(self): |
1160 | 1216 | self.connection.run_protocol( self.join_protocol ) |
1161 | 1217 | |
| 1218 | + def part(self): |
| 1219 | + self.connection.run_protocol( self.part_protocol ) |
| 1220 | + |
1162 | 1221 | def create_room(self): |
1163 | 1222 | # use our own desired nickname as resource part of the group's JID |
1164 | 1223 | jid = self.jid.getStripped() + "/" + self.nick; |
— | — | @@ -1167,13 +1226,33 @@ |
1168 | 1227 | join.addChild( name = 'x', namespace = 'http://jabber.org/protocol/muc' ) #announce full MUC support |
1169 | 1228 | |
1170 | 1229 | def set_room_info( self, iq ): |
1171 | | - self.connection.info("ROOM IDENITY: " + iq.T.query.T.identity.__str__()) |
| 1230 | + self.connection.debug("ROOM IDENITY: " + iq.T.query.T.identity.__str__()) |
1172 | 1231 | self.room_identity = iq.T.query.T.identity |
1173 | 1232 | |
1174 | | - def room_joined( self, presence ): |
1175 | | - info = presence.T.x.T.item |
| 1233 | + def set_my_presence( self, presence, callback = None ): |
| 1234 | + self.connection.debug("MY PRESENCE: %s" + presence.__str__() ) |
| 1235 | + |
| 1236 | + self.presence_type = presence.getAttr("type") |
| 1237 | + if self.presence_type is None: |
| 1238 | + self.presence_type = "subscribed" |
| 1239 | + |
| 1240 | + if self.presence_type != "unavailable" and self.presence is None: |
| 1241 | + self.connection.info("joined room " + presence.getFrom().__str__() ) |
| 1242 | + |
| 1243 | + self.presence = presence |
1176 | 1244 | self.status = self.connection.get_status_codes(presence) |
| 1245 | + self.is_new_room = ( self.is_new_room or "201" in self.status ) |
1177 | 1246 | |
| 1247 | + if self.presence_type == "unavailable": |
| 1248 | + self.connection.info("left room " + presence.getFrom().__str__() ) |
| 1249 | + self.status = None |
| 1250 | + self.room_identity = None |
| 1251 | + self.is_new_room = None |
| 1252 | + self.presence = None |
| 1253 | + |
| 1254 | + if callback: |
| 1255 | + self.connection.remove_callback(callback) |
| 1256 | + |
1178 | 1257 | def is_my_presence( self, presence ): |
1179 | 1258 | if presence.T.x and presence.T.x.getNamespace() == "http://jabber.org/protocol/muc#user": |
1180 | 1259 | if presence.T.x.T.item: |
— | — | @@ -1183,6 +1262,7 @@ |
1184 | 1263 | if jid.startswith( me ): |
1185 | 1264 | return True |
1186 | 1265 | else: |
| 1266 | + self.connection.debug("not my presence: %s" + presence.__str__() ) |
1187 | 1267 | return False |
1188 | 1268 | |
1189 | 1269 | |