예제 #1
0
파일: xso.py 프로젝트: migarbo1/SpyAgent
class Info(xso.XSO):
    """
    An info node specifying avatar metadata for a specific MIME type.

    .. attribute:: id_

       The SHA1 of the avatar image data.

    .. attribute:: mime_type

       The MIME type of the avatar image.

    .. attribute:: nbytes

       The size of the image data in bytes.

    .. attribute:: width

       The width of the image in pixels. Defaults to :data:`None`.

    .. attribute:: height

       The height of the image in pixels. Defaults to :data:`None`.

    .. attribute:: url

       The URL of the image. Defaults to :data:`None`.
    """
    TAG = (namespaces.xep0084_metadata, "info")

    id_ = xso.Attr(tag="id", type_=xso.String())
    mime_type = xso.Attr(tag="type", type_=xso.String())
    nbytes = xso.Attr(tag="bytes", type_=xso.Integer())
    width = xso.Attr(tag="width", type_=xso.Integer(), default=None)
    height = xso.Attr(tag="height", type_=xso.Integer(), default=None)
    url = xso.Attr(tag="url", type_=xso.String(), default=None)

    def __init__(self,
                 id_,
                 mime_type,
                 nbytes,
                 width=None,
                 height=None,
                 url=None):
        self.id_ = id_
        self.mime_type = mime_type
        self.nbytes = nbytes
        self.width = width
        self.height = height
        self.url = url
예제 #2
0
 def test_format_works_with_actual_enums(self):
     e = xso.EnumType(self.SomeEnum, xso.Integer())
     for enum_value in self.SomeEnum:
         self.assertEqual(
             e.format(enum_value),
             str(enum_value.value),
         )
예제 #3
0
class First(_RangeLimitBase):
    """
    .. attribute:: value

       Identifier of the first element in the result set.

    .. attribute:: index

       Approximate index of the first element in the result set.

       Can be used with :attr:`ResultSetMetadata.index` and
       :meth:`ResultSetMetadata.fetch_page` to approximately re-retrieve the
       page.

       .. seealso::

          :meth:`~ResultSetMetadata.fetch_page`
             for hints on caveats and inaccuracies
    """

    TAG = namespaces.xep0059_rsm, "first"

    index = xso.Attr(
        "index",
        type_=xso.Integer(),
        default=None,
    )
예제 #4
0
class Items(xso.XSO):
    TAG = (namespaces.xep0060, "items")

    max_items = xso.Attr(
        (None, "max_items"),
        type_=xso.Integer(),
        validator=xso.NumericRange(min_=1),
        default=None,
    )

    node = xso.Attr(
        "node",
    )

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

    items = xso.ChildList(
        [Item]
    )

    def __init__(self, node, subid=None, max_items=None):
        super().__init__()
        self.node = node
        self.subid = subid
        self.max_items = max_items
예제 #5
0
 def test_parse_works_with_actual_enum(self):
     e = xso.EnumType(self.SomeEnum, xso.Integer())
     for enum_value in self.SomeEnum:
         self.assertEqual(
             e.parse(str(enum_value.value)),
             enum_value,
         )
예제 #6
0
class Status(xso.XSO):
    TAG = (namespaces.xep0045_muc_user, "status")

    code = xso.Attr("code", type_=xso.Integer())

    def __init__(self, code):
        super().__init__()
        self.code = code
예제 #7
0
    def test_accept_unknown_by_default(self):
        enum_class = self.SomeEnum
        e = xso.EnumType(
            enum_class,
            xso.Integer(),
        )

        value = e.coerce(xso.Unknown(10))
        self.assertIsInstance(value, xso.Unknown)
        self.assertEqual(xso.Unknown(10), value)
예제 #8
0
    def test_allow_unknown_by_default(self):
        enum_class = self.SomeEnum
        e = xso.EnumType(
            enum_class,
            xso.Integer(),
        )

        value = e.parse("10")
        self.assertIsInstance(value, xso.Unknown)
        self.assertEqual(xso.Unknown(10), value)
예제 #9
0
    def test_allow_unknown_can_be_turned_off(self):
        enum_class = self.SomeEnum
        e = xso.EnumType(
            enum_class,
            xso.Integer(),
            allow_unknown=False,
        )

        with self.assertRaisesRegex(ValueError, r"10 is not a valid SomeEnum"):
            e.parse(10)
예제 #10
0
    def test_accept_unknown_can_be_turned_off(self):
        enum_class = self.SomeEnum
        e = xso.EnumType(
            enum_class,
            xso.Integer(),
            accept_unknown=False,
        )

        with self.assertRaisesRegex(TypeError,
                                    r"not a valid .* value: <Unknown: 10>"):
            e.coerce(xso.Unknown(10))
예제 #11
0
class Data(xso.XSO):
    TAG = (namespaces.xep0047, "data")

    seq = xso.Attr("seq", type_=xso.Integer())
    sid = xso.Attr("sid", type_=xso.String())
    content = xso.Text(type_=xso.Base64Binary())

    def __init__(self, sid, seq, content):
        self.seq = seq
        self.sid = sid
        self.content = content
