Skip to content
This repository has been archived by the owner on Jan 14, 2024. It is now read-only.

Commit

Permalink
implement vcard-temp (XEP-0054)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianriese committed Dec 11, 2017
1 parent 9b96ccc commit 95c0a64
Show file tree
Hide file tree
Showing 10 changed files with 496 additions and 0 deletions.
42 changes: 42 additions & 0 deletions aioxmpp/vcard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
########################################################################
# File name: __init__.py
# This file is part of: aioxmpp
#
# LICENSE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
########################################################################
"""
:mod:`~aioxmpp.vcard` --- vcard-temp support (:xep:`0054`)
##########################################################
This subpackage provides minimal support for setting and retrieving
vCard as per :xep:`0054`.
.. versionadded:: 0.10
We supply the service:
.. autoclass:: VCardService()
.. currentmodule:: aioxmpp.vcard.xso
The VCards are exposed as:
.. autoclass:: VCard()
"""
from .service import VCardService # NOQA
97 changes: 97 additions & 0 deletions aioxmpp/vcard/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
########################################################################
# File name: xso.py
# This file is part of: aioxmpp
#
# LICENSE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
########################################################################
import asyncio

import aioxmpp
import aioxmpp.xso as xso
import aioxmpp.service as service

from aioxmpp.utils import namespaces

from . import xso as vcard_xso


class VCardService(service.Service):
"""
Service for handling vcard-temp.
.. automethod:: get_vcard
.. automethod:: set_vcard
"""

@asyncio.coroutine
def get_vcard(self, jid=None):
"""
Get the vCard stored for the bare jid `jid`. If `jid` is
:data:`None` get the vCard of the connected entity.
:param jid: the object to retrieve.
:returns: the stored vCard.
We mask a :class:`XMPPCancelError` in case it is
``feature-not-implemented`` or ``item-not-found`` and return
an empty vCard, since this can be understood to be semantically
equivalent.
"""
if not (jid is None or jid.is_bare):
raise ValueError("JID must be None or bare")

iq = aioxmpp.IQ(
type_=aioxmpp.IQType.GET,
to=jid,
payload=vcard_xso.VCard(),
)

try:
return (yield from self.client.stream.send(iq))
except aioxmpp.XMPPCancelError as e:
if e.condition in (
(namespaces.stanzas, "feature-not-implemented"),
(namespaces.stanzas, "item-not-found")):
return vcard_xso.VCard()
else:
raise

@asyncio.coroutine
def set_vcard(self, vcard):
"""
Store the vCard `vcard` for the connected entity.
:param vcard: the vCard to store.
.. note::
`vcard` should always be derived from the result of
`get_vcard` to preserve the elements of the vcard the
client does not modify.
.. warning::
It is in the responsibility of the user to supply valid
vcard data as per :xep:`0054`.
"""
iq = aioxmpp.IQ(
type_=aioxmpp.IQType.SET,
payload=vcard,
)
yield from self.client.stream.send(iq)
41 changes: 41 additions & 0 deletions aioxmpp/vcard/xso.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
########################################################################
# File name: xso.py
# This file is part of: aioxmpp
#
# LICENSE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
########################################################################
import aioxmpp
import aioxmpp.xso as xso

from aioxmpp.utils import namespaces

namespaces.xep0054 = "vcard-temp"

@aioxmpp.IQ.as_payload_class
class VCard(xso.XSO):
"""
The container for vCard data as per :xep:`vcard-temp <54>`.
.. attribute:: elements
The raw elements of the vCard (as etree).
"""

TAG = (namespaces.xep0054, "vCard")

elements = xso.Collector()
1 change: 1 addition & 0 deletions docs/api/public/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ functionality or provide backwards compatibility.
rfc3921
rsm
shim
vcard


Less common and helper classes
Expand Down
1 change: 1 addition & 0 deletions docs/api/public/vcard.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. automodule:: aioxmpp.vcard
18 changes: 18 additions & 0 deletions examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,21 @@ operations:
--set-avatar AVATAR_FILE
set the avatar to content of the supplied PNG file.
--wipe-avatar set the avatar to no avatar.

`get_vcard.py`
==============

``get_vcard.py`` gets the vCard for a remote JID.

Additional optional argument:

--remote-jid REMOTE_JID
the jid of which to retrieve the avatar

The remote JID may also be supplied in the examples config file::

[vcard]
remote_jid=foo@example.com

If the remote JID is not given on the command line and also missing
from the config file ``get_vcard.py`` will prompt for it.
83 changes: 83 additions & 0 deletions examples/get_vcard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
########################################################################
# File name: get_vcard.py
# This file is part of: aioxmpp
#
# LICENSE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
########################################################################

import asyncio

import lxml

import aioxmpp
import aioxmpp.vcard as vcard

from framework import Example, exec_example


class VCard(Example):
def prepare_argparse(self):
super().prepare_argparse()

# this gives a nicer name in argparse errors
def jid(s):
return aioxmpp.JID.fromstr(s)

self.argparse.add_argument(
"--remote-jid",
type=jid,
help="the jid of which to retrieve the avatar"
)

def configure(self):
super().configure()

self.remote_jid = self.args.remote_jid
if self.remote_jid is None:
try:
self.remote_jid = aioxmpp.JID.fromstr(
self.config.get("vcard", "remote_jid")
)
except (configparser.NoSectionError,
configparser.NoOptionError):
self.remote_jid = aioxmpp.JID.fromstr(
input("Remote JID> ")
)

def make_simple_client(self):
client = super().make_simple_client()
self.vcard = client.summon(aioxmpp.vcard.VCardService)
return client

@asyncio.coroutine
def run_simple_example(self):
vcard = yield from self.vcard.get_vcard(
self.remote_jid
)

for element in vcard.elements:
es = lxml.etree.tostring(element, pretty_print=True,
encoding="utf-8")
print(es.decode("utf-8"))

@asyncio.coroutine
def run_example(self):
yield from super().run_example()

if __name__ == "__main__":
exec_example(VCard())
21 changes: 21 additions & 0 deletions tests/vcard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
########################################################################
# File name: __init__.py
# This file is part of: aioxmpp
#
# LICENSE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
########################################################################

0 comments on commit 95c0a64

Please sign in to comment.