- core: 2 new convenient methods: getJidNStream and getClient - new param in plugin info: "handler" to know if there is a handler to plug on profiles clients - plugins with handler now use an other class which is returned to profile client with the new method "getHandler" and pluged when connecting
204 lines
8.2 KiB
Python
204 lines
8.2 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
helper class for making a SAT frontend
|
|
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, error
|
|
from tools.jid import JID
|
|
from sat_bridge_frontend.DBus import DBusBridgeFrontend
|
|
import pdb
|
|
|
|
class QuickApp():
|
|
"""This class contain the main methods needed for the frontend"""
|
|
|
|
def __init__(self):
|
|
self.rosterList = {}
|
|
|
|
## bridge ##
|
|
self.bridge=DBusBridgeFrontend()
|
|
self.bridge.register("connected", self.connected)
|
|
self.bridge.register("disconnected", self.disconnected)
|
|
self.bridge.register("newContact", self.newContact)
|
|
self.bridge.register("newMessage", self.newMessage)
|
|
self.bridge.register("presenceUpdate", self.presenceUpdate)
|
|
self.bridge.register("subscribe", self.subscribe)
|
|
self.bridge.register("paramUpdate", self.paramUpdate)
|
|
self.bridge.register("contactDeleted", self.contactDeleted)
|
|
self.bridge.register("updatedValue", self.updatedValue, "request")
|
|
self.bridge.register("askConfirmation", self.askConfirmation, "request")
|
|
self.bridge.register("actionResult", self.actionResult, "request")
|
|
self.bridge.register("actionResultExt", self.actionResult, "request")
|
|
|
|
###now we get the essential params###
|
|
self.whoami=JID(self.bridge.getParamA("JabberID","Connection"))
|
|
self.watched=self.bridge.getParamA("Watched", "Misc").split() #TODO: put this in a plugin
|
|
|
|
## misc ##
|
|
self.current_action_ids = set()
|
|
self.current_action_ids_cb = {}
|
|
self.onlineContact = set() #FIXME: temporary
|
|
|
|
if self.bridge.isConnected():
|
|
self.setStatusOnline(True)
|
|
else:
|
|
self.setStatusOnline(False)
|
|
return
|
|
|
|
### now we fill the contact list ###
|
|
for contact in self.bridge.getContacts():
|
|
self.newContact(contact[0], contact[1], contact[2])
|
|
|
|
presences = self.bridge.getPresenceStatus()
|
|
for contact in presences:
|
|
for res in presences[contact]:
|
|
jabber_id = contact+('/'+res if res else '')
|
|
show = presences[contact][res][0]
|
|
priority = presences[contact][res][1]
|
|
statuses = presences[contact][res][2]
|
|
self.presenceUpdate(jabber_id, show, priority, statuses)
|
|
|
|
waitingSub = self.bridge.getWaitingSub()
|
|
for sub in waitingSub:
|
|
self.subscribe(waitingSub[sub], sub)
|
|
|
|
|
|
def connected(self):
|
|
"""called when the connection is made"""
|
|
debug("Connected")
|
|
self.setStatusOnline(True)
|
|
|
|
def disconnected(self):
|
|
"""called when the connection is closed"""
|
|
debug("Disconnected")
|
|
self.CM.clear()
|
|
self.contactList.clear_contacts()
|
|
self.setStatusOnline(False)
|
|
|
|
def newContact(self, JabberId, attributes, groups):
|
|
entity=JID(JabberId)
|
|
self.rosterList[entity.short]=(dict(attributes), list(groups))
|
|
|
|
def newMessage(self, from_jid, msg, type, to_jid):
|
|
sender=JID(from_jid)
|
|
addr=JID(to_jid)
|
|
win = addr if sender.short == self.whoami.short else sender
|
|
self.chat_wins[win.short].printMessage(sender, msg)
|
|
|
|
def setStatusOnline(self, online=True):
|
|
pass
|
|
|
|
def presenceUpdate(self, jabber_id, show, priority, statuses):
|
|
debug ("presence update for %s (show=%s, statuses=%s)", jabber_id, show, statuses);
|
|
from_jid=JID(jabber_id)
|
|
debug ("from_jid.short=%s whoami.short=%s", from_jid.short, self.whoami.short)
|
|
|
|
if from_jid.short==self.whoami.short:
|
|
if not type:
|
|
self.setStatusOnline(True)
|
|
elif type=="unavailable":
|
|
self.setStatusOnline(False)
|
|
return
|
|
|
|
if show != 'unavailable':
|
|
name=""
|
|
groups = []
|
|
if self.rosterList.has_key(from_jid.short):
|
|
if self.rosterList[from_jid.short][0].has_key("name"):
|
|
name=self.rosterList[from_jid.short][0]["name"]
|
|
groups=self.rosterList[from_jid.short][1]
|
|
|
|
#FIXME: must be moved in a plugin
|
|
if from_jid.short in self.watched and not from_jid.short in self.onlineContact:
|
|
self.showAlert("Watched jid [%s] is connected !" % from_jid.short)
|
|
|
|
self.onlineContact.add(from_jid) #FIXME onlineContact is useless with CM, must be removed
|
|
self.CM.add(from_jid)
|
|
self.CM.update(from_jid, 'name', name)
|
|
self.CM.update(from_jid, 'show', show)
|
|
self.CM.update(from_jid, 'statuses', statuses)
|
|
self.CM.update(from_jid, 'groups', groups)
|
|
cache = self.bridge.getCardCache(from_jid)
|
|
if cache.has_key('nick'):
|
|
self.CM.update(from_jid, 'nick', cache['nick'])
|
|
if cache.has_key('avatar'):
|
|
self.CM.update(from_jid, 'avatar', self.bridge.getAvatarFile(cache['avatar']))
|
|
self.contactList.replace(from_jid)
|
|
|
|
if show=="unavailable" and from_jid in self.onlineContact:
|
|
self.onlineContact.remove(from_jid)
|
|
self.CM.remove(from_jid)
|
|
if not self.CM.isConnected(from_jid):
|
|
self.contactList.disconnect(from_jid)
|
|
|
|
def subscribe(self, type, raw_jid):
|
|
"""Called when a subsciption maangement signal is received"""
|
|
entity = JID(raw_jid)
|
|
if type=="subscribed":
|
|
# this is a subscription confirmation, we just have to inform user
|
|
self.showDialog("The contact %s has accepted your subscription" % entity.short, 'Subscription confirmation')
|
|
elif type=="unsubscribed":
|
|
# this is a subscription refusal, we just have to inform user
|
|
self.showDialog("The contact %s has refused your subscription" % entity.short, 'Subscription refusal', 'error')
|
|
elif type=="subscribe":
|
|
# this is a subscriptionn request, we have to ask for user confirmation
|
|
answer = self.showDialog("The contact %s wants to subscribe to your presence.\nDo you accept ?" % entity.short, 'Subscription confirmation', 'yes/no')
|
|
if answer:
|
|
self.bridge.subscription("subscribed", entity.short)
|
|
else:
|
|
self.bridge.subscribed("unsubscribed", entity.short)
|
|
|
|
def showDialog(self, message, title, type="info"):
|
|
raise NotImplementedError
|
|
|
|
def showAlert(self, message):
|
|
pass #FIXME
|
|
|
|
def paramUpdate(self, name, value, namespace):
|
|
debug("param update: [%s] %s = %s", namespace, name, value)
|
|
if (namespace,name) == ("Connection", "JabberID"):
|
|
debug ("Changing ID to %s", value)
|
|
self.whoami=JID(value)
|
|
elif (namespace,name) == ("Misc", "Watched"):
|
|
self.watched=value.split()
|
|
|
|
def contactDeleted(self, jid):
|
|
target = JID(jid)
|
|
self.CM.remove(target)
|
|
self.contactList.remove(self.CM.get_full(target))
|
|
try:
|
|
self.onlineContact.remove(target.short)
|
|
except KeyError:
|
|
pass
|
|
|
|
def updatedValue(self, name, data):
|
|
if name == "profile_nick":
|
|
target = JID(data['jid'])
|
|
self.CM.update(target, 'nick', data['nick'])
|
|
self.contactList.replace(target)
|
|
elif name == "profile_avatar":
|
|
target = JID(data['jid'])
|
|
filename = self.bridge.getAvatarFile(data['avatar'])
|
|
self.CM.update(target, 'avatar', filename)
|
|
self.contactList.replace(target)
|
|
|
|
def askConfirmation(self, type, id, data):
|
|
raise NotImplementedError
|
|
|
|
def actionResult(self, type, id, data):
|
|
raise NotImplementedError
|