예제 #12
0
    def test_format_works_with_unknown(self):
        enum_class = self.SomeEnum
        e = xso.EnumType(
            enum_class,
            xso.Integer(),
        )

        self.assertEqual(
            e.format(xso.Unknown(10)),
            "10",
        )
예제 #13
0
    def test_coerce_requires_integral_number(self):
        t = xso.Integer()

        values = [
            1.2, "1",
            decimal.Decimal("1"),
            fractions.Fraction(1, 1), "foo", [], (), 1.
        ]

        for value in values:
            with self.assertRaisesRegex(TypeError, "must be integral number"):
                t.coerce(value)
예제 #14
0
    def test_coerce_passes_integral_numbers(self):
        t = xso.Integer()

        values = [-2, 0, 1, 2, 3, 4, 100]

        for value in values:
            self.assertIs(value, t.coerce(value))

        import random
        value = random.randint(1, 1e10)
        self.assertIs(value, t.coerce(value))
        value = -value
        self.assertIs(value, t.coerce(value))
예제 #15
0
class Open(xso.XSO):
    TAG = (namespaces.xep0047, "open")

    block_size = xso.Attr("block-size", type_=xso.Integer())

    # XXX: sid should be restricted to NMTOKEN
    sid = xso.Attr("sid", type_=xso.String())

    stanza = xso.Attr(
        "stanza",
        type_=xso.EnumCDataType(IBBStanzaType),
        default=IBBStanzaType.IQ,
    )
예제 #16
0
class History(xso.XSO):
    TAG = (namespaces.xep0045_muc, "history")

    maxchars = xso.Attr(
        "maxchars",
        type_=xso.Integer(),
        default=None,
    )

    maxstanzas = xso.Attr(
        "maxstanzas",
        type_=xso.Integer(),
        default=None,
    )

    seconds = xso.Attr(
        "seconds",
        type_=xso.Integer(),
        default=None,
    )

    since = xso.Attr(
        "since",
        type_=xso.DateTime(),
        default=None,
    )

    def __init__(self,
                 *,
                 maxchars=None,
                 maxstanzas=None,
                 seconds=None,
                 since=None):
        super().__init__()
        self.maxchars = maxchars
        self.maxstanzas = maxstanzas
        self.seconds = seconds
        self.since = since
예제 #17
0
class Status(xso.XSO):
    TAG = (namespaces.xep0045_muc_user, "status")

    code = xso.Attr("code",
                    type_=xso.EnumCDataType(
                        StatusCode,
                        xso.Integer(),
                        allow_coerce=True,
                        pass_unknown=True,
                    ))

    def __init__(self, code):
        super().__init__()
        self.code = code
예제 #18
0
 def test_parse_failure(self):
     t = xso.Integer()
     with self.assertRaises(ValueError):
         t.parse("123f")
예제 #19
0
 def test_is_abstract_type(self):
     self.assertIsInstance(xso.Integer(), xso.AbstractType)
예제 #20
0
 def test_parse(self):
     t = xso.Integer()
     self.assertEqual(123, t.parse("123"))
예제 #21
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
예제 #22
0
class Pointer(xso.XSO):
    """
    A pointer metadata node. The contents are implementation defined.

    The following attributes may be present (they default to
    :data:`None`):

    .. attribute:: id_

       The SHA1 of the avatar image data.

    .. attribute:: mime_type

       The MIME type of the avatar image.

    .. attribute:: nbytes

       The size of the image data in bytes.

    .. attribute:: width

       The width of the image in pixels.

    .. attribute:: height

       The height of the image in pixels.
    """
    TAG = (namespaces.xep0084_metadata, "pointer")

    # according to the XEP those MAY occur if their values are known
    id_ = xso.Attr(tag="id", type_=xso.String(), default=None)
    mime_type = xso.Attr(tag="type", type_=xso.String(), default=None)
    nbytes = xso.Attr(tag="bytes", type_=xso.Integer(), default=None)
    width = xso.Attr(tag="width", type_=xso.Integer(), default=None)
    height = xso.Attr(tag="height", type_=xso.Integer(), default=None)

    registered_payload = xso.Child([])
    unregistered_payload = xso.Collector()

    @classmethod
    def as_payload_class(mycls, cls):
        """
        Register the given class `cls` as possible payload for a
        :class:`Pointer`.

        Return the class, to allow this to be used as decorator.
        """

        mycls.register_child(
            Pointer.registered_payload,
            cls
        )

        return cls

    def __init__(self, payload, id_, mime_type, nbytes, width=None,
                 height=None, url=None):
        self.registered_payload = payload

        self.id_ = id_
        self.mime_type = mime_type
        self.nbytes = nbytes
        self.width = width
        self.height = height
예제 #23
0
 def test_format(self):
     t = xso.Integer()
     self.assertEqual("123", t.format(123))