Esempio n. 1
0
class Conference(Bookmark):
    """
    An bookmark for a groupchat.

    .. attribute:: name

       The name of the bookmark.

    .. attribute:: jid

       The jid under which the groupchat is accessible.

    .. attribute:: autojoin

       Whether to join automatically, when the client starts.

    .. attribute:: nick

       The nick to use in the groupchat.

    .. attribute:: password

       The password used to access the groupchat.
    """

    TAG = (namespaces.xep0048, "conference")

    autojoin = xso.Attr(tag="autojoin", type_=xso.Bool(), default=False)
    jid = xso.Attr(tag="jid", type_=xso.JID())
    name = xso.Attr(tag="name", type_=xso.String(), default=None)

    nick = xso.ChildText(
        (namespaces.xep0048, "nick"),
        default=None
    )
    password = xso.ChildText(
        (namespaces.xep0048, "password"),
        default=None
    )

    def __init__(self, name, jid, *, autojoin=False, nick=None, password=None):
        self.autojoin = autojoin
        self.jid = jid
        self.name = name
        self.nick = nick
        self.password = password

    def __repr__(self):
        return "Conference({!r}, {!r}, autojoin={!r}, " \
            "nick={!r}, password{!r})".\
            format(self.name, self.jid, self.autojoin, self.nick,
                   self.password)

    @property
    def primary(self):
        return self.jid

    @property
    def secondary(self):
        return (self.name, self.nick, self.password, self.autojoin)
Esempio n. 2
0
class Query(xso.XSO):
    """
    :xep:`92` Software Version query :class:`~aioxmpp.xso.XSO`.

    .. attribute:: name

        Software name as string. May be :data:`None`.

    .. attribute:: version

        Software version as string. May be :data:`None`.

    .. attribute:: os

        Operating system as string. May be :data:`None`.
    """

    TAG = namespaces.xep0092_version, "query"

    version = xso.ChildText(
        (namespaces.xep0092_version, "version"),
        default=None,
    )

    name = xso.ChildText(
        (namespaces.xep0092_version, "name"),
        default=None,
    )

    os = xso.ChildText(
        (namespaces.xep0092_version, "os"),
        default=None,
    )
Esempio n. 3
0
class DestroyRequest(xso.XSO):
    TAG = (namespaces.xep0045_muc_owner, "destroy")

    reason = xso.ChildText((namespaces.xep0045_muc_owner, "reason"),
                           default=None)

    password = xso.ChildText((namespaces.xep0045_muc_owner, "password"),
                             default=None)

    jid = xso.Attr("jid", type_=xso.JID(), default=None)
Esempio n. 4
0
class Invite(xso.XSO):
    TAG = (namespaces.xep0045_muc_user, "invite")

    from_ = xso.Attr("from", type_=xso.JID(), default=None)

    to = xso.Attr("to", type_=xso.JID(), default=None)

    reason = xso.ChildText((namespaces.xep0045_muc_user, "reason"),
                           default=None)

    password = xso.ChildText((namespaces.xep0045_muc_user, "password"),
                             default=None)
Esempio n. 5
0
class UserExt(xso.XSO):
    TAG = (namespaces.xep0045_muc_user, "x")

    status_codes = xso.ChildValueList(StatusCodeList(), container_type=set)

    destroy = xso.Child([DestroyNotification])

    decline = xso.Child([Decline])

    invites = xso.ChildList([Invite])

    items = xso.ChildList([UserItem])

    password = xso.ChildText((namespaces.xep0045_muc_user, "password"),
                             default=None)

    def __init__(self,
                 status_codes=[],
                 destroy=None,
                 decline=None,
                 invites=[],
                 items=[],
                 password=None):
        super().__init__()
        self.status_codes.update(status_codes)
        self.destroy = destroy
        self.decline = decline
        self.invites.extend(invites)
        self.items.extend(items)
        self.password = password
Esempio n. 6
0
class GenericExt(xso.XSO):
    TAG = (namespaces.xep0045_muc, "x")

    history = xso.Child([History])

    password = xso.ChildText((namespaces.xep0045_muc, "password"),
                             default=None)
