From 2ffd6cbcb8f5927373fb0765adc6a4624b66544d Mon Sep 17 00:00:00 2001 From: Yann Leboulanger <asterix@lagaule.org> Date: Fri, 31 Jul 2009 17:11:55 +0200 Subject: [PATCH] store bookmarks in both pubsub and xml, and copy those from xml to pubsub on startup --- src/common/connection.py | 20 +++++++++-------- src/common/connection_handlers.py | 36 +++++++++++++------------------ src/common/pubsub.py | 21 ++++++++++++++++-- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/common/connection.py b/src/common/connection.py index 7c07bdef49..d15e62b176 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -1589,22 +1589,24 @@ class Connection(ConnectionHandlers): iq2.addChild(name='gajim', namespace='gajim:prefs') self.connection.send(iq) - def get_bookmarks(self): + def get_bookmarks(self, storage_type=None): '''Get Bookmarks from storage or PubSub if supported as described in - XEP 0048''' - self.bookmarks = [] #avoid multiple bookmarks when re-connecting + XEP 0048 + storage_type can be set to xml to force request to xml storage''' if not self.connection: return - if self.pubsub_supported: - self.send_pb_retrieve('', 'storage:bookmarks', self._PrivatePubsubCB) + if self.pubsub_supported and storage_type != 'xml': + self.send_pb_retrieve('', 'storage:bookmarks') else: iq = common.xmpp.Iq(typ='get') iq2 = iq.addChild(name='query', namespace=common.xmpp.NS_PRIVATE) iq2.addChild(name='storage', namespace='storage:bookmarks') self.connection.send(iq) - def store_bookmarks(self): - ''' Send bookmarks to the storage namespace or PubSub if supported''' + def store_bookmarks(self, storage_type=None): + ''' Send bookmarks to the storage namespace or PubSub if supported + storage_type can be set to 'pubsub' or 'xml' so store in only one method + else it will be stored on both''' if not self.connection: return iq = common.xmpp.Node(tag='storage', attrs={'xmlns': 'storage:bookmarks'}) @@ -1624,7 +1626,7 @@ class Connection(ConnectionHandlers): if bm.get('print_status', None): iq2.setTagData('print_status', bm['print_status']) - if self.pubsub_supported: + if self.pubsub_supported and storage_type != 'xml': if self.pubsub_publish_options_supported: options = common.xmpp.Node(common.xmpp.NS_DATA + ' x', attrs={'type': 'submit'}) @@ -1639,7 +1641,7 @@ class Connection(ConnectionHandlers): options = None self.send_pb_publish('', 'storage:bookmarks', iq, 'current', options=options) - else: + if storage_type != 'pubsub': iqA = common.xmpp.Iq(typ='set') iqB = iqA.addChild(name='query', namespace=common.xmpp.NS_PRIVATE) iqB.addChild(node=iq) diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index be525b0f31..af4894a9d7 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -1529,7 +1529,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, if storage: ns = storage.getNamespace() if ns == 'storage:bookmarks': - self._parse_bookmarks(storage) + self._parse_bookmarks(storage, 'xml') elif ns == 'gajim:prefs': # Preferences data # http://www.xmpp.org/extensions/xep-0049.html @@ -1548,27 +1548,12 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, annotation = note.getData() self.annotations[jid] = annotation - def _PrivatePubsubCB(self, conn, request): - '''Private data from PubSub''' - gajim.log.debug('_PrivatePubsubCB') - pubsub = request.getTag('pubsub') - if not pubsub: - return - items = pubsub.getTag('items') - if not items: - return - item = items.getTag('item') - if not item: - return - storage = item.getTag('storage') - if storage: - ns = storage.getNamespace() - if ns == 'storage:bookmarks': - self._parse_bookmarks(storage) - - def _parse_bookmarks(self, storage): + def _parse_bookmarks(self, storage, storage_type): + '''storage_type can be 'pubsub' or 'xml' to tell from where we got + bookmarks''' # Bookmarked URLs and Conferences # http://www.xmpp.org/extensions/xep-0048.html + resend_to_pubsub = False confs = storage.getTags('conference') for conf in confs: autojoin_val = conf.getAttr('autojoin') @@ -1592,8 +1577,17 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, log.warn('Invalid JID: %s, ignoring it' % conf.getAttr('jid')) continue - self.bookmarks.append(bm) + if bm not in self.bookmarks: + self.bookmarks.append(bm) + if storage_type == 'xml': + # We got a bookmark that was not in pubsub + resend_to_pubsub = True self.dispatch('BOOKMARKS', self.bookmarks) + if storage_type == 'pubsub': + # We gor bookmarks from pubsub, now get those from xml to merge them + self.get_bookmarks(storage_type='xml') + if self.pubsub_supported and resend_to_pubsub: + self.store_bookmarks('pubsub') def _rosterSetCB(self, con, iq_obj): log.debug('rosterSetCB') diff --git a/src/common/pubsub.py b/src/common/pubsub.py index 105294af78..354d6f97e1 100644 --- a/src/common/pubsub.py +++ b/src/common/pubsub.py @@ -78,7 +78,7 @@ class ConnectionPubSub: self.connection.send(query) - def send_pb_retrieve(self, jid, node, cb, *args, **kwargs): + def send_pb_retrieve(self, jid, node, cb=None, *args, **kwargs): '''Get items from a node''' if not self.connection or self.connected < 2: return @@ -87,7 +87,8 @@ class ConnectionPubSub: r = r.addChild('items', {'node': node}) id_ = self.connection.send(query) - self.__callbacks[id_]=(cb, args, kwargs) + if cb: + self.__callbacks[id_]=(cb, args, kwargs) def send_pb_retract(self, jid, node, id_): '''Delete item from a node''' @@ -143,12 +144,28 @@ class ConnectionPubSub: self.connection.send(query) def _PubSubCB(self, conn, stanza): + gajim.log.debug('_PubsubCB') try: cb, args, kwargs = self.__callbacks.pop(stanza.getID()) cb(conn, stanza, *args, **kwargs) except Exception: pass + pubsub = stanza.getTag('pubsub') + if not pubsub: + return + items = pubsub.getTag('items') + if not items: + return + item = items.getTag('item') + if not item: + return + storage = item.getTag('storage') + if storage: + ns = storage.getNamespace() + if ns == 'storage:bookmarks': + self._parse_bookmarks(storage, 'pubsub') + def request_pb_configuration(self, jid, node): if not self.connection or self.connected < 2: return -- GitLab