Commit 2ca0ca38 authored by Philipp Hörist's avatar Philipp Hörist

Refactor Pubsub/Bookmarks/UserAvatar into own modules

parent 858e472e
......@@ -73,6 +73,9 @@ from gajim.common.modules.last_activity import LastActivity
from gajim.common.modules.http_auth import HTTPAuth
from gajim.common.modules.vcard_temp import VCardTemp
from gajim.common.modules.vcard_avatars import VCardAvatars
from gajim.common.modules.pubsub import PubSub
from gajim.common.modules.bookmarks import Bookmarks
from gajim.common.modules.user_avatar import UserAvatar
from gajim.common.connection_handlers import *
from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action
......@@ -113,7 +116,6 @@ class CommonConnection:
self.old_show = ''
self.priority = app.get_priority(name, 'offline')
self.time_to_reconnect = None
self.bookmarks = []
self.blocked_list = []
self.blocked_contacts = []
......@@ -491,18 +493,6 @@ class CommonConnection:
def account_changed(self, new_name):
self.name = new_name
def get_bookmarks(self):
"""
To be implemented by derived classes
"""
raise NotImplementedError
def store_bookmarks(self):
"""
To be implemented by derived classes
"""
raise NotImplementedError
def get_metacontacts(self):
"""
To be implemented by derived classes
......@@ -670,6 +660,9 @@ class Connection(CommonConnection, ConnectionHandlers):
self.register_module('HTTPAuth', HTTPAuth, self)
self.register_module('VCardTemp', VCardTemp, self)
self.register_module('VCardAvatars', VCardAvatars, self)
self.register_module('PubSub', PubSub, self)
self.register_module('Bookmarks', Bookmarks, self)
self.register_module('UserAvatar', UserAvatar, self)
app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
......@@ -1774,8 +1767,8 @@ class Connection(CommonConnection, ConnectionHandlers):
# ask our VCard
self.get_module('VCardTemp').request_vcard()
# Get bookmarks from private namespace
self.get_bookmarks()
# Get bookmarks
self.get_module('Bookmarks').get_bookmarks()
# Get annotations
self.get_module('Annotations').get_annotations()
......@@ -1916,8 +1909,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.pubsub_publish_options_supported = True
else:
# Remove stored bookmarks accessible to everyone.
self.send_pb_purge(our_jid, 'storage:bookmarks')
self.send_pb_delete(our_jid, 'storage:bookmarks')
self.get_module('Bookmarks').purge_pubsub_bookmarks()
if obj.fjid == hostname:
if nbxmpp.NS_SECLABEL in obj.features:
......@@ -2255,99 +2247,6 @@ class Connection(CommonConnection, ConnectionHandlers):
return True
return False
def _request_bookmarks_xml(self):
if not app.account_is_connected(self.name):
return
iq = nbxmpp.Iq(typ='get')
iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE)
iq2.addChild(name='storage', namespace='storage:bookmarks')
self.connection.send(iq)
app.log('bookmarks').info('Request Bookmarks (PrivateStorage)')
def _check_bookmarks_received(self):
if not self.bookmarks:
self._request_bookmarks_xml()
def get_bookmarks(self, storage_type=None):
"""
Get Bookmarks from storage or PubSub if supported as described in XEP
0048
storage_type can be set to xml to force request to xml storage
"""
if not app.account_is_connected(self.name):
return
if storage_type != 'xml':
if self.pep_supported and self.pubsub_publish_options_supported:
self.send_pb_retrieve('', 'storage:bookmarks')
app.log('bookmarks').info('Request Bookmarks (PubSub)')
# some server (ejabberd) are so slow to answer that we
# request via XML if we don't get answer in the next 30 seconds
app.idlequeue.set_alarm(self._check_bookmarks_received, 30)
return
self._request_bookmarks_xml()
def get_bookmarks_storage_node(self):
NS_GAJIM_BM = 'xmpp:gajim.org/bookmarks'
storage_node = nbxmpp.Node(
tag='storage', attrs={'xmlns': 'storage:bookmarks'})
for bm in self.bookmarks:
conf_node = storage_node.addChild(name="conference")
conf_node.setAttr('jid', bm['jid'])
conf_node.setAttr('autojoin', bm['autojoin'])
conf_node.setAttr('name', bm['name'])
conf_node.setTag(
'minimize', namespace=NS_GAJIM_BM).setData(bm['minimize'])
# Only add optional elements if not empty
# Note: need to handle both None and '' as empty
# thus shouldn't use "is not None"
if bm.get('nick', None):
conf_node.setTagData('nick', bm['nick'])
if bm.get('password', None):
conf_node.setTagData('password', bm['password'])
if bm.get('print_status', None):
conf_node.setTag(
'print_status',
namespace=NS_GAJIM_BM).setData(bm['print_status'])
return storage_node
@staticmethod
def get_bookmark_publish_options():
options = nbxmpp.Node(nbxmpp.NS_DATA + ' x',
attrs={'type': 'submit'})
f = options.addChild('field',
attrs={'var': 'FORM_TYPE', 'type': 'hidden'})
f.setTagData('value', nbxmpp.NS_PUBSUB_PUBLISH_OPTIONS)
f = options.addChild('field', attrs={'var': 'pubsub#access_model'})
f.setTagData('value', 'whitelist')
return options
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 app.account_is_connected(self.name):
return
storage_node = self.get_bookmarks_storage_node()
if storage_type != 'xml':
if self.pep_supported and self.pubsub_publish_options_supported:
self.send_pb_publish(
'', 'storage:bookmarks', storage_node, 'current',
options=self.get_bookmark_publish_options())
app.log('bookmarks').info('Bookmarks published (PubSub)')
if storage_type != 'pubsub':
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVATE, payload=storage_node)
self.connection.send(iq)
app.log('bookmarks').info('Bookmarks published (PrivateStorage)')
def get_roster_delimiter(self):
"""
Get roster group delimiter from storage as described in XEP 0083
......@@ -2614,11 +2513,7 @@ class Connection(CommonConnection, ConnectionHandlers):
destroy.setAttr('jid', jid)
self.connection.send(iq)
i = 0
for bm in self.bookmarks:
if bm['jid'] == room_jid:
del self.bookmarks[i]
break
i += 1
self.get_module('Bookmarks').bookmarks.pop(jid, None)
self.store_bookmarks()
def send_gc_status(self, nick, jid, show, status, auto=False):
......
......@@ -50,7 +50,6 @@ from gajim.common import jingle_xtls
from gajim.common import configpaths
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.commands import ConnectionCommands
from gajim.common.pubsub import ConnectionPubSub
from gajim.common.protocol.caps import ConnectionCaps
from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
from gajim.common.protocol.bytestream import ConnectionIBBytestream
......@@ -339,15 +338,15 @@ class ConnectionPEP(object):
if message:
i = item.addChild('text')
i.addData(message)
self._pubsub_connection.send_pb_publish('', nbxmpp.NS_ACTIVITY, item,
'0')
self.get_module('PubSub').send_pb_publish(
'', nbxmpp.NS_ACTIVITY, item, '0')
def retract_activity(self):
if not self.pep_supported:
return
self.send_activity(None)
# not all client support new XEP, so we still retract
self._pubsub_connection.send_pb_retract('', nbxmpp.NS_ACTIVITY, '0')
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_ACTIVITY, '0')
def send_mood(self, mood, message=None):
if self.connected == 1:
......@@ -363,14 +362,14 @@ class ConnectionPEP(object):
if message:
i = item.addChild('text')
i.addData(message)
self._pubsub_connection.send_pb_publish('', nbxmpp.NS_MOOD, item, '0')
self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_MOOD, item, '0')
def retract_mood(self):
if not self.pep_supported:
return
self.send_mood(None)
# not all client support new XEP, so we still retract
self._pubsub_connection.send_pb_retract('', nbxmpp.NS_MOOD, '0')
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_MOOD, '0')
def send_tune(self, artist='', title='', source='', track=0, length=0,
items=None):
......@@ -399,14 +398,14 @@ class ConnectionPEP(object):
i.addData(length)
if items:
item.addChild(payload=items)
self._pubsub_connection.send_pb_publish('', nbxmpp.NS_TUNE, item, '0')
self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_TUNE, item, '0')
def retract_tune(self):
if not self.pep_supported:
return
self.send_tune(None)
# not all client support new XEP, so we still retract
self._pubsub_connection.send_pb_retract('', nbxmpp.NS_TUNE, '0')
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_TUNE, '0')
def send_nickname(self, nick):
if self.connected == 1:
......@@ -418,13 +417,13 @@ class ConnectionPEP(object):
return
item = nbxmpp.Node('nick', {'xmlns': nbxmpp.NS_NICK})
item.addData(nick)
self._pubsub_connection.send_pb_publish('', nbxmpp.NS_NICK, item, '0')
self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_NICK, item, '0')
def retract_nickname(self):
if not self.pep_supported:
return
self._pubsub_connection.send_pb_retract('', nbxmpp.NS_NICK, '0')
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_NICK, '0')
def send_location(self, info):
if self.connected == 1:
......@@ -439,14 +438,14 @@ class ConnectionPEP(object):
if info.get(field, None):
i = item.addChild(field)
i.addData(info[field])
self._pubsub_connection.send_pb_publish('', nbxmpp.NS_LOCATION, item, '0')
self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_LOCATION, item, '0')
def retract_location(self):
if not self.pep_supported:
return
self.send_location({})
# not all client support new XEP, so we still retract
self._pubsub_connection.send_pb_retract('', nbxmpp.NS_LOCATION, '0')
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_LOCATION, '0')
# basic connection handlers used here and in zeroconf
class ConnectionHandlersBase:
......@@ -915,7 +914,7 @@ class ConnectionHandlersBase:
class ConnectionHandlers(ConnectionArchive313,
ConnectionSocks5Bytestream, ConnectionDisco,
ConnectionCommands, ConnectionPubSub, ConnectionPEP, ConnectionCaps,
ConnectionCommands, ConnectionPEP, ConnectionCaps,
ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream,
ConnectionHTTPUpload):
def __init__(self):
......@@ -923,7 +922,6 @@ ConnectionHTTPUpload):
ConnectionSocks5Bytestream.__init__(self)
ConnectionIBBytestream.__init__(self)
ConnectionCommands.__init__(self)
ConnectionPubSub.__init__(self)
ConnectionPEP.__init__(self, account=self.name, dispatcher=self,
pubsub_connection=self)
ConnectionHTTPUpload.__init__(self)
......@@ -949,8 +947,6 @@ ConnectionHTTPUpload):
self.privacy_default_list = None
app.nec.register_incoming_event(PrivateStorageBookmarksReceivedEvent)
app.nec.register_incoming_event(BookmarksReceivedEvent)
app.nec.register_incoming_event(StreamConflictReceivedEvent)
app.nec.register_incoming_event(StreamOtherHostReceivedEvent)
app.nec.register_incoming_event(MessageReceivedEvent)
......@@ -961,8 +957,6 @@ ConnectionHTTPUpload):
app.ged.register_event_handler('roster-set-received',
ged.CORE, self._nec_roster_set_received)
app.ged.register_event_handler('private-storage-bookmarks-received',
ged.CORE, self._nec_private_storate_bookmarks_received)
app.ged.register_event_handler('roster-received', ged.CORE,
self._nec_roster_received)
app.ged.register_event_handler('iq-error-received', ged.CORE,
......@@ -988,12 +982,9 @@ ConnectionHTTPUpload):
ConnectionHandlersBase.cleanup(self)
ConnectionCaps.cleanup(self)
ConnectionArchive313.cleanup(self)
ConnectionPubSub.cleanup(self)
ConnectionHTTPUpload.cleanup(self)
app.ged.remove_event_handler('roster-set-received',
ged.CORE, self._nec_roster_set_received)
app.ged.remove_event_handler('private-storage-bookmarks-received',
ged.CORE, self._nec_private_storate_bookmarks_received)
app.ged.remove_event_handler('roster-received', ged.CORE,
self._nec_roster_received)
app.ged.remove_event_handler('iq-error-received', ged.CORE,
......@@ -1144,28 +1135,6 @@ ConnectionHTTPUpload):
conn=self, stanza=obj.stanza))
return True
def _nec_private_storate_bookmarks_received(self, obj):
if obj.conn.name != self.name:
return
app.log('bookmarks').info('Received Bookmarks (PrivateStorage)')
resend_to_pubsub = False
bm_jids = [b['jid'] for b in self.bookmarks]
for bm in obj.bookmarks:
if bm['jid'] not in bm_jids:
self.bookmarks.append(bm)
# We got a bookmark that was not in pubsub
resend_to_pubsub = True
if resend_to_pubsub:
self.store_bookmarks('pubsub')
def _PrivateCB(self, con, iq_obj):
"""
Private Data (XEP 048 and 049)
"""
log.debug('PrivateCB')
app.nec.push_incoming_event(PrivateStorageReceivedEvent(None,
conn=self, stanza=iq_obj))
def _SecLabelCB(self, con, iq_obj):
"""
Security Label callback, used for catalogues.
......@@ -1540,8 +1509,8 @@ ConnectionHTTPUpload):
# ask our VCard
self.get_module('VCardTemp').request_vcard()
# Get bookmarks from private namespace
self.get_bookmarks()
# Get bookmarks
self.get_module('Bookmarks').get_bookmarks()
# Get annotations from private namespace
self.get_module('Annotations').get_annotations()
......@@ -1645,7 +1614,6 @@ ConnectionHTTPUpload):
nbxmpp.NS_MUC_OWNER)
con.RegisterHandler('iq', self._MucAdminCB, 'result',
nbxmpp.NS_MUC_ADMIN)
con.RegisterHandler('iq', self._PrivateCB, 'result', nbxmpp.NS_PRIVATE)
con.RegisterHandler('iq', self._SecLabelCB, 'result',
nbxmpp.NS_SECLABEL_CATALOG)
con.RegisterHandler('iq', self._CommandExecuteCB, 'set',
......@@ -1657,8 +1625,6 @@ ConnectionHTTPUpload):
con.RegisterHandler('iq', self._PrivacySetCB, 'set', nbxmpp.NS_PRIVACY)
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM_1)
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM_2)
con.RegisterHandler('iq', self._PubSubCB, 'result')
con.RegisterHandler('iq', self._PubSubErrorCB, 'error')
con.RegisterHandler('iq', self._JingleCB, 'result')
con.RegisterHandler('iq', self._JingleCB, 'error')
con.RegisterHandler('iq', self._JingleCB, 'set', nbxmpp.NS_JINGLE)
......
......@@ -309,118 +309,6 @@ class MucAdminReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.users_dict[jid]['reason'] = reason
return True
class PrivateStorageReceivedEvent(nec.NetworkIncomingEvent):
name = 'private-storage-received'
base_network_events = []
def generate(self):
query = self.stanza.getTag('query')
self.storage_node = query.getTag('storage')
if self.storage_node:
self.namespace = self.storage_node.getNamespace()
return True
class BookmarksHelper:
def parse_bookmarks(self):
self.bookmarks = []
NS_GAJIM_BM = 'xmpp:gajim.org/bookmarks'
confs = self.storage_node.getTags('conference')
for conf in confs:
autojoin_val = conf.getAttr('autojoin')
if not autojoin_val: # not there (it's optional)
autojoin_val = False
minimize_val = conf.getTag('minimize', namespace=NS_GAJIM_BM)
if not minimize_val: # not there, try old Gajim behaviour
minimize_val = conf.getAttr('minimize')
if not minimize_val: # not there (it's optional)
minimize_val = False
else:
minimize_val = minimize_val.getData()
print_status = conf.getTag('print_status', namespace=NS_GAJIM_BM)
if not print_status: # not there, try old Gajim behaviour
print_status = conf.getTagData('print_status')
if not print_status: # not there, try old Gajim behaviour
print_status = conf.getTagData('show_status')
else:
print_status = print_status.getData()
try:
jid = helpers.parse_jid(conf.getAttr('jid'))
except helpers.InvalidFormat:
log.warning('Invalid JID: %s, ignoring it'
% conf.getAttr('jid'))
continue
bm = {'name': conf.getAttr('name'),
'jid': jid,
'autojoin': autojoin_val,
'minimize': minimize_val,
'password': conf.getTagData('password'),
'nick': conf.getTagData('nick'),
'print_status': print_status}
bm_jids = [b['jid'] for b in self.bookmarks]
if bm['jid'] not in bm_jids:
self.bookmarks.append(bm)
class PrivateStorageBookmarksReceivedEvent(nec.NetworkIncomingEvent,
BookmarksHelper):
name = 'private-storage-bookmarks-received'
base_network_events = ['private-storage-received']
def generate(self):
self.conn = self.base_event.conn
self.storage_node = self.base_event.storage_node
if self.base_event.namespace != nbxmpp.NS_BOOKMARKS:
return
self.parse_bookmarks()
return True
class BookmarksReceivedEvent(nec.NetworkIncomingEvent):
name = 'bookmarks-received'
base_network_events = ['private-storage-bookmarks-received',
'pubsub-bookmarks-received']
def generate(self):
self.conn = self.base_event.conn
self.bookmarks = self.base_event.bookmarks
return True
class PubsubReceivedEvent(nec.NetworkIncomingEvent):
name = 'pubsub-received'
base_network_events = []
def generate(self):
self.jid = self.stanza.getFrom()
self.pubsub_node = self.stanza.getTag('pubsub')
if not self.pubsub_node:
return
self.items_node = self.pubsub_node.getTag('items')
if not self.items_node:
return
return True
class PubsubBookmarksReceivedEvent(nec.NetworkIncomingEvent, BookmarksHelper):
name = 'pubsub-bookmarks-received'
base_network_events = ['pubsub-received']
def generate(self):
self.conn = self.base_event.conn
self.item_node = self.base_event.items_node.getTag('item')
if not self.item_node:
return
children = self.item_node.getChildren()
if not children:
return
self.storage_node = children[0]
ns = self.storage_node.getNamespace()
if ns != nbxmpp.NS_BOOKMARKS:
return
self.parse_bookmarks()
return True
class IqErrorReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
name = 'iq-error-received'
base_network_events = []
......
......@@ -119,6 +119,11 @@ class RequestAvatar(IntEnum):
ROOM = 1
USER = 2
@unique
class BookmarkStorageType(IntEnum):
PRIVATE = 0
PUBSUB = 1
SSLError = {
2: _("Unable to get issuer certificate"),
3: _("Unable to get certificate CRL"),
......
This diff is collapsed.
# This file is part of Gajim.
#
# Gajim 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; version 3 only.
#
# Gajim 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
# XEP-0084: User Avatar
import logging
import base64
import binascii
import nbxmpp
from gajim.common import app
from gajim.common.exceptions import StanzaMalformed
log = logging.getLogger('gajim.c.m.user_avatar')
class UserAvatar:
def __init__(self, con):
self._con = con
self._account = con.name
self.handlers = []
def get_pubsub_avatar(self, jid, item_id):
log.info('Request: %s %s', jid, item_id)
self._con.get_module('PubSub').send_pb_retrieve(
jid, 'urn:xmpp:avatar:data', item_id, self._avatar_received)
def _validate_avatar_node(self, stanza):
jid = stanza.getFrom()
if jid is None:
jid = self._con.get_own_jid().getStripped()
else:
jid = jid.getStripped()
if nbxmpp.isErrorNode(stanza):
raise StanzaMalformed(stanza.getErrorMsg())
pubsub_node = stanza.getTag('pubsub')
if pubsub_node is None:
raise StanzaMalformed('No pubsub node', stanza)
items_node = pubsub_node.getTag('items')
if items_node is None:
raise StanzaMalformed('No items node', stanza)
if items_node.getAttr('node') != 'urn:xmpp:avatar:data':
raise StanzaMalformed('Wrong namespace', stanza)
item = items_node.getTag('item')
if item is None:
raise StanzaMalformed('No item node', stanza)
sha = item.getAttr('id')
data_tag = item.getTag('data', namespace='urn:xmpp:avatar:data')
if sha is None or data_tag is None:
raise StanzaMalformed('No id attr or data node found', stanza)
data = data_tag.getData()
if data is None:
raise StanzaMalformed('Data node empty', stanza)
data = base64.b64decode(data.encode('utf-8'))
return jid, sha, data
def _avatar_received(self, conn, stanza):
try:
jid, sha, data = self._validate_avatar_node(stanza)
except (StanzaMalformed, binascii.Error) as error:
log.warning('Error: %s %s', stanza.getFrom(), error)
return
log.info('Received: %s %s', jid, sha)
app.interface.save_avatar(data)
if self._con.get_own_jid().bareMatch(jid):
app.config.set_per('accounts', self._account, 'avatar_sha', sha)
else:
own_jid = self._con.get_own_jid().getStripped()
app.logger.set_avatar_sha(own_jid, jid, sha)
app.contacts.set_avatar(self._account, jid, sha)
app.interface.update_avatar(self._account, jid)
......@@ -485,7 +485,8 @@ class AvatarNotificationPEP(AbstractPEP):
for item in items.getTags('item'):
metadata = item.getTag('metadata')
if metadata is None:
app.log('avatar').warning('Invalid avatar stanza:\n%s', items)
app.log('c.m.user_avatar').warning(
'Invalid avatar stanza:\n%s', items)
break
info = item.getTag('metadata').getTag('info')
if info is not None:
......@@ -498,23 +499,22 @@ class AvatarNotificationPEP(AbstractPEP):
con = app.connections[account]
if self.avatar is None:
# Remove avatar
app.log('avatar').info('Remove (Pubsub): %s', jid)
app.log('c.m.user_avatar').info('Remove: %s', jid)
app.contacts.set_avatar(account, jid, None)
own_jid = con.get_own_jid().getStripped()
app.logger.set_avatar_sha(own_jid, jid, None)
app.interface.update_avatar(account, jid)
else:
sha = app.contacts.get_avatar_sha(account, jid)
app.log('avatar').info(
'Update (Pubsub): %s %s', jid, self.avatar['id'])
app.log('c.m.user_avatar').info(
'Update: %s %s', jid, self.avatar['id'])
if sha == self.avatar['id']:
app.log('avatar').info(
'Avatar already known (Pubsub): %s %s',
app.log('c.m.user_avatar').info(
'Avatar already known: %s %s',
jid, self.avatar['id'])
return
app.log('avatar').info('Request (Pubsub): %s', jid)
con.get_pubsub_avatar(jid, 'urn:xmpp:avatar:data',
self.avatar['id'])
con.get_module('UserAvatar').get_pubsub_avatar(
jid, self.avatar['id'])
SUPPORTED_PERSONAL_USER_EVENTS = [
......
......@@ -1900,11 +1900,13 @@ class ManageBookmarksWindow:
iter_ = self.treestore.append(None, [None, account, None, None,
None, None, None, None])
for bookmark in app.connections[account].bookmarks:
con = app.connections[account]
bookmarks = con.get_module('Bookmarks').bookmarks
for jid, bookmark in bookmarks.items():
if not bookmark['name']:
# No name was given for this bookmark.
# Use the first part of JID instead...
name = bookmark['jid'].split("@")[0]
name = jid.split("@")[0]
bookmark['name'] = name
# make '1', '0', 'true', 'false' (or other) to True/False
......@@ -1920,7 +1922,7 @@ class ManageBookmarksWindow:
self.treestore.append(iter_, [
account,
bookmark['name'],
bookmark['jid'],
jid,
autojoin,
minimize,
bookmark['password'],
......@@ -2047,15 +2049,17 @@ class ManageBookmarksWindow:
Parse the treestore data into our new bookmarks array, then send the new
bookmarks to the server.
"""
(model, iter_) = self.selection.get_selected()
if iter_ and model.iter_parent(iter_):
#bookmark selected, check it
# bookmark selected, check it
if not self.check_valid_bookmark():
return
for account in self.treestore:
acct = account[1]
app.connections[acct].bookmarks = []
con = app.connections[acct]
con.get_module('Bookmarks').bookmarks = {}
for bm in account.iterchildren():
# Convert True/False/None to '1' or '0'
......@@ -2067,13 +2071,17 @@ class ManageBookmarksWindow:
nick = bm[6]
# create the bookmark-dict
bmdict = { 'name': name, 'jid': jid, 'autojoin': autojoin,
'minimize': minimize, 'password': pw, 'nick': nick,
bmdict = {
'name': name,
'autojoin': autojoin,
'minimize': minimize,
'password': pw,
'nick': nick,
'print_status': bm[7]}
app.connections[acct].bookmarks.append(bmdict)
con.get_module('Bookmarks').bookmarks[jid] =