Esempio n. 7
0
class DestroyNotification(xso.XSO):
    TAG = (namespaces.xep0045_muc_user, "destroy")

    reason = xso.ChildText((namespaces.xep0045_muc_user, "reason"),
                           default=None)

    jid = xso.Attr("jid", type_=xso.JID(), default=None)
class Query(xso.XSO):
    TAG = (namespace, "query")

    name = xso.ChildText(
        (namespace, "name"),
        default=None,
    )

    version = xso.ChildText(
        (namespace, "version"),
        default=None,
    )

    os = xso.ChildText(
        (namespace, "os"),
        default=None,
    )
Esempio n. 9
0
class Conference(xso.XSO):
    """
    An bookmark for a groupchat.

    .. attribute:: name

       The name of the bookmark.

    .. attribute:: jid

       The jid under which the groupchat is accessible.

    .. attribute:: autojoin

       Whether to join automatically, when the client starts.

    .. attribute:: nick

       The nick to use in the groupchat.

    .. attribute:: password

       The password used to access the groupchat.
    """

    TAG = (namespaces.xep0048, "conference")

    autojoin = xso.Attr(tag="autojoin", type_=xso.Bool(), default=False)
    jid = xso.Attr(tag="jid", type_=xso.JID())
    name = xso.Attr(tag="name", type_=xso.String(), default=None)

    nick = xso.ChildText((namespaces.xep0048, "nick"), default=None)
    password = xso.ChildText((namespaces.xep0048, "password"), default=None)

    def __init__(self, name, jid, *, autojoin=False, nick=None, password=None):
        self.autojoin = autojoin
        self.jid = jid
        self.name = name
        self.nick = nick
        self.password = password

    def __eq__(self, other):
        return (isinstance(other, Conference) and other.name == self.name
                and other.jid == self.jid and other.autojoin == self.autojoin
                and other.name == self.name
                and other.password == self.password)
Esempio n. 10
0
class Decline(xso.XSO):
    TAG = (namespaces.xep0045_muc_user, "decline")

    from_ = xso.Attr("from", type_=xso.JID(), default=None)

    to = xso.Attr("to", type_=xso.JID(), default=None)

    reason = xso.ChildText((namespaces.xep0045_muc_user, "reason"),
                           default=None)
Esempio n. 11
0
class AdminItem(ItemBase):
    TAG = (namespaces.xep0045_muc_admin, "item")

    actor = xso.Child([AdminActor])

    continue_ = xso.Child([Continue])

    reason = xso.ChildText((namespaces.xep0045_muc_admin, "reason"),
                           default=None)
Esempio n. 12
0
class UserItem(ItemBase):
    TAG = (namespaces.xep0045_muc_user, "item")

    actor = xso.Child([UserActor])

    continue_ = xso.Child([Continue])

    reason = xso.ChildText((namespaces.xep0045_muc_user, "reason"),
                           default=None)
Esempio n. 13
0
class VCardTempUpdate(xso.XSO):
    """
    The vcard update notify element as per :xep:`0153`
    """

    TAG = (namespaces.xep0153, "x")

    def __init__(self, photo=None):
        self.photo = photo

    photo = xso.ChildText((namespaces.xep0153, "photo"),
                          type_=xso.String(),
                          default=None)
Esempio n. 14
0
class Option(xso.XSO):
    TAG = (namespaces.xep0004_data, "option")

    label = xso.Attr(
        tag="label",
        default=None,
    )

    value = xso.ChildText(
        (namespaces.xep0004_data, "value"),
        default=None,
    )

    def validate(self):
        if self.value is None:
            raise ValueError("option is missing a value")
