diff options
Diffstat (limited to 'poezio/bookmarks.py')
-rw-r--r-- | poezio/bookmarks.py | 161 |
1 files changed, 86 insertions, 75 deletions
diff --git a/poezio/bookmarks.py b/poezio/bookmarks.py index 0406de94..64d7a437 100644 --- a/poezio/bookmarks.py +++ b/poezio/bookmarks.py @@ -30,11 +30,20 @@ Adding a remote bookmark: import functools import logging -from typing import Optional, List, Union - -from slixmpp import JID +from typing import ( + Callable, + List, + Optional, + Union, +) + +from slixmpp import ( + InvalidJID, + JID, +) +from slixmpp.exceptions import IqError, IqTimeout from slixmpp.plugins.xep_0048 import Bookmarks, Conference, URL -from poezio.common import safeJID +from poezio.connection import Connection from poezio.config import config log = logging.getLogger(__name__) @@ -42,20 +51,43 @@ log = logging.getLogger(__name__) class Bookmark: def __init__(self, - jid: JID, + jid: Union[JID, str], name: Optional[str] = None, autojoin=False, nick: Optional[str] = None, password: Optional[str] = None, method='local') -> None: - self.jid = jid - self.name = name or jid + try: + if isinstance(jid, JID): + self._jid = jid + else: + self._jid = JID(jid) + except InvalidJID: + log.debug('Invalid JID %r provided for bookmark', jid) + raise + self.name = name or str(self.jid) self.autojoin = autojoin self.nick = nick self.password = password self._method = method @property + def jid(self) -> JID: + """Jid getter""" + return self._jid + + @jid.setter + def jid(self, jid: JID) -> None: + try: + if isinstance(jid, JID): + self._jid = jid + else: + self._jid = JID(jid) + except InvalidJID: + log.debug('Invalid JID %r provided for bookmark', jid) + raise + + @property def method(self) -> str: return self._method @@ -86,7 +118,7 @@ class Bookmark: def local(self) -> str: """Generate a str for local storage""" - local = self.jid + local = str(self.jid) if self.nick: local += '/%s' % self.nick local += ':' @@ -130,8 +162,8 @@ class Bookmark: class BookmarkList: def __init__(self): - self.bookmarks = [] # type: List[Bookmark] - preferred = config.get('use_bookmarks_method').lower() + self.bookmarks: List[Bookmark] = [] + preferred = config.getstr('use_bookmarks_method').lower() if preferred not in ('pep', 'privatexml'): preferred = 'privatexml' self.preferred = preferred @@ -149,7 +181,7 @@ class BookmarkList: return self.bookmarks[key] return None - def __in__(self, key) -> bool: + def __contains__(self, key) -> bool: if isinstance(key, (str, JID)): for bookmark in self.bookmarks: if bookmark.jid == key: @@ -191,17 +223,17 @@ class BookmarkList: self.preferred = value config.set_and_save('use_bookmarks_method', value) - def save_remote(self, xmpp, callback): + async def save_remote(self, xmpp: Connection): """Save the remote bookmarks.""" if not any(self.available_storage.values()): return method = 'xep_0049' if self.preferred == 'privatexml' else 'xep_0223' if method: - xmpp.plugin['xep_0048'].set_bookmarks( + return await xmpp.plugin['xep_0048'].set_bookmarks( stanza_storage(self.bookmarks), method=method, - callback=callback) + ) def save_local(self): """Save the local bookmarks.""" @@ -209,86 +241,65 @@ class BookmarkList: if bookmark.method == 'local') config.set_and_save('rooms', local) - def save(self, xmpp, core=None, callback=None): + async def save(self, xmpp: Connection, core=None): """Save all the bookmarks.""" self.save_local() - - def _cb(iq): - if callback: - callback(iq) - if iq["type"] == "error" and core: - core.information('Could not save remote bookmarks.', 'Error') - elif core: - core.information('Bookmarks saved', 'Info') - - if config.get('use_remote_bookmarks'): - self.save_remote(xmpp, _cb) - - def get_pep(self, xmpp, callback): + if config.getbool('use_remote_bookmarks'): + try: + result = await self.save_remote(xmpp) + if core is not None: + core.information('Bookmarks saved', 'Info') + return result + except (IqError, IqTimeout): + if core is not None: + core.information( + 'Could not save remote bookmarks.', + 'Error' + ) + raise + + async def get_pep(self, xmpp: Connection): """Add the remotely stored bookmarks via pep to the list.""" + iq = await xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0223') + for conf in iq['pubsub']['items']['item']['bookmarks'][ + 'conferences']: + if isinstance(conf, URL): + continue + bookm = Bookmark.parse(conf) + self.append(bookm) + return iq - def _cb(iq): - if iq['type'] == 'result': - for conf in iq['pubsub']['items']['item']['bookmarks'][ - 'conferences']: - if isinstance(conf, URL): - continue - b = Bookmark.parse(conf) - self.append(b) - if callback: - callback(iq) - - xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0223', callback=_cb) - - def get_privatexml(self, xmpp, callback): + async def get_privatexml(self, xmpp: Connection): """ Fetch the remote bookmarks stored via privatexml. """ - def _cb(iq): - if iq['type'] == 'result': - for conf in iq['private']['bookmarks']['conferences']: - b = Bookmark.parse(conf) - self.append(b) - if callback: - callback(iq) + iq = await xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0049') + for conf in iq['private']['bookmarks']['conferences']: + bookm = Bookmark.parse(conf) + self.append(bookm) + return iq - xmpp.plugin['xep_0048'].get_bookmarks(method='xep_0049', callback=_cb) - - def get_remote(self, xmpp, information, callback): + async def get_remote(self, xmpp: Connection, information: Callable): """Add the remotely stored bookmarks to the list.""" - force = config.get('force_remote_bookmarks') - if xmpp.anon or not (any(self.available_storage.values()) or force): + if xmpp.anon or not any(self.available_storage.values()): information('No remote bookmark storage available', 'Warning') return - - if force and not any(self.available_storage.values()): - old_callback = callback - method = 'pep' if self.preferred == 'pep' else 'privatexml' - - def new_callback(result): - if result['type'] != 'error': - self.available_storage[method] = True - old_callback(result) - else: - information('No remote bookmark storage available', - 'Warning') - - callback = new_callback - if self.preferred == 'pep': - self.get_pep(xmpp, callback=callback) + return await self.get_pep(xmpp) else: - self.get_privatexml(xmpp, callback=callback) + return await self.get_privatexml(xmpp) def get_local(self): """Add the locally stored bookmarks to the list.""" - rooms = config.get('rooms') + rooms = config.getlist('rooms') if not rooms: return - rooms = rooms.split(':') for room in rooms: - jid = safeJID(room) + try: + jid = JID(room) + except InvalidJID: + continue if jid.bare == '': continue if jid.resource != '': @@ -307,7 +318,7 @@ class BookmarkList: self.append(b) -def stanza_storage(bookmarks: BookmarkList) -> Bookmarks: +def stanza_storage(bookmarks: Union[BookmarkList, List[Bookmark]]) -> Bookmarks: """Generate a <storage/> stanza with the conference elements.""" storage = Bookmarks() for b in (b for b in bookmarks if b.method == 'remote'): |