예제 #1
0
    def handle_iq(self, iq, payload):
        if not iq.with_attrs("from", type="set"):
            return False
        jid = JID(iq.get_attr("from"))
        if jid.bare() != self.room.jid.bare():
            return False
        if not payload.named("start").with_attrs("id"):
            return False

        service_id = payload.get_attr("id")
        self._start(iq, jid, service_id, payload)
        return True
예제 #2
0
    def _run(self):
        with self.xmpp.core.iq_handler(self.handle_iq, "start", SERVICE_NS):
            while True:
                elements = yield idiokit.next()

                for message in elements.named("message").with_attrs("from"):
                    for end in message.children("end", SERVICE_NS).with_attrs("id"):
                        jid = JID(message.get_attr("from"))
                        session_id = end.get_attr("id")
                        self._discard_session(jid, session_id)

                presences = elements.named("presence").with_attrs("from")
                for presence in presences:
                    jid = JID(presence.get_attr("from"))
                    if presence.with_attrs(type="unavailable"):
                        self._discard_jid(jid, Unavailable())
                    else:
                        self._update_catalogue(jid, presence.children())
예제 #3
0
def _encode_room_jid(jid):
    r"""
    Return a sanitized and normalized path name for a bare room JID.

    The a argument should be a unicode string, a byte string or an
    idiokit.xmpp.jid.JID instance.

    >>> _encode_room_jid(u"*****@*****.**")
    '*****@*****.**'

    >>> _encode_room_jid(u"*****@*****.**")
    '*****@*****.**'

    >>> _encode_room_jid(JID("*****@*****.**"))
    '*****@*****.**'

    The argument should be a "bare JID", i.e. contain only the node@domain
    part. Otherwise a ValueError will get raised.

    >>> _encode_room_jid("[email protected]/resource")
    Traceback (most recent call last):
        ...
    ValueError: given room JID does not match with the bare room JID

    Byte strings will be first converted to unicode with the default "ascii"
    encoding. UnicodeDecodeError will be raised on failure.

    >>> _encode_room_jid(u"room.caf\[email protected]")
    '*****@*****.**'

    >>> _encode_room_jid("room.caf\[email protected]")
    Traceback (most recent call last):
        ...
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 8: ordinal not in range(128)
    """

    room_jid = JID(jid)

    if room_jid != room_jid.bare():
        raise ValueError("given room JID does not match with the bare room JID")

    return urllib.quote(unicode(room_jid).encode("utf-8"), safe=" @")
예제 #4
0
    def xmpp_to_log(self, own_jid, participants):
        in_room = set()
        for participant in participants:
            in_room.add(participant.name.resource)

        while True:
            elements = yield idiokit.next()

            for message in elements.with_attrs("from"):
                sender = JID(elements.get_attr("from"))
                if sender == own_jid or sender.resource is None:
                    continue

                resource = sender.resource.encode("unicode-escape")
                bare = unicode(sender.bare()).encode("unicode-escape")

                type_ = message.get_attr("type", None)
                if type_ == "unavailable":
                    if sender.resource in in_room:
                        in_room.discard(sender.resource)
                        self.log.info("* {0} left the room {1}.".format(
                            resource, bare))
                else:
                    if sender.resource not in in_room:
                        in_room.add(sender.resource)
                        self.log.info("* {0} entered the room {1}.".format(
                            resource, bare))

                for body in message.children("body"):
                    self.log.info("<{0}> {1}".format(
                        unicode(sender).encode("unicode-escape"),
                        body.text.encode("unicode-escape")))

                if self.show_events:
                    for event in events.Event.from_elements(message):
                        self.log.info("<{0}> {1}".format(
                            unicode(sender).encode("unicode-escape"),
                            event))
예제 #5
0
    def parse(self, db):
        queries = QuerySet()

        while True:
            next = idiokit.next()
            if queries:
                idiokit.pipe(self._timeout(0.0), next)

            try:
                elements = yield next
            except Timeout:
                pass
            else:
                for element in elements.with_attrs("from"):
                    sender = JID(element.get_attr("from"))

                    if element.named("presence").with_attrs(
                            type="unavailable"):
                        db.purge_jid(sender)
                        queries.discard_jid(sender)

                    for message in element.named("message"):
                        if not message.with_attrs(type="groupchat"):
                            continue

                        for event in events.Event.from_elements(message):
                            db.add_event(sender, event)

                    for query in element.named("message").children(ns=NS):
                        try:
                            args = json.loads(query.text)
                        except JSONDecodeError:
                            self.log.error("Invalid query data from %r: %r",
                                           sender, query.text)
                            continue

                        if "id" not in args:
                            self.log.error("Query without an ID from %r: %r",
                                           sender, args)
                            continue
                        id = args.get("id")

                        if query.named("start"):
                            start = args.get("start", None)
                            end = args.get("end", None)
                            queries.start(sender, id, db.query(start, end))
                            self.log.info("Start from %r: %r", sender, args)
                        elif query.named("load"):
                            if "size" in args:
                                queries.load(sender, id, args.get("size"))
                                self.log.debug("Load from %r: %r", sender,
                                               args)
                            else:
                                self.log.error(
                                    "Load without an ID from %r: %r", sender,
                                    args)
                        elif query.named("histogram"):
                            start = args.get("start", None)
                            end = args.get("end", None)
                            step = args.get("step", None)
                            if None not in (start, end, step):
                                element = db.histogram(id, start, end, step)
                                self.xmpp.core.message(sender, element)
                                self.log.debug("Histogram from %r: %r", sender,
                                               args)
                        elif query.named("cancel"):
                            queries.cancel(sender, id)
                            self.log.info("Cancel from %r: %r", sender, args)

            for sender, element in queries:
                yield self.xmpp.core.message(sender, element)