poezio/src/bookmark.py

224 lines
6.8 KiB
Python
Raw Normal View History

2011-11-26 22:05:09 +00:00
import os
2012-03-13 20:39:06 +00:00
import logging
2011-11-28 20:27:40 +00:00
from sys import version_info
2011-11-26 22:05:09 +00:00
2011-11-26 14:47:41 +00:00
from sleekxmpp.plugins.xep_0048 import *
from common import safeJID
2011-11-26 22:05:09 +00:00
from config import config
2012-03-13 20:39:06 +00:00
log = logging.getLogger(__name__)
2011-11-28 20:27:40 +00:00
def iter(xml, tag=''):
if version_info[1] >= 2:
return xml.iter(tag)
else:
return xml.getiterator(tag)
2011-11-26 22:05:09 +00:00
preferred = config.get('use_bookmarks_method', 'pep').lower()
if preferred not in ('pep', 'privatexml'):
preferred = 'privatexml'
2012-03-13 20:39:06 +00:00
not_preferred = 'privatexml' if preferred == 'pep' else 'privatexml'
2011-11-26 22:05:09 +00:00
methods = ('local', preferred, not_preferred)
2011-11-26 14:47:41 +00:00
class Bookmark(object):
2011-11-26 22:05:09 +00:00
possible_methods = methods
2012-03-13 20:39:06 +00:00
def __init__(self, jid, name=None, autojoin=False, nick=None, password=None, method='privatexml'):
2011-11-26 14:47:41 +00:00
self.jid = jid
self.name = name or jid
self.autojoin = autojoin
self.nick = nick
self.password = password
self._method = method
@property
def method(self):
return self._method
@method.setter
def method(self, value):
if value not in self.possible_methods:
2012-03-13 20:39:06 +00:00
log.debug('Could not set bookmark storing method: %s', value)
2011-11-26 14:47:41 +00:00
return
self._method = value
2011-11-26 22:05:09 +00:00
def __repr__(self):
2013-06-08 10:28:07 +00:00
return '<%s%s%s>' % (self.jid, ('/'+self.nick) if self.nick else '', '|autojoin' if self.autojoin else '')
2011-11-26 22:05:09 +00:00
2011-11-26 14:47:41 +00:00
def stanza(self):
"""
Generate a <conference/> stanza from the instance
"""
el = Conference()
el['name'] = self.name
el['jid'] = self.jid
el['autojoin'] = 'true' if self.autojoin else 'false'
if self.nick:
el['nick'] = self.nick
2011-11-26 14:47:41 +00:00
if self.password:
el['password'] = self.password
2011-11-26 14:47:41 +00:00
return el
def local(self):
"""Generate a str for local storage"""
local = self.jid
if self.nick:
local += '/%s' % self.nick
local += ':'
if self.password:
config.set_and_save('password', self.password, section=self.jid)
return local
def parse_from_element(el, method=None):
"""
Generate a Bookmark object from a <conference/> element
"""
jid = el.get('jid')
name = el.get('name')
2012-01-26 09:04:42 +00:00
autojoin = True if el.get('autojoin', 'false').lower() in ('true', '1') else False
nick = None
2011-11-28 20:27:40 +00:00
for n in iter(el, 'nick'):
nick = nick.text
password = None
2011-11-28 20:27:40 +00:00
for p in iter(el, 'password'):
password = p.text
return Bookmark(jid, name, autojoin, nick, password, method)
bookmarks = []
def get_by_jid(value):
"""
Get a bookmark by bare jid
"""
for item in bookmarks:
if item.jid == value:
return item
def remove(value):
"""
Remove a bookmark (with its jid or directly the Bookmark object).
"""
if isinstance(value, str):
value = get_by_jid(value)
bookmarks.remove(value)
def stanza_storage(method):
"""Generate a <storage/> stanza with the conference elements."""
storage = Bookmarks()
for b in filter(lambda b: b.method == method, bookmarks):
storage.append(b.stanza())
return storage
def save_pep(xmpp):
"""Save the remote bookmarks via PEP."""
xmpp.plugin['xep_0048'].set_bookmarks(stanza_storage('pep'),
method='xep_0223')
def save_privatexml(xmpp):
""""Save the remote bookmarks with privatexml."""
xmpp.plugin['xep_0048'].set_bookmarks(stanza_storage('privatexml'),
method='xep_0049')
def save_remote(xmpp, method=preferred):
"""Save the remote bookmarks."""
method = "privatexml" if method != 'pep' else 'pep'
try:
if method is 'privatexml':
xmpp.plugin['xep_0048'].set_bookmarks(stanza_storage('privatexml'),
method='xep_0049')
else:
xmpp.plugin['xep_0048'].set_bookmarks(stanza_storage('pep'),
method='xep_0223')
except:
2012-03-13 20:39:06 +00:00
import traceback
log.debug("Could not save the bookmarks:\n%s" % traceback.format_exc())
return False
return True
def save_local():
"""Save the local bookmarks."""
2012-03-30 13:57:43 +00:00
all = ''.join(bookmark.local() for bookmark in bookmarks if bookmark.method is 'local')
config.set_and_save('rooms', all)
def save(xmpp, core=None):
"""Save all the bookmarks."""
save_local()
if config.get('use_remote_bookmarks', 'true').lower() != 'false':
preferred = config.get('use_bookmarks_method', 'privatexml')
if not save_remote(xmpp, method=preferred) and core:
core.information('Could not save bookmarks.', 'Error')
2012-03-13 20:39:06 +00:00
return False
elif core:
2012-03-13 20:39:06 +00:00
core.information('Bookmarks saved', 'Info')
return True
def get_pep(xmpp):
"""Add the remotely stored bookmarks via pep to the list."""
try:
iq = xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0223', block=True)
except:
return False
2011-11-28 20:27:40 +00:00
for conf in iter(iq.xml, '{storage:bookmarks}conference'):
b = Bookmark.parse_from_element(conf, method='pep')
if not get_by_jid(b.jid):
bookmarks.append(b)
return True
def get_privatexml(xmpp):
"""Add the remotely stored bookmarks via privatexml to the list."""
try:
iq = xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0049', block=True)
except:
return False
2011-11-28 20:27:40 +00:00
for conf in iter(iq.xml, '{storage:bookmarks}conference'):
b = Bookmark.parse_from_element(conf, method='privatexml')
if not get_by_jid(b.jid):
bookmarks.append(b)
return True
def get_remote(xmpp):
"""Add the remotely stored bookmarks to the list."""
if xmpp.anon:
return
method = config.get('use_bookmarks_method', '')
if not method:
pep, privatexml = True, True
for method in methods[1:]:
if method == 'pep':
pep = get_pep(xmpp)
else:
privatexml = get_privatexml(xmpp)
if pep and not privatexml:
config.set_and_save('use_bookmarks_method', 'pep')
elif privatexml and not pep:
config.set_and_save('use_bookmarks_method', 'privatexml')
elif not pep and not privatexml:
config.set_and_save('use_bookmarks_method', '')
else:
if method == 'pep':
get_pep(xmpp)
else:
get_privatexml(xmpp)
def get_local():
"""Add the locally stored bookmarks to the list."""
rooms = config.get('rooms', '')
if not rooms:
return
rooms = rooms.split(':')
for room in rooms:
jid = safeJID(room)
if jid.bare == '':
continue
if jid.resource != '':
nick = jid.resource
else:
nick = None
passwd = config.get_by_tabname('password', '', jid.bare, fallback=False) or None
b = Bookmark(jid.bare, autojoin=True, nick=nick, password=passwd, method='local')
if not get_by_jid(b.jid):
bookmarks.append(b)