- DBus: new addSignal method - plugins XEP-0045: roomJoined is now a dynamically added signal
134 lines
4.9 KiB
Python
Executable file
134 lines
4.9 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)
|
|
host.bridge.addSignal("roomJoined", ".communication", signature='ssasss') #args: room_id, room_service, room_nicks, user_nick, profile
|
|
|
|
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 []
|
|
|