Mercurial > xib
diff muc.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 | cb0daec4b778 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/muc.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +import xmppony as xmpp +from time import sleep + + +class muc: + + class PasswordNeeded(Exception): pass + class MembersOnlyRoom(Exception): pass + class BannedFromRoom(Exception): pass + class NicknameConflict(Exception): pass + class RoomIsFull(Exception): pass + class RoomIsLocked(Exception): pass + class ForgotNickname(Exception): pass + class UnknownError(Exception): pass + + def __init__(self, room_jid): + self.room_jid = room_jid + self.connected = False + self.participants = {} + + + def join(self, xmpp_c, nickname, status=None, callback=None): + """Join room on xmpp_c connection using nickname""" + self.jid = self.room_jid+'/'+nickname + self.nickname = nickname + self.xmpp_c = xmpp_c + self.callback = callback + self.xmpp_c.RegisterHandler('presence', self._xmpp_presence_handler) + self.xmpp_c.send(xmpp.protocol.Presence(to=self.jid, status=status)) + + + def _xmpp_presence_handler(self, xmpp_c, presence): + if presence.getFrom() == self.jid: + errors = [] + if presence.getAttr('type') == 'error': + for c in presence.getChildren(): + if c.getName() == 'error': + for cc in c.getChildren(): + if cc.getNamespace() == 'urn:ietf:params:xml:ns:xmpp-stanzas' and cc.getName() != 'text': + err = c.getAttr('type')+' '+cc.getName() + if err == 'auth not-authorized': + # password-protected room + errors.append(self.__class__.PasswordNeeded()) + elif err == 'auth registration-required': + # members-only room + errors.append(self.__class__.MembersOnlyRoom()) + elif err == 'auth forbidden': + # banned from room + errors.append(self.__class__.BannedFromRoom()) + elif err == 'cancel conflict': + # nickname conflict + errors.append(self.__class__.NicknameConflict()) + elif err == 'wait service-unavailable': + # room is full + errors.append(self.__class__.RoomIsFull()) + elif err == 'cancel item-not-found': + # room is locked + errors.append(self.__class__.RoomIsLocked()) + elif err == 'modify jid-malformed': + # forgot to give a nickname + errors.append(self.__class__.ForgotNickname()) + else: + errors.append(self.__class__.UnknownError(presence.__str__(fancy=1).decode('utf-8'))) + break + if len(errors) == 0: + errors.append(self.__class__.UnknownError(presence.__str__(fancy=1).decode('utf-8'))) + else: + self.connected = True + xmpp_c.UnregisterHandler('presence', self._xmpp_presence_handler) + if self.callback != None: + self.callback(errors) + + + def _check(self): + i = 0 + while not self.connected: + i += 1 + if i > 30: + raise Exception('Error: connection to room timed out') + sleep(1) + + + def say(self, message): + """Say message in the room""" + self._check() + self.xmpp_c.send(xmpp.protocol.Message(to=self.room_jid, typ='groupchat', body=message)) + + + def sayTo(self, to, message): + """Send a private message""" + self._check() + self.xmpp_c.send(xmpp.protocol.Message(to=self.room_jid+'/'+to, typ='chat', body=message)) + + + def change_nick(self, nickname, callback=None): + """Change nickname""" + self._check() + self.jid = self.room_jid+'/'+nickname + self.callback = callback + self.xmpp_c.RegisterHandler('presence', self._xmpp_presence_handler) + self.xmpp_c.send(xmpp.protocol.Presence(to=self.jid)) + + + def leave(self, message=''): + """Leave the room""" + self.xmpp_c.send(xmpp.protocol.Presence(to=self.jid, typ='unavailable', status=message)) + self.connected = False + + + def __del__(self): + if self.connected: + self.leave() + +xmpp.muc = muc \ No newline at end of file