Esempio n. 15
0
class Data(AbstractItem):
    """
    A :xep:`4` ``x`` element, that is, a Data Form.

    :param type_: Initial value for the :attr:`type_` attribute.

    .. attribute:: type_

       The ``type`` attribute of the form, represented by one of the members of
       the :class:`DataType` enumeration.

    .. attribute:: title

       The (optional) title of the form. Either a :class:`str` or :data:`None`.

    .. attribute:: instructions

       A sequence of strings which represent the instructions elements on the
       form.

    .. attribute:: fields

       If the :class:`Data` is a form, this is a sequence of :class:`Field`
       elements which represent the fields to be filled in.

       This does not make sense on :attr:`.DataType.RESULT` typed objects.

    .. attribute:: items

       If the :class:`Data` is a table, this is a sequence of :class:`Item`
       instances which represent the table rows.

       This only makes sense on :attr:`.DataType.RESULT` typed objects.

    .. attribute:: reported

       If the :class:`Data` is a table, this is a :class:`Reported` object
       representing the table header.

       This only makes sense on :attr:`.DataType.RESULT` typed objects.

    .. automethod:: get_form_type
    """

    TAG = (namespaces.xep0004_data, "x")

    type_ = xso.Attr("type", type_=xso.EnumCDataType(DataType))

    title = xso.ChildText(
        (namespaces.xep0004_data, "title"),
        default=None,
    )

    instructions = xso.ChildValueList(type_=InstructionsElement())

    items = xso.ChildList([Item])

    reported = xso.Child([Reported], required=False)

    def __init__(self, type_):
        super().__init__()
        self.type_ = type_

    def _validate_result(self):
        if self.fields:
            raise ValueError("field in report result")

        fieldvars = {field.var for field in self.reported.fields}

        if not fieldvars:
            raise ValueError("empty report header")

        for item in self.items:
            itemvars = {field.var for field in item.fields}
            if itemvars != fieldvars:
                raise ValueError("field mismatch between row and header")

    def validate(self):
        super().validate()

        if (self.type_ != DataType.RESULT
                and (self.reported is not None or self.items)):
            raise ValueError("report in non-result")

        if (self.type_ == DataType.RESULT
                and (self.reported is not None or self.items)):
            self._validate_result()

    def get_form_type(self):
        """
        Extract the ``FORM_TYPE`` from the fields.

        :return: ``FORM_TYPE`` value or :data:`None`
        :rtype: :class:`str` or :data:`None`

        Return :data:`None` if no well-formed ``FORM_TYPE`` field is found in
        the list of fields.

        .. versionadded:: 0.8
        """

        for field in self.fields:
            if field.var == "FORM_TYPE" and field.type_ == FieldType.HIDDEN:
                if len(field.values) != 1:
                    return None
                return field.values[0]
