libervia-backend/plugins/plugin_xep_0045.py
Goffi 724a97b14d MUC implementation: first draft
/!\ the experimental muc branche of wokkel must be used
- bridge: new roomJoined signal
- wix: contact list widget is now in a separate file, and manage different kinds of presentation
- wix: chat window now manage group chat (first draft, not working yet)
- wix: constants are now in a separate class, so then can be accessible from everywhere
- wix: new menu to join room (do nothing yet, except entering in a test room)
- new plugin for xep 0045 (MUC), use wokkel experimental MUC branch
- plugins: the profile is now given for get_handler, cause it can be used internally by a plugin (e.g.: xep-0045 plugin)
2010-03-21 10:28:55 +11:00

133 lines
4.7 KiB
Python
Executable file

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
SAT plugin for managing xep-0045
Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
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/>.
"""
from logging import debug, info, warning, error
from twisted.words.xish import domish
from twisted.internet import protocol, defer, threads, reactor
from twisted.words.protocols.jabber import client, jid, xmlstream
from twisted.words.protocols.jabber import error as jab_error
from twisted.words.protocols.jabber.xmlstream import IQ
import os.path
import pdb
from zope.interface import implements
from wokkel import disco, iwokkel, muc
from base64 import b64decode
from hashlib import sha1
from time import sleep
try:
from twisted.words.protocols.xmlstream import XMPPHandler
except ImportError:
from wokkel.subprotocols import XMPPHandler
AVATAR_PATH = "/avatars"
IQ_GET = '/iq[@type="get"]'
NS_VCARD = 'vcard-temp'
VCARD_REQUEST = IQ_GET + '/vCard[@xmlns="' + NS_VCARD + '"]' #TODO: manage requests
PRESENCE = '/presence'
NS_VCARD_UPDATE = 'vcard-temp:x:update'
VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]'
PLUGIN_INFO = {
"name": "XEP 0045 Plugin",
"import_name": "XEP_0045",
"type": "XEP",
"protocols": ["XEP-0045"],
"dependencies": [],
"main": "XEP_0045",
"handler": "yes",
"description": _("""Implementation of Multi-User Chat""")
}
class XEP_0045():
def __init__(self, host):
info(_("Plugin XEP_0045 initialization"))
self.host = host
self.clients={}
host.bridge.addMethod("joinMUC", ".communication", in_sign='ssss', out_sign='', method=self.join)
def __check_profile(self, profile):
if not profile or not self.clients.has_key(profile) or not self.host.isConnected(profile):
error (_('Unknown or disconnected profile'))
if self.clients.has_key(profile):
del self.clients[profile]
return False
return True
def __room_joined(self, room, profile):
"""Called when the user is in the requested room"""
print "room joined (profile = %s)" % profile
room_jid = room.roomIdentifier+'@'+room.service
self.clients[profile].joined_rooms[room_jid] = room
self.host.bridge.roomJoined(room.roomIdentifier, room.service, room.roster.keys(), room.nick, profile)
def __err_joining_room(self, failure, profile): #, profile):
"""Called when something is going wrong when joining the room"""
error ("Error when joining the room")
pdb.set_trace()
def join(self, service, roomId, nick, profile_key='@DEFAULT@'):
profile = self.host.memory.getProfileName(profile_key)
if not self.__check_profile(profile):
return
room_jid = roomId+'@'+service
if self.clients[profile].joined_rooms.has_key(room_jid):
warning(_('%(profile)s is already in room %(room_jid)s') % {'profile':profile, 'room_jid':room_jid})
return
info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':roomId+'@'+service, 'nick':nick})
self.clients[profile].join(service, roomId, nick).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile})
def getHandler(self, profile):
#reactor.callLater(15,self.join,"conference.necton2.int", "test", "Goffi \o/", profile)
self.clients[profile] = SatMUCClient(self)
return self.clients[profile]
class SatMUCClient (muc.MUCClient):
#implements(iwokkel.IDisco)
def __init__(self, plugin_parent):
self.plugin_parent = plugin_parent
self.host = plugin_parent.host
muc.MUCClient.__init__(self)
self.joined_rooms = {} #FIXME gof: check if necessary
print "init SatMUCClient OK"
def receivedGroupChat(self, room, user, body):
debug('receivedGroupChat: room=%s user=%s body=%s', room, user, body)
#def connectionInitialized(self):
#pass
#def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
#return [disco.DiscoFeature(NS_VCARD)]
#def getDiscoItems(self, requestor, target, nodeIdentifier=''):
#return []