bookmarks
– Bookmark support (XEP-0048)¶
This module provides support for storing and retrieving bookmarks on the server as per Bookmarks.
Service¶
-
class
aioxmpp.
BookmarkClient
(client, **kwargs)[source]¶ Supports retrieval and storage of bookmarks on the server. It currently only supports Private XML Storage as backend.
There is the general rule never to modify the bookmark instances retrieved from this class (either by
get_bookmarks()
or as an argument to one of the signals). If you need to modify a bookmark for use withupdate_bookmark()
usecopy.copy()
to create a copy.-
async
sync
()[source]¶ Sync the bookmarks between the local representation and the server.
This must be called periodically to assure that the signals are fired.
-
async
get_bookmarks
()[source]¶ Get the stored bookmarks from the server. Causes signals to be fired to reflect the changes.
- Returns
a list of bookmarks
-
async
set_bookmarks
(bookmarks)[source]¶ Store the sequence of bookmarks bookmarks.
Causes signals to be fired to reflect the changes.
Note
This should normally not be used. It does not mitigate the race condition between clients concurrently modifying the bookmarks and may lead to data loss. Use
add_bookmark()
,discard_bookmark()
andupdate_bookmark()
instead. This method still has use-cases (modifying the bookmarklist at large, e.g. by syncing the remote store with local data).
The following methods change the bookmark list in a get-modify-set pattern, to mitigate the danger of race conditions and should be used in most circumstances:
-
async
add_bookmark
(new_bookmark, *, max_retries=3)[source]¶ Add a bookmark and check whether it was successfully added to the bookmark list. Already existent bookmarks are not added twice.
- Parameters
new_bookmark (an instance of
Bookmark
) – the bookmark to addmax_retries (
int
) – the number of retries if setting the bookmark fails
- Raises
RuntimeError – if the bookmark is not in the bookmark list after max_retries retries.
After setting the bookmark it is checked, whether the bookmark is in the online storage, if it is not it is tried again at most max_retries times to add the bookmark. A
RuntimeError
is raised if the bookmark could not be added successfully after max_retries.
-
async
discard_bookmark
(bookmark_to_remove, *, max_retries=3)[source]¶ Remove a bookmark and check it has been removed.
- Parameters
bookmark_to_remove (a
Bookmark
subclass.) – the bookmark to removemax_retries (
int
) – the number of retries of removing the bookmark fails.
- Raises
RuntimeError – if the bookmark is not removed from bookmark list after max_retries retries.
If there are multiple occurrences of the same bookmark exactly one is removed.
This does nothing if the bookmarks does not match an existing bookmark according to bookmark-equality.
After setting the bookmark it is checked, whether the bookmark is removed in the online storage, if it is not it is tried again at most max_retries times to remove the bookmark. A
RuntimeError
is raised if the bookmark could not be removed successfully after max_retries.
-
async
update_bookmark
(old, new, *, max_retries=3)[source]¶ Update a bookmark and check it was successful.
The bookmark matches an existing bookmark old according to bookmark equalitiy and replaces it by new. The bookmark new is added if no bookmark matching old exists.
- Parameters
old – the bookmark to replace
new – the replacement bookmark
max_retries (
int
) – the number of retries of removing the bookmark fails.
- Raises
RuntimeError – if the bookmark is not in the bookmark list after max_retries retries.
After replacing the bookmark it is checked, whether the bookmark new is in the online storage, if it is not it is tried again at most max_retries times to replace the bookmark. A
RuntimeError
is raised if the bookmark could not be replaced successfully after max_retries.Note
Do not modify a bookmark retrieved from the signals or from
get_bookmarks()
to obtain the bookmark new, this will lead to data corruption as they are passed by reference. Instead usecopy.copy()
and modify the copy.
The following signals are provided that allow tracking the changes to the bookmark list:
-
signal
on_bookmark_added
(added_bookmark)¶ Fires when a new bookmark is added.
-
signal
on_bookmark_removed
(removed_bookmark)¶ Fires when a bookmark is removed.
-
signal
on_bookmark_changed
(old_bookmark, new_bookmark)¶ Fires when a bookmark is changed.
Note
A heuristic is used to determine the change of bookmarks and the reported changes may not directly reflect the used methods, but it will always be possible to construct the list of bookmarks from the events. For example, when using
update_bookmark()
to change the JID of aConference
bookmark a removed and a added signal will fire.Note
The bookmark protocol is prone to race conditions if several clients access it concurrently. Be careful to use a get-modify-set pattern or the provided highlevel interface.
Note
Some other clients extend the bookmark format. For now those extensions are silently dropped by our XSOs, and therefore are lost, when changing the bookmarks with aioxmpp. This is considered a bug to be fixed in the future.
-
async
XSOs¶
All bookmark types must adhere to the following ABC:
-
class
aioxmpp.bookmarks.
Bookmark
(*args, **kwargs)[source]¶ A bookmark XSO abstract base class.
Every XSO class registered as child of
Storage
must be aBookmark
subclass.Bookmarks must provide the following interface:
-
primary
¶ Return the primary category of the bookmark.
The internal structure of the category is opaque to the code using it; only equality and hashing must be provided and operate by value. It is recommended that this be either a single datum (e.g. a string or JID) or a tuple of data items.
Together with the type and
secondary
this must fully determine the value of the bookmark.This is used in the computation of the change signals. Bookmarks with different type or
primary
keys cannot be identified as changed from/to one another.
-
secondary
¶ Return the tuple of secondary categories of the bookmark.
Together with the type and
primary
they must fully determine the value of the bookmark.This is used in the computation of the change signals. The categories in the tuple are ordered in decreasing precedence, when calculating which bookmarks have changed the ones which mismatch in the category with the lowest precedence are grouped together.
The length of the tuple must be the same for all bookmarks of a type.
-
name
¶ The human-readable label or description of the bookmark.
Equality is defined in terms of those properties:
-
__eq__
(other)[source]¶ Compare for equality by value and type.
The value of a bookmark must be fully determined by the values of the
primary
andsecondary
properties.This is used for generating the bookmark list change signals and for the get-modify-set methods.
It is highly recommended not to redefine
__eq__()
in a subclass, if you do so make sure that the following axiom relating__eq__()
,primary
andsecondary
holds:(type(a) == type(b) and a.primary == b.primary and a.secondary == b.secondary)
if and only if:
a == b
Otherwise the generation of bookmark change signals is not guaranteed to be correct.
-
The following XSOs are used to represent an manipulate bookmark lists.
-
class
aioxmpp.bookmarks.
Conference
(*args, **kwargs)[source]¶ An bookmark for a groupchat.
-
name
¶ The name of the bookmark.
-
jid
¶ The jid under which the groupchat is accessible.
-
autojoin
¶ Whether to join automatically, when the client starts.
-
nick
¶ The nick to use in the groupchat.
-
password
¶ The password used to access the groupchat.
-
-
class
aioxmpp.bookmarks.
URL
(*args, **kwargs)[source]¶ An URL bookmark.
-
name
¶ The name of the bookmark.
-
url
¶ The URL the bookmark saves.
-
To register custom bookmark classes use:
-
aioxmpp.bookmarks.
as_bookmark_class
(xso_class)[source]¶ Decorator to register xso_class as a custom bookmark class.
This is necessary to store and retrieve such bookmarks. The registered class must be a subclass of the abstract base class
Bookmark
.
The following is used internally as the XSO container for bookmarks.
Notes on usage¶
It is highly recommended to interact with the bookmark client via the
provided signals and the get-modify-set methods
add_bookmark()
,
discard_bookmark()
and
update_bookmark()
. Using
set_bookmarks()
directly is error prone and
might cause data loss due to race conditions.