Esempio n. 16
0
class Field(xso.XSO):
    """
    Represent a single field in a Data Form.

    :param type_: Field type, must be one of the valid field types specified in
                  :xep:`4`.
    :type type_: :class:`FieldType`
    :param options: A mapping of values to labels defining the options in a
                    ``list-*`` field.
    :type options: :class:`dict` mapping :class:`str` to :class:`str`
    :param values: A sequence of values currently given for the field. Having
                   more than one value is only valid in ``*-multi`` fields.
    :type values: :class:`list` of :class:`str`
    :param desc: Description which can be shown in a tool-tip or similar,
                 without newlines.
    :type desc: :class:`str` or :data:`None`s
    :param label: Human-readable label to be shown next to the field input
    :type label: :class:`str` or :data:`None`
    :param required: Flag to indicate that the field is required
    :type required: :class:`bool`
    :param var: "ID" identifying the field uniquely inside the form. Only
                required for fields carrying a meaning (thus, not for
                ``fixed``).
    :type var: :class:`str` or :data:`None`

    The semantics of a :class:`Field` are different depending on where it
    occurs: in a :class:`Data`, it is a form field to be filled in, in a
    :class:`Item` it is a cell of a row and in a :class:`Reported` it
    represents a column header.

    .. attribute:: required

       A boolean flag indicating whether the field is required.

       If true, the XML serialisation will contain the corresponding
       ``<required/>`` tag.

    .. attribute:: desc

       Single line of description for the field. This attribute represents the
       ``<desc/>`` element from :xep:`4`.

    .. attribute:: values

       A sequence of strings representing the ``<value/>`` elements of the
       field, one string for each value.

       .. note::

          Since the requirements on the sequence of strings in :attr:`values`
          change depending on the :attr:`type_` attribute, validation and type
          conversion on assignment is very lax. The attribute accepts all
          sequences of strings, even if the field is for example a
          :attr:`FieldType.BOOLEAN` field, which allows for at most one string
          of a well-defined format (see the documentation there for the
          details).

          This makes it easy to inadvertendly generate invalid forms, which is
          why you should be using :class:`Form` subclasses when accessing forms
          from within normal code and some other, generic mechanism taking care
          of these details when showing forms in a UI framework to users. Note
          that devising such a mechanism is out of scope for :mod:`aioxmpp`, as
          every UI framework has different requirements.

    .. attribute:: options

       A dictionary mapping values to human-readable labels, representing the
       ``<option/>`` elements of the field.

    .. attribute:: var

       The uniquely identifying string of the (valued, that is,
       non-:attr:`FieldType.FIXED` field). Represents the ``var`` attribute of
       the field.

    .. attribute:: type_

       The type of the field. The :attr:`type_` must be a :class:`FieldType`
       enumeration value and determines restrictions and constraints on other
       attributes. See the :class:`FieldType` enumeration and :xep:`4` for
       details.

    .. attribute:: label

       The human-readable label for the field, representing the ``label``
       attribute of the field. May be :data:`None` if the label is omitted.

    """

    TAG = (namespaces.xep0004_data, "field")

    required = xso.ChildFlag((namespaces.xep0004_data, "required"), )

    desc = xso.ChildText((namespaces.xep0004_data, "desc"), default=None)

    values = xso.ChildValueList(type_=ValueElement())

    options = xso.ChildValueMap(
        type_=OptionElement(),
        mapping_type=collections.OrderedDict,
    )

    var = xso.Attr((None, "var"), default=None)

    type_ = xso.Attr(
        (None, "type"),
        type_=xso.EnumCDataType(FieldType, ),
        default=FieldType.TEXT_SINGLE,
    )

    label = xso.Attr((None, "label"), default=None)

    def __init__(self,
                 *,
                 type_=FieldType.TEXT_SINGLE,
                 options={},
                 values=[],
                 desc=None,
                 label=None,
                 required=False,
                 var=None):
        super().__init__()
        self.type_ = type_
        self.options.update(options)
        self.values[:] = values
        self.desc = desc
        self.label = label
        self.required = required
        self.var = var

    def validate(self):
        super().validate()

        if self.type_ != FieldType.FIXED and not self.var:
            raise ValueError("missing attribute var")

        if not self.type_.has_options and self.options:
            raise ValueError("unexpected option on non-list field")

        if not self.type_.is_multivalued and len(self.values) > 1:
            raise ValueError("too many values on non-multi field")

        values_list = [opt for opt in self.options.values()]
        values_set = set(values_list)

        if len(values_list) != len(values_set):
            raise ValueError("duplicate option value")
Esempio n. 17
0
class Field(xso.XSO):
    TAG = (namespaces.xep0004_data, "field")

    required = xso.ChildTag(
        tags=[
            (namespaces.xep0004_data, "required"),
        ],
        allow_none=True)

    desc = xso.ChildText(
        (namespaces.xep0004_data, "desc"),
        default=None
    )

    values = xso.ChildValueList(
        type_=ValueElement()
    )

    options = xso.ChildValueMap(
        type_=OptionElement()
    )

    var = xso.Attr(
        (None, "var"),
        default=None
    )

    type_ = xso.Attr(
        (None, "type"),
        validator=xso.RestrictToSet([
            "boolean",
            "fixed",
            "hidden",
            "jid-multi",
            "jid-single",
            "list-multi",
            "list-single",
            "text-multi",
            "text-private",
            "text-single",
        ]),
        default="text-single"
    )

    label = xso.Attr(
        (None, "label"),
        default=None
    )

    def __init__(self, *,
                 type_="text-single",
                 options={},
                 values=[],
                 desc=None,
                 label=None,
                 required=False,
                 var=None):
        super().__init__()
        self.type_ = type_
        self.options.update(options)
        self.values[:] = values
        self.desc = desc
        self.label = label
        if required:
            self.required = (namespaces.xep0004_data, "required")
        self.var = var

    def validate(self):
        super().validate()

        if self.type_ != "fixed" and not self.var:
            raise ValueError("missing attribute var")

        if not self.type_.startswith("list-") and self.options:
            raise ValueError("unexpected option on non-list field")

        if not self.type_.endswith("-multi") and len(self.values) > 1:
            raise ValueError("too many values on non-multi field")

        values_list = [opt for opt in self.options.values()]
        values_set = set(values_list)

        if len(values_list) != len(values_set):
            raise ValueError("duplicate option value")
