Changeset 710

Show
Ignore:
Timestamp:
07/07/08 05:52:38 (5 months ago)
Author:
sylvain
Message:

added Presence support

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • oss/jlib/examples/basic/client.py

    r709 r710  
    2727 
    2828    def start(self): 
    29         self.connection.emit(QtCore.SIGNAL("registerLinkages(PyQt_PyObject)"), self.contactUi.qobj) 
     29        self.connection.emit(QtCore.SIGNAL("registerLinkages(PyQt_PyObject)"), self.contactUi.contact) 
     30        self.connection.emit(QtCore.SIGNAL("registerLinkages(PyQt_PyObject)"), self.contactUi.presence) 
    3031        self.connection.emit(QtCore.SIGNAL("start()")) 
    3132         
     
    4041    def showConnectionSettings(self): 
    4142        self.dialog = jlibConnectionDialog() 
     43 
     44        # Just because I can't be bothered to type them over and over again 
    4245        self.dialog.connection.domain.setText('localhost') 
    4346        self.dialog.connection.resource.setText('Home') 
    4447        self.dialog.connection.host.setText('localhost') 
     48 
    4549        if self.dialog.exec_() == QtGui.QDialog.Accepted: 
    4650            self.connection = self.dialog.connection 
  • oss/jlib/jlib/core/contact.py

    r709 r710  
    55 
    66from headstock.protocol.core.roster import RosterDispatcher 
     7from headstock.protocol.core.presence import PresenceDispatcher 
    78from headstock.api.jid import JID 
    89from headstock.api import Entity 
     10from headstock.api.contact import Presence, Roster, Item 
    911from headstock.lib.utils import generate_unique 
    1012 
    1113from bridge import Element as E 
    12 from bridge.common import XMPP_ROSTER_NS 
     14from bridge.common import XMPP_CLIENT_NS, XMPP_ROSTER_NS 
    1315 
    1416from PyQt4 import QtCore, QtGui 
     
    1618from jlib.core.qaxon import QAxonObject 
    1719 
    18 __all__ = ['jlibContact', 'jlibContactComponent', 'jlibContactModel'] 
     20__all__ = ['jlibContact', 'jlibContactComponent', 'jlibContactModel', 
     21           'jlibPresence', 'jlibPresenceComponent'] 
    1922 
    2023class jlibContact(QAxonObject): 
     
    2528        QAxonObject.setComponent(self, component) 
    2629        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'inbox') 
     30        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'pushed') 
    2731 
    2832    def getLinkages(self): 
     
    8185                roster = self.recv('pushed') 
    8286                for nodeid in roster.items: 
     87                    contact = roster.items[nodeid] 
     88                    if contact.subscription == 'remove': 
     89                        self.qobj.emit(QtCore.SIGNAL("removedContact(PyQt_PyObject)"), contact) 
     90                    elif contact.subscription == 'from': 
     91                        self.qobj.emit(QtCore.SIGNAL("addedContact(PyQt_PyObject)"), contact) 
    8392                    self.send(Roster(from_jid=self.from_jid, to_jid=nodeid, 
    8493                                     type=u'result', stanza_id=generate_unique()), 'result') 
     
    117126        for nodeid in roster.items: 
    118127            contact = roster.items[nodeid] 
    119             item = QtGui.QStandardItem() 
    120             self.appendRow(item) 
    121             self.setData(self.index(item.row(), 0),  
    122                          QtCore.QVariant(QtCore.QString(nodeid))) 
     128            self.addContact(contact) 
    123129 
    124130    def getContact(self, index): 
    125131        return self.roster.items.values()[index.row()] 
     132 
     133    def getIndex(self, contact): 
     134        for nodeid in self.roster.items: 
     135            if str(contact.jid) == nodeid: 
     136                return self.index(self.roster.items.keys().index(nodeid), 0) 
     137 
     138        return QtCore.QModelIndex() 
     139 
     140    def deleteContact(self, contact): 
     141        index = None 
     142        for nodeid in self.roster.items: 
     143            if str(contact.jid) == nodeid: 
     144                index = self.index(self.roster.items.keys().index(nodeid), 0) 
     145                del self.roster.items[nodeid] 
     146                break 
     147 
     148        if index: 
     149            self.removeRow(index.row(), index.parent()) 
     150         
     151    def addContact(self, contact): 
     152        item = QtGui.QStandardItem() 
     153        self.appendRow(item) 
     154        nodejid = str(contact.jid) 
     155        self.setData(self.index(item.row(), 0),  
     156                     QtCore.QVariant(QtCore.QString(nodejid))) 
     157        if nodejid not in self.roster.items: 
     158            self.roster.items[nodejid] = contact 
     159 
     160class jlibPresence(QAxonObject): 
     161    def __init__(self, parent=None): 
     162        QAxonObject.__init__(self, parent)         
     163        QtCore.QObject.connect(self, QtCore.SIGNAL("acceptSubscription(PyQt_PyObject)"), 
     164                               self.acceptSubscription)  
     165        QtCore.QObject.connect(self, QtCore.SIGNAL("rejectSubscription(PyQt_PyObject)"), 
     166                               self.rejectSubscription)    
     167        QtCore.QObject.connect(self, QtCore.SIGNAL("requestSubscription(PyQt_PyObject)"), 
     168                               self.requestSubscription)  
     169        QtCore.QObject.connect(self, QtCore.SIGNAL("requestUnsubscription(PyQt_PyObject)"), 
     170                               self.requestUnsubscription) 
     171 
     172    def setComponent(self, component): 
     173        QAxonObject.setComponent(self, component) 
     174        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'inbox') 
     175        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'acceptsub') 
     176        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'rejectsub') 
     177        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'requestsub') 
     178        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'requestunsub') 
     179        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'requestedsub') 
     180        self.emit(QtCore.SIGNAL("setupOneMapping(PyQt_PyObject)"), 'requestedunsub') 
     181 
     182    def getLinkages(self): 
     183        linkages = {("xmpp", "%s.presence" % XMPP_CLIENT_NS): ("presencedisp", "inbox"), 
     184                    ("presencedisp", "log"): ('logger', "inbox"), 
     185                    ("presencedisp", "xmpp.subscribe"): ("presencehandler", "requestedsub"), 
     186                    ("presencedisp", "xmpp.unsubscribe"): ("presencehandler", "requestedunsub"), 
     187                    ("presencehandler", "outbox"): ("presencedisp", "forward"), 
     188                    ("presencehandler", "roster"): ("rosterdisp", "forward"), 
     189                    ("presencedisp", "outbox"): ("xmpp", "forward")} 
     190        return dict(presencedisp=PresenceDispatcher(), presencehandler=self.component), linkages 
     191 
     192    def acceptSubscription(self, contact_jid): 
     193        self._deliver(contact_jid, 'acceptsub') 
     194 
     195    def rejectSubscription(self, contact_jid): 
     196        self._deliver(contact_jid, 'rejectsub') 
     197         
     198    def requestSubscription(self, contact_jid): 
     199        self._deliver(contact_jid, 'requestsub') 
     200 
     201    def requestUnsubscription(self, contact_jid): 
     202        self._deliver(contact_jid, 'requestunsub') 
     203 
     204class jlibPresenceComponent(component): 
     205    Inboxes = {"inbox"       : "headstock.api.contact.Presence instance", 
     206               "control"     : "Shutdown the client stream", 
     207               "jid"          : "headstock.api.jid.JID instance received from the server", 
     208               "requestedsub"   : "Received subscription from a peer", 
     209               "requestedunsub" : "Received unsubscription from a peer", 
     210               "acceptsub"   : "Accepted subscription", 
     211               "rejectsub"   : "Rejected subscription", 
     212               "requestsub"  : "Request subscription to a peer", 
     213               "requestunsub"  : "Request unsubscription to a peer"} 
     214     
     215    Outboxes = {"outbox" : "headstock.api.contact.Presence instance to return to the server", 
     216                "signal" : "Shutdown signal", 
     217                "roster" : "", 
     218                "log"    : "log",} 
     219     
     220    def __init__(self): 
     221        super(jlibPresenceComponent, self).__init__() 
     222 
     223    def setQObject(self, qobj): 
     224        self.qobj = qobj 
     225 
     226    def initComponents(self): 
     227        sub = SubscribeTo("JID") 
     228        self.link((sub, 'outbox'), (self, 'jid')) 
     229        self.addChildren(sub) 
     230        sub.activate() 
     231 
     232        return 1 
     233 
     234    def main(self): 
     235        yield self.initComponents() 
     236 
     237        while 1: 
     238            if self.dataReady("control"): 
     239                mes = self.recv("control") 
     240                 
     241                if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): 
     242                    self.send(producerFinished(), "signal") 
     243                    break 
     244 
     245            if self.dataReady("jid"): 
     246                self.from_jid = self.recv('jid') 
     247             
     248            if self.dataReady("requestedsub"): 
     249                p = self.recv("requestedsub") 
     250                p.swap_jids() 
     251 
     252                self.qobj.emit(QtCore.SIGNAL("requestedSubscription(PyQt_PyObject)"), p) 
     253 
     254            if self.dataReady("requestedunsub"): 
     255                p = self.recv("requestedunsub") 
     256                p.swap_jids() 
     257                 
     258                self.qobj.emit(QtCore.SIGNAL("requestedUnsubscription(PyQt_PyObject)"), p) 
     259 
     260            if self.dataReady("acceptsub"): 
     261                to_jid = self.recv("acceptsub") 
     262                p = Presence(from_jid=self.from_jid, to_jid=unicode(to_jid), 
     263                             type=u'subscribed') 
     264                self.send(p, "outbox") 
     265 
     266            if self.dataReady("rejectsub"): 
     267                to_jid = self.recv("rejectsub") 
     268                p = Presence(from_jid=self.from_jid, to_jid=unicode(to_jid), 
     269                             type=u'unsubscribed') 
     270                self.send(p, "outbox") 
     271 
     272            if self.dataReady("requestsub"): 
     273                to_jid = self.recv("requestsub") 
     274                p = Presence(from_jid=self.from_jid, to_jid=unicode(to_jid), 
     275                             type=u'subscribe') 
     276                self.send(p, "outbox") 
     277 
     278            if self.dataReady("requestunsub"): 
     279                to_jid = self.recv("requestunsub") 
     280                p = Presence(from_jid=self.from_jid, to_jid=unicode(to_jid), 
     281                             type=u'unsubscribe') 
     282                self.send(p, "outbox") 
     283 
     284                 
     285            if not self.anyReady(): 
     286                self.pause() 
     287   
     288            yield 1 
     289     
  • oss/jlib/jlib/gui/chat.py

    r709 r710  
    2727                       message) 
    2828        history = self.chat.toPlainText() 
    29         self.chat.setText(history + QtCore.QString("%s: %s\n" % (str(self.qobj.jid), str(message)))) 
     29        self.chat.setText(history + QtCore.QString("%s: %s\n" % (str(self.contact_jid), str(message)))) 
    3030        self.message.clear() 
    3131 
  • oss/jlib/jlib/gui/contact.py

    r709 r710  
    33 
    44from jlib.gui.contactui import Ui_jlibContacts 
    5 from jlib.core.contact import jlibContact, jlibContactComponent, jlibContactModel 
     5from jlib.core.contact import jlibContact, jlibContactComponent, \ 
     6    jlibContactModel, jlibPresence, jlibPresenceComponent 
    67 
    78__all__ = ['jlibContactWidget'] 
     
    1516        Ui_jlibContacts.setupUi(self, parent) 
    1617 
    17         self.qobj = jlibContact(parent=self) 
    18         self.qobj.setComponent(jlibContactComponent()) 
    19         QtCore.QObject.connect(self.qobj, QtCore.SIGNAL("receivedRoster(PyQt_PyObject)"),  
     18        self.contacts.contextMenuEvent = self.contextMenuEvent 
     19 
     20        self.contact = jlibContact(parent=self) 
     21        self.contact.setComponent(jlibContactComponent()) 
     22 
     23        self.presence = jlibPresence(parent=self) 
     24        self.presence.setComponent(jlibPresenceComponent()) 
     25 
     26        QtCore.QObject.connect(self.contact, QtCore.SIGNAL("receivedRoster(PyQt_PyObject)"),  
    2027                               self.receivedRoster) 
     28        QtCore.QObject.connect(self.contact, QtCore.SIGNAL("removedContact(PyQt_PyObject)"), 
     29                               self.removedContact) 
     30        QtCore.QObject.connect(self.contact, QtCore.SIGNAL("addedContact(PyQt_PyObject)"), 
     31                               self.addedContact) 
     32 
     33        QtCore.QObject.connect(self.presence, QtCore.SIGNAL("requestedSubscription(PyQt_PyObject)"), 
     34                               self.requestedSubscription) 
     35 
    2136 
    2237        model = jlibContactModel(parent=self.contacts) 
     
    2843        model = self.contacts.model() 
    2944        model.setRoster(roster) 
     45         
     46    def removedContact(self, contact): 
     47        model = self.contacts.model() 
     48        model.deleteContact(contact) 
     49 
     50    def addedContact(self, contact): 
     51        model = self.contacts.model() 
     52        model.addContact(contact) 
    3053 
    3154    def clicked(self, index): 
     
    3356        self.emit(QtCore.SIGNAL("contactClicked(PyQt_PyObject)"), contact) 
    3457 
     58    def requestedSubscription(self, presence): 
     59        reply = QtGui.QMessageBox.question(self, 'Subscription requested', 
     60                                           "%s wants to connect to you. Do you agree?" % str(presence.to_jid),  
     61                                           QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 
     62        if reply == QtGui.QMessageBox.Yes: 
     63            self.presence.emit(QtCore.SIGNAL("acceptSubscription(PyQt_PyObject)"), presence.to_jid) 
     64            self.presence.emit(QtCore.SIGNAL("requestSubscription(PyQt_PyObject)"), presence.to_jid) 
     65        else: 
     66            self.presence.emit(QtCore.SIGNAL("rejectSubscription(PyQt_PyObject)"), presence.to_jid) 
     67             
     68    def unsubscribeFromContact(self): 
     69        index = self.contacts.currentIndex() 
     70        if index.isValid(): 
     71            contact = index.model().getContact(index) 
     72            reply = QtGui.QMessageBox.question(self, 'Unsubscribe from contact', 
     73                                               "Do you really want to unsubscribe from %s?" % str(contact.jid),  
     74                                               QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 
     75            if reply == QtGui.QMessageBox.Yes: 
     76                self.presence.emit(QtCore.SIGNAL("rejectSubscription(PyQt_PyObject)"), contact.jid) 
     77                self.presence.emit(QtCore.SIGNAL("requestUnsubscription(PyQt_PyObject)"), contact.jid) 
     78 
     79    def contextMenuEvent(self, event): 
     80        menu = QtGui.QMenu(self.parent()) 
     81        actionUnsub = QtGui.QAction(QtCore.QString("Unsubscribe"), self.parent()) 
     82        QtCore.QObject.connect(actionUnsub, QtCore.SIGNAL("triggered()"), self.unsubscribeFromContact) 
     83        menu.addAction(actionUnsub) 
     84        menu.exec_(event.globalPos()) 
     85