Esempio n. 18
0
class OOBExtension(xso.XSO):
    TAG = namespaces.xep0066_oob_x, "x"

    url = xso.ChildText((namespaces.xep0066_oob_x, "url"))
Esempio n. 19
0
class ResultSetMetadata(xso.XSO):
    """
    Represent the result set or query metadata.

    For requests, the following attributes are relevant:

    .. attribute:: after

       Either :data:`None` or a :class:`After` object.

       Generally mutually exclusive with :attr:`index`.

    .. attribute:: before

       Either :data:`None` or a :class:`Before` object.

       Generally mutually exclusive with :attr:`index`.

    .. attribute:: index

       The index of the first result to return, or :data:`None`.

       Generally mutually exclusive with :attr:`after` and :attr:`before`.

    .. attribute:: max

       The maximum number of items to return or :data:`None`.

       Setting :attr:`max` to zero will make the peer return a
       :class:`ResultSetMetadata` with the total number of items in the
       :attr:`count` field.

    These methods are useful when constructing queries:

    .. automethod:: fetch_page

    .. automethod:: limit

    .. automethod:: last_page

    For responses, the following attributes are relevant:

    .. attribute:: first

       Either :data:`None` or a :class:`First` object.

    .. attribute:: last

       Either :data:`None` or a :class:`Last` object.

    .. attribute:: count

       Either :data:`None` or the number of elements in the result set.

       If this is a response to a query with :attr:`max` set to zero, this is
       the total number of elements in the queried data.

    These methods are useful to construct a new request from a previous
    response:

    .. automethod:: next_page

    .. automethod:: previous_page
    """

    TAG = namespaces.xep0059_rsm, "set"

    after = xso.Child([After])

    before = xso.Child([Before])

    first = xso.Child([First])

    last = xso.Child([Last])

    count = xso.ChildText(
        (namespaces.xep0059_rsm, "count"),
        type_=xso.Integer(),
        default=None,
    )

    max_ = xso.ChildText(
        (namespaces.xep0059_rsm, "max"),
        type_=xso.Integer(),
        default=None,
    )

    index = xso.ChildText(
        (namespaces.xep0059_rsm, "index"),
        type_=xso.Integer(),
        default=None,
    )

    @classmethod
    def fetch_page(cls, index, max_=None):
        """
        Return a query set which requests a specific page.

        :param index: Index of the first element of the page to fetch.
        :type index: :class:`int`
        :param max_: Maximum number of elements to fetch
        :type max_: :class:`int` or :data:`None`
        :rtype: :class:`ResultSetMetadata`
        :return: A new request set up to request a page starting with the
                 element indexed by `index`.

        .. note::

           This way of retrieving items may be approximate. See :xep:`59` and
           the embedding protocol for which RSM is used for specifics.
        """

        result = cls()
        result.index = index
        result.max_ = max_
        return result

    @magicmethod
    def limit(self, max_):
        """
        Limit the result set to a given number of items.

        :param max_: Maximum number of items to return.
        :type max_: :class:`int` or :data:`None`
        :rtype: :class:`ResultSetMetadata`
        :return: A new request set up to request at most `max_` items.

        This method can be called on the class and on objects. When called on
        objects, it returns a copy of the object with :attr:`max_` set
        accordingly. When called on the class, it creates a fresh object with
        :attr:`max_` set accordingly.
        """

        if isinstance(self, type):
            result = self()
        else:
            result = copy.deepcopy(self)
        result.max_ = max_
        return result

    def next_page(self, max_=None):
        """
        Return a query set which requests the page after this response.

        :param max_: Maximum number of items to return.
        :type max_: :class:`int` or :data:`None`
        :rtype: :class:`ResultSetMetadata`
        :return: A new request set up to request the next page.

        Must be called on a result set which has :attr:`last` set.
        """

        result = type(self)()
        result.after = After(self.last.value)
        result.max_ = max_
        return result

    def previous_page(self, max_=None):
        """
        Return a query set which requests the page before this response.

        :param max_: Maximum number of items to return.
        :type max_: :class:`int` or :data:`None`
        :rtype: :class:`ResultSetMetadata`
        :return: A new request set up to request the previous page.

        Must be called on a result set which has :attr:`first` set.
        """

        result = type(self)()
        result.before = Before(self.first.value)
        result.max_ = max_
        return result

    @classmethod
    def last_page(self_or_cls, max_=None):
        """
        Return a query set which requests the last page.

        :param max_: Maximum number of items to return.
        :type max_: :class:`int` or :data:`None`
        :rtype: :class:`ResultSetMetadata`
        :return: A new request set up to request the last page.
        """
        result = self_or_cls()
        result.before = Before()
        result.max_ = max_
        return result
Esempio n. 20
0
class Query(xso.XSO):
    """
    :xep:`077` In-Band Registraion query :class:`~aioxmpp.xso.XSO`.

    It has the following fields described in the XEP document:

    .. attribute:: username

    .. attribute:: nick

    .. attribute:: password

    .. attribute:: name

    .. attribute:: first

    .. attribute:: last

    .. attribute:: email

    .. attribute:: address

    .. attribute:: city

    .. attribute:: state

    .. attribute:: zip

    .. attribute:: phone

    .. attribute:: url

    .. attribute:: date

    .. attribute:: misc

    .. attribute:: text

    .. attribute:: key

    .. attribute:: registered

    .. attribute:: remove
    """

    TAG = (namespaces.xep0077_in_band, "query")
    username = xso.ChildText(
        (namespaces.xep0077_in_band, "username"),
        default=None,
    )

    instructions = xso.ChildText(
        (namespaces.xep0077_in_band, "instructions"),
        default=None,
    )

    nick = xso.ChildText(
        (namespaces.xep0077_in_band, "nick"),
        default=None,
    )

    password = xso.ChildText(
        (namespaces.xep0077_in_band, "password"),
        default=None,
    )

    name = xso.ChildText(
        (namespaces.xep0077_in_band, "name"),
        default=None,
    )

    first = xso.ChildText(
        (namespaces.xep0077_in_band, "first"),
        default=None,
    )

    last = xso.ChildText(
        (namespaces.xep0077_in_band, "last"),
        default=None,
    )

    email = xso.ChildText(
        (namespaces.xep0077_in_band, "email"),
        default=None,
    )

    address = xso.ChildText(
        (namespaces.xep0077_in_band, "address"),
        default=None,
    )

    city = xso.ChildText(
        (namespaces.xep0077_in_band, "city"),
        default=None,
    )

    state = xso.ChildText(
        (namespaces.xep0077_in_band, "state"),
        default=None,
    )

    zip = xso.ChildText(
        (namespaces.xep0077_in_band, "zip"),
        default=None,
    )

    phone = xso.ChildText(
        (namespaces.xep0077_in_band, "phone"),
        default=None,
    )

    url = xso.ChildText(
        (namespaces.xep0077_in_band, "url"),
        default=None,
    )

    date = xso.ChildText(
        (namespaces.xep0077_in_band, "date"),
        default=None,
    )

    misc = xso.ChildText(
        (namespaces.xep0077_in_band, "misc"),
        default=None,
    )

    text = xso.ChildText(
        (namespaces.xep0077_in_band, "text"),
        default=None,
    )

    key = xso.ChildText(
        (namespaces.xep0077_in_band, "key"),
        default=None,
    )

    registered = xso.ChildFlag((namespaces.xep0077_in_band, "registered"))

    remove = xso.ChildFlag((namespaces.xep0077_in_band, "remove"))

    def __init__(self, username=None, password=None, aux_fields=None):
        """
        Get an xso.Query object with the info provided in he parameters.

        :param username: Username of the query
        :type username: :class:`str`
        :param password: Password of the query.
        :type password: :class:`str`
        :param aux_fields: Auxiliary fields in case additional info is needed.
        :type aux_fields: :class:`dict`
        :return: :class:`xso.Query`
        """
        self.username = username
        self.password = password

        if aux_fields is not None:
            for key, value in aux_fields.items():
                setattr(self